24 #if defined(__CYGWIN__) || defined(__MINGW32__) 25 #undef IID_IMultiLanguage2 26 const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A}};
29 #define WIN32OLE_VERSION "1.8.6" 31 typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
32 (REFCLSID, IUnknown*,
DWORD, COSERVERINFO*,
DWORD, MULTI_QI*);
39 #if defined(RB_THREAD_SPECIFIC) && (defined(__CYGWIN__)) 41 # define g_ole_initialized_init() ((void)0) 42 # define g_ole_initialized_set(val) (g_ole_initialized = (val)) 44 static volatile DWORD g_ole_initialized_key = TLS_OUT_OF_INDEXES;
45 # define g_ole_initialized (TlsGetValue(g_ole_initialized_key)!=0) 46 # define g_ole_initialized_init() (g_ole_initialized_key = TlsAlloc()) 47 # define g_ole_initialized_set(val) TlsSetValue(g_ole_initialized_key, (void*)(val)) 50 static BOOL g_uninitialize_hooked =
FALSE;
51 static BOOL g_cp_installed =
FALSE;
52 static BOOL g_lcid_installed =
FALSE;
53 static BOOL g_running_nano =
FALSE;
54 static HINSTANCE ghhctrl =
NULL;
55 static HINSTANCE gole32 =
NULL;
56 static FNCOCREATEINSTANCEEX *gCoCreateInstanceEx =
NULL;
57 static VALUE com_hash;
58 static VALUE enc2cp_hash;
59 static IDispatchVtbl com_vtbl;
60 static UINT cWIN32OLE_cp = CP_ACP;
62 static UINT g_cp_to_check = CP_ACP;
63 static char g_lcid_to_check[8 + 1];
64 static VARTYPE g_nil_to = VT_ERROR;
65 static IMessageFilterVtbl message_filter;
66 static IMessageFilter imessage_filter = { &message_filter };
67 static IMessageFilter* previous_filter;
69 #if defined(HAVE_TYPE_IMULTILANGUAGE2) 71 #elif defined(HAVE_TYPE_IMULTILANGUAGE) 74 #define pIMultiLanguage NULL 82 static HRESULT ( STDMETHODCALLTYPE QueryInterface )(IDispatch __RPC_FAR *, REFIID
riid,
void __RPC_FAR *__RPC_FAR *
ppvObject);
83 static ULONG ( STDMETHODCALLTYPE AddRef )(IDispatch __RPC_FAR * This);
84 static ULONG ( STDMETHODCALLTYPE Release )(IDispatch __RPC_FAR * This);
85 static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )(IDispatch __RPC_FAR * This, UINT __RPC_FAR *
pctinfo);
86 static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )(IDispatch __RPC_FAR * This, UINT
iTInfo, LCID
lcid, ITypeInfo __RPC_FAR *__RPC_FAR *
ppTInfo);
89 static IDispatch* val2dispatch(
VALUE val);
90 static double rbtime2vtdate(
VALUE tmobj);
91 static VALUE vtdate2rbtime(
double date);
94 NORETURN(
static void failed_load_conv51932(
void));
95 #ifndef pIMultiLanguage 98 static UINT ole_init_cp(
void);
99 static void ole_freeexceptinfo(EXCEPINFO *pExInfo);
100 static VALUE ole_excepinfo2msg(EXCEPINFO *pExInfo);
101 static void ole_free(
void *ptr);
102 static size_t ole_size(
const void *ptr);
103 static LPWSTR ole_mb2wc(
char *pm,
int len, UINT cp);
105 static VALUE is_all_index_under(LONG *pid,
long *pub,
long dim);
106 static void * get_ptr_of_variant(VARIANT *pvar);
107 static void ole_set_safe_array(
long n, SAFEARRAY *psa, LONG *pid,
long *pub,
VALUE val,
long dim, VARTYPE vt);
109 static long ary_len_of_dim(
VALUE ary,
long dim);
110 static VALUE ole_set_member(
VALUE self, IDispatch *dispatch);
113 static VALUE ary_new_dim(
VALUE myary, LONG *pid, LONG *plb, LONG dim);
114 static void ary_store_dim(
VALUE myary, LONG *pid, LONG *plb, LONG dim,
VALUE val);
115 static void ole_const_load(ITypeLib *pTypeLib,
VALUE klass,
VALUE self);
121 static ULONG reference_count(
struct oledata * pole);
126 static VALUE fole_s_get_code_page(
VALUE self);
127 static BOOL CALLBACK installed_code_page_proc(LPTSTR str);
128 static BOOL code_page_installed(UINT cp);
131 static BOOL CALLBACK installed_lcid_proc(LPTSTR str);
132 static BOOL lcid_installed(LCID
lcid);
135 static VALUE fole_s_ole_initialize(
VALUE self);
136 static VALUE fole_s_ole_uninitialize(
VALUE self);
139 static VALUE set_argv(VARIANTARG* realargs,
unsigned int beg,
unsigned int end);
155 static HRESULT typeinfo_from_ole(
struct oledata *pole, ITypeInfo **ppti);
156 static VALUE ole_methods(
VALUE self,
int mask);
165 static VALUE ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc,
VALUE typedetails);
166 static VALUE ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc,
VALUE typedetails);
168 static VALUE fole_activex_initialize(
VALUE self);
170 static void com_hash_free(
void *ptr);
171 static void com_hash_mark(
void *ptr);
172 static size_t com_hash_size(
const void *ptr);
173 static void check_nano_server(
void);
177 {
NULL, ole_free, ole_size,},
183 {com_hash_mark, com_hash_free, com_hash_size,},
184 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
187 static HRESULT (STDMETHODCALLTYPE mf_QueryInterface)(
188 IMessageFilter __RPC_FAR * This,
192 if (
MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0
193 ||
MEMCMP(riid, &IID_IMessageFilter, GUID, 1) == 0)
198 return E_NOINTERFACE;
201 static ULONG (STDMETHODCALLTYPE mf_AddRef)(
202 IMessageFilter __RPC_FAR * This)
207 static ULONG (STDMETHODCALLTYPE mf_Release)(
208 IMessageFilter __RPC_FAR * This)
213 static DWORD (STDMETHODCALLTYPE mf_HandleInComingCall)(
214 IMessageFilter __RPC_FAR * pThis,
221 #ifdef DEBUG_MESSAGEFILTER 222 printf(
"incoming %08X, %08X, %d\n", dwCallType, threadIDCaller, dwTickCount);
228 case CALLTYPE_TOPLEVEL_CALLPENDING:
229 case CALLTYPE_ASYNC_CALLPENDING:
231 return SERVERCALL_RETRYLATER;
237 if (previous_filter) {
238 return previous_filter->lpVtbl->HandleInComingCall(previous_filter,
244 return SERVERCALL_ISHANDLED;
247 static DWORD (STDMETHODCALLTYPE mf_RetryRejectedCall)(
248 IMessageFilter* pThis,
254 if (previous_filter) {
255 return previous_filter->lpVtbl->RetryRejectedCall(previous_filter,
263 static DWORD (STDMETHODCALLTYPE mf_MessagePending)(
264 IMessageFilter* pThis,
271 return PENDINGMSG_WAITNOPROCESS;
273 if (previous_filter) {
274 return previous_filter->lpVtbl->MessagePending(previous_filter,
279 return PENDINGMSG_WAITNOPROCESS;
289 static HRESULT ( STDMETHODCALLTYPE QueryInterface )(
290 IDispatch __RPC_FAR * This,
294 if (
MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0
295 ||
MEMCMP(riid, &IID_IDispatch, GUID, 1) == 0)
302 return E_NOINTERFACE;
305 static ULONG ( STDMETHODCALLTYPE AddRef )(
306 IDispatch __RPC_FAR * This)
312 static ULONG ( STDMETHODCALLTYPE Release )(
313 IDispatch __RPC_FAR * This)
325 static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )(
326 IDispatch __RPC_FAR * This,
332 static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )(
333 IDispatch __RPC_FAR * This,
336 ITypeInfo __RPC_FAR *__RPC_FAR *
ppTInfo)
342 static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )(
343 IDispatch __RPC_FAR * This,
356 if ((
ID)(DISPID)nameid != nameid)
return E_NOINTERFACE;
361 static HRESULT ( STDMETHODCALLTYPE Invoke )(
362 IDispatch __RPC_FAR * This,
374 int args = pDispParams->cArgs;
377 ID mid = (
ID)dispIdMember;
378 for (i = 0; i < args; i++) {
381 if (dispIdMember == DISPID_VALUE) {
382 if (wFlags == DISPATCH_METHOD) {
384 }
else if (wFlags & DISPATCH_PROPERTYGET) {
420 rbtime2vtdate(
VALUE tmobj)
432 st.wMilliseconds = 0;
433 SystemTimeToVariantTime(&st, &t);
442 nsec /= (24.0 * 3600.0);
448 vtdate2rbtime(
double date)
454 VariantTimeToSystemTime(date, &st);
468 st.wMilliseconds = 0;
469 SystemTimeToVariantTime(&st, &sec);
488 #define ENC_MACHING_CP(enc,encname,cp) if(strcasecmp(rb_enc_name((enc)),(encname)) == 0) return cp 556 failed_load_conv51932(
void)
561 #ifndef pIMultiLanguage 568 #if defined(HAVE_TYPE_IMULTILANGUAGE2) 569 hr = CoCreateInstance(&CLSID_CMultiLanguage,
NULL, CLSCTX_INPROC_SERVER,
570 &IID_IMultiLanguage2, &p);
571 #elif defined(HAVE_TYPE_IMULTILANGUAGE) 572 hr = CoCreateInstance(&CLSID_CMultiLanguage,
NULL, CLSCTX_INPROC_SERVER,
573 &IID_IMultiLanguage, &p);
576 failed_load_conv51932();
581 #define need_conv_function51932() (load_conv_function51932(), 1) 583 #define load_conv_function51932() failed_load_conv51932() 584 #define need_conv_function51932() (failed_load_conv51932(), 0) 587 #define conv_51932(cp) ((cp) == 51932 && need_conv_function51932()) 590 set_ole_codepage(UINT cp)
592 if (code_page_installed(cp)) {
610 rb_raise(
eWIN32OLERuntimeError,
"codepage should be WIN32OLE::CP_ACP, WIN32OLE::CP_OEMCP, WIN32OLE::CP_MACCP, WIN32OLE::CP_THREAD_ACP, WIN32OLE::CP_SYMBOL, WIN32OLE::CP_UTF7, WIN32OLE::CP_UTF8, or installed codepage.");
614 cWIN32OLE_enc = ole_cp2encoding(cWIN32OLE_cp);
627 cp = ole_encoding2cp(encdef);
628 set_ole_codepage(cp);
638 char CodePageName[MAX_PATH];
642 ole_cp2encoding(UINT cp)
650 if (!code_page_installed(cp)) {
662 GetProcAddress(GetModuleHandle(
"kernel32"),
"GetCPInfoEx");
664 pGetCPInfoEx = (
void*)-1;
669 if (pGetCPInfoEx == (
void*)-1 || !pGetCPInfoEx(cp, 0, buf)) {
683 rb_raise(
eWIN32OLERuntimeError,
"codepage should be WIN32OLE::CP_ACP, WIN32OLE::CP_OEMCP, WIN32OLE::CP_MACCP, WIN32OLE::CP_THREAD_ACP, WIN32OLE::CP_SYMBOL, WIN32OLE::CP_UTF7, WIN32OLE::CP_UTF8, or installed codepage.");
695 #ifndef pIMultiLanguage 697 ole_ml_wc2mb_conv0(LPWSTR pw, LPSTR pm, UINT *
size)
701 &dw, cWIN32OLE_cp, pw,
NULL, pm, size);
703 #define ole_ml_wc2mb_conv(pw, pm, size, onfailure) do { \ 704 HRESULT hr = ole_ml_wc2mb_conv0(pw, pm, &size); \ 707 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert Unicode to CP%d", cWIN32OLE_cp); \ 712 #define ole_wc2mb_conv(pw, pm, size) WideCharToMultiByte(cWIN32OLE_cp, 0, (pw), -1, (pm), (size), NULL, NULL) 715 ole_wc2mb_alloc(LPWSTR pw,
char *(alloc)(UINT size,
void *arg),
void *arg)
720 #ifndef pIMultiLanguage 721 ole_ml_wc2mb_conv(pw,
NULL, size, {});
722 pm = alloc(size, arg);
723 if (size) ole_ml_wc2mb_conv(pw, pm, size,
xfree(pm));
729 pm = alloc(size, arg);
736 ole_alloc_str(UINT size,
void *arg)
738 return ALLOC_N(
char, size + 1);
744 return ole_wc2mb_alloc(pw, ole_alloc_str,
NULL);
748 ole_freeexceptinfo(EXCEPINFO *pExInfo)
750 SysFreeString(pExInfo->bstrDescription);
751 SysFreeString(pExInfo->bstrSource);
752 SysFreeString(pExInfo->bstrHelpFile);
756 ole_excepinfo2msg(EXCEPINFO *pExInfo)
759 char *pSource =
NULL;
760 char *pDescription =
NULL;
762 if(pExInfo->pfnDeferredFillIn !=
NULL) {
763 (*pExInfo->pfnDeferredFillIn)(pExInfo);
765 if (pExInfo->bstrSource !=
NULL) {
766 pSource =
ole_wc2mb(pExInfo->bstrSource);
768 if (pExInfo->bstrDescription !=
NULL) {
769 pDescription =
ole_wc2mb(pExInfo->bstrDescription);
771 if(pExInfo->wCode == 0) {
772 sprintf(error_code,
"\n OLE error code:%lX in ", (
unsigned long)pExInfo->scode);
775 sprintf(error_code,
"\n OLE error code:%u in ", pExInfo->wCode);
778 if(pSource !=
NULL) {
785 if(pDescription !=
NULL) {
791 if(pSource)
free(pSource);
792 if(pDescription)
free(pDescription);
793 ole_freeexceptinfo(pExInfo);
816 if(!g_uninitialize_hooked) {
818 g_uninitialize_hooked =
TRUE;
823 hr = CoInitializeEx(
NULL, COINIT_MULTITHREADED);
825 hr = OleInitialize(
NULL);
832 if (g_running_nano ==
FALSE) {
833 hr = CoRegisterMessageFilter(&imessage_filter, &previous_filter);
835 previous_filter =
NULL;
850 static size_t ole_size(
const void *ptr)
852 return ptr ?
sizeof(
struct oledata) : 0;
884 cp = ole_encoding2cp(enc);
885 if (code_page_installed(cp) ||
889 cp == CP_THREAD_ACP ||
905 ole_mb2wc(
char *pm,
int len, UINT cp)
911 #ifndef pIMultiLanguage 915 &dw, cp, pm, &n,
NULL, &size);
919 pw = SysAllocStringLen(
NULL, size);
922 &dw, cp, pm, &n, pw, &size);
929 size = MultiByteToWideChar(cp, 0, pm, len,
NULL, 0);
930 pw = SysAllocStringLen(
NULL, size);
932 MultiByteToWideChar(cp, 0, pm, len, pw, size);
937 ole_alloc_vstr(UINT size,
void *arg)
948 ole_wc2mb_alloc(pw, ole_alloc_vstr, &vstr);
956 ole_ary_m_entry(
VALUE val, LONG *pid)
969 is_all_index_under(LONG *pid,
long *pub,
long dim)
972 for (i = 0; i < dim; i++) {
973 if (pid[i] > pub[i]) {
984 if (vt == VT_VARIANT) {
987 V_VT(var) = (vt & ~VT_BYREF);
988 if (V_VT(var) == VT_DISPATCH) {
989 V_DISPATCH(var) =
NULL;
990 }
else if (V_VT(var) == VT_UNKNOWN) {
991 V_UNKNOWN(var) =
NULL;
996 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) 997 switch(vt & ~VT_BYREF) {
1000 V_I8(var) =
NUM2I8 (val);
1021 if ((vt & ~VT_BYREF) == VT_VARIANT) {
1024 if ( (vt & ~VT_BYREF) != V_VT(var)) {
1025 hr = VariantChangeTypeEx(var, var,
1031 p = get_ptr_of_variant(var);
1040 get_ptr_of_variant(VARIANT *pvar)
1042 switch(V_VT(pvar)) {
1044 return &V_UI1(pvar);
1050 return &V_UI2(pvar);
1056 return &V_UI4(pvar);
1064 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) 1069 return &V_UI8(pvar);
1073 return &
V_INT(pvar);
1082 return &V_DATE(pvar);
1085 return V_BSTR(pvar);
1088 return V_DISPATCH(pvar);
1091 return &V_ERROR(pvar);
1094 return &V_BOOL(pvar);
1097 return V_UNKNOWN(pvar);
1100 return &V_ARRAY(pvar);
1109 ole_set_safe_array(
long n, SAFEARRAY *psa, LONG *pid,
long *pub,
VALUE val,
long dim, VARTYPE vt)
1117 val1 = ole_ary_m_entry(val, pid);
1120 if (is_all_index_under(pid, pub, dim) ==
Qtrue) {
1121 if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) ==
NULL) ||
1122 (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) ==
NULL)) {
1125 hr = SafeArrayPutElement(psa, pid, p);
1131 if (pid[i] > pub[i]) {
1141 dimension(
VALUE val) {
1148 for (i = 0; i <
len; i++) {
1160 ary_len_of_dim(
VALUE ary,
long dim) {
1173 for (i = 0; i <
len; i++) {
1175 ary_len1 = ary_len_of_dim(val, dim-1);
1176 if (ary_len < ary_len1) {
1192 SAFEARRAYBOUND *psab =
NULL;
1193 SAFEARRAY *psa =
NULL;
1199 dim = dimension(val);
1201 psab =
ALLOC_N(SAFEARRAYBOUND, dim);
1205 if(!psab || !pub || !pid) {
1207 if(psab)
free(psab);
1212 for (i = 0; i < dim; i++) {
1213 psab[i].cElements = ary_len_of_dim(val, i);
1214 psab[i].lLbound = 0;
1215 pub[i] = psab[i].cElements - 1;
1219 if ((vt & ~VT_BYREF) == VT_ARRAY) {
1220 vt = (vt | VT_VARIANT);
1222 psa = SafeArrayCreate((VARTYPE)(vt & VT_TYPEMASK), dim, psab);
1226 hr = SafeArrayLock(psa);
1227 if (SUCCEEDED(hr)) {
1228 ole_set_safe_array(dim-1, psa, pid, pub, val, dim, (VARTYPE)(vt & VT_TYPEMASK));
1229 hr = SafeArrayUnlock(psa);
1233 if(psab)
free(psab);
1236 if (SUCCEEDED(hr)) {
1242 SafeArrayDestroy(psa);
1254 V_VT(var) = VT_DISPATCH;
1267 V_VT(var) = VT_DATE;
1268 V_DATE(var) = rbtime2vtdate(val);
1271 switch (
TYPE(val)) {
1276 V_VT(var) = VT_BSTR;
1283 V_I4(var) = (LONG)v;
1285 if (V_I4(var) != v) {
1301 V_VT(var) = VT_BOOL;
1302 V_BOOL(var) = VARIANT_TRUE;
1305 V_VT(var) = VT_BOOL;
1306 V_BOOL(var) = VARIANT_FALSE;
1309 if (g_nil_to == VT_ERROR) {
1310 V_VT(var) = VT_ERROR;
1311 V_ERROR(var) = DISP_E_PARAMNOTFOUND;
1313 V_VT(var) = VT_EMPTY;
1317 V_VT(var) = VT_DISPATCH;
1318 V_DISPATCH(var) = val2dispatch(val);
1326 g_nil_to = VT_EMPTY;
1328 g_nil_to = VT_ERROR;
1351 ole_set_member(
VALUE self, IDispatch *dispatch)
1365 fole_s_allocate(
VALUE klass)
1378 VALUE obj = fole_s_allocate(klass);
1379 ole_set_member(obj, pDispatch);
1384 ary_new_dim(
VALUE myary, LONG *pid, LONG *plb, LONG dim) {
1388 long *ids =
ALLOC_N(
long, dim);
1392 for(i = 0; i < dim; i++) {
1393 ids[i] = pid[i] - plb[i];
1397 for(i = 0; i < dim-1; i++) {
1410 ary_store_dim(
VALUE myary, LONG *pid, LONG *plb, LONG dim,
VALUE val) {
1411 long id = pid[dim - 1] - plb[dim - 1];
1412 VALUE obj = ary_new_dim(myary, pid, plb, dim);
1420 VARTYPE vt = V_VT(pvar);
1422 while ( vt == (VT_BYREF | VT_VARIANT) ) {
1423 pvar = V_VARIANTREF(pvar);
1427 if(V_ISARRAY(pvar)) {
1428 VARTYPE vt_base = vt & VT_TYPEMASK;
1429 SAFEARRAY *psa = V_ISBYREF(pvar) ? *V_ARRAYREF(pvar) : V_ARRAY(pvar);
1431 LONG *pid, *plb, *pub;
1438 dim = SafeArrayGetDim(psa);
1443 if(!pid || !plb || !pub) {
1450 for(i = 0; i < dim; ++i) {
1451 SafeArrayGetLBound(psa, i+1, &plb[i]);
1452 SafeArrayGetLBound(psa, i+1, &pid[i]);
1453 SafeArrayGetUBound(psa, i+1, &pub[i]);
1455 hr = SafeArrayLock(psa);
1456 if (SUCCEEDED(hr)) {
1459 VariantInit(&variant);
1460 V_VT(&variant) = vt_base | VT_BYREF;
1461 if (vt_base == VT_RECORD) {
1462 hr = SafeArrayGetRecordInfo(psa, &V_RECORDINFO(&variant));
1463 if (SUCCEEDED(hr)) {
1464 V_VT(&variant) = VT_RECORD;
1468 ary_new_dim(obj, pid, plb, dim);
1469 if (vt_base == VT_RECORD)
1470 hr = SafeArrayPtrOfIndex(psa, pid, &V_RECORD(&variant));
1472 hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant));
1473 if (SUCCEEDED(hr)) {
1475 ary_store_dim(obj, pid, plb, dim, val);
1477 for (i = 0; i < dim; ++i) {
1478 if (++pid[i] <= pub[i])
1483 SafeArrayUnlock(psa);
1490 switch(V_VT(pvar) & ~VT_BYREF){
1551 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) 1554 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) 1566 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) 1596 bstr = *V_BSTRREF(pvar);
1598 bstr = V_BSTR(pvar);
1599 obj = (SysStringLen(bstr) == 0)
1613 if (V_ISBYREF(pvar))
1623 if (V_ISBYREF(pvar))
1624 pDispatch = *V_DISPATCHREF(pvar);
1626 pDispatch = V_DISPATCH(pvar);
1628 if (pDispatch !=
NULL ) {
1630 obj = create_win32ole_object(
cWIN32OLE, pDispatch, 0, 0);
1643 if (V_ISBYREF(pvar))
1644 punk = *V_UNKNOWNREF(pvar);
1646 punk = V_UNKNOWN(pvar);
1649 hr = punk->lpVtbl->QueryInterface(punk, &IID_IDispatch, &p);
1652 obj = create_win32ole_object(
cWIN32OLE, pDispatch, 0, 0);
1662 date = *V_DATEREF(pvar);
1664 date = V_DATE(pvar);
1666 obj = vtdate2rbtime(date);
1672 IRecordInfo *pri = V_RECORDINFO(pvar);
1673 void *prec = V_RECORD(pvar);
1683 VariantInit(&variant);
1684 hr = VariantChangeTypeEx(&variant, pvar,
1686 if (SUCCEEDED(hr) && V_VT(&variant) == VT_BSTR) {
1689 VariantClear(&variant);
1699 return RegOpenKeyEx(hkey, name, 0, KEY_READ, phkey);
1711 char buf[BUFSIZ + 1];
1714 LONG
err = RegEnumKeyEx(hkey, i, buf, &size_buf,
1716 if(err == ERROR_SUCCESS) {
1730 LONG
err = RegQueryValueEx(hkey, subkey,
NULL, &dwtype,
NULL, &size);
1732 if (err == ERROR_SUCCESS) {
1733 pbuf =
ALLOC_N(
char, size + 1);
1734 err = RegQueryValueEx(hkey, subkey,
NULL, &dwtype, (BYTE *)pbuf, &size);
1735 if (err == ERROR_SUCCESS) {
1737 if (dwtype == REG_EXPAND_SZ) {
1738 char* pbuf2 = (
char *)pbuf;
1739 DWORD len = ExpandEnvironmentStrings(pbuf2,
NULL, 0);
1740 pbuf =
ALLOC_N(
char, len + 1);
1741 ExpandEnvironmentStrings(pbuf2, pbuf, len + 1);
1757 err = RegOpenKeyEx(hkey, subkey, 0, KEY_READ, &hsubkey);
1758 if (err == ERROR_SUCCESS) {
1760 RegCloseKey(hsubkey);
1769 ole_const_load(ITypeLib *pTypeLib,
VALUE klass,
VALUE self)
1774 ITypeInfo *pTypeInfo;
1775 TYPEATTR *pTypeAttr;
1785 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
1786 for (index = 0; index <
count; index++) {
1787 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, index, &pTypeInfo);
1795 for(iVar = 0; iVar < pTypeAttr->cVars; iVar++) {
1796 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, iVar, &pVarDesc);
1799 if(pVarDesc->varkind == VAR_CONST &&
1800 !(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
1801 VARFLAG_FRESTRICTED |
1802 VARFLAG_FNONBROWSABLE))) {
1803 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
1805 if(FAILED(hr) || len == 0 || !bstr)
1809 *pName = toupper((
int)*pName);
1817 SysFreeString(bstr);
1823 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
1825 pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
1832 clsid_from_remote(
VALUE host,
VALUE com, CLSID *pclsid)
1843 err = RegConnectRegistry(
StringValuePtr(host), HKEY_LOCAL_MACHINE, &hlm);
1844 if (err != ERROR_SUCCESS)
1845 return HRESULT_FROM_WIN32(err);
1849 err = RegOpenKeyEx(hlm,
StringValuePtr(subkey), 0, KEY_READ, &hpid);
1850 if (err != ERROR_SUCCESS)
1851 hr = HRESULT_FROM_WIN32(err);
1853 len =
sizeof(clsid);
1854 err = RegQueryValueEx(hpid,
"",
NULL, &dwtype, (BYTE *)clsid, &len);
1855 if (err == ERROR_SUCCESS && dwtype == REG_SZ) {
1856 pbuf = ole_mb2wc(clsid, -1, cWIN32OLE_cp);
1857 hr = CLSIDFromString(pbuf, pclsid);
1858 SysFreeString(pbuf);
1861 hr = HRESULT_FROM_WIN32(err);
1876 COSERVERINFO serverinfo;
1878 DWORD clsctx = CLSCTX_REMOTE_SERVER;
1881 gole32 = LoadLibrary(
"OLE32");
1884 if (!gCoCreateInstanceEx)
1885 gCoCreateInstanceEx = (FNCOCREATEINSTANCEEX*)
1886 GetProcAddress(gole32,
"CoCreateInstanceEx");
1887 if (!gCoCreateInstanceEx)
1891 hr = CLSIDFromProgID(pbuf, &clsid);
1893 hr = clsid_from_remote(host, ole, &clsid);
1895 hr = CLSIDFromString(pbuf, &clsid);
1896 SysFreeString(pbuf);
1899 "unknown OLE server: `%s'",
1901 memset(&serverinfo, 0,
sizeof(COSERVERINFO));
1903 memset(&multi_qi, 0,
sizeof(MULTI_QI));
1904 multi_qi.pIID = &IID_IDispatch;
1905 hr = gCoCreateInstanceEx(&clsid,
NULL, clsctx, &serverinfo, 1, &multi_qi);
1906 SysFreeString(serverinfo.pwszName);
1909 "failed to create DCOM server `%s' in `%s'",
1913 ole_set_member(
self, (IDispatch*)multi_qi.pItf);
1930 hr = CreateBindCtx(0, &pBindCtx);
1933 "failed to create bind context");
1937 hr = MkParseDisplayName(pBindCtx, pbuf, &eaten, &pMoniker);
1938 SysFreeString(pbuf);
1942 "failed to parse display name of moniker `%s'",
1945 hr = pMoniker->lpVtbl->BindToObject(pMoniker, pBindCtx,
NULL,
1946 &IID_IDispatch, &p);
1953 "failed to bind moniker `%s'",
1956 return create_win32ole_object(
self, pDispatch, argc, argv);
1969 fole_s_connect(
int argc,
VALUE *argv,
VALUE self)
1992 hr = CLSIDFromProgID(pBuf, &clsid);
1994 hr = CLSIDFromString(pBuf, &clsid);
1996 SysFreeString(pBuf);
1998 return ole_bind_obj(svr_name, argc, argv,
self);
2001 hr = GetActiveObject(&clsid, 0, &pUnknown);
2006 hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch, &p);
2011 "failed to create WIN32OLE server `%s'",
2017 return create_win32ole_object(
self, pDispatch, argc, argv);
2050 fole_s_const_load(
int argc,
VALUE *argv,
VALUE self)
2055 ITypeInfo *pTypeInfo;
2072 0, lcid, &pTypeInfo);
2076 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
2083 ole_const_load(pTypeLib, klass,
self);
2086 ole_const_load(pTypeLib,
cWIN32OLE,
self);
2096 hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib);
2097 SysFreeString(pBuf);
2101 ole_const_load(pTypeLib, klass,
self);
2104 ole_const_load(pTypeLib,
cWIN32OLE,
self);
2115 reference_count(
struct oledata * pole)
2134 fole_s_reference_count(
VALUE self,
VALUE obj)
2157 if (reference_count(pole) > 0) {
2165 ole_show_help(
VALUE helpfile,
VALUE helpcontext)
2167 FNHTMLHELP *pfnHtmlHelp;
2171 ghhctrl = LoadLibrary(
"HHCTRL.OCX");
2174 pfnHtmlHelp = (FNHTMLHELP*)GetProcAddress(ghhctrl,
"HtmlHelpA");
2197 fole_s_show_help(
int argc,
VALUE *argv,
VALUE self)
2220 hwnd = ole_show_help(helpfile, helpcontext);
2236 fole_s_get_code_page(
VALUE self)
2241 static BOOL CALLBACK
2242 installed_code_page_proc(LPTSTR str) {
2243 if (strtoul(str,
NULL, 10) == g_cp_to_check) {
2244 g_cp_installed =
TRUE;
2251 code_page_installed(UINT cp)
2253 g_cp_installed =
FALSE;
2255 EnumSystemCodePages(installed_code_page_proc, CP_INSTALLED);
2256 return g_cp_installed;
2276 set_ole_codepage(cp);
2293 fole_s_get_locale(
VALUE self)
2299 CALLBACK installed_lcid_proc(LPTSTR str)
2301 if (strcmp(str, g_lcid_to_check) == 0) {
2302 g_lcid_installed =
TRUE;
2309 lcid_installed(LCID lcid)
2311 g_lcid_installed =
FALSE;
2312 snprintf(g_lcid_to_check,
sizeof(g_lcid_to_check),
"%08lx", (
unsigned long)lcid);
2313 EnumSystemLocales(installed_lcid_proc, LCID_INSTALLED);
2314 return g_lcid_installed;
2331 if (lcid_installed(lcid)) {
2335 case LOCALE_SYSTEM_DEFAULT:
2336 case LOCALE_USER_DEFAULT:
2354 fole_s_create_guid(
VALUE self)
2360 hr = CoCreateGuid(&guid);
2364 len = StringFromGUID2(&guid, bstr,
sizeof(bstr)/
sizeof(OLECHAR));
2379 fole_s_ole_initialize(
VALUE self)
2387 fole_s_ole_uninitialize(
VALUE self)
2458 fole_initialize(
int argc,
VALUE *argv,
VALUE self)
2469 IClassFactory2 * pIClassFactory2;
2471 static ID keyword_ids[1];
2475 rb_scan_args(argc, argv,
"11*:", &svr_name, &host, &others, &opts);
2488 return ole_create_dcom(
self, svr_name, host, others);
2493 hr = CLSIDFromProgID(pBuf, &clsid);
2495 hr = CLSIDFromString(pBuf, &clsid);
2497 SysFreeString(pBuf);
2500 "unknown OLE server: `%s'",
2504 if (!keyword_ids[0]) {
2509 if (kwargs[0] ==
Qundef) {
2511 hr = CoCreateInstance(
2514 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
2519 hr = CoGetClassObject(
2521 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
2523 &IID_IClassFactory2,
2524 (LPVOID)&pIClassFactory2
2528 hr = pIClassFactory2->lpVtbl->CreateInstanceLic(pIClassFactory2,
NULL,
NULL, &IID_IDispatch, key_buf, &p);
2529 SysFreeString(key_buf);
2536 "failed to create WIN32OLE object from `%s'",
2540 ole_set_member(
self, pDispatch);
2548 unsigned int index, i;
2549 index = pOp->
dp.cNamedArgs;
2555 for(i = 1; i < index + 1; i++) {
2559 for(i = 0; i < index; i++ ) {
2560 VariantClear(&(pOp->
dp.rgvarg[i]));
2572 VariantInit(&(pOp->
dp.rgvarg[index]));
2575 pOp->
dp.cNamedArgs += 1;
2580 set_argv(VARIANTARG* realargs,
unsigned int beg,
unsigned int end)
2586 while (end-- > beg) {
2588 if (V_VT(&realargs[end]) != VT_RECORD) {
2589 VariantClear(&realargs[end]);
2596 ole_invoke(
int argc,
VALUE *argv,
VALUE self, USHORT wFlags, BOOL is_bracket)
2611 EXCEPINFO excepinfo;
2613 VARIANTARG* realargs =
NULL;
2614 unsigned int argErr = 0;
2616 unsigned int cNamedArgs;
2619 memset(&excepinfo, 0,
sizeof(EXCEPINFO));
2621 VariantInit(&result);
2624 op.
dp.rgdispidNamedArgs =
NULL;
2625 op.
dp.cNamedArgs = 0;
2640 DispID = DISPID_VALUE;
2646 &wcmdname, 1, lcid, &DispID);
2647 SysFreeString(wcmdname);
2656 op.
dp.cNamedArgs = 0;
2664 op.
dp.cArgs = cNamedArgs + argc - 2;
2670 pDispID =
ALLOCA_N(DISPID, cNamedArgs + 1);
2675 op.dp.cNamedArgs + 1,
2677 for(i = 0; i < op.dp.cNamedArgs + 1; i++) {
2678 SysFreeString(op.pNamedArgs[i]);
2679 op.pNamedArgs[i] =
NULL;
2683 for(i = 0; i < op.dp.cArgs; i++ ) {
2684 VariantClear(&op.dp.rgvarg[i]);
2687 "failed to get named argument info: `%s'",
2690 op.dp.rgdispidNamedArgs = &(pDispID[1]);
2694 op.
dp.cArgs = argc - 1;
2696 if (op.
dp.cArgs > 0) {
2703 if(op.
dp.cArgs > cNamedArgs) {
2704 realargs =
ALLOCA_N(VARIANTARG, op.
dp.cArgs-cNamedArgs+1);
2705 for(i = cNamedArgs; i < op.
dp.cArgs; i++) {
2706 n = op.
dp.cArgs - i + cNamedArgs - 1;
2707 VariantInit(&realargs[n]);
2708 VariantInit(&op.
dp.rgvarg[n]);
2714 op.
dp.rgvarg[n] = realargs[n];
2715 V_VT(&op.
dp.rgvarg[n]) = VT_RECORD | VT_BYREF;
2718 V_VT(&op.
dp.rgvarg[n]) = VT_VARIANT | VT_BYREF;
2719 V_VARIANTREF(&op.
dp.rgvarg[n]) = &realargs[n];
2724 if (wFlags & DISPATCH_PROPERTYPUT) {
2725 if (op.
dp.cArgs == 0)
2728 op.
dp.cNamedArgs = 1;
2729 op.
dp.rgdispidNamedArgs =
ALLOCA_N( DISPID, 1 );
2730 op.
dp.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
2733 &IID_NULL, lcid, wFlags, &op.
dp,
2734 &result, &excepinfo, &argErr);
2738 if(op.
dp.cArgs >= cNamedArgs) {
2739 for(i = cNamedArgs; i < op.
dp.cArgs; i++) {
2740 n = op.
dp.cArgs - i + cNamedArgs - 1;
2744 if (hr == DISP_E_EXCEPTION) {
2745 ole_freeexceptinfo(&excepinfo);
2747 memset(&excepinfo, 0,
sizeof(EXCEPINFO));
2748 VariantInit(&result);
2750 &IID_NULL, lcid, wFlags,
2752 &excepinfo, &argErr);
2758 if ((hr == DISP_E_EXCEPTION || hr == DISP_E_MEMBERNOTFOUND) && DispID > 0x8000) {
2759 if (hr == DISP_E_EXCEPTION) {
2760 ole_freeexceptinfo(&excepinfo);
2762 memset(&excepinfo, 0,
sizeof(EXCEPINFO));
2764 &IID_NULL, lcid, wFlags,
2766 &excepinfo, &argErr);
2769 for(i = cNamedArgs; i < op.
dp.cArgs; i++) {
2770 n = op.
dp.cArgs - i + cNamedArgs - 1;
2771 if (V_VT(&op.
dp.rgvarg[n]) != VT_RECORD) {
2772 VariantClear(&op.
dp.rgvarg[n]);
2779 if (op.
dp.cArgs > cNamedArgs) {
2780 for(i = cNamedArgs; i < op.
dp.cArgs; i++) {
2781 n = op.
dp.cArgs - i + cNamedArgs - 1;
2785 if (hr == DISP_E_EXCEPTION) {
2786 ole_freeexceptinfo(&excepinfo);
2788 memset(&excepinfo, 0,
sizeof(EXCEPINFO));
2789 VariantInit(&result);
2791 &IID_NULL, lcid, wFlags,
2793 &excepinfo, &argErr);
2794 for(i = cNamedArgs; i < op.
dp.cArgs; i++) {
2795 n = op.
dp.cArgs - i + cNamedArgs - 1;
2796 if (V_VT(&op.
dp.rgvarg[n]) != VT_RECORD) {
2797 VariantClear(&op.
dp.rgvarg[n]);
2805 if(op.
dp.cArgs > cNamedArgs) {
2806 for(i = cNamedArgs; i < op.
dp.cArgs; i++) {
2807 n = op.
dp.cArgs - i + cNamedArgs - 1;
2812 V_VT(&realargs[n]) == VT_RECORD ) {
2816 set_argv(realargs, cNamedArgs, op.
dp.cArgs);
2819 for(i = 0; i < op.
dp.cArgs; i++) {
2820 VariantClear(&op.
dp.rgvarg[i]);
2825 v = ole_excepinfo2msg(&excepinfo);
2831 VariantClear(&result);
2849 fole_invoke(
int argc,
VALUE *argv,
VALUE self)
2851 VALUE v = ole_invoke(argc, argv,
self, DISPATCH_METHOD|DISPATCH_PROPERTYGET,
FALSE);
2863 unsigned int argErr = 0;
2864 EXCEPINFO excepinfo;
2866 DISPPARAMS dispParams;
2867 VARIANTARG* realargs =
NULL;
2876 memset(&excepinfo, 0,
sizeof(EXCEPINFO));
2877 memset(&dispParams, 0,
sizeof(DISPPARAMS));
2878 VariantInit(&result);
2882 dispParams.rgvarg =
ALLOCA_N(VARIANTARG, dispParams.cArgs);
2883 realargs =
ALLOCA_N(VARIANTARG, dispParams.cArgs);
2884 for (i = 0, j = dispParams.cArgs - 1; i < (
int)dispParams.cArgs; i++, j--)
2886 VariantInit(&realargs[i]);
2887 VariantInit(&dispParams.rgvarg[i]);
2890 V_VT(&dispParams.rgvarg[i]) = vt;
2895 V_VT(&dispParams.rgvarg[i]) = V_VT(&realargs[i]) = VT_ERROR;
2896 V_ERROR(&dispParams.rgvarg[i]) = V_ERROR(&realargs[i]) = DISP_E_PARAMNOTFOUND;
2909 SAFEARRAYBOUND rgsabound[1];
2911 rgsabound[0].lLbound = 0;
2913 v = vt & ~(VT_ARRAY | VT_BYREF);
2914 V_ARRAY(&realargs[i]) = SafeArrayCreate(v, 1, rgsabound);
2915 V_VT(&realargs[i]) = VT_ARRAY | v;
2916 SafeArrayLock(V_ARRAY(&realargs[i]));
2917 pb = V_ARRAY(&realargs[i])->pvData;
2918 ps = V_ARRAY(&realargs[i])->pvData;
2919 pl = V_ARRAY(&realargs[i])->pvData;
2920 py = V_ARRAY(&realargs[i])->pvData;
2921 pv = V_ARRAY(&realargs[i])->pvData;
2922 for (ent = 0; ent < (int)rgsabound[0].cElements; ent++)
2927 if (v != VT_VARIANT)
2929 VariantChangeTypeEx(&velem, &velem,
2942 *py++ = V_CY(&velem);
2948 *ps++ = V_I2(&velem);
2953 *pb++ = V_UI1(&velem);
2957 *pl++ = V_I4(&velem);
2961 SafeArrayUnlock(V_ARRAY(&realargs[i]));
2966 if ((vt & (~VT_BYREF)) != VT_VARIANT)
2968 hr = VariantChangeTypeEx(&realargs[i], &realargs[i],
2970 (VARTYPE)(vt & (~VT_BYREF)));
2977 if ((vt & VT_BYREF) || vt == VT_VARIANT)
2979 if (vt == VT_VARIANT)
2980 V_VT(&dispParams.rgvarg[i]) = VT_VARIANT | VT_BYREF;
2981 switch (vt & (~VT_BYREF))
2985 V_VARIANTREF(&dispParams.rgvarg[i]) = &realargs[i];
2991 V_CYREF(&dispParams.rgvarg[i]) = &V_CY(&realargs[i]);
2997 V_I2REF(&dispParams.rgvarg[i]) = &V_I2(&realargs[i]);
3002 V_UI1REF(&dispParams.rgvarg[i]) = &V_UI1(&realargs[i]);
3006 V_I4REF(&dispParams.rgvarg[i]) = &V_I4(&realargs[i]);
3013 V_CY(&dispParams.rgvarg[i]) = V_CY(&realargs[i]);
3018 if (dispkind & DISPATCH_PROPERTYPUT) {
3019 dispParams.cNamedArgs = 1;
3020 dispParams.rgdispidNamedArgs =
ALLOCA_N( DISPID, 1 );
3021 dispParams.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
3027 &dispParams, &result,
3028 &excepinfo, &argErr);
3031 v = ole_excepinfo2msg(&excepinfo);
3038 if(dispParams.cArgs > 0) {
3039 set_argv(realargs, 0, dispParams.cArgs);
3043 VariantClear(&result);
3062 return ole_invoke2(
self, dispid, args, types, DISPATCH_METHOD);
3080 return ole_invoke2(
self, dispid, args, types, DISPATCH_PROPERTYGET);
3098 return ole_invoke2(
self, dispid, args, types, DISPATCH_PROPERTYPUT);
3120 fole_setproperty_with_bracket(
int argc,
VALUE *argv,
VALUE self)
3122 VALUE v = ole_invoke(argc, argv,
self, DISPATCH_PROPERTYPUT,
TRUE);
3143 fole_setproperty(
int argc,
VALUE *argv,
VALUE self)
3145 VALUE v = ole_invoke(argc, argv,
self, DISPATCH_PROPERTYPUT,
FALSE);
3169 fole_getproperty_with_bracket(
int argc,
VALUE *argv,
VALUE self)
3171 VALUE v = ole_invoke(argc, argv,
self, DISPATCH_PROPERTYGET,
TRUE);
3185 EXCEPINFO excepinfo;
3186 DISPID dispID = DISPID_VALUE;
3187 DISPID dispIDParam = DISPID_PROPERTYPUT;
3188 USHORT wFlags = DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF;
3189 DISPPARAMS dispParams;
3190 VARIANTARG propertyValue[2];
3194 dispParams.rgdispidNamedArgs = &dispIDParam;
3195 dispParams.rgvarg = propertyValue;
3196 dispParams.cNamedArgs = 1;
3197 dispParams.cArgs = 1;
3199 VariantInit(&propertyValue[0]);
3200 VariantInit(&propertyValue[1]);
3201 memset(&excepinfo, 0,
sizeof(excepinfo));
3208 pBuf, 1, lcid, &dispID);
3209 SysFreeString(pBuf[0]);
3214 "unknown property or method: `%s'",
3220 lcid, wFlags, &dispParams,
3221 NULL, &excepinfo, &argErr);
3223 for(index = 0; index < dispParams.cArgs; ++index) {
3224 VariantClear(&propertyValue[index]);
3227 v = ole_excepinfo2msg(&excepinfo);
3245 fole_free(
VALUE self)
3255 ole_each_sub(
VALUE pEnumV)
3259 IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
3260 VariantInit(&variant);
3261 while(pEnum->lpVtbl->Next(pEnum, 1, &variant,
NULL) == S_OK) {
3263 VariantClear(&variant);
3264 VariantInit(&variant);
3271 ole_ienum_free(
VALUE pEnumV)
3273 IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
3293 fole_each(
VALUE self)
3299 unsigned int argErr;
3300 EXCEPINFO excepinfo;
3301 DISPPARAMS dispParams;
3304 IEnumVARIANT *pEnum =
NULL;
3309 VariantInit(&result);
3310 dispParams.rgvarg =
NULL;
3311 dispParams.rgdispidNamedArgs =
NULL;
3312 dispParams.cNamedArgs = 0;
3313 dispParams.cArgs = 0;
3314 memset(&excepinfo, 0,
sizeof(excepinfo));
3319 DISPATCH_METHOD | DISPATCH_PROPERTYGET,
3320 &dispParams, &result,
3321 &excepinfo, &argErr);
3324 VariantClear(&result);
3328 if (V_VT(&result) == VT_UNKNOWN) {
3329 hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result),
3333 }
else if (V_VT(&result) == VT_DISPATCH) {
3334 hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result),
3339 if (FAILED(hr) || !pEnum) {
3340 VariantClear(&result);
3344 VariantClear(&result);
3356 fole_missing(
int argc,
VALUE *argv,
VALUE self)
3362 mid = org_mid = argv[0];
3370 if(mname[n-1] ==
'=') {
3374 return ole_propertyput(
self, argv[0], argv[1]);
3378 v = ole_invoke(argc, argv,
self, DISPATCH_METHOD|DISPATCH_PROPERTYGET,
FALSE);
3388 typeinfo_from_ole(
struct oledata *pole, ITypeInfo **ppti)
3390 ITypeInfo *pTypeInfo;
3398 0, lcid, &pTypeInfo);
3402 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo,
3407 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
3412 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
3413 for (i = 0; i <
count; i++) {
3414 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
3417 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
3418 if (SUCCEEDED(hr)) {
3429 ole_methods(
VALUE self,
int mask)
3431 ITypeInfo *pTypeInfo;
3439 hr = typeinfo_from_ole(pole, &pTypeInfo);
3459 fole_methods(
VALUE self)
3461 return ole_methods(
self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
3475 fole_get_methods(
VALUE self)
3477 return ole_methods(
self, INVOKE_PROPERTYGET);
3491 fole_put_methods(
VALUE self)
3493 return ole_methods(
self, INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF);
3508 fole_func_methods(
VALUE self)
3510 return ole_methods(
self, INVOKE_FUNC);
3523 fole_type(
VALUE self)
3525 ITypeInfo *pTypeInfo;
3557 fole_typelib(
VALUE self)
3561 ITypeInfo *pTypeInfo;
3567 0, lcid, &pTypeInfo);
3573 if (vtlib ==
Qnil) {
3590 fole_query_interface(
VALUE self,
VALUE str_iid)
3600 hr = CLSIDFromString(pBuf, &iid);
3601 SysFreeString(pBuf);
3604 "invalid iid: `%s'",
3617 "failed to get interface `%s'",
3622 return create_win32ole_object(
cWIN32OLE, pDispatch, 0, 0);
3651 SysFreeString(wcmdname);
3662 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
3667 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
3669 helpcontext, helpfile);
3679 ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc,
VALUE typedetails)
3683 ITypeInfo *pRefTypeInfo;
3686 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
3698 if(typedetails !=
Qnil)
3704 ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc,
VALUE typedetails)
3706 TYPEDESC *p = pTypeDesc;
3709 if (p->vt == VT_PTR || p->vt == VT_SAFEARRAY) {
3721 switch(pTypeDesc->vt) {
3764 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) 3786 if(typedetails !=
Qnil)
3788 return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
3791 if(typedetails !=
Qnil)
3793 return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
3797 case VT_USERDEFINED:
3799 if (typedetails !=
Qnil)
3801 str = ole_usertype2val(pTypeInfo, pTypeDesc, typedetails);
3829 if (typedetails !=
Qnil)
3848 ITypeInfo *pTypeInfo;
3855 hr = typeinfo_from_ole(pole, &pTypeInfo);
3889 fole_activex_initialize(
VALUE self)
3892 IPersistMemory *pPersistMemory;
3899 hr = pole->
pDispatch->lpVtbl->QueryInterface(pole->
pDispatch, &IID_IPersistMemory, &p);
3901 if (SUCCEEDED(hr)) {
3902 hr = pPersistMemory->lpVtbl->InitNew(pPersistMemory);
3904 if (SUCCEEDED(hr)) {
3923 ITypeInfo *pTypeInfo;
3926 0, lcid, &pTypeInfo);
3930 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, pTypeLib, &index);
3936 com_hash_free(
void *ptr)
3943 com_hash_mark(
void *ptr)
3950 com_hash_size(
const void *ptr)
3957 check_nano_server(
void)
3961 const char * subkey =
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Server\\ServerLevels";
3962 const char * regval =
"NanoServer";
3964 err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subkey, 0, KEY_READ, &hsubkey);
3965 if (err == ERROR_SUCCESS) {
3967 if (err == ERROR_SUCCESS) {
3968 g_running_nano =
TRUE;
3970 RegCloseKey(hsubkey);
3980 check_nano_server();
3982 com_vtbl.QueryInterface = QueryInterface;
3983 com_vtbl.AddRef = AddRef;
3984 com_vtbl.Release = Release;
3985 com_vtbl.GetTypeInfoCount = GetTypeInfoCount;
3986 com_vtbl.GetTypeInfo = GetTypeInfo;
3987 com_vtbl.GetIDsOfNames = GetIDsOfNames;
3988 com_vtbl.Invoke = Invoke;
3990 message_filter.QueryInterface = mf_QueryInterface;
3991 message_filter.AddRef = mf_AddRef;
3992 message_filter.Release = mf_Release;
3993 message_filter.HandleInComingCall = mf_HandleInComingCall;
3994 message_filter.RetryRejectedCall = mf_RetryRejectedCall;
3995 message_filter.MessagePending = mf_MessagePending;
static DWORD HTASK DWORD LPINTERFACEINFO lpInterfaceInfo
#define load_conv_function51932()
#define MEMCMP(p1, p2, type, n)
VALUE rb_ary_unshift(VALUE ary, VALUE item)
#define RUBY_EVENT_THREAD_END
void Init_win32ole_param(void)
#define ole_wc2mb_conv(pw, pm, size)
RUBY_EXTERN VALUE rb_cData
VALUE eWIN32OLERuntimeError
VALUE rb_ary_entry(VALUE ary, long offset)
#define RUBY_TYPED_FREE_IMMEDIATELY
size_t strlen(const char *)
void Init_win32ole_method(void)
VOID * val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt)
static DWORD HTASK threadIDCaller
struct oledata * oledata_get_struct(VALUE ole)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
VALUE create_win32ole_record(IRecordInfo *pri, void *prec)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_str_cat(VALUE, const char *, long)
static DISPID REFIID LCID WORD DISPPARAMS __RPC_FAR VARIANT __RPC_FAR EXCEPINFO __RPC_FAR * pExcepInfo
static REFIID LPOLESTR __RPC_FAR * rgszNames
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
#define g_ole_initialized_set(val)
void ole_variant2variant(VALUE val, VARIANT *var)
static DWORD HTASK DWORD dwTickCount
#define TypedData_Wrap_Struct(klass, data_type, sval)
#define TypedData_Get_Struct(obj, type, data_type, sval)
static REFIID LPOLESTR __RPC_FAR UINT cNames
ID rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
int rb_is_const_id(ID id)
rb_encoding * rb_default_internal_encoding(void)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_str_concat(VALUE, VALUE)
LPWSTR ole_vstr2wc(VALUE vstr)
struct _Win32OLEIDispatch Win32OLEIDispatch
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
void Init_win32ole_variant_m(void)
void rb_str_set_len(VALUE, long)
#define OLE_GET_TYPEATTR(X, Y)
VALUE rb_ivar_get(VALUE, ID)
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
VALUE rb_ary_clear(VALUE ary)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
void ole_initialize(void)
VALUE reg_get_val(HKEY hkey, const char *subkey)
void Init_win32ole_type(void)
double rb_big2dbl(VALUE x)
int rb_str_cmp(VALUE, VALUE)
IUnknown COSERVERINFO MULTI_QI *typedef LPCSTR UINT DWORD dwData
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
An equivalent to ensure clause.
BOOL() FNENUMSYSEMCODEPAGES(CODEPAGE_ENUMPROC, DWORD)
static HTASK threadIDCallee
void ole_rec2variant(VALUE rec, VARIANT *var)
VALUE rb_fix2str(VALUE, int)
void Init_win32ole_variant(void)
HRESULT typelib_from_val(VALUE obj, ITypeLib **pTypeLib)
VALUE make_inspect(const char *class_name, VALUE detail)
NORETURN(static void failed_load_conv51932(void))
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
void ole_val2variant2(VALUE val, VARIANT *var)
void rb_hash_foreach(VALUE hash, int(*func)(ANYARGS), VALUE farg)
IUnknown COSERVERINFO MULTI_QI *typedef LPCSTR UINT uCommand
#define g_ole_initialized_init()
#define RB_TYPE_P(obj, type)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
static DISPID REFIID LCID WORD wFlags
BOOL ole_initialized(void)
void ole_raise(HRESULT hr, VALUE ecs, const char *fmt,...)
rb_encoding * rb_default_external_encoding(void)
void Init_win32ole_variable(void)
VALUE default_inspect(VALUE self, const char *class_name)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
RUBY_EXTERN VALUE rb_cObject
size_t st_memsize(const st_table *tab)
VALUE ole_type_from_itypeinfo(ITypeInfo *pTypeInfo)
#define g_ole_initialized
VALUE reg_get_val2(HKEY hkey, const char *subkey)
VALUE rb_str_cat2(VALUE, const char *)
VALUE typelib_file(VALUE ole)
static UINT __RPC_FAR * pctinfo
LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
void Init_win32ole_record(void)
void rb_define_const(VALUE, const char *, VALUE)
void rb_ary_store(VALUE ary, long idx, VALUE val)
VALUE ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask)
#define ALLOCA_N(type, n)
void rb_gc_register_mark_object(VALUE obj)
static DISPID REFIID LCID WORD DISPPARAMS __RPC_FAR * pDispParams
void ole_val2variant_ex(VALUE val, VARIANT *var, VARTYPE vt)
VALUE ole_variant2val(VARIANT *pvar)
VALUE rb_const_get(VALUE, ID)
VALUE rb_str_subseq(VALUE, long, long)
LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey)
static REFIID LPOLESTR __RPC_FAR UINT LCID DISPID __RPC_FAR * rgDispId
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
static DISPID dispIdMember
VALUE rb_sprintf(const char *format,...)
char * ole_wc2mb(LPWSTR pw)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
unsigned char buf[MIME_BUF_SIZE]
void rb_add_event_hook(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data)
static DISPID REFIID LCID WORD DISPPARAMS __RPC_FAR VARIANT __RPC_FAR EXCEPINFO __RPC_FAR UINT __RPC_FAR * puArgErr
int rb_define_dummy_encoding(const char *name)
static HTASK DWORD DWORD dwPendingType
void olerecord_set_ivar(VALUE obj, IRecordInfo *pri, void *prec)
void ole_uninitialize(void)
#define ENC_MACHING_CP(enc, encname, cp)
static HTASK DWORD DWORD dwRejectType
VALUE rb_call_super(int, const VALUE *)
register unsigned int len
#define StringValueCStr(v)
void Init_win32ole_event(void)
VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
rb_encoding * rb_enc_get(VALUE obj)
#define UNLIMITED_ARGUMENTS
static REFIID void __RPC_FAR *__RPC_FAR * ppvObject
IUnknown COSERVERINFO MULTI_QI *typedef HWND(WINAPI FNHTMLHELP)(HWND hwndCaller
void Init_win32ole_typelib(void)
VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree)
typedef HRESULT(STDAPICALLTYPE FNCOCREATEINSTANCEEX)(REFCLSID
VALUE reg_enum_key(HKEY hkey, DWORD i)
VALUE create_win32ole_method(ITypeInfo *pTypeInfo, VALUE name)
#define TypedData_Make_Struct(klass, type, data_type, sval)
VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo)
VALUE rb_ary_concat(VALUE x, VALUE y)
VALUE rb_check_symbol(volatile VALUE *namep)
#define RETURN_ENUMERATOR(obj, argc, argv)
#define SafeStringValue(v)
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
#define StringValuePtr(v)
IUnknown COSERVERINFO MULTI_QI *typedef LPCSTR pszFile
static UINT LCID ITypeInfo __RPC_FAR *__RPC_FAR * ppTInfo
void Init_win32ole_error(void)
#define RTYPEDDATA_DATA(v)
int rb_enc_find_index(const char *name)
#define RSTRING_LENINT(str)
HRESULT ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt)
#define rb_intern_const(str)
void rb_mark_hash(st_table *tbl)
RUBY_EXTERN VALUE rb_cTime
HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
static DISPID REFIID LCID WORD DISPPARAMS __RPC_FAR VARIANT __RPC_FAR * pVarResult
rb_encoding * rb_enc_from_index(int index)
void ole_val2variant(VALUE val, VARIANT *var)