25#if defined(__CYGWIN__) || defined(__MINGW32__)
26#undef IID_IMultiLanguage2
27const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A}};
30#define WIN32OLE_VERSION "1.8.8"
32typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
33 (REFCLSID, IUnknown*,
DWORD, COSERVERINFO*,
DWORD, MULTI_QI*);
40#if defined(RB_THREAD_SPECIFIC) && (defined(__CYGWIN__))
42# define g_ole_initialized_init() ((void)0)
43# define g_ole_initialized_set(val) (g_ole_initialized = (val))
45static volatile DWORD g_ole_initialized_key = TLS_OUT_OF_INDEXES;
46# define g_ole_initialized (TlsGetValue(g_ole_initialized_key)!=0)
47# define g_ole_initialized_init() (g_ole_initialized_key = TlsAlloc())
48# define g_ole_initialized_set(val) TlsSetValue(g_ole_initialized_key, (void*)(val))
51static BOOL g_uninitialize_hooked =
FALSE;
52static BOOL g_cp_installed =
FALSE;
53static BOOL g_lcid_installed =
FALSE;
54static BOOL g_running_nano =
FALSE;
55static HINSTANCE ghhctrl =
NULL;
56static HINSTANCE gole32 =
NULL;
57static FNCOCREATEINSTANCEEX *gCoCreateInstanceEx =
NULL;
59static VALUE enc2cp_hash;
60static IDispatchVtbl com_vtbl;
61static UINT cWIN32OLE_cp = CP_ACP;
63static UINT g_cp_to_check = CP_ACP;
64static char g_lcid_to_check[8 + 1];
65static VARTYPE g_nil_to = VT_ERROR;
66static IMessageFilterVtbl message_filter;
67static IMessageFilter imessage_filter = { &message_filter };
68static IMessageFilter* previous_filter;
70#if defined(HAVE_TYPE_IMULTILANGUAGE2)
72#elif defined(HAVE_TYPE_IMULTILANGUAGE)
75#define pIMultiLanguage NULL
83static HRESULT ( STDMETHODCALLTYPE QueryInterface )(IDispatch __RPC_FAR *, REFIID
riid,
void __RPC_FAR *__RPC_FAR *
ppvObject);
84static ULONG ( STDMETHODCALLTYPE AddRef )(IDispatch __RPC_FAR * This);
85static ULONG ( STDMETHODCALLTYPE Release )(IDispatch __RPC_FAR * This);
86static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )(IDispatch __RPC_FAR * This, UINT __RPC_FAR *
pctinfo);
87static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )(IDispatch __RPC_FAR * This, UINT
iTInfo, LCID
lcid, ITypeInfo __RPC_FAR *__RPC_FAR *
ppTInfo);
90static IDispatch* val2dispatch(
VALUE val);
91static double rbtime2vtdate(
VALUE tmobj);
92static VALUE vtdate2rbtime(
double date);
95NORETURN(
static void failed_load_conv51932(
void));
96#ifndef pIMultiLanguage
99static UINT ole_init_cp(
void);
100static void ole_freeexceptinfo(EXCEPINFO *pExInfo);
101static VALUE ole_excepinfo2msg(EXCEPINFO *pExInfo);
102static void ole_free(
void *
ptr);
103static size_t ole_size(
const void *
ptr);
104static LPWSTR ole_mb2wc(
char *pm,
int len, UINT cp);
105static VALUE ole_ary_m_entry(
VALUE val, LONG *pid);
106static VALUE is_all_index_under(LONG *pid,
long *pub,
long dim);
107static void * get_ptr_of_variant(VARIANT *pvar);
108static void ole_set_safe_array(
long n, SAFEARRAY *psa, LONG *pid,
long *pub,
VALUE val,
long dim, VARTYPE vt);
109static long dimension(
VALUE val);
110static long ary_len_of_dim(
VALUE ary,
long dim);
111static VALUE ole_set_member(
VALUE self, IDispatch *dispatch);
114static VALUE ary_new_dim(
VALUE myary, LONG *pid, LONG *plb, LONG dim);
115static void ary_store_dim(
VALUE myary, LONG *pid, LONG *plb, LONG dim,
VALUE val);
116static void ole_const_load(ITypeLib *pTypeLib,
VALUE klass,
VALUE self);
122static ULONG reference_count(
struct oledata * pole);
128static BOOL CALLBACK installed_code_page_proc(LPTSTR
str);
129static BOOL code_page_installed(UINT cp);
132static BOOL CALLBACK installed_lcid_proc(LPTSTR
str);
133static BOOL lcid_installed(LCID
lcid);
136static VALUE fole_s_ole_initialize(
VALUE self);
137static VALUE fole_s_ole_uninitialize(
VALUE self);
140static VALUE set_argv(VARIANTARG* realargs,
unsigned int beg,
unsigned int end);
156static HRESULT typeinfo_from_ole(
struct oledata *pole, ITypeInfo **ppti);
166static VALUE ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc,
VALUE typedetails);
167static VALUE ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc,
VALUE typedetails);
169static VALUE fole_activex_initialize(
VALUE self);
171static void com_hash_free(
void *
ptr);
172static void com_hash_mark(
void *
ptr);
173static size_t com_hash_size(
const void *
ptr);
174static void check_nano_server(
void);
178 {
NULL, ole_free, ole_size,},
184 {com_hash_mark, com_hash_free, com_hash_size,},
188static HRESULT (STDMETHODCALLTYPE mf_QueryInterface)(
189 IMessageFilter __RPC_FAR * This,
194 ||
MEMCMP(
riid, &IID_IMessageFilter, GUID, 1) == 0)
199 return E_NOINTERFACE;
202static ULONG (STDMETHODCALLTYPE mf_AddRef)(
203 IMessageFilter __RPC_FAR * This)
208static ULONG (STDMETHODCALLTYPE mf_Release)(
209 IMessageFilter __RPC_FAR * This)
214static DWORD (STDMETHODCALLTYPE mf_HandleInComingCall)(
215 IMessageFilter __RPC_FAR * pThis,
222#ifdef DEBUG_MESSAGEFILTER
229 case CALLTYPE_TOPLEVEL_CALLPENDING:
230 case CALLTYPE_ASYNC_CALLPENDING:
232 return SERVERCALL_RETRYLATER;
238 if (previous_filter) {
239 return previous_filter->lpVtbl->HandleInComingCall(previous_filter,
245 return SERVERCALL_ISHANDLED;
248static DWORD (STDMETHODCALLTYPE mf_RetryRejectedCall)(
249 IMessageFilter* pThis,
255 if (previous_filter) {
256 return previous_filter->lpVtbl->RetryRejectedCall(previous_filter,
264static DWORD (STDMETHODCALLTYPE mf_MessagePending)(
265 IMessageFilter* pThis,
272 return PENDINGMSG_WAITNOPROCESS;
274 if (previous_filter) {
275 return previous_filter->lpVtbl->MessagePending(previous_filter,
280 return PENDINGMSG_WAITNOPROCESS;
290static HRESULT ( STDMETHODCALLTYPE QueryInterface )(
291 IDispatch __RPC_FAR * This,
296 ||
MEMCMP(
riid, &IID_IDispatch, GUID, 1) == 0)
303 return E_NOINTERFACE;
306static ULONG ( STDMETHODCALLTYPE AddRef )(
307 IDispatch __RPC_FAR * This)
313static ULONG ( STDMETHODCALLTYPE Release )(
314 IDispatch __RPC_FAR * This)
326static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )(
327 IDispatch __RPC_FAR * This,
333static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )(
334 IDispatch __RPC_FAR * This,
337 ITypeInfo __RPC_FAR *__RPC_FAR *
ppTInfo)
343static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )(
344 IDispatch __RPC_FAR * This,
362static HRESULT ( STDMETHODCALLTYPE Invoke )(
363 IDispatch __RPC_FAR * This,
379 for (i = 0; i < args; i++) {
383 if (
wFlags == DISPATCH_METHOD) {
385 }
else if (
wFlags & DISPATCH_PROPERTYGET) {
401val2dispatch(
VALUE val)
421rbtime2vtdate(
VALUE tmobj)
433 st.wMilliseconds = 0;
434 SystemTimeToVariantTime(&st, &
t);
443 nsec /= (24.0 * 3600.0);
449vtdate2rbtime(
double date)
455 VariantTimeToSystemTime(date, &st);
457 RB_INT2FIX(st.wYear),
458 RB_INT2FIX(st.wMonth),
460 RB_INT2FIX(st.wHour),
461 RB_INT2FIX(st.wMinute),
462 RB_INT2FIX(st.wSecond));
469 st.wMilliseconds = 0;
470 SystemTimeToVariantTime(&st, &sec);
489#define ENC_MACHING_CP(enc,encname,cp) if(strcasecmp(rb_enc_name((enc)),(encname)) == 0) return cp
558failed_load_conv51932(
void)
563#ifndef pIMultiLanguage
570#if defined(HAVE_TYPE_IMULTILANGUAGE2)
571 hr = CoCreateInstance(&CLSID_CMultiLanguage,
NULL, CLSCTX_INPROC_SERVER,
572 &IID_IMultiLanguage2, &p);
573#elif defined(HAVE_TYPE_IMULTILANGUAGE)
574 hr = CoCreateInstance(&CLSID_CMultiLanguage,
NULL, CLSCTX_INPROC_SERVER,
575 &IID_IMultiLanguage, &p);
578 failed_load_conv51932();
583#define need_conv_function51932() (load_conv_function51932(), 1)
585#define load_conv_function51932() failed_load_conv51932()
586#define need_conv_function51932() (failed_load_conv51932(), 0)
589#define conv_51932(cp) ((cp) == 51932 && need_conv_function51932())
592set_ole_codepage(UINT cp)
594 if (code_page_installed(cp)) {
612 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.");
616 cWIN32OLE_enc = ole_cp2encoding(cWIN32OLE_cp);
629 cp = ole_encoding2cp(encdef);
630 set_ole_codepage(cp);
644ole_cp2encoding(UINT cp)
652 if (!code_page_installed(cp)) {
664 GetProcAddress(GetModuleHandle(
"kernel32"),
"GetCPInfoEx");
666 pGetCPInfoEx = (
void*)-1;
671 if (pGetCPInfoEx == (
void*)-1 || !pGetCPInfoEx(cp, 0,
buf)) {
685 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.");
697#ifndef pIMultiLanguage
699ole_ml_wc2mb_conv0(LPWSTR pw, LPSTR pm, UINT *
size)
703 &dw, cWIN32OLE_cp, pw,
NULL, pm,
size);
705#define ole_ml_wc2mb_conv(pw, pm, size, onfailure) do { \
706 HRESULT hr = ole_ml_wc2mb_conv0(pw, pm, &size); \
709 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert Unicode to CP%d", cWIN32OLE_cp); \
714#define ole_wc2mb_conv(pw, pm, size) WideCharToMultiByte(cWIN32OLE_cp, 0, (pw), -1, (pm), (size), NULL, NULL)
717ole_wc2mb_alloc(LPWSTR pw,
char *(alloc)(UINT
size,
void *arg),
void *arg)
722#ifndef pIMultiLanguage
723 ole_ml_wc2mb_conv(pw,
NULL,
size, {});
724 pm = alloc(
size, arg);
731 pm = alloc(
size, arg);
738ole_alloc_str(UINT
size,
void *arg)
746 return ole_wc2mb_alloc(pw, ole_alloc_str,
NULL);
750ole_freeexceptinfo(EXCEPINFO *pExInfo)
752 SysFreeString(pExInfo->bstrDescription);
753 SysFreeString(pExInfo->bstrSource);
754 SysFreeString(pExInfo->bstrHelpFile);
758ole_excepinfo2msg(EXCEPINFO *pExInfo)
761 char *pSource =
NULL;
762 char *pDescription =
NULL;
764 if(pExInfo->pfnDeferredFillIn !=
NULL) {
765 (*pExInfo->pfnDeferredFillIn)(pExInfo);
767 if (pExInfo->bstrSource !=
NULL) {
768 pSource =
ole_wc2mb(pExInfo->bstrSource);
770 if (pExInfo->bstrDescription !=
NULL) {
771 pDescription =
ole_wc2mb(pExInfo->bstrDescription);
773 if(pExInfo->wCode == 0) {
774 sprintf(error_code,
"\n OLE error code:%lX in ", (
unsigned long)pExInfo->scode);
777 sprintf(error_code,
"\n OLE error code:%u in ", pExInfo->wCode);
780 if(pSource !=
NULL) {
787 if(pDescription !=
NULL) {
793 if(pSource)
free(pSource);
794 if(pDescription)
free(pDescription);
795 ole_freeexceptinfo(pExInfo);
818 if(!g_uninitialize_hooked) {
820 g_uninitialize_hooked =
TRUE;
825 hr = CoInitializeEx(
NULL, COINIT_MULTITHREADED);
827 hr = OleInitialize(
NULL);
834 if (g_running_nano ==
FALSE) {
835 hr = CoRegisterMessageFilter(&imessage_filter, &previous_filter);
837 previous_filter =
NULL;
852static size_t ole_size(
const void *
ptr)
884 cp = RB_FIX2INT((
VALUE)data);
886 cp = ole_encoding2cp(enc);
887 if (code_page_installed(cp) ||
891 cp == CP_THREAD_ACP ||
901 pw = ole_mb2wc(
RSTRING_PTR(vstr), RSTRING_LENINT(vstr), cp);
907ole_mb2wc(
char *pm,
int len, UINT cp)
913#ifndef pIMultiLanguage
924 &dw, cp, pm, &n, pw, &
size);
931 size = MultiByteToWideChar(cp, 0, pm,
len,
NULL, 0);
934 MultiByteToWideChar(cp, 0, pm,
len, pw,
size);
939ole_alloc_vstr(UINT
size,
void *arg)
950 ole_wc2mb_alloc(pw, ole_alloc_vstr, &vstr);
958ole_ary_m_entry(
VALUE val, LONG *pid)
963 while(RB_TYPE_P(obj,
T_ARRAY)) {
971is_all_index_under(LONG *pid,
long *pub,
long dim)
974 for (i = 0; i < dim; i++) {
975 if (pid[i] > pub[i]) {
986 if (vt == VT_VARIANT) {
989 V_VT(var) = (vt & ~VT_BYREF);
990 if (V_VT(var) == VT_DISPATCH) {
991 V_DISPATCH(var) =
NULL;
992 }
else if (V_VT(var) == VT_UNKNOWN) {
993 V_UNKNOWN(var) =
NULL;
998#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
999 switch(vt & ~VT_BYREF) {
1002 V_I8(var) =
NUM2I8 (val);
1023 if ((vt & ~VT_BYREF) == VT_VARIANT) {
1026 if ( (vt & ~VT_BYREF) != V_VT(var)) {
1027 hr = VariantChangeTypeEx(var, var,
1033 p = get_ptr_of_variant(var);
1042get_ptr_of_variant(VARIANT *pvar)
1044 switch(V_VT(pvar)) {
1046 return &V_UI1(pvar);
1052 return &V_UI2(pvar);
1058 return &V_UI4(pvar);
1066#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
1071 return &V_UI8(pvar);
1075 return &
V_INT(pvar);
1084 return &V_DATE(pvar);
1087 return V_BSTR(pvar);
1090 return V_DISPATCH(pvar);
1093 return &V_ERROR(pvar);
1096 return &V_BOOL(pvar);
1099 return V_UNKNOWN(pvar);
1102 return &V_ARRAY(pvar);
1111ole_set_safe_array(
long n, SAFEARRAY *psa, LONG *pid,
long *pub,
VALUE val,
long dim, VARTYPE vt)
1119 val1 = ole_ary_m_entry(val, pid);
1122 if (is_all_index_under(pid, pub, dim) ==
Qtrue) {
1123 if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) ==
NULL) ||
1124 (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) ==
NULL)) {
1127 hr = SafeArrayPutElement(psa, pid, p);
1133 if (pid[i] > pub[i]) {
1143dimension(
VALUE val) {
1148 if (RB_TYPE_P(val,
T_ARRAY)) {
1150 for (i = 0; i <
len; i++) {
1162ary_len_of_dim(
VALUE ary,
long dim) {
1169 if (RB_TYPE_P(ary,
T_ARRAY)) {
1173 if (RB_TYPE_P(ary,
T_ARRAY)) {
1175 for (i = 0; i <
len; i++) {
1177 ary_len1 = ary_len_of_dim(val, dim-1);
1178 if (ary_len < ary_len1) {
1194 SAFEARRAYBOUND *psab =
NULL;
1195 SAFEARRAY *psa =
NULL;
1201 dim = dimension(val);
1203 psab =
ALLOC_N(SAFEARRAYBOUND, dim);
1207 if(!psab || !pub || !pid) {
1209 if(psab)
free(psab);
1214 for (i = 0; i < dim; i++) {
1215 psab[i].cElements = ary_len_of_dim(val, i);
1216 psab[i].lLbound = 0;
1217 pub[i] = psab[i].cElements - 1;
1221 if ((vt & ~VT_BYREF) == VT_ARRAY) {
1222 vt = (vt | VT_VARIANT);
1224 psa = SafeArrayCreate((VARTYPE)(vt & VT_TYPEMASK), dim, psab);
1228 hr = SafeArrayLock(psa);
1229 if (SUCCEEDED(hr)) {
1230 ole_set_safe_array(dim-1, psa, pid, pub, val, dim, (VARTYPE)(vt & VT_TYPEMASK));
1231 hr = SafeArrayUnlock(psa);
1235 if(psab)
free(psab);
1238 if (SUCCEEDED(hr)) {
1244 SafeArrayDestroy(psa);
1256 V_VT(var) = VT_DISPATCH;
1269 V_VT(var) = VT_DATE;
1270 V_DATE(var) = rbtime2vtdate(val);
1273 switch (
TYPE(val)) {
1278 V_VT(var) = VT_BSTR;
1285 V_I4(var) = (LONG)v;
1287 if (V_I4(var) != v) {
1303 V_VT(var) = VT_BOOL;
1304 V_BOOL(var) = VARIANT_TRUE;
1307 V_VT(var) = VT_BOOL;
1308 V_BOOL(var) = VARIANT_FALSE;
1311 if (g_nil_to == VT_ERROR) {
1312 V_VT(var) = VT_ERROR;
1313 V_ERROR(var) = DISP_E_PARAMNOTFOUND;
1315 V_VT(var) = VT_EMPTY;
1319 V_VT(var) = VT_DISPATCH;
1320 V_DISPATCH(var) = val2dispatch(val);
1328 g_nil_to = VT_EMPTY;
1330 g_nil_to = VT_ERROR;
1353ole_set_member(
VALUE self, IDispatch *dispatch)
1367fole_s_allocate(
VALUE klass)
1380 VALUE obj = fole_s_allocate(klass);
1386ary_new_dim(
VALUE myary, LONG *pid, LONG *plb, LONG dim) {
1390 long *ids =
ALLOC_N(
long, dim);
1394 for(i = 0; i < dim; i++) {
1395 ids[i] = pid[i] - plb[i];
1399 for(i = 0; i < dim-1; i++) {
1412ary_store_dim(
VALUE myary, LONG *pid, LONG *plb, LONG dim,
VALUE val) {
1413 long id = pid[dim - 1] - plb[dim - 1];
1414 VALUE obj = ary_new_dim(myary, pid, plb, dim);
1422 VARTYPE vt = V_VT(pvar);
1424 while ( vt == (VT_BYREF | VT_VARIANT) ) {
1425 pvar = V_VARIANTREF(pvar);
1429 if(V_ISARRAY(pvar)) {
1430 VARTYPE vt_base = vt & VT_TYPEMASK;
1431 SAFEARRAY *psa = V_ISBYREF(pvar) ? *V_ARRAYREF(pvar) : V_ARRAY(pvar);
1433 LONG *pid, *plb, *pub;
1440 dim = SafeArrayGetDim(psa);
1445 if(!pid || !plb || !pub) {
1452 for(i = 0; i < dim; ++i) {
1453 SafeArrayGetLBound(psa, i+1, &plb[i]);
1454 SafeArrayGetLBound(psa, i+1, &pid[i]);
1455 SafeArrayGetUBound(psa, i+1, &pub[i]);
1457 hr = SafeArrayLock(psa);
1458 if (SUCCEEDED(hr)) {
1461 VariantInit(&variant);
1462 V_VT(&variant) = vt_base | VT_BYREF;
1463 if (vt_base == VT_RECORD) {
1464 hr = SafeArrayGetRecordInfo(psa, &V_RECORDINFO(&variant));
1465 if (SUCCEEDED(hr)) {
1466 V_VT(&variant) = VT_RECORD;
1470 ary_new_dim(obj, pid, plb, dim);
1471 if (vt_base == VT_RECORD)
1472 hr = SafeArrayPtrOfIndex(psa, pid, &V_RECORD(&variant));
1474 hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant));
1475 if (SUCCEEDED(hr)) {
1477 ary_store_dim(obj, pid, plb, dim, val);
1479 for (i = 0; i < dim; ++i) {
1480 if (++pid[i] <= pub[i])
1485 SafeArrayUnlock(psa);
1492 switch(V_VT(pvar) & ~VT_BYREF){
1553#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
1556#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
1568#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
1598 bstr = *V_BSTRREF(pvar);
1600 bstr = V_BSTR(pvar);
1601 obj = (SysStringLen(bstr) == 0)
1615 if (V_ISBYREF(pvar))
1625 if (V_ISBYREF(pvar))
1645 if (V_ISBYREF(pvar))
1646 punk = *V_UNKNOWNREF(pvar);
1648 punk = V_UNKNOWN(pvar);
1651 hr = punk->lpVtbl->QueryInterface(punk, &IID_IDispatch, &p);
1664 date = *V_DATEREF(pvar);
1666 date = V_DATE(pvar);
1668 obj = vtdate2rbtime(date);
1674 IRecordInfo *pri = V_RECORDINFO(pvar);
1675 void *prec = V_RECORD(pvar);
1685 VariantInit(&variant);
1686 hr = VariantChangeTypeEx(&variant, pvar,
1688 if (SUCCEEDED(hr) && V_VT(&variant) == VT_BSTR) {
1691 VariantClear(&variant);
1701 return RegOpenKeyEx(hkey,
name, 0, KEY_READ, phkey);
1713 char buf[BUFSIZ + 1];
1716 LONG
err = RegEnumKeyEx(hkey, i,
buf, &size_buf,
1718 if(
err == ERROR_SUCCESS) {
1734 if (
err == ERROR_SUCCESS) {
1736 err = RegQueryValueEx(hkey, subkey,
NULL, &dwtype, (BYTE *)pbuf, &
size);
1737 if (
err == ERROR_SUCCESS) {
1739 if (dwtype == REG_EXPAND_SZ) {
1740 char* pbuf2 = (
char *)pbuf;
1743 ExpandEnvironmentStrings(pbuf2, pbuf,
len + 1);
1759 err = RegOpenKeyEx(hkey, subkey, 0, KEY_READ, &hsubkey);
1760 if (
err == ERROR_SUCCESS) {
1762 RegCloseKey(hsubkey);
1771ole_const_load(ITypeLib *pTypeLib,
VALUE klass,
VALUE self)
1776 ITypeInfo *pTypeInfo;
1777 TYPEATTR *pTypeAttr;
1787 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
1788 for (index = 0; index <
count; index++) {
1789 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, index, &pTypeInfo);
1797 for(iVar = 0; iVar < pTypeAttr->cVars; iVar++) {
1798 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, iVar, &pVarDesc);
1801 if(pVarDesc->varkind == VAR_CONST &&
1802 !(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
1803 VARFLAG_FRESTRICTED |
1804 VARFLAG_FNONBROWSABLE))) {
1805 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
1807 if(FAILED(hr) ||
len == 0 || !bstr)
1811 *pName = toupper((
int)*pName);
1821 SysFreeString(bstr);
1827 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
1829 pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
1836clsid_from_remote(
VALUE host,
VALUE com, CLSID *pclsid)
1848 if (
err != ERROR_SUCCESS)
1849 return HRESULT_FROM_WIN32(
err);
1854 if (
err != ERROR_SUCCESS)
1855 hr = HRESULT_FROM_WIN32(
err);
1857 len =
sizeof(clsid);
1858 err = RegQueryValueEx(hpid,
"",
NULL, &dwtype, (BYTE *)clsid, &
len);
1859 if (
err == ERROR_SUCCESS && dwtype == REG_SZ) {
1860 pbuf = ole_mb2wc(clsid, -1, cWIN32OLE_cp);
1861 hr = CLSIDFromString(pbuf, pclsid);
1862 SysFreeString(pbuf);
1865 hr = HRESULT_FROM_WIN32(
err);
1880 COSERVERINFO serverinfo;
1882 DWORD clsctx = CLSCTX_REMOTE_SERVER;
1885 gole32 = LoadLibrary(
"OLE32");
1888 if (!gCoCreateInstanceEx)
1889 gCoCreateInstanceEx = (FNCOCREATEINSTANCEEX*)
1890 GetProcAddress(gole32,
"CoCreateInstanceEx");
1891 if (!gCoCreateInstanceEx)
1895 hr = CLSIDFromProgID(pbuf, &clsid);
1897 hr = clsid_from_remote(host, ole, &clsid);
1899 hr = CLSIDFromString(pbuf, &clsid);
1900 SysFreeString(pbuf);
1903 "unknown OLE server: `%s'",
1905 memset(&serverinfo, 0,
sizeof(COSERVERINFO));
1907 memset(&multi_qi, 0,
sizeof(MULTI_QI));
1908 multi_qi.pIID = &IID_IDispatch;
1909 hr = gCoCreateInstanceEx(&clsid,
NULL, clsctx, &serverinfo, 1, &multi_qi);
1910 SysFreeString(serverinfo.pwszName);
1913 "failed to create DCOM server `%s' in `%s'",
1917 ole_set_member(self, (IDispatch*)multi_qi.pItf);
1934 hr = CreateBindCtx(0, &pBindCtx);
1937 "failed to create bind context");
1941 hr = MkParseDisplayName(pBindCtx, pbuf, &eaten, &pMoniker);
1942 SysFreeString(pbuf);
1946 "failed to parse display name of moniker `%s'",
1949 hr = pMoniker->lpVtbl->BindToObject(pMoniker, pBindCtx,
NULL,
1950 &IID_IDispatch, &p);
1957 "failed to bind moniker `%s'",
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'",
2055 ITypeInfo *pTypeInfo;
2064 if (!RB_TYPE_P(klass,
T_CLASS) &&
2066 !RB_TYPE_P(klass,
T_NIL)) {
2072 0,
lcid, &pTypeInfo);
2076 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
2082 if(!RB_TYPE_P(klass,
T_NIL)) {
2083 ole_const_load(pTypeLib, klass, self);
2086 ole_const_load(pTypeLib,
cWIN32OLE, self);
2090 else if(RB_TYPE_P(ole,
T_STRING)) {
2096 hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib);
2097 SysFreeString(pBuf);
2100 if(!RB_TYPE_P(klass,
T_NIL)) {
2101 ole_const_load(pTypeLib, klass, self);
2104 ole_const_load(pTypeLib,
cWIN32OLE, self);
2115reference_count(
struct oledata * pole)
2157 if (reference_count(pole) > 0) {
2165ole_show_help(
VALUE helpfile,
VALUE helpcontext)
2167 FNHTMLHELP *pfnHtmlHelp;
2171 ghhctrl = LoadLibrary(
"HHCTRL.OCX");
2174 pfnHtmlHelp = (FNHTMLHELP*)GetProcAddress(ghhctrl,
"HtmlHelpA");
2217 if (!RB_TYPE_P(helpfile,
T_STRING)) {
2220 hwnd = ole_show_help(helpfile, helpcontext);
2236fole_s_get_code_page(
VALUE self)
2238 return RB_INT2FIX(cWIN32OLE_cp);
2242installed_code_page_proc(LPTSTR
str) {
2243 if (strtoul(
str,
NULL, 10) == g_cp_to_check) {
2244 g_cp_installed =
TRUE;
2251code_page_installed(UINT cp)
2253 g_cp_installed =
FALSE;
2255 EnumSystemCodePages(installed_code_page_proc, CP_INSTALLED);
2256 return g_cp_installed;
2275 UINT cp = RB_FIX2INT(vcp);
2276 set_ole_codepage(cp);
2293fole_s_get_locale(
VALUE self)
2299CALLBACK installed_lcid_proc(LPTSTR
str)
2301 if (strcmp(
str, g_lcid_to_check) == 0) {
2302 g_lcid_installed =
TRUE;
2309lcid_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;
2330 LCID
lcid = RB_FIX2INT(vlcid);
2331 if (lcid_installed(
lcid)) {
2335 case LOCALE_SYSTEM_DEFAULT:
2336 case LOCALE_USER_DEFAULT:
2354fole_s_create_guid(
VALUE self)
2360 hr = CoCreateGuid(&guid);
2364 len = StringFromGUID2(&guid, bstr,
sizeof(bstr)/
sizeof(OLECHAR));
2379fole_s_ole_initialize(
VALUE self)
2387fole_s_ole_uninitialize(
VALUE self)
2469 IClassFactory2 * pIClassFactory2;
2471 static ID keyword_ids[1];
2480 return ole_create_dcom(self, svr_name, host, others);
2485 hr = CLSIDFromProgID(pBuf, &clsid);
2487 hr = CLSIDFromString(pBuf, &clsid);
2489 SysFreeString(pBuf);
2492 "unknown OLE server: `%s'",
2496 if (!keyword_ids[0]) {
2497 keyword_ids[0] = rb_intern_const(
"license");
2501 if (kwargs[0] ==
Qundef) {
2503 hr = CoCreateInstance(
2506 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
2511 hr = CoGetClassObject(
2513 CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
2515 &IID_IClassFactory2,
2516 (LPVOID)&pIClassFactory2
2520 hr = pIClassFactory2->lpVtbl->CreateInstanceLic(pIClassFactory2,
NULL,
NULL, &IID_IDispatch, key_buf, &p);
2521 SysFreeString(key_buf);
2528 "failed to create WIN32OLE object from `%s'",
2540 unsigned int index, i;
2541 index = pOp->
dp.cNamedArgs;
2547 for(i = 1; i < index + 1; i++) {
2551 for(i = 0; i < index; i++ ) {
2552 VariantClear(&(pOp->
dp.rgvarg[i]));
2564 VariantInit(&(pOp->
dp.rgvarg[index]));
2567 pOp->
dp.cNamedArgs += 1;
2572set_argv(VARIANTARG* realargs,
unsigned int beg,
unsigned int end)
2578 while (end-- > beg) {
2580 if (V_VT(&realargs[end]) != VT_RECORD) {
2581 VariantClear(&realargs[end]);
2603 EXCEPINFO excepinfo;
2605 VARIANTARG* realargs =
NULL;
2606 unsigned int argErr = 0;
2608 unsigned int cNamedArgs;
2611 memset(&excepinfo, 0,
sizeof(EXCEPINFO));
2613 VariantInit(&result);
2615 op.dp.rgvarg =
NULL;
2616 op.dp.rgdispidNamedArgs =
NULL;
2617 op.dp.cNamedArgs = 0;
2621 if(!RB_TYPE_P(cmd,
T_STRING) && !RB_TYPE_P(cmd,
T_SYMBOL) && !is_bracket) {
2632 DispID = DISPID_VALUE;
2638 &wcmdname, 1,
lcid, &DispID);
2639 SysFreeString(wcmdname);
2648 op.dp.cNamedArgs = 0;
2651 if(RB_TYPE_P(param,
T_HASH)) {
2656 op.dp.cArgs = cNamedArgs +
argc - 2;
2657 op.pNamedArgs =
ALLOCA_N(OLECHAR*, cNamedArgs + 1);
2658 op.dp.rgvarg =
ALLOCA_N(VARIANTARG, op.dp.cArgs);
2662 pDispID =
ALLOCA_N(DISPID, cNamedArgs + 1);
2667 op.dp.cNamedArgs + 1,
2669 for(i = 0; i < op.dp.cNamedArgs + 1; i++) {
2670 SysFreeString(op.pNamedArgs[i]);
2671 op.pNamedArgs[i] =
NULL;
2675 for(i = 0; i < op.dp.cArgs; i++ ) {
2676 VariantClear(&op.dp.rgvarg[i]);
2679 "failed to get named argument info: `%s'",
2682 op.dp.rgdispidNamedArgs = &(pDispID[1]);
2686 op.dp.cArgs =
argc - 1;
2687 op.pNamedArgs =
ALLOCA_N(OLECHAR*, cNamedArgs + 1);
2688 if (op.dp.cArgs > 0) {
2689 op.dp.rgvarg =
ALLOCA_N(VARIANTARG, op.dp.cArgs);
2695 if(op.dp.cArgs > cNamedArgs) {
2696 realargs =
ALLOCA_N(VARIANTARG, op.dp.cArgs-cNamedArgs+1);
2697 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
2698 n = op.dp.cArgs - i + cNamedArgs - 1;
2699 VariantInit(&realargs[n]);
2700 VariantInit(&op.dp.rgvarg[n]);
2706 op.dp.rgvarg[n] = realargs[n];
2707 V_VT(&op.dp.rgvarg[n]) = VT_RECORD | VT_BYREF;
2710 V_VT(&op.dp.rgvarg[n]) = VT_VARIANT | VT_BYREF;
2711 V_VARIANTREF(&op.dp.rgvarg[n]) = &realargs[n];
2716 if (
wFlags & DISPATCH_PROPERTYPUT) {
2717 if (op.dp.cArgs == 0)
2720 op.dp.cNamedArgs = 1;
2721 op.dp.rgdispidNamedArgs =
ALLOCA_N( DISPID, 1 );
2722 op.dp.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
2726 &result, &excepinfo, &argErr);
2730 if(op.dp.cArgs >= cNamedArgs) {
2731 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
2732 n = op.dp.cArgs - i + cNamedArgs - 1;
2736 if (hr == DISP_E_EXCEPTION) {
2737 ole_freeexceptinfo(&excepinfo);
2739 memset(&excepinfo, 0,
sizeof(EXCEPINFO));
2740 VariantInit(&result);
2744 &excepinfo, &argErr);
2750 if ((hr == DISP_E_EXCEPTION || hr == DISP_E_MEMBERNOTFOUND) && DispID > 0x8000) {
2751 if (hr == DISP_E_EXCEPTION) {
2752 ole_freeexceptinfo(&excepinfo);
2754 memset(&excepinfo, 0,
sizeof(EXCEPINFO));
2758 &excepinfo, &argErr);
2761 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
2762 n = op.dp.cArgs - i + cNamedArgs - 1;
2763 if (V_VT(&op.dp.rgvarg[n]) != VT_RECORD) {
2764 VariantClear(&op.dp.rgvarg[n]);
2771 if (op.dp.cArgs > cNamedArgs) {
2772 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
2773 n = op.dp.cArgs - i + cNamedArgs - 1;
2777 if (hr == DISP_E_EXCEPTION) {
2778 ole_freeexceptinfo(&excepinfo);
2780 memset(&excepinfo, 0,
sizeof(EXCEPINFO));
2781 VariantInit(&result);
2785 &excepinfo, &argErr);
2786 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
2787 n = op.dp.cArgs - i + cNamedArgs - 1;
2788 if (V_VT(&op.dp.rgvarg[n]) != VT_RECORD) {
2789 VariantClear(&op.dp.rgvarg[n]);
2797 if(op.dp.cArgs > cNamedArgs) {
2798 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
2799 n = op.dp.cArgs - i + cNamedArgs - 1;
2804 V_VT(&realargs[n]) == VT_RECORD ) {
2808 set_argv(realargs, cNamedArgs, op.dp.cArgs);
2811 for(i = 0; i < op.dp.cArgs; i++) {
2812 VariantClear(&op.dp.rgvarg[i]);
2817 v = ole_excepinfo2msg(&excepinfo);
2823 VariantClear(&result);
2855 unsigned int argErr = 0;
2856 EXCEPINFO excepinfo;
2858 DISPPARAMS dispParams;
2859 VARIANTARG* realargs =
NULL;
2868 memset(&excepinfo, 0,
sizeof(EXCEPINFO));
2869 memset(&dispParams, 0,
sizeof(DISPPARAMS));
2870 VariantInit(&result);
2874 dispParams.rgvarg =
ALLOCA_N(VARIANTARG, dispParams.cArgs);
2875 realargs =
ALLOCA_N(VARIANTARG, dispParams.cArgs);
2876 for (i = 0, j = dispParams.cArgs - 1; i < (
int)dispParams.cArgs; i++, j--)
2878 VariantInit(&realargs[i]);
2879 VariantInit(&dispParams.rgvarg[i]);
2881 vt = (VARTYPE)RB_FIX2INT(tp);
2882 V_VT(&dispParams.rgvarg[i]) = vt;
2887 V_VT(&dispParams.rgvarg[i]) = V_VT(&realargs[i]) = VT_ERROR;
2888 V_ERROR(&dispParams.rgvarg[i]) = V_ERROR(&realargs[i]) = DISP_E_PARAMNOTFOUND;
2901 SAFEARRAYBOUND rgsabound[1];
2903 rgsabound[0].lLbound = 0;
2905 v = vt & ~(VT_ARRAY | VT_BYREF);
2906 V_ARRAY(&realargs[i]) = SafeArrayCreate(v, 1, rgsabound);
2907 V_VT(&realargs[i]) = VT_ARRAY | v;
2908 SafeArrayLock(V_ARRAY(&realargs[i]));
2909 pb = V_ARRAY(&realargs[i])->pvData;
2910 ps = V_ARRAY(&realargs[i])->pvData;
2911 pl = V_ARRAY(&realargs[i])->pvData;
2912 py = V_ARRAY(&realargs[i])->pvData;
2913 pv = V_ARRAY(&realargs[i])->pvData;
2914 for (ent = 0; ent < (
int)rgsabound[0].cElements; ent++)
2919 if (v != VT_VARIANT)
2921 VariantChangeTypeEx(&velem, &velem,
2934 *py++ = V_CY(&velem);
2940 *ps++ = V_I2(&velem);
2945 *pb++ = V_UI1(&velem);
2949 *pl++ = V_I4(&velem);
2953 SafeArrayUnlock(V_ARRAY(&realargs[i]));
2958 if ((vt & (~VT_BYREF)) != VT_VARIANT)
2960 hr = VariantChangeTypeEx(&realargs[i], &realargs[i],
2962 (VARTYPE)(vt & (~VT_BYREF)));
2969 if ((vt & VT_BYREF) || vt == VT_VARIANT)
2971 if (vt == VT_VARIANT)
2972 V_VT(&dispParams.rgvarg[i]) = VT_VARIANT | VT_BYREF;
2973 switch (vt & (~VT_BYREF))
2977 V_VARIANTREF(&dispParams.rgvarg[i]) = &realargs[i];
2983 V_CYREF(&dispParams.rgvarg[i]) = &V_CY(&realargs[i]);
2989 V_I2REF(&dispParams.rgvarg[i]) = &V_I2(&realargs[i]);
2994 V_UI1REF(&dispParams.rgvarg[i]) = &V_UI1(&realargs[i]);
2998 V_I4REF(&dispParams.rgvarg[i]) = &V_I4(&realargs[i]);
3005 V_CY(&dispParams.rgvarg[i]) = V_CY(&realargs[i]);
3010 if (dispkind & DISPATCH_PROPERTYPUT) {
3011 dispParams.cNamedArgs = 1;
3012 dispParams.rgdispidNamedArgs =
ALLOCA_N( DISPID, 1 );
3013 dispParams.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
3019 &dispParams, &result,
3020 &excepinfo, &argErr);
3023 v = ole_excepinfo2msg(&excepinfo);
3030 if(dispParams.cArgs > 0) {
3031 set_argv(realargs, 0, dispParams.cArgs);
3035 VariantClear(&result);
3054 return ole_invoke2(self, dispid, args,
types, DISPATCH_METHOD);
3072 return ole_invoke2(self, dispid, args,
types, DISPATCH_PROPERTYGET);
3090 return ole_invoke2(self, dispid, args,
types, DISPATCH_PROPERTYPUT);
3177 EXCEPINFO excepinfo;
3178 DISPID dispID = DISPID_VALUE;
3179 DISPID dispIDParam = DISPID_PROPERTYPUT;
3180 USHORT
wFlags = DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF;
3181 DISPPARAMS dispParams;
3182 VARIANTARG propertyValue[2];
3186 dispParams.rgdispidNamedArgs = &dispIDParam;
3187 dispParams.rgvarg = propertyValue;
3188 dispParams.cNamedArgs = 1;
3189 dispParams.cArgs = 1;
3191 VariantInit(&propertyValue[0]);
3192 VariantInit(&propertyValue[1]);
3193 memset(&excepinfo, 0,
sizeof(excepinfo));
3200 pBuf, 1,
lcid, &dispID);
3201 SysFreeString(pBuf[0]);
3206 "unknown property or method: `%s'",
3213 NULL, &excepinfo, &argErr);
3215 for(index = 0; index < dispParams.cArgs; ++index) {
3216 VariantClear(&propertyValue[index]);
3219 v = ole_excepinfo2msg(&excepinfo);
3237fole_free(
VALUE self)
3247ole_each_sub(
VALUE pEnumV)
3251 IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
3252 VariantInit(&variant);
3253 while(pEnum->lpVtbl->Next(pEnum, 1, &variant,
NULL) == S_OK) {
3255 VariantClear(&variant);
3256 VariantInit(&variant);
3263ole_ienum_free(
VALUE pEnumV)
3265 IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
3285fole_each(
VALUE self)
3291 unsigned int argErr;
3292 EXCEPINFO excepinfo;
3293 DISPPARAMS dispParams;
3296 IEnumVARIANT *pEnum =
NULL;
3301 VariantInit(&result);
3302 dispParams.rgvarg =
NULL;
3303 dispParams.rgdispidNamedArgs =
NULL;
3304 dispParams.cNamedArgs = 0;
3305 dispParams.cArgs = 0;
3306 memset(&excepinfo, 0,
sizeof(excepinfo));
3311 DISPATCH_METHOD | DISPATCH_PROPERTYGET,
3312 &dispParams, &result,
3313 &excepinfo, &argErr);
3316 VariantClear(&result);
3320 if (V_VT(&result) == VT_UNKNOWN) {
3321 hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result),
3325 }
else if (V_VT(&result) == VT_DISPATCH) {
3326 hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result),
3331 if (FAILED(hr) || !pEnum) {
3332 VariantClear(&result);
3336 VariantClear(&result);
3354 mid = org_mid =
argv[0];
3362 if(mname[n-1] ==
'=') {
3366 return ole_propertyput(self,
argv[0],
argv[1]);
3370 v = ole_invoke(
argc,
argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET,
FALSE);
3380typeinfo_from_ole(
struct oledata *pole, ITypeInfo **ppti)
3382 ITypeInfo *pTypeInfo;
3390 0,
lcid, &pTypeInfo);
3394 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo,
3399 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
3404 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
3405 for (i = 0; i <
count; i++) {
3406 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
3409 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
3410 if (SUCCEEDED(hr)) {
3423 ITypeInfo *pTypeInfo;
3431 hr = typeinfo_from_ole(pole, &pTypeInfo);
3451fole_methods(
VALUE self)
3453 return ole_methods( self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
3467fole_get_methods(
VALUE self)
3469 return ole_methods( self, INVOKE_PROPERTYGET);
3483fole_put_methods(
VALUE self)
3485 return ole_methods( self, INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF);
3500fole_func_methods(
VALUE self)
3502 return ole_methods( self, INVOKE_FUNC);
3515fole_type(
VALUE self)
3517 ITypeInfo *pTypeInfo;
3549fole_typelib(
VALUE self)
3553 ITypeInfo *pTypeInfo;
3559 0,
lcid, &pTypeInfo);
3565 if (vtlib ==
Qnil) {
3582fole_query_interface(
VALUE self,
VALUE str_iid)
3592 hr = CLSIDFromString(pBuf, &iid);
3593 SysFreeString(pBuf);
3596 "invalid iid: `%s'",
3609 "failed to get interface `%s'",
3643 SysFreeString(wcmdname);
3654 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
3659 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
3661 helpcontext, helpfile);
3671ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc,
VALUE typedetails)
3675 ITypeInfo *pRefTypeInfo;
3678 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
3690 if(typedetails !=
Qnil)
3696ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc,
VALUE typedetails)
3698 TYPEDESC *p = pTypeDesc;
3701 if (p->vt == VT_PTR || p->vt == VT_SAFEARRAY) {
3713 switch(pTypeDesc->vt) {
3756#if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
3778 if(typedetails !=
Qnil)
3780 return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
3783 if(typedetails !=
Qnil)
3785 return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
3789 case VT_USERDEFINED:
3791 if (typedetails !=
Qnil)
3793 str = ole_usertype2val(pTypeInfo, pTypeDesc, typedetails);
3821 if (typedetails !=
Qnil)
3840 ITypeInfo *pTypeInfo;
3847 hr = typeinfo_from_ole(pole, &pTypeInfo);
3881fole_activex_initialize(
VALUE self)
3884 IPersistMemory *pPersistMemory;
3891 hr = pole->
pDispatch->lpVtbl->QueryInterface(pole->
pDispatch, &IID_IPersistMemory, &p);
3893 if (SUCCEEDED(hr)) {
3894 hr = pPersistMemory->lpVtbl->InitNew(pPersistMemory);
3896 if (SUCCEEDED(hr)) {
3915 ITypeInfo *pTypeInfo;
3918 0,
lcid, &pTypeInfo);
3922 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, pTypeLib, &index);
3928com_hash_free(
void *
ptr)
3935com_hash_mark(
void *
ptr)
3942com_hash_size(
const void *
ptr)
3949check_nano_server(
void)
3953 const char * subkey =
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Server\\ServerLevels";
3954 const char * regval =
"NanoServer";
3956 err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, subkey, 0, KEY_READ, &hsubkey);
3957 if (
err == ERROR_SUCCESS) {
3959 if (
err == ERROR_SUCCESS) {
3960 g_running_nano =
TRUE;
3962 RegCloseKey(hsubkey);
3973 check_nano_server();
3975 com_vtbl.QueryInterface = QueryInterface;
3976 com_vtbl.AddRef = AddRef;
3977 com_vtbl.Release = Release;
3978 com_vtbl.GetTypeInfoCount = GetTypeInfoCount;
3979 com_vtbl.GetTypeInfo = GetTypeInfo;
3980 com_vtbl.GetIDsOfNames = GetIDsOfNames;
3981 com_vtbl.Invoke = Invoke;
3983 message_filter.QueryInterface = mf_QueryInterface;
3984 message_filter.AddRef = mf_AddRef;
3985 message_filter.Release = mf_Release;
3986 message_filter.HandleInComingCall = mf_HandleInComingCall;
3987 message_filter.RetryRejectedCall = mf_RetryRejectedCall;
3988 message_filter.MessagePending = mf_MessagePending;
void rb_ary_store(VALUE ary, long idx, VALUE val)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_ary_unshift(VALUE ary, VALUE item)
VALUE rb_ary_concat(VALUE x, VALUE y)
VALUE rb_ary_clear(VALUE ary)
VALUE rb_ary_entry(VALUE ary, long offset)
double rb_big2dbl(VALUE x)
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
void rb_add_event_hook(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data)
VALUE rb_enc_associate(VALUE obj, rb_encoding *enc)
rb_encoding * rb_enc_from_index(int index)
rb_encoding * rb_default_internal_encoding(void)
rb_encoding * rb_enc_get(VALUE obj)
int rb_define_dummy_encoding(const char *name)
rb_encoding * rb_default_external_encoding(void)
int rb_enc_find_index(const char *name)
char str[HTML_ESCAPE_MAX_LEN+1]
#define RUBY_EVENT_THREAD_END
#define RSTRING_LEN(string)
#define RSTRING_PTR(string)
void rb_mark_hash(st_table *tbl)
void rb_gc_register_mark_object(VALUE obj)
Inform the garbage collector that object is a live Ruby object that should not be moved.
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
VALUE rb_cObject
Object class.
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
ID rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
VALUE rb_call_super(int, const VALUE *)
#define RETURN_ENUMERATOR(obj, argc, argv)
#define UNLIMITED_ARGUMENTS
VALUE rb_fix2str(VALUE, int)
VALUE rb_str_concat(VALUE, VALUE)
VALUE rb_str_cat(VALUE, const char *, long)
void rb_str_set_len(VALUE, long)
int rb_str_cmp(VALUE, VALUE)
VALUE rb_str_subseq(VALUE, long, long)
VALUE rb_const_get(VALUE, ID)
VALUE rb_ivar_get(VALUE, ID)
int rb_const_defined_at(VALUE, ID)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_check_symbol(volatile VALUE *namep)
Returns Symbol for the given name if it is interned already, or nil.
ID rb_intern(const char *)
void rb_define_const(VALUE, const char *, VALUE)
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
#define ALLOCA_N(type, n)
#define MEMCMP(p1, p2, type, n)
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define SafeStringValue(v)
#define StringValuePtr(v)
#define StringValueCStr(v)
#define RTYPEDDATA_DATA(v)
#define TypedData_Get_Struct(obj, type, data_type, sval)
#define TypedData_Wrap_Struct(klass, data_type, sval)
@ RUBY_TYPED_FREE_IMMEDIATELY
#define TypedData_Make_Struct(klass, type, data_type, sval)
VALUE rb_sprintf(const char *,...)
size_t strlen(const char *)
char CodePageName[MAX_PATH]
HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile)
LPWSTR ole_vstr2wc(VALUE vstr)
VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
VALUE reg_get_val2(HKEY hkey, const char *subkey)
HRESULT ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt)
LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey)
IUnknown COSERVERINFO MULTI_QI *typedef LPCSTR pszFile
static DISPID dispIdMember
typedef HRESULT(STDAPICALLTYPE FNCOCREATEINSTANCEEX)(REFCLSID
VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree)
void ole_uninitialize(void)
BOOL() FNENUMSYSEMCODEPAGES(CODEPAGE_ENUMPROC, DWORD)
static DWORD HTASK threadIDCaller
void ole_val2variant_ex(VALUE val, VARIANT *var, VARTYPE vt)
static DISPID REFIID LCID WORD DISPPARAMS __RPC_FAR VARIANT __RPC_FAR * pVarResult
#define load_conv_function51932()
static DISPID REFIID LCID WORD wFlags
VALUE default_inspect(VALUE self, const char *class_name)
#define ENC_MACHING_CP(enc, encname, cp)
VALUE ole_variant2val(VARIANT *pvar)
void ole_val2variant2(VALUE val, VARIANT *var)
IUnknown COSERVERINFO MULTI_QI *typedef LPCSTR UINT uCommand
#define g_ole_initialized
static HTASK threadIDCallee
IUnknown COSERVERINFO MULTI_QI *typedef HWND(WINAPI FNHTMLHELP)(HWND hwndCaller
static HTASK DWORD DWORD dwPendingType
static DWORD HTASK DWORD LPINTERFACEINFO lpInterfaceInfo
static REFIID LPOLESTR __RPC_FAR * rgszNames
static DISPID REFIID LCID WORD DISPPARAMS __RPC_FAR VARIANT __RPC_FAR EXCEPINFO __RPC_FAR * pExcepInfo
static UINT LCID ITypeInfo __RPC_FAR *__RPC_FAR * ppTInfo
VALUE reg_get_val(HKEY hkey, const char *subkey)
BOOL ole_initialized(void)
#define g_ole_initialized_init()
static REFIID void __RPC_FAR *__RPC_FAR * ppvObject
void ole_initialize(void)
static DISPID REFIID LCID WORD DISPPARAMS __RPC_FAR VARIANT __RPC_FAR EXCEPINFO __RPC_FAR UINT __RPC_FAR * puArgErr
static REFIID LPOLESTR __RPC_FAR UINT LCID DISPID __RPC_FAR * rgDispId
IUnknown COSERVERINFO MULTI_QI *typedef LPCSTR UINT DWORD dwData
VOID * val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt)
static HTASK DWORD DWORD dwRejectType
static UINT __RPC_FAR * pctinfo
#define ole_wc2mb_conv(pw, pm, size)
static REFIID LPOLESTR __RPC_FAR UINT cNames
VALUE make_inspect(const char *class_name, VALUE detail)
char * ole_wc2mb(LPWSTR pw)
static DISPID REFIID LCID WORD DISPPARAMS __RPC_FAR * pDispParams
void ole_val2variant(VALUE val, VARIANT *var)
LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey)
struct _Win32OLEIDispatch Win32OLEIDispatch
static DWORD HTASK DWORD dwTickCount
VALUE reg_enum_key(HKEY hkey, DWORD i)
HRESULT typelib_from_val(VALUE obj, ITypeLib **pTypeLib)
struct oledata * oledata_get_struct(VALUE ole)
#define g_ole_initialized_set(val)
#define OLE_GET_TYPEATTR(X, Y)
VALUE eWIN32OLERuntimeError
VALUE eWIN32OLEQueryInterfaceError
void Init_win32ole_error(void)
void ole_raise(HRESULT hr, VALUE ecs, const char *fmt,...)
void Init_win32ole_event(void)
VALUE ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask)
VALUE create_win32ole_method(ITypeInfo *pTypeInfo, VALUE name)
void Init_win32ole_method(void)
void Init_win32ole_param(void)
void Init_win32ole_record(void)
void ole_rec2variant(VALUE rec, VARIANT *var)
void olerecord_set_ivar(VALUE obj, IRecordInfo *pri, void *prec)
VALUE create_win32ole_record(IRecordInfo *pri, void *prec)
VALUE ole_type_from_itypeinfo(ITypeInfo *pTypeInfo)
void Init_win32ole_type(void)
VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo)
void Init_win32ole_typelib(void)
VALUE typelib_file(VALUE ole)
void Init_win32ole_variable(void)
void ole_variant2variant(VALUE val, VARIANT *var)
void Init_win32ole_variant(void)
void Init_win32ole_variant_m(void)