COM を学ぶ(4) : ProgID から CLSID を求める。

CLSID は GUID の別名として定義されています。

typedef struct _GUID {
    DWORD  Data1;      // 4バイト
    WORD   Data2;      // 2バイト
    WORD   Data3;      // 2バイト
    BYTE   Data4[8];   // 1バイト×8
} GUID;

typedef GUID  CLSID;
typedef GUID  IID;

ProgID "ADODB.Connection" から CLSID を求めてみます。
COM はマルチバイト文字列を使用しているので C の文字列からマルチバイトへ文字列の変換が必要です。

#include "stdio.h"
#include "windows.h"
#include "objbase.h"

/* gcc clsid.c -lole32 -loleaut32 -o clsid */

int main(int argc, char* argv[])
{
    char    *vstr     = "ADODB.Connection";
    int     vstrlen   = 0;
    int     out_size  = 0;
    LPWSTR  name_work;
    CLSID   clsid;
    HRESULT hr;
    BYTE    *p;

    /* LPWSTR from C string */
    vstrlen   = strlen(vstr);
    out_size  = MultiByteToWideChar(CP_ACP, 0, vstr, vstrlen, NULL, 0);
    name_work = SysAllocStringLen(NULL, out_size);
    MultiByteToWideChar(CP_ACP, 0, vstr, vstrlen, name_work, out_size);

    /* get CLSID from OLE server name */
    hr = CLSIDFromProgID(name_work, &clsid);
    printf("hr    :%08X\n",hr);

    if(FAILED(hr)) {
        hr = CLSIDFromString(name_work, &clsid);
        printf("hr :%08X\n",hr);
    }
    printf("clsid :%08X-",clsid.Data1);
    printf("%04X-",clsid.Data2);
    printf("%04X-",clsid.Data3);
    p = clsid.Data4;
    printf("%02X",*p);
    printf("%02X-",*(p+1));
    printf("%02X" ,*(p+2));
    printf("%02X" ,*(p+3));
    printf("%02X" ,*(p+4));
    printf("%02X" ,*(p+5));
    printf("%02X" ,*(p+6));
    printf("%02X\n" ,*(p+7));
    SysFreeString(name_work);

}
PS D:\lang\com\c> gcc clsid.c -lole32 -loleaut32 -o clsid
PS D:\lang\com\c> ./clsid
hr    :00000000
clsid :00000514-0000-0010-8000-00AA006D2EA4

Ruby /trunk/ext/win32ole/win32ole.c の static VALUE fole_s_connect(int argc, VALUE *argv, VALUE self) あたりを参考にしています。