00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "ruby/ruby.h"
00019 #include "ruby/st.h"
00020 #include "ruby/encoding.h"
00021
00022 #define GNUC_OLDER_3_4_4 \
00023 ((__GNUC__ < 3) || \
00024 ((__GNUC__ <= 3) && (__GNUC_MINOR__ < 4)) || \
00025 ((__GNUC__ <= 3) && (__GNUC_MINOR__ <= 4) && (__GNUC_PATCHLEVEL__ <= 4)))
00026
00027 #if (defined(__GNUC__)) && (GNUC_OLDER_3_4_4)
00028 #ifndef NONAMELESSUNION
00029 #define NONAMELESSUNION 1
00030 #endif
00031 #endif
00032
00033 #include <ctype.h>
00034
00035 #include <windows.h>
00036 #include <ocidl.h>
00037 #include <olectl.h>
00038 #include <ole2.h>
00039 #if defined(HAVE_TYPE_IMULTILANGUAGE2) || defined(HAVE_TYPE_IMULTILANGUAGE)
00040 #include <mlang.h>
00041 #endif
00042 #include <stdlib.h>
00043 #include <math.h>
00044 #ifdef HAVE_STDARG_PROTOTYPES
00045 #include <stdarg.h>
00046 #define va_init_list(a,b) va_start(a,b)
00047 #else
00048 #include <varargs.h>
00049 #define va_init_list(a,b) va_start(a)
00050 #endif
00051 #include <objidl.h>
00052
00053 #define DOUT fprintf(stderr,"[%d]\n",__LINE__)
00054 #define DOUTS(x) fprintf(stderr,"[%d]:" #x "=%s\n",__LINE__,x)
00055 #define DOUTMSG(x) fprintf(stderr, "[%d]:" #x "\n",__LINE__)
00056 #define DOUTI(x) fprintf(stderr, "[%ld]:" #x "=%d\n",__LINE__,x)
00057 #define DOUTD(x) fprintf(stderr, "[%d]:" #x "=%f\n",__LINE__,x)
00058
00059 #if (defined(__GNUC__)) && (GNUC_OLDER_3_4_4)
00060 #define V_UNION1(X, Y) ((X)->u.Y)
00061 #else
00062 #define V_UNION1(X, Y) ((X)->Y)
00063 #endif
00064
00065 #if (defined(__GNUC__)) && (GNUC_OLDER_3_4_4)
00066 #undef V_UNION
00067 #define V_UNION(X,Y) ((X)->n1.n2.n3.Y)
00068
00069 #undef V_VT
00070 #define V_VT(X) ((X)->n1.n2.vt)
00071
00072 #undef V_BOOL
00073 #define V_BOOL(X) V_UNION(X,boolVal)
00074 #endif
00075
00076 #ifndef V_I1REF
00077 #define V_I1REF(X) V_UNION(X, pcVal)
00078 #endif
00079
00080 #ifndef U_UI2REF
00081 #define V_UI2REF(X) V_UNION(X, puiVal)
00082 #endif
00083
00084 #ifndef V_INT
00085 #define V_INT(X) V_UNION(X, intVal)
00086 #endif
00087
00088 #ifndef V_INTREF
00089 #define V_INTREF(X) V_UNION(X, pintVal)
00090 #endif
00091
00092 #ifndef V_UINT
00093 #define V_UINT(X) V_UNION(X, uintVal)
00094 #endif
00095
00096 #ifndef V_UINTREF
00097 #define V_UINTREF(X) V_UNION(X, puintVal)
00098 #endif
00099
00100
00101
00102
00103
00104 #if defined(__CYGWIN__) || defined(__MINGW32__)
00105 #undef IID_IMultiLanguage2
00106 const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A}};
00107 #endif
00108
00109 #define OLE_RELEASE(X) (X) ? ((X)->lpVtbl->Release(X)) : 0
00110
00111 #define OLE_ADDREF(X) (X) ? ((X)->lpVtbl->AddRef(X)) : 0
00112
00113 #define OLE_GET_TYPEATTR(X, Y) ((X)->lpVtbl->GetTypeAttr((X), (Y)))
00114 #define OLE_RELEASE_TYPEATTR(X, Y) ((X)->lpVtbl->ReleaseTypeAttr((X), (Y)))
00115
00116 #define OLE_FREE(x) {\
00117 if(g_ole_initialized == TRUE) {\
00118 if(x) {\
00119 OLE_RELEASE(x);\
00120 (x) = 0;\
00121 }\
00122 }\
00123 }
00124
00125 #define OLEData_Get_Struct(obj, pole) {\
00126 Data_Get_Struct(obj, struct oledata, pole);\
00127 if(!pole->pDispatch) {\
00128 rb_raise(rb_eRuntimeError, "failed to get Dispatch Interface");\
00129 }\
00130 }
00131
00132 #ifdef HAVE_LONG_LONG
00133 #define I8_2_NUM LL2NUM
00134 #define UI8_2_NUM ULL2NUM
00135 #define NUM2I8 NUM2LL
00136 #define NUM2UI8 NUM2ULL
00137 #else
00138 #define I8_2_NUM INT2NUM
00139 #define UI8_2_NUM UINT2NUM
00140 #define NUM2I8 NUM2INT
00141 #define NUM2UI8 NUM2UINT
00142 #endif
00143
00144 #define WC2VSTR(x) ole_wc2vstr((x), TRUE)
00145
00146 #define WIN32OLE_VERSION "1.4.9"
00147
00148 typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
00149 (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
00150
00151 typedef HWND (WINAPI FNHTMLHELP)(HWND hwndCaller, LPCSTR pszFile,
00152 UINT uCommand, DWORD dwData);
00153 typedef BOOL (FNENUMSYSEMCODEPAGES) (CODEPAGE_ENUMPROC, DWORD);
00154 typedef struct {
00155 struct IEventSinkVtbl * lpVtbl;
00156 } IEventSink, *PEVENTSINK;
00157
00158 typedef struct IEventSinkVtbl IEventSinkVtbl;
00159
00160 struct IEventSinkVtbl {
00161 STDMETHOD(QueryInterface)(
00162 PEVENTSINK,
00163 REFIID,
00164 LPVOID *);
00165 STDMETHOD_(ULONG, AddRef)(PEVENTSINK);
00166 STDMETHOD_(ULONG, Release)(PEVENTSINK);
00167
00168 STDMETHOD(GetTypeInfoCount)(
00169 PEVENTSINK,
00170 UINT *);
00171 STDMETHOD(GetTypeInfo)(
00172 PEVENTSINK,
00173 UINT,
00174 LCID,
00175 ITypeInfo **);
00176 STDMETHOD(GetIDsOfNames)(
00177 PEVENTSINK,
00178 REFIID,
00179 OLECHAR **,
00180 UINT,
00181 LCID,
00182 DISPID *);
00183 STDMETHOD(Invoke)(
00184 PEVENTSINK,
00185 DISPID,
00186 REFIID,
00187 LCID,
00188 WORD,
00189 DISPPARAMS *,
00190 VARIANT *,
00191 EXCEPINFO *,
00192 UINT *);
00193 };
00194
00195 typedef struct tagIEVENTSINKOBJ {
00196 IEventSinkVtbl *lpVtbl;
00197 DWORD m_cRef;
00198 IID m_iid;
00199 int m_event_id;
00200 ITypeInfo *pTypeInfo;
00201 }IEVENTSINKOBJ, *PIEVENTSINKOBJ;
00202
00203 VALUE cWIN32OLE;
00204 VALUE cWIN32OLE_TYPELIB;
00205 VALUE cWIN32OLE_TYPE;
00206 VALUE cWIN32OLE_VARIABLE;
00207 VALUE cWIN32OLE_METHOD;
00208 VALUE cWIN32OLE_PARAM;
00209 VALUE cWIN32OLE_EVENT;
00210 VALUE cWIN32OLE_VARIANT;
00211 VALUE eWIN32OLERuntimeError;
00212 VALUE mWIN32OLE_VARIANT;
00213 VALUE cWIN32OLE_PROPERTY;
00214
00215 static VALUE ary_ole_event;
00216 static ID id_events;
00217 static BOOL g_ole_initialized = FALSE;
00218 static BOOL g_cp_installed = FALSE;
00219 static BOOL g_lcid_installed = FALSE;
00220 static HINSTANCE ghhctrl = NULL;
00221 static HINSTANCE gole32 = NULL;
00222 static FNCOCREATEINSTANCEEX *gCoCreateInstanceEx = NULL;
00223 static VALUE com_hash;
00224 static IDispatchVtbl com_vtbl;
00225 static UINT cWIN32OLE_cp = CP_ACP;
00226 static LCID cWIN32OLE_lcid = LOCALE_SYSTEM_DEFAULT;
00227 static rb_encoding *cWIN32OLE_enc;
00228 static UINT g_cp_to_check = CP_ACP;
00229 static char g_lcid_to_check[8 + 1];
00230 static VARTYPE g_nil_to = VT_ERROR;
00231 static st_table *enc2cp_table;
00232 static IMessageFilterVtbl message_filter;
00233 static IMessageFilter imessage_filter = { &message_filter };
00234 static IMessageFilter* previous_filter;
00235
00236 #if defined(HAVE_TYPE_IMULTILANGUAGE2)
00237 static IMultiLanguage2 *pIMultiLanguage = NULL;
00238 #elif defined(HAVE_TYPE_IMULTILANGUAGE)
00239 static IMultiLanguage *pIMultiLanguage = NULL;
00240 #else
00241 #define pIMultiLanguage NULL
00242 #endif
00243
00244 struct oledata {
00245 IDispatch *pDispatch;
00246 };
00247
00248 struct oletypelibdata {
00249 ITypeLib *pTypeLib;
00250 };
00251
00252 struct oletypedata {
00253 ITypeInfo *pTypeInfo;
00254 };
00255
00256 struct olemethoddata {
00257 ITypeInfo *pOwnerTypeInfo;
00258 ITypeInfo *pTypeInfo;
00259 UINT index;
00260 };
00261
00262 struct olevariabledata {
00263 ITypeInfo *pTypeInfo;
00264 UINT index;
00265 };
00266
00267 struct oleparamdata {
00268 ITypeInfo *pTypeInfo;
00269 UINT method_index;
00270 UINT index;
00271 };
00272
00273 struct oleeventdata {
00274 DWORD dwCookie;
00275 IConnectionPoint *pConnectionPoint;
00276 long event_id;
00277 };
00278
00279 struct oleparam {
00280 DISPPARAMS dp;
00281 OLECHAR** pNamedArgs;
00282 };
00283
00284 struct olevariantdata {
00285 VARIANT realvar;
00286 VARIANT var;
00287 };
00288
00289
00290 static HRESULT ( STDMETHODCALLTYPE QueryInterface )(IDispatch __RPC_FAR *, REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject);
00291 static ULONG ( STDMETHODCALLTYPE AddRef )(IDispatch __RPC_FAR * This);
00292 static ULONG ( STDMETHODCALLTYPE Release )(IDispatch __RPC_FAR * This);
00293 static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )(IDispatch __RPC_FAR * This, UINT __RPC_FAR *pctinfo);
00294 static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )(IDispatch __RPC_FAR * This, UINT iTInfo, LCID lcid, ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
00295 static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )(IDispatch __RPC_FAR * This, REFIID riid, LPOLESTR __RPC_FAR *rgszNames, UINT cNames, LCID lcid, DISPID __RPC_FAR *rgDispId);
00296 static HRESULT ( STDMETHODCALLTYPE Invoke )( IDispatch __RPC_FAR * This, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS __RPC_FAR *pDispParams, VARIANT __RPC_FAR *pVarResult, EXCEPINFO __RPC_FAR *pExcepInfo, UINT __RPC_FAR *puArgErr);
00297 static IDispatch* val2dispatch(VALUE val);
00298 static double rbtime2vtdate(VALUE tmobj);
00299 static VALUE vtdate2rbtime(double date);
00300 static rb_encoding *ole_cp2encoding(UINT cp);
00301 static UINT ole_encoding2cp(rb_encoding *enc);
00302 NORETURN(static void failed_load_conv51932(void));
00303 #ifndef pIMultiLanguage
00304 static void load_conv_function51932(void);
00305 #endif
00306 static UINT ole_init_cp(void);
00307 static char *ole_wc2mb(LPWSTR pw);
00308 static VALUE ole_hresult2msg(HRESULT hr);
00309 static void ole_freeexceptinfo(EXCEPINFO *pExInfo);
00310 static VALUE ole_excepinfo2msg(EXCEPINFO *pExInfo);
00311 static void ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...);
00312 static void ole_initialize();
00313 static void ole_msg_loop();
00314 static void ole_free(struct oledata *pole);
00315 static void oletypelib_free(struct oletypelibdata *poletypelib);
00316 static void oletype_free(struct oletypedata *poletype);
00317 static void olemethod_free(struct olemethoddata *polemethod);
00318 static void olevariable_free(struct olevariabledata *polevar);
00319 static void oleparam_free(struct oleparamdata *pole);
00320 static LPWSTR ole_vstr2wc(VALUE vstr);
00321 static LPWSTR ole_mb2wc(char *pm, int len);
00322 static VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree);
00323 static VALUE ole_ary_m_entry(VALUE val, long *pid);
00324 static void * get_ptr_of_variant(VARIANT *pvar);
00325 static VALUE is_all_index_under(long *pid, long *pub, long dim);
00326 static void ole_set_safe_array(long n, SAFEARRAY *psa, long *pid, long *pub, VALUE val, long dim, VARTYPE vt);
00327 static long dimension(VALUE val);
00328 static long ary_len_of_dim(VALUE ary, long dim);
00329 static HRESULT ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt);
00330 static void ole_val2variant(VALUE val, VARIANT *var);
00331 static void ole_val2variant_ex(VALUE val, VARIANT *var, VARTYPE vt);
00332 static void ole_val2ptr_variant(VALUE val, VARIANT *var);
00333 static void ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt);
00334 static void ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar);
00335 static void ole_val2variant2(VALUE val, VARIANT *var);
00336 static VALUE make_inspect(const char *class_name, VALUE detail);
00337 static VALUE default_inspect(VALUE self, const char *class_name);
00338 static VALUE ole_set_member(VALUE self, IDispatch *dispatch);
00339 static VALUE fole_s_allocate(VALUE klass);
00340 static VALUE create_win32ole_object(VALUE klass, IDispatch *pDispatch, int argc, VALUE *argv);
00341 static VALUE ary_new_dim(VALUE myary, long *pid, long *plb, long dim);
00342 static void ary_store_dim(VALUE myary, long *pid, long *plb, long dim, VALUE val);
00343 static VALUE ole_variant2val(VARIANT *pvar);
00344 static LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey);
00345 static LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey);
00346 static VALUE reg_enum_key(HKEY hkey, DWORD i);
00347 static VALUE reg_get_val(HKEY hkey, const char *subkey);
00348 static VALUE reg_get_typelib_file_path(HKEY hkey);
00349 static VALUE typelib_file_from_clsid(VALUE ole);
00350 static VALUE typelib_file_from_typelib(VALUE ole);
00351 static VALUE typelib_file(VALUE ole);
00352 static void ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self);
00353 static HRESULT clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid);
00354 static VALUE ole_create_dcom(int argc, VALUE *argv, VALUE self);
00355 static VALUE ole_bind_obj(VALUE moniker, int argc, VALUE *argv, VALUE self);
00356 static VALUE fole_s_connect(int argc, VALUE *argv, VALUE self);
00357 static VALUE fole_s_const_load(int argc, VALUE *argv, VALUE self);
00358 static VALUE ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes);
00359 static ULONG reference_count(struct oledata * pole);
00360 static VALUE fole_s_reference_count(VALUE self, VALUE obj);
00361 static VALUE fole_s_free(VALUE self, VALUE obj);
00362 static HWND ole_show_help(VALUE helpfile, VALUE helpcontext);
00363 static VALUE fole_s_show_help(int argc, VALUE *argv, VALUE self);
00364 static VALUE fole_s_get_code_page(VALUE self);
00365 static BOOL CALLBACK installed_code_page_proc(LPTSTR str);
00366 static BOOL code_page_installed(UINT cp);
00367 static VALUE fole_s_set_code_page(VALUE self, VALUE vcp);
00368 static VALUE fole_s_get_locale(VALUE self);
00369 static BOOL CALLBACK installed_lcid_proc(LPTSTR str);
00370 static BOOL lcid_installed(LCID lcid);
00371 static VALUE fole_s_set_locale(VALUE self, VALUE vlcid);
00372 static VALUE fole_s_create_guid(VALUE self);
00373 static void ole_pure_initialize();
00374 static VALUE fole_s_ole_initialize(VALUE self);
00375 static void ole_pure_uninitialize();
00376 static VALUE fole_s_ole_uninitialize(VALUE self);
00377 static VALUE fole_initialize(int argc, VALUE *argv, VALUE self);
00378 static VALUE hash2named_arg(VALUE pair, struct oleparam* pOp);
00379 static VALUE set_argv(VARIANTARG* realargs, unsigned int beg, unsigned int end);
00380 static VALUE ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket);
00381 static VALUE fole_invoke(int argc, VALUE *argv, VALUE self);
00382 static VALUE ole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types, USHORT dispkind);
00383 static VALUE fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types);
00384 static VALUE fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types);
00385 static VALUE fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types);
00386 static VALUE fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self);
00387 static VALUE fole_setproperty(int argc, VALUE *argv, VALUE self);
00388 static VALUE fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self);
00389 static VALUE ole_propertyput(VALUE self, VALUE property, VALUE value);
00390 static VALUE fole_free(VALUE self);
00391 static VALUE ole_each_sub(VALUE pEnumV);
00392 static VALUE ole_ienum_free(VALUE pEnumV);
00393 static VALUE fole_each(VALUE self);
00394 static VALUE fole_missing(int argc, VALUE *argv, VALUE self);
00395 static VALUE ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name);
00396 static VALUE olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name);
00397 static VALUE ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask);
00398 static VALUE ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask);
00399 static HRESULT typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti);
00400 static VALUE ole_methods(VALUE self, int mask);
00401 static VALUE fole_methods(VALUE self);
00402 static VALUE fole_get_methods(VALUE self);
00403 static VALUE fole_put_methods(VALUE self);
00404 static VALUE fole_func_methods(VALUE self);
00405 static VALUE ole_type_from_itypeinfo(ITypeInfo *pTypeInfo);
00406 static VALUE fole_type(VALUE self);
00407 static VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo);
00408 static VALUE fole_typelib(VALUE self);
00409 static VALUE fole_query_interface(VALUE self, VALUE str_iid);
00410 static VALUE fole_respond_to(VALUE self, VALUE method);
00411 static HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile);
00412 static VALUE ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails);
00413 static VALUE ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails);
00414 static VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails);
00415 static VALUE fole_method_help(VALUE self, VALUE cmdname);
00416 static VALUE fole_activex_initialize(VALUE self);
00417 static VALUE foletype_s_ole_classes(VALUE self, VALUE typelib);
00418 static VALUE foletype_s_typelibs(VALUE self);
00419 static VALUE foletype_s_progids(VALUE self);
00420 static VALUE foletype_s_allocate(VALUE klass);
00421 static VALUE oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name);
00422 static VALUE oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass);
00423 static VALUE oletypelib_set_member(VALUE self, ITypeLib *pTypeLib);
00424 static ITypeLib * oletypelib_get_typelib(VALUE self);
00425 static void oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr);
00426 static VALUE foletypelib_s_typelibs(VALUE self);
00427 static VALUE make_version_str(VALUE major, VALUE minor);
00428 static VALUE oletypelib_search_registry2(VALUE self, VALUE args);
00429 static VALUE oletypelib_search_registry(VALUE self, VALUE typelib);
00430 static VALUE foletypelib_s_allocate(VALUE klass);
00431 static VALUE foletypelib_initialize(VALUE self, VALUE args);
00432 static VALUE foletypelib_guid(VALUE self);
00433 static VALUE foletypelib_name(VALUE self);
00434 static VALUE foletypelib_version(VALUE self);
00435 static VALUE foletypelib_major_version(VALUE self);
00436 static VALUE foletypelib_minor_version(VALUE self);
00437 static VALUE oletypelib_path(VALUE guid, VALUE version);
00438 static HRESULT oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib);
00439 static VALUE foletypelib_path(VALUE self);
00440 static VALUE foletypelib_visible(VALUE self);
00441 static VALUE foletypelib_library_name(VALUE self);
00442 static VALUE foletypelib_ole_types(VALUE self);
00443 static VALUE foletypelib_inspect(VALUE self);
00444 static VALUE foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass);
00445 static VALUE foletype_name(VALUE self);
00446 static VALUE ole_ole_type(ITypeInfo *pTypeInfo);
00447 static VALUE foletype_ole_type(VALUE self);
00448 static VALUE ole_type_guid(ITypeInfo *pTypeInfo);
00449 static VALUE foletype_guid(VALUE self);
00450 static VALUE ole_type_progid(ITypeInfo *pTypeInfo);
00451 static VALUE foletype_progid(VALUE self);
00452 static VALUE ole_type_visible(ITypeInfo *pTypeInfo);
00453 static VALUE foletype_visible(VALUE self);
00454 static VALUE ole_type_major_version(ITypeInfo *pTypeInfo);
00455 static VALUE foletype_major_version(VALUE self);
00456 static VALUE ole_type_minor_version(ITypeInfo *pTypeInfo);
00457 static VALUE foletype_minor_version(VALUE self);
00458 static VALUE ole_type_typekind(ITypeInfo *pTypeInfo);
00459 static VALUE foletype_typekind(VALUE self);
00460 static VALUE ole_type_helpstring(ITypeInfo *pTypeInfo);
00461 static VALUE foletype_helpstring(VALUE self);
00462 static VALUE ole_type_src_type(ITypeInfo *pTypeInfo);
00463 static VALUE foletype_src_type(VALUE self);
00464 static VALUE ole_type_helpfile(ITypeInfo *pTypeInfo);
00465 static VALUE foletype_helpfile(VALUE self);
00466 static VALUE ole_type_helpcontext(ITypeInfo *pTypeInfo);
00467 static VALUE foletype_helpcontext(VALUE self);
00468 static VALUE foletype_ole_typelib(VALUE self);
00469 static VALUE ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags);
00470 static VALUE foletype_impl_ole_types(VALUE self);
00471 static VALUE foletype_source_ole_types(VALUE self);
00472 static VALUE foletype_default_event_sources(VALUE self);
00473 static VALUE foletype_default_ole_types(VALUE self);
00474 static VALUE foletype_inspect(VALUE self);
00475 static VALUE ole_variables(ITypeInfo *pTypeInfo);
00476 static VALUE foletype_variables(VALUE self);
00477 static VALUE foletype_methods(VALUE self);
00478 static VALUE folevariable_name(VALUE self);
00479 static VALUE ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index);
00480 static VALUE folevariable_ole_type(VALUE self);
00481 static VALUE ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index);
00482 static VALUE folevariable_ole_type_detail(VALUE self);
00483 static VALUE ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index);
00484 static VALUE folevariable_value(VALUE self);
00485 static VALUE ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index);
00486 static VALUE folevariable_visible(VALUE self);
00487 static VALUE ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index);
00488 static VALUE folevariable_variable_kind(VALUE self);
00489 static VALUE ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index);
00490 static VALUE folevariable_varkind(VALUE self);
00491 static VALUE folevariable_inspect(VALUE self);
00492 static VALUE olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name);
00493 static VALUE folemethod_s_allocate(VALUE klass);
00494 static VALUE folemethod_initialize(VALUE self, VALUE oletype, VALUE method);
00495 static VALUE folemethod_name(VALUE self);
00496 static VALUE ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index);
00497 static VALUE folemethod_return_type(VALUE self);
00498 static VALUE ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index);
00499 static VALUE folemethod_return_vtype(VALUE self);
00500 static VALUE ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index);
00501 static VALUE folemethod_return_type_detail(VALUE self);
00502 static VALUE ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index);
00503 static VALUE ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index);
00504 static VALUE folemethod_invkind(VALUE self);
00505 static VALUE folemethod_invoke_kind(VALUE self);
00506 static VALUE ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index);
00507 static VALUE folemethod_visible(VALUE self);
00508 static VALUE ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name);
00509 static VALUE folemethod_event(VALUE self);
00510 static VALUE folemethod_event_interface(VALUE self);
00511 static VALUE ole_method_docinfo_from_type(ITypeInfo *pTypeInfo, UINT method_index, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile);
00512 static VALUE ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index);
00513 static VALUE folemethod_helpstring(VALUE self);
00514 static VALUE ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index);
00515 static VALUE folemethod_helpfile(VALUE self);
00516 static VALUE ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index);
00517 static VALUE folemethod_helpcontext(VALUE self);
00518 static VALUE ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index);
00519 static VALUE folemethod_dispid(VALUE self);
00520 static VALUE ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index);
00521 static VALUE folemethod_offset_vtbl(VALUE self);
00522 static VALUE ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index);
00523 static VALUE folemethod_size_params(VALUE self);
00524 static VALUE ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index);
00525 static VALUE folemethod_size_opt_params(VALUE self);
00526 static VALUE ole_method_params(ITypeInfo *pTypeInfo, UINT method_index);
00527 static VALUE folemethod_params(VALUE self);
00528 static VALUE folemethod_inspect(VALUE self);
00529 static VALUE foleparam_s_allocate(VALUE klass);
00530 static VALUE oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index);
00531 static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n);
00532 static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n);
00533 static VALUE foleparam_name(VALUE self);
00534 static VALUE ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index);
00535 static VALUE foleparam_ole_type(VALUE self);
00536 static VALUE ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index);
00537 static VALUE foleparam_ole_type_detail(VALUE self);
00538 static VALUE ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask);
00539 static VALUE foleparam_input(VALUE self);
00540 static VALUE foleparam_output(VALUE self);
00541 static VALUE foleparam_optional(VALUE self);
00542 static VALUE foleparam_retval(VALUE self);
00543 static VALUE ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index);
00544 static VALUE foleparam_default(VALUE self);
00545 static VALUE foleparam_inspect(VALUE self);
00546 static long ole_search_event_at(VALUE ary, VALUE ev);
00547 static VALUE ole_search_event(VALUE ary, VALUE ev, BOOL *is_default);
00548 static VALUE ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler);
00549 static void ole_delete_event(VALUE ary, VALUE ev);
00550 static void hash2ptr_dispparams(VALUE hash, ITypeInfo *pTypeInfo, DISPID dispid, DISPPARAMS *pdispparams);
00551 static VALUE hash2result(VALUE hash);
00552 static void ary2ptr_dispparams(VALUE ary, DISPPARAMS *pdispparams);
00553 static VALUE exec_callback(VALUE arg);
00554 static VALUE rescue_callback(VALUE arg);
00555 static HRESULT find_iid(VALUE ole, char *pitf, IID *piid, ITypeInfo **ppTypeInfo);
00556 static HRESULT find_coclass(ITypeInfo *pTypeInfo, TYPEATTR *pTypeAttr, ITypeInfo **pTypeInfo2, TYPEATTR **pTypeAttr2);
00557 static HRESULT find_default_source_from_typeinfo(ITypeInfo *pTypeInfo, TYPEATTR *pTypeAttr, ITypeInfo **ppTypeInfo);
00558 static HRESULT find_default_source(VALUE ole, IID *piid, ITypeInfo **ppTypeInfo);
00559 static void ole_event_free(struct oleeventdata *poleev);
00560 static VALUE fev_s_allocate(VALUE klass);
00561 static VALUE ev_advise(int argc, VALUE *argv, VALUE self);
00562 static VALUE fev_initialize(int argc, VALUE *argv, VALUE self);
00563 static VALUE fev_s_msg_loop(VALUE klass);
00564 static void add_event_call_back(VALUE obj, VALUE event, VALUE data);
00565 static VALUE ev_on_event(int argc, VALUE *argv, VALUE self, VALUE is_ary_arg);
00566 static VALUE fev_on_event(int argc, VALUE *argv, VALUE self);
00567 static VALUE fev_on_event_with_outargs(int argc, VALUE *argv, VALUE self);
00568 static VALUE fev_off_event(int argc, VALUE *argv, VALUE self);
00569 static VALUE fev_unadvise(VALUE self);
00570 static VALUE fev_set_handler(VALUE self, VALUE val);
00571 static VALUE fev_get_handler(VALUE self);
00572 static VALUE evs_push(VALUE ev);
00573 static VALUE evs_delete(long i);
00574 static VALUE evs_entry(long i);
00575 static VALUE evs_length();
00576 static void olevariant_free(struct olevariantdata *pvar);
00577 static VALUE folevariant_s_allocate(VALUE klass);
00578 static VALUE folevariant_s_array(VALUE klass, VALUE dims, VALUE vvt);
00579 static VALUE folevariant_initialize(VALUE self, VALUE args);
00580 static long *ary2safe_array_index(int ary_size, VALUE *ary, SAFEARRAY *psa);
00581 static void unlock_safe_array(SAFEARRAY *psa);
00582 static SAFEARRAY *get_locked_safe_array(VALUE val);
00583 static VALUE folevariant_ary_aref(int argc, VALUE *argv, VALUE self);
00584 static VOID * val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt);
00585 static VALUE folevariant_ary_aset(int argc, VALUE *argv, VALUE self);
00586 static VALUE folevariant_value(VALUE self);
00587 static VALUE folevariant_vartype(VALUE self);
00588 static VALUE folevariant_set_value(VALUE self, VALUE val);
00589 static void init_enc2cp();
00590 static void free_enc2cp();
00591
00592 static HRESULT (STDMETHODCALLTYPE mf_QueryInterface)(
00593 IMessageFilter __RPC_FAR * This,
00594 REFIID riid,
00595 void __RPC_FAR *__RPC_FAR *ppvObject)
00596 {
00597 if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0
00598 || MEMCMP(riid, &IID_IMessageFilter, GUID, 1) == 0)
00599 {
00600 *ppvObject = &message_filter;
00601 return S_OK;
00602 }
00603 return E_NOINTERFACE;
00604 }
00605
00606 static ULONG (STDMETHODCALLTYPE mf_AddRef)(
00607 IMessageFilter __RPC_FAR * This)
00608 {
00609 return 1;
00610 }
00611
00612 static ULONG (STDMETHODCALLTYPE mf_Release)(
00613 IMessageFilter __RPC_FAR * This)
00614 {
00615 return 1;
00616 }
00617
00618 static DWORD (STDMETHODCALLTYPE mf_HandleInComingCall)(
00619 IMessageFilter __RPC_FAR * pThis,
00620 DWORD dwCallType,
00621 HTASK threadIDCaller,
00622 DWORD dwTickCount,
00623 LPINTERFACEINFO lpInterfaceInfo
00624 )
00625 {
00626 #ifdef DEBUG_MESSAGEFILTER
00627 printf("incoming %08X, %08X, %d\n", dwCallType, threadIDCaller, dwTickCount);
00628 fflush(stdout);
00629 #endif
00630 switch (dwCallType)
00631 {
00632 case CALLTYPE_ASYNC:
00633 case CALLTYPE_TOPLEVEL_CALLPENDING:
00634 case CALLTYPE_ASYNC_CALLPENDING:
00635 if (rb_during_gc()) {
00636 return SERVERCALL_RETRYLATER;
00637 }
00638 break;
00639 default:
00640 break;
00641 }
00642 if (previous_filter) {
00643 return previous_filter->lpVtbl->HandleInComingCall(previous_filter,
00644 dwCallType,
00645 threadIDCaller,
00646 dwTickCount,
00647 lpInterfaceInfo);
00648 }
00649 return SERVERCALL_ISHANDLED;
00650 }
00651
00652 static DWORD (STDMETHODCALLTYPE mf_RetryRejectedCall)(
00653 IMessageFilter* pThis,
00654 HTASK threadIDCallee,
00655 DWORD dwTickCount,
00656 DWORD dwRejectType
00657 )
00658 {
00659 if (previous_filter) {
00660 return previous_filter->lpVtbl->RetryRejectedCall(previous_filter,
00661 threadIDCallee,
00662 dwTickCount,
00663 dwRejectType);
00664 }
00665 return 1000;
00666 }
00667
00668 static DWORD (STDMETHODCALLTYPE mf_MessagePending)(
00669 IMessageFilter* pThis,
00670 HTASK threadIDCallee,
00671 DWORD dwTickCount,
00672 DWORD dwPendingType
00673 )
00674 {
00675 if (rb_during_gc()) {
00676 return PENDINGMSG_WAITNOPROCESS;
00677 }
00678 if (previous_filter) {
00679 return previous_filter->lpVtbl->MessagePending(previous_filter,
00680 threadIDCallee,
00681 dwTickCount,
00682 dwPendingType);
00683 }
00684 return PENDINGMSG_WAITNOPROCESS;
00685 }
00686
00687 typedef struct _Win32OLEIDispatch
00688 {
00689 IDispatch dispatch;
00690 ULONG refcount;
00691 VALUE obj;
00692 } Win32OLEIDispatch;
00693
00694 static HRESULT ( STDMETHODCALLTYPE QueryInterface )(
00695 IDispatch __RPC_FAR * This,
00696 REFIID riid,
00697 void __RPC_FAR *__RPC_FAR *ppvObject)
00698 {
00699 if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0
00700 || MEMCMP(riid, &IID_IDispatch, GUID, 1) == 0)
00701 {
00702 Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
00703 p->refcount++;
00704 *ppvObject = This;
00705 return S_OK;
00706 }
00707 return E_NOINTERFACE;
00708 }
00709
00710 static ULONG ( STDMETHODCALLTYPE AddRef )(
00711 IDispatch __RPC_FAR * This)
00712 {
00713 Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
00714 return ++(p->refcount);
00715 }
00716
00717 static ULONG ( STDMETHODCALLTYPE Release )(
00718 IDispatch __RPC_FAR * This)
00719 {
00720 Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
00721 ULONG u = --(p->refcount);
00722 if (u == 0) {
00723 st_data_t key = p->obj;
00724 st_delete(DATA_PTR(com_hash), &key, 0);
00725 free(p);
00726 }
00727 return u;
00728 }
00729
00730 static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )(
00731 IDispatch __RPC_FAR * This,
00732 UINT __RPC_FAR *pctinfo)
00733 {
00734 return E_NOTIMPL;
00735 }
00736
00737 static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )(
00738 IDispatch __RPC_FAR * This,
00739 UINT iTInfo,
00740 LCID lcid,
00741 ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
00742 {
00743 return E_NOTIMPL;
00744 }
00745
00746
00747 static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )(
00748 IDispatch __RPC_FAR * This,
00749 REFIID riid,
00750 LPOLESTR __RPC_FAR *rgszNames,
00751 UINT cNames,
00752 LCID lcid,
00753 DISPID __RPC_FAR *rgDispId)
00754 {
00755
00756
00757
00758 char* psz = ole_wc2mb(*rgszNames);
00759 *rgDispId = rb_intern(psz);
00760 free(psz);
00761 return S_OK;
00762 }
00763
00764 static HRESULT ( STDMETHODCALLTYPE Invoke )(
00765 IDispatch __RPC_FAR * This,
00766 DISPID dispIdMember,
00767 REFIID riid,
00768 LCID lcid,
00769 WORD wFlags,
00770 DISPPARAMS __RPC_FAR *pDispParams,
00771 VARIANT __RPC_FAR *pVarResult,
00772 EXCEPINFO __RPC_FAR *pExcepInfo,
00773 UINT __RPC_FAR *puArgErr)
00774 {
00775 VALUE v;
00776 int i;
00777 int args = pDispParams->cArgs;
00778 Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
00779 VALUE* parg = ALLOCA_N(VALUE, args);
00780 for (i = 0; i < args; i++) {
00781 *(parg + i) = ole_variant2val(&pDispParams->rgvarg[args - i - 1]);
00782 }
00783 if (dispIdMember == DISPID_VALUE) {
00784 if (wFlags == DISPATCH_METHOD) {
00785 dispIdMember = rb_intern("call");
00786 } else if (wFlags & DISPATCH_PROPERTYGET) {
00787 dispIdMember = rb_intern("value");
00788 }
00789 }
00790 v = rb_funcall2(p->obj, dispIdMember, args, parg);
00791 ole_val2variant(v, pVarResult);
00792 return S_OK;
00793 }
00794
00795 static IDispatch*
00796 val2dispatch(VALUE val)
00797 {
00798 struct st_table *tbl = DATA_PTR(com_hash);
00799 Win32OLEIDispatch* pdisp;
00800 st_data_t data;
00801
00802 if (st_lookup(tbl, val, &data)) {
00803 pdisp = (Win32OLEIDispatch *)(data & ~FIXNUM_FLAG);
00804 pdisp->refcount++;
00805 }
00806 else {
00807 pdisp = ALLOC(Win32OLEIDispatch);
00808 pdisp->dispatch.lpVtbl = &com_vtbl;
00809 pdisp->refcount = 1;
00810 pdisp->obj = val;
00811 st_insert(tbl, val, (VALUE)pdisp | FIXNUM_FLAG);
00812 }
00813 return &pdisp->dispatch;
00814 }
00815
00816 static double
00817 rbtime2vtdate(VALUE tmobj)
00818 {
00819 SYSTEMTIME st;
00820 double t = 0;
00821 memset(&st, 0, sizeof(SYSTEMTIME));
00822 st.wYear = FIX2INT(rb_funcall(tmobj, rb_intern("year"), 0));
00823 st.wMonth = FIX2INT(rb_funcall(tmobj, rb_intern("month"), 0));
00824 st.wDay = FIX2INT(rb_funcall(tmobj, rb_intern("mday"), 0));
00825 st.wHour = FIX2INT(rb_funcall(tmobj, rb_intern("hour"), 0));
00826 st.wMinute = FIX2INT(rb_funcall(tmobj, rb_intern("min"), 0));
00827 st.wSecond = FIX2INT(rb_funcall(tmobj, rb_intern("sec"), 0));
00828 st.wMilliseconds = FIX2INT(rb_funcall(tmobj, rb_intern("nsec"), 0)) / 1000000;
00829 SystemTimeToVariantTime(&st, &t);
00830 return t;
00831 }
00832
00833 static VALUE
00834 vtdate2rbtime(double date)
00835 {
00836 SYSTEMTIME st;
00837 VALUE v;
00838 VariantTimeToSystemTime(date, &st);
00839
00840 v = rb_funcall(rb_cTime, rb_intern("new"), 6,
00841 INT2FIX(st.wYear),
00842 INT2FIX(st.wMonth),
00843 INT2FIX(st.wDay),
00844 INT2FIX(st.wHour),
00845 INT2FIX(st.wMinute),
00846 INT2FIX(st.wSecond));
00847 if (st.wMilliseconds > 0) {
00848 return rb_funcall(v, rb_intern("+"), 1, rb_float_new((double)(st.wMilliseconds / 1000.0)));
00849 }
00850 return v;
00851 }
00852
00853 #define ENC_MACHING_CP(enc,encname,cp) if(strcasecmp(rb_enc_name((enc)),(encname)) == 0) return cp
00854
00855 static UINT ole_encoding2cp(rb_encoding *enc)
00856 {
00857
00858
00859
00860
00861 ENC_MACHING_CP(enc, "Big5", 950);
00862 ENC_MACHING_CP(enc, "CP51932", 51932);
00863 ENC_MACHING_CP(enc, "CP850", 850);
00864 ENC_MACHING_CP(enc, "CP852", 852);
00865 ENC_MACHING_CP(enc, "CP855", 855);
00866 ENC_MACHING_CP(enc, "CP949", 949);
00867 ENC_MACHING_CP(enc, "EUC-JP", 20932);
00868 ENC_MACHING_CP(enc, "EUC-KR", 51949);
00869 ENC_MACHING_CP(enc, "EUC-TW", 51950);
00870 ENC_MACHING_CP(enc, "GB18030", 54936);
00871 ENC_MACHING_CP(enc, "GB2312", 20936);
00872 ENC_MACHING_CP(enc, "GBK", 936);
00873 ENC_MACHING_CP(enc, "IBM437", 437);
00874 ENC_MACHING_CP(enc, "IBM737", 737);
00875 ENC_MACHING_CP(enc, "IBM775", 775);
00876 ENC_MACHING_CP(enc, "IBM852", 852);
00877 ENC_MACHING_CP(enc, "IBM855", 855);
00878 ENC_MACHING_CP(enc, "IBM857", 857);
00879 ENC_MACHING_CP(enc, "IBM860", 860);
00880 ENC_MACHING_CP(enc, "IBM861", 861);
00881 ENC_MACHING_CP(enc, "IBM862", 862);
00882 ENC_MACHING_CP(enc, "IBM863", 863);
00883 ENC_MACHING_CP(enc, "IBM864", 864);
00884 ENC_MACHING_CP(enc, "IBM865", 865);
00885 ENC_MACHING_CP(enc, "IBM866", 866);
00886 ENC_MACHING_CP(enc, "IBM869", 869);
00887 ENC_MACHING_CP(enc, "ISO-2022-JP", 50220);
00888 ENC_MACHING_CP(enc, "ISO-8859-1", 28591);
00889 ENC_MACHING_CP(enc, "ISO-8859-15", 28605);
00890 ENC_MACHING_CP(enc, "ISO-8859-2", 28592);
00891 ENC_MACHING_CP(enc, "ISO-8859-3", 28593);
00892 ENC_MACHING_CP(enc, "ISO-8859-4", 28594);
00893 ENC_MACHING_CP(enc, "ISO-8859-5", 28595);
00894 ENC_MACHING_CP(enc, "ISO-8859-6", 28596);
00895 ENC_MACHING_CP(enc, "ISO-8859-7", 28597);
00896 ENC_MACHING_CP(enc, "ISO-8859-8", 28598);
00897 ENC_MACHING_CP(enc, "ISO-8859-9", 28599);
00898 ENC_MACHING_CP(enc, "KOI8-R", 20866);
00899 ENC_MACHING_CP(enc, "KOI8-U", 21866);
00900 ENC_MACHING_CP(enc, "Shift_JIS", 932);
00901 ENC_MACHING_CP(enc, "UTF-16BE", 1201);
00902 ENC_MACHING_CP(enc, "UTF-16LE", 1200);
00903 ENC_MACHING_CP(enc, "UTF-7", 65000);
00904 ENC_MACHING_CP(enc, "UTF-8", 65001);
00905 ENC_MACHING_CP(enc, "Windows-1250", 1250);
00906 ENC_MACHING_CP(enc, "Windows-1251", 1251);
00907 ENC_MACHING_CP(enc, "Windows-1252", 1252);
00908 ENC_MACHING_CP(enc, "Windows-1253", 1253);
00909 ENC_MACHING_CP(enc, "Windows-1254", 1254);
00910 ENC_MACHING_CP(enc, "Windows-1255", 1255);
00911 ENC_MACHING_CP(enc, "Windows-1256", 1256);
00912 ENC_MACHING_CP(enc, "Windows-1257", 1257);
00913 ENC_MACHING_CP(enc, "Windows-1258", 1258);
00914 ENC_MACHING_CP(enc, "Windows-31J", 932);
00915 ENC_MACHING_CP(enc, "Windows-874", 874);
00916 ENC_MACHING_CP(enc, "eucJP-ms", 20932);
00917 return CP_ACP;
00918 }
00919
00920 static void
00921 failed_load_conv51932(void)
00922 {
00923 rb_raise(eWIN32OLERuntimeError, "fail to load convert function for CP51932");
00924 }
00925
00926 #ifndef pIMultiLanguage
00927 static void
00928 load_conv_function51932(void)
00929 {
00930 HRESULT hr = E_NOINTERFACE;
00931 void *p;
00932 if (!pIMultiLanguage) {
00933 #if defined(HAVE_TYPE_IMULTILANGUAGE2)
00934 hr = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER,
00935 &IID_IMultiLanguage2, &p);
00936 #elif defined(HAVE_TYPE_IMULTILANGUAGE)
00937 hr = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER,
00938 &IID_IMultiLanguage, &p);
00939 #endif
00940 if (FAILED(hr)) {
00941 failed_load_conv51932();
00942 }
00943 pIMultiLanguage = p;
00944 }
00945 }
00946 #else
00947 #define load_conv_function51932() failed_load_conv51932()
00948 #endif
00949
00950 #define conv_51932(cp) ((cp) == 51932 && (load_conv_function51932(), 1))
00951
00952 static void
00953 set_ole_codepage(UINT cp)
00954 {
00955 if (code_page_installed(cp)) {
00956 cWIN32OLE_cp = cp;
00957 } else {
00958 switch(cp) {
00959 case CP_ACP:
00960 case CP_OEMCP:
00961 case CP_MACCP:
00962 case CP_THREAD_ACP:
00963 case CP_SYMBOL:
00964 case CP_UTF7:
00965 case CP_UTF8:
00966 cWIN32OLE_cp = cp;
00967 break;
00968 case 51932:
00969 cWIN32OLE_cp = cp;
00970 load_conv_function51932();
00971 break;
00972 default:
00973 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.");
00974 break;
00975 }
00976 }
00977 cWIN32OLE_enc = ole_cp2encoding(cWIN32OLE_cp);
00978 }
00979
00980
00981 static UINT
00982 ole_init_cp(void)
00983 {
00984 UINT cp;
00985 rb_encoding *encdef;
00986 encdef = rb_default_internal_encoding();
00987 if (!encdef) {
00988 encdef = rb_default_external_encoding();
00989 }
00990 cp = ole_encoding2cp(encdef);
00991 set_ole_codepage(cp);
00992 return cp;
00993 }
00994
00995 struct myCPINFOEX {
00996 UINT MaxCharSize;
00997 BYTE DefaultChar[2];
00998 BYTE LeadByte[12];
00999 WCHAR UnicodeDefaultChar;
01000 UINT CodePage;
01001 char CodePageName[MAX_PATH];
01002 };
01003
01004 static rb_encoding *
01005 ole_cp2encoding(UINT cp)
01006 {
01007 static BOOL (*pGetCPInfoEx)(UINT, DWORD, struct myCPINFOEX *) = NULL;
01008 struct myCPINFOEX* buf;
01009 VALUE enc_name;
01010 char *enc_cstr;
01011 int idx;
01012
01013 if (!code_page_installed(cp)) {
01014 switch(cp) {
01015 case CP_ACP:
01016 cp = GetACP();
01017 break;
01018 case CP_OEMCP:
01019 cp = GetOEMCP();
01020 break;
01021 case CP_MACCP:
01022 case CP_THREAD_ACP:
01023 if (!pGetCPInfoEx) {
01024 pGetCPInfoEx = (BOOL (*)(UINT, DWORD, struct myCPINFOEX *))
01025 GetProcAddress(GetModuleHandle("kernel32"), "GetCPInfoEx");
01026 if (!pGetCPInfoEx) {
01027 pGetCPInfoEx = (void*)-1;
01028 }
01029 }
01030 buf = ALLOCA_N(struct myCPINFOEX, 1);
01031 ZeroMemory(buf, sizeof(struct myCPINFOEX));
01032 if (pGetCPInfoEx == (void*)-1 || !pGetCPInfoEx(cp, 0, buf)) {
01033 rb_raise(eWIN32OLERuntimeError, "cannot map codepage to encoding.");
01034 break;
01035 }
01036 cp = buf->CodePage;
01037 break;
01038 case CP_SYMBOL:
01039 case CP_UTF7:
01040 case CP_UTF8:
01041 break;
01042 case 51932:
01043 load_conv_function51932();
01044 break;
01045 default:
01046 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.");
01047 break;
01048 }
01049 }
01050
01051 enc_name = rb_sprintf("CP%d", cp);
01052 idx = rb_enc_find_index(enc_cstr = StringValueCStr(enc_name));
01053 if (idx < 0)
01054 idx = rb_define_dummy_encoding(enc_cstr);
01055 return rb_enc_from_index(idx);
01056 }
01057
01058 static char *
01059 ole_wc2mb(LPWSTR pw)
01060 {
01061 LPSTR pm;
01062 int size = 0;
01063 if (conv_51932(cWIN32OLE_cp)) {
01064 #ifndef pIMultiLanguage
01065 DWORD dw = 0;
01066 HRESULT hr = pIMultiLanguage->lpVtbl->ConvertStringFromUnicode(pIMultiLanguage,
01067 &dw, cWIN32OLE_cp, pw, NULL, NULL, &size);
01068 if (FAILED(hr)) {
01069 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert Unicode to CP%d", cWIN32OLE_cp);
01070 }
01071 pm = ALLOC_N(char, size + 1);
01072 hr = pIMultiLanguage->lpVtbl->ConvertStringFromUnicode(pIMultiLanguage,
01073 &dw, cWIN32OLE_cp, pw, NULL, pm, &size);
01074 if (FAILED(hr)) {
01075 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert Unicode to CP%d", cWIN32OLE_cp);
01076 }
01077 pm[size] = '\0';
01078 #endif
01079 return pm;
01080 }
01081 size = WideCharToMultiByte(cWIN32OLE_cp, 0, pw, -1, NULL, 0, NULL, NULL);
01082 if (size) {
01083 pm = ALLOC_N(char, size + 1);
01084 WideCharToMultiByte(cWIN32OLE_cp, 0, pw, -1, pm, size, NULL, NULL);
01085 pm[size] = '\0';
01086 }
01087 else {
01088 pm = ALLOC_N(char, 1);
01089 *pm = '\0';
01090 }
01091 return pm;
01092 }
01093
01094 static VALUE
01095 ole_hresult2msg(HRESULT hr)
01096 {
01097 VALUE msg = Qnil;
01098 char *p_msg = NULL;
01099 char *term = NULL;
01100 DWORD dwCount;
01101
01102 char strhr[100];
01103 sprintf(strhr, " HRESULT error code:0x%08x\n ", (unsigned)hr);
01104 msg = rb_str_new2(strhr);
01105
01106 dwCount = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
01107 FORMAT_MESSAGE_FROM_SYSTEM |
01108 FORMAT_MESSAGE_IGNORE_INSERTS,
01109 NULL, hr, cWIN32OLE_lcid,
01110 (LPTSTR)&p_msg, 0, NULL);
01111 if (dwCount > 0) {
01112 term = p_msg + strlen(p_msg);
01113 while (p_msg < term) {
01114 term--;
01115 if (*term == '\r' || *term == '\n')
01116 *term = '\0';
01117 else break;
01118 }
01119 if (p_msg[0] != '\0') {
01120 rb_str_cat2(msg, p_msg);
01121 }
01122 }
01123 LocalFree(p_msg);
01124 return msg;
01125 }
01126
01127 static void
01128 ole_freeexceptinfo(EXCEPINFO *pExInfo)
01129 {
01130 SysFreeString(pExInfo->bstrDescription);
01131 SysFreeString(pExInfo->bstrSource);
01132 SysFreeString(pExInfo->bstrHelpFile);
01133 }
01134
01135 static VALUE
01136 ole_excepinfo2msg(EXCEPINFO *pExInfo)
01137 {
01138 char error_code[40];
01139 char *pSource = NULL;
01140 char *pDescription = NULL;
01141 VALUE error_msg;
01142 if(pExInfo->pfnDeferredFillIn != NULL) {
01143 (*pExInfo->pfnDeferredFillIn)(pExInfo);
01144 }
01145 if (pExInfo->bstrSource != NULL) {
01146 pSource = ole_wc2mb(pExInfo->bstrSource);
01147 }
01148 if (pExInfo->bstrDescription != NULL) {
01149 pDescription = ole_wc2mb(pExInfo->bstrDescription);
01150 }
01151 if(pExInfo->wCode == 0) {
01152 sprintf(error_code, "\n OLE error code:%lX in ", pExInfo->scode);
01153 }
01154 else{
01155 sprintf(error_code, "\n OLE error code:%u in ", pExInfo->wCode);
01156 }
01157 error_msg = rb_str_new2(error_code);
01158 if(pSource != NULL) {
01159 rb_str_cat(error_msg, pSource, strlen(pSource));
01160 }
01161 else {
01162 rb_str_cat(error_msg, "<Unknown>", 9);
01163 }
01164 rb_str_cat2(error_msg, "\n ");
01165 if(pDescription != NULL) {
01166 rb_str_cat2(error_msg, pDescription);
01167 }
01168 else {
01169 rb_str_cat2(error_msg, "<No Description>");
01170 }
01171 if(pSource) free(pSource);
01172 if(pDescription) free(pDescription);
01173 ole_freeexceptinfo(pExInfo);
01174 return error_msg;
01175 }
01176
01177 static void
01178 ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...)
01179 {
01180 va_list args;
01181 char buf[BUFSIZ];
01182 VALUE err_msg;
01183 va_init_list(args, fmt);
01184 vsnprintf(buf, BUFSIZ, fmt, args);
01185 va_end(args);
01186
01187 err_msg = ole_hresult2msg(hr);
01188 if(err_msg != Qnil) {
01189 rb_raise(ecs, "%s\n%s", buf, StringValuePtr(err_msg));
01190 }
01191 else {
01192 rb_raise(ecs, "%s", buf);
01193 }
01194 }
01195
01196 void
01197 ole_uninitialize()
01198 {
01199 OleUninitialize();
01200 g_ole_initialized = FALSE;
01201 }
01202
01203 static void
01204 ole_initialize()
01205 {
01206 HRESULT hr;
01207
01208 if(g_ole_initialized == FALSE) {
01209 hr = OleInitialize(NULL);
01210 if(FAILED(hr)) {
01211 ole_raise(hr, rb_eRuntimeError, "fail: OLE initialize");
01212 }
01213 g_ole_initialized = TRUE;
01214
01215
01216
01217
01218
01219
01220 hr = CoRegisterMessageFilter(&imessage_filter, &previous_filter);
01221 if(FAILED(hr)) {
01222 previous_filter = NULL;
01223 ole_raise(hr, rb_eRuntimeError, "fail: install OLE MessageFilter");
01224 }
01225 }
01226 }
01227
01228 static void
01229 ole_msg_loop() {
01230 MSG msg;
01231 while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
01232 TranslateMessage(&msg);
01233 DispatchMessage(&msg);
01234 }
01235 }
01236
01237 static void
01238 ole_free(struct oledata *pole)
01239 {
01240 OLE_FREE(pole->pDispatch);
01241 free(pole);
01242 }
01243
01244 static void
01245 oletypelib_free(struct oletypelibdata *poletypelib)
01246 {
01247 OLE_FREE(poletypelib->pTypeLib);
01248 free(poletypelib);
01249 }
01250
01251 static void
01252 oletype_free(struct oletypedata *poletype)
01253 {
01254 OLE_FREE(poletype->pTypeInfo);
01255 free(poletype);
01256 }
01257
01258 static void
01259 olemethod_free(struct olemethoddata *polemethod)
01260 {
01261 OLE_FREE(polemethod->pTypeInfo);
01262 OLE_FREE(polemethod->pOwnerTypeInfo);
01263 free(polemethod);
01264 }
01265
01266 static void
01267 olevariable_free(struct olevariabledata *polevar)
01268 {
01269 OLE_FREE(polevar->pTypeInfo);
01270 free(polevar);
01271 }
01272
01273 static void
01274 oleparam_free(struct oleparamdata *pole)
01275 {
01276 OLE_FREE(pole->pTypeInfo);
01277 free(pole);
01278 }
01279
01280
01281 static LPWSTR
01282 ole_vstr2wc(VALUE vstr)
01283 {
01284 rb_encoding *enc;
01285 int cp;
01286 int size = 0;
01287 LPWSTR pw;
01288 st_data_t data;
01289 enc = rb_enc_get(vstr);
01290
01291 if (st_lookup(enc2cp_table, (st_data_t)enc, &data)) {
01292 cp = data;
01293 } else {
01294 cp = ole_encoding2cp(enc);
01295 if (code_page_installed(cp) ||
01296 cp == CP_ACP ||
01297 cp == CP_OEMCP ||
01298 cp == CP_MACCP ||
01299 cp == CP_THREAD_ACP ||
01300 cp == CP_SYMBOL ||
01301 cp == CP_UTF7 ||
01302 cp == CP_UTF8 ||
01303 cp == 51932) {
01304 st_insert(enc2cp_table, (st_data_t)enc, (st_data_t)cp);
01305 } else {
01306 rb_raise(eWIN32OLERuntimeError, "not installed Windows codepage(%d) according to `%s'", cp, rb_enc_name(enc));
01307 }
01308 }
01309 if (conv_51932(cp)) {
01310 #ifndef pIMultiLanguage
01311 DWORD dw = 0;
01312 int len = RSTRING_LEN(vstr);
01313 HRESULT hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage,
01314 &dw, cp, RSTRING_PTR(vstr), &len, NULL, &size);
01315 if (FAILED(hr)) {
01316 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cp);
01317 }
01318 pw = SysAllocStringLen(NULL, size);
01319 len = RSTRING_LEN(vstr);
01320 hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage,
01321 &dw, cp, RSTRING_PTR(vstr), &len, pw, &size);
01322 if (FAILED(hr)) {
01323 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cp);
01324 }
01325 #endif
01326 return pw;
01327 }
01328 size = MultiByteToWideChar(cp, 0, RSTRING_PTR(vstr), RSTRING_LEN(vstr), NULL, 0);
01329 pw = SysAllocStringLen(NULL, size);
01330 MultiByteToWideChar(cp, 0, RSTRING_PTR(vstr), RSTRING_LEN(vstr), pw, size);
01331 return pw;
01332 }
01333
01334 static LPWSTR
01335 ole_mb2wc(char *pm, int len)
01336 {
01337 int size = 0;
01338 LPWSTR pw;
01339
01340 if (conv_51932(cWIN32OLE_cp)) {
01341 #ifndef pIMultiLanguage
01342 DWORD dw = 0;
01343 int n = len;
01344 HRESULT hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage,
01345 &dw, cWIN32OLE_cp, pm, &n, NULL, &size);
01346 if (FAILED(hr)) {
01347 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cWIN32OLE_cp);
01348 }
01349 pw = SysAllocStringLen(NULL, size);
01350 hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage,
01351 &dw, cWIN32OLE_cp, pm, &n, pw, &size);
01352 if (FAILED(hr)) {
01353 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cWIN32OLE_cp);
01354 }
01355 #endif
01356 return pw;
01357 }
01358 size = MultiByteToWideChar(cWIN32OLE_cp, 0, pm, len, NULL, 0);
01359 pw = SysAllocStringLen(NULL, size - 1);
01360 MultiByteToWideChar(cWIN32OLE_cp, 0, pm, len, pw, size);
01361 return pw;
01362 }
01363
01364 static VALUE
01365 ole_wc2vstr(LPWSTR pw, BOOL isfree)
01366 {
01367 char *p = ole_wc2mb(pw);
01368 VALUE vstr = rb_enc_str_new(p, strlen(p), cWIN32OLE_enc);
01369 if(isfree)
01370 SysFreeString(pw);
01371 free(p);
01372 return vstr;
01373 }
01374
01375 static VALUE
01376 ole_ary_m_entry(VALUE val, long *pid)
01377 {
01378 VALUE obj = Qnil;
01379 int i = 0;
01380 obj = val;
01381 while(TYPE(obj) == T_ARRAY) {
01382 obj = rb_ary_entry(obj, pid[i]);
01383 i++;
01384 }
01385 return obj;
01386 }
01387
01388 static void *
01389 get_ptr_of_variant(VARIANT *pvar)
01390 {
01391 switch(V_VT(pvar)) {
01392 case VT_UI1:
01393 return &V_UI1(pvar);
01394 break;
01395 case VT_I2:
01396 return &V_I2(pvar);
01397 break;
01398 case VT_UI2:
01399 return &V_UI2(pvar);
01400 break;
01401 case VT_I4:
01402 return &V_I4(pvar);
01403 break;
01404 case VT_UI4:
01405 return &V_UI4(pvar);
01406 break;
01407 case VT_R4:
01408 return &V_R4(pvar);
01409 break;
01410 case VT_R8:
01411 return &V_R8(pvar);
01412 break;
01413 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
01414 case VT_I8:
01415 return &V_I8(pvar);
01416 break;
01417 case VT_UI8:
01418 return &V_UI8(pvar);
01419 break;
01420 #endif
01421 case VT_INT:
01422 return &V_INT(pvar);
01423 break;
01424 case VT_UINT:
01425 return &V_UINT(pvar);
01426 break;
01427 case VT_CY:
01428 return &V_CY(pvar);
01429 break;
01430 case VT_DATE:
01431 return &V_DATE(pvar);
01432 break;
01433 case VT_BSTR:
01434 return V_BSTR(pvar);
01435 break;
01436 case VT_DISPATCH:
01437 return V_DISPATCH(pvar);
01438 break;
01439 case VT_ERROR:
01440 return &V_ERROR(pvar);
01441 break;
01442 case VT_BOOL:
01443 return &V_BOOL(pvar);
01444 break;
01445 case VT_UNKNOWN:
01446 return V_UNKNOWN(pvar);
01447 break;
01448 case VT_ARRAY:
01449 return &V_ARRAY(pvar);
01450 break;
01451 default:
01452 return NULL;
01453 break;
01454 }
01455 }
01456
01457 static VALUE
01458 is_all_index_under(long *pid, long *pub, long dim)
01459 {
01460 long i = 0;
01461 for (i = 0; i < dim; i++) {
01462 if (pid[i] > pub[i]) {
01463 return Qfalse;
01464 }
01465 }
01466 return Qtrue;
01467 }
01468
01469 static void
01470 ole_set_safe_array(long n, SAFEARRAY *psa, long *pid, long *pub, VALUE val, long dim, VARTYPE vt)
01471 {
01472 VALUE val1;
01473 HRESULT hr = S_OK;
01474 VARIANT var;
01475 VOID *p = NULL;
01476 long i = n;
01477 while(i >= 0) {
01478 val1 = ole_ary_m_entry(val, pid);
01479 VariantInit(&var);
01480 p = val2variant_ptr(val1, &var, vt);
01481 if (is_all_index_under(pid, pub, dim) == Qtrue) {
01482 if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) ||
01483 (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) {
01484 rb_raise(eWIN32OLERuntimeError, "element of array does not have IDispatch or IUnknown Interface");
01485 }
01486 hr = SafeArrayPutElement(psa, pid, p);
01487 }
01488 if (FAILED(hr)) {
01489 ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayPutElement");
01490 }
01491 pid[i] += 1;
01492 if (pid[i] > pub[i]) {
01493 pid[i] = 0;
01494 i -= 1;
01495 } else {
01496 i = dim - 1;
01497 }
01498 }
01499 }
01500
01501 static long
01502 dimension(VALUE val) {
01503 long dim = 0;
01504 long dim1 = 0;
01505 long len = 0;
01506 long i = 0;
01507 if (TYPE(val) == T_ARRAY) {
01508 len = RARRAY_LEN(val);
01509 for (i = 0; i < len; i++) {
01510 dim1 = dimension(rb_ary_entry(val, i));
01511 if (dim < dim1) {
01512 dim = dim1;
01513 }
01514 }
01515 dim += 1;
01516 }
01517 return dim;
01518 }
01519
01520 static long
01521 ary_len_of_dim(VALUE ary, long dim) {
01522 long ary_len = 0;
01523 long ary_len1 = 0;
01524 long len = 0;
01525 long i = 0;
01526 VALUE val;
01527 if (dim == 0) {
01528 if (TYPE(ary) == T_ARRAY) {
01529 ary_len = RARRAY_LEN(ary);
01530 }
01531 } else {
01532 if (TYPE(ary) == T_ARRAY) {
01533 len = RARRAY_LEN(ary);
01534 for (i = 0; i < len; i++) {
01535 val = rb_ary_entry(ary, i);
01536 ary_len1 = ary_len_of_dim(val, dim-1);
01537 if (ary_len < ary_len1) {
01538 ary_len = ary_len1;
01539 }
01540 }
01541 }
01542 }
01543 return ary_len;
01544 }
01545
01546 static HRESULT
01547 ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt)
01548 {
01549 long dim = 0;
01550 int i = 0;
01551 HRESULT hr = S_OK;
01552
01553 SAFEARRAYBOUND *psab = NULL;
01554 SAFEARRAY *psa = NULL;
01555 long *pub, *pid;
01556
01557 Check_Type(val, T_ARRAY);
01558
01559 dim = dimension(val);
01560
01561 psab = ALLOC_N(SAFEARRAYBOUND, dim);
01562 pub = ALLOC_N(long, dim);
01563 pid = ALLOC_N(long, dim);
01564
01565 if(!psab || !pub || !pid) {
01566 if(pub) free(pub);
01567 if(psab) free(psab);
01568 if(pid) free(pid);
01569 rb_raise(rb_eRuntimeError, "memory allocation error");
01570 }
01571
01572 for (i = 0; i < dim; i++) {
01573 psab[i].cElements = ary_len_of_dim(val, i);
01574 psab[i].lLbound = 0;
01575 pub[i] = psab[i].cElements - 1;
01576 pid[i] = 0;
01577 }
01578
01579 if ((vt & ~VT_BYREF) == VT_ARRAY) {
01580 vt = (vt | VT_VARIANT);
01581 }
01582 psa = SafeArrayCreate((VARTYPE)(vt & VT_TYPEMASK), dim, psab);
01583 if (psa == NULL)
01584 hr = E_OUTOFMEMORY;
01585 else
01586 hr = SafeArrayLock(psa);
01587 if (SUCCEEDED(hr)) {
01588 ole_set_safe_array(dim-1, psa, pid, pub, val, dim, (VARTYPE)(vt & VT_TYPEMASK));
01589 hr = SafeArrayUnlock(psa);
01590 }
01591
01592 if(pub) free(pub);
01593 if(psab) free(psab);
01594 if(pid) free(pid);
01595
01596 if (SUCCEEDED(hr)) {
01597 V_VT(var) = vt;
01598 V_ARRAY(var) = psa;
01599 }
01600 else {
01601 if (psa != NULL)
01602 SafeArrayDestroy(psa);
01603 }
01604 return hr;
01605 }
01606
01607 static void
01608 ole_val2variant(VALUE val, VARIANT *var)
01609 {
01610 struct oledata *pole;
01611 struct olevariantdata *pvar;
01612 if(rb_obj_is_kind_of(val, cWIN32OLE)) {
01613 Data_Get_Struct(val, struct oledata, pole);
01614 OLE_ADDREF(pole->pDispatch);
01615 V_VT(var) = VT_DISPATCH;
01616 V_DISPATCH(var) = pole->pDispatch;
01617 return;
01618 }
01619 if (rb_obj_is_kind_of(val, cWIN32OLE_VARIANT)) {
01620 Data_Get_Struct(val, struct olevariantdata, pvar);
01621 VariantCopy(var, &(pvar->var));
01622 return;
01623 }
01624
01625 if (rb_obj_is_kind_of(val, rb_cTime)) {
01626 V_VT(var) = VT_DATE;
01627 V_DATE(var) = rbtime2vtdate(val);
01628 return;
01629 }
01630 switch (TYPE(val)) {
01631 case T_ARRAY:
01632 ole_val_ary2variant_ary(val, var, VT_VARIANT|VT_ARRAY);
01633 break;
01634 case T_STRING:
01635 V_VT(var) = VT_BSTR;
01636 V_BSTR(var) = ole_vstr2wc(val);
01637 break;
01638 case T_FIXNUM:
01639 V_VT(var) = VT_I4;
01640 V_I4(var) = NUM2INT(val);
01641 break;
01642 case T_BIGNUM:
01643 V_VT(var) = VT_R8;
01644 V_R8(var) = rb_big2dbl(val);
01645 break;
01646 case T_FLOAT:
01647 V_VT(var) = VT_R8;
01648 V_R8(var) = NUM2DBL(val);
01649 break;
01650 case T_TRUE:
01651 V_VT(var) = VT_BOOL;
01652 V_BOOL(var) = VARIANT_TRUE;
01653 break;
01654 case T_FALSE:
01655 V_VT(var) = VT_BOOL;
01656 V_BOOL(var) = VARIANT_FALSE;
01657 break;
01658 case T_NIL:
01659 if (g_nil_to == VT_ERROR) {
01660 V_VT(var) = VT_ERROR;
01661 V_ERROR(var) = DISP_E_PARAMNOTFOUND;
01662 }else {
01663 V_VT(var) = VT_EMPTY;
01664 }
01665 break;
01666 default:
01667 V_VT(var) = VT_DISPATCH;
01668 V_DISPATCH(var) = val2dispatch(val);
01669 break;
01670 }
01671 }
01672
01673 static void
01674 ole_val2variant_ex(VALUE val, VARIANT *var, VARTYPE vt)
01675 {
01676 if (val == Qnil) {
01677 if (vt == VT_VARIANT) {
01678 ole_val2variant2(val, var);
01679 } else {
01680 V_VT(var) = (vt & ~VT_BYREF);
01681 if (V_VT(var) == VT_DISPATCH) {
01682 V_DISPATCH(var) = NULL;
01683 } else if (V_VT(var) == VT_UNKNOWN) {
01684 V_UNKNOWN(var) = NULL;
01685 }
01686 }
01687 return;
01688 }
01689 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
01690 switch(vt & ~VT_BYREF) {
01691 case VT_I8:
01692 V_VT(var) = VT_I8;
01693 V_I8(var) = NUM2I8 (val);
01694 break;
01695 case VT_UI8:
01696 V_VT(var) = VT_UI8;
01697 V_UI8(var) = NUM2UI8(val);
01698 break;
01699 default:
01700 ole_val2variant2(val, var);
01701 break;
01702 }
01703 #else
01704 ole_val2variant2(val, var);
01705 #endif
01706 }
01707
01708 static void
01709 ole_val2ptr_variant(VALUE val, VARIANT *var)
01710 {
01711 switch (TYPE(val)) {
01712 case T_STRING:
01713 if (V_VT(var) == (VT_BSTR | VT_BYREF)) {
01714 *V_BSTRREF(var) = ole_vstr2wc(val);
01715 }
01716 break;
01717 case T_FIXNUM:
01718 switch(V_VT(var)) {
01719 case (VT_UI1 | VT_BYREF) :
01720 *V_UI1REF(var) = NUM2CHR(val);
01721 break;
01722 case (VT_I2 | VT_BYREF) :
01723 *V_I2REF(var) = (short)NUM2INT(val);
01724 break;
01725 case (VT_I4 | VT_BYREF) :
01726 *V_I4REF(var) = NUM2INT(val);
01727 break;
01728 case (VT_R4 | VT_BYREF) :
01729 *V_R4REF(var) = (float)NUM2INT(val);
01730 break;
01731 case (VT_R8 | VT_BYREF) :
01732 *V_R8REF(var) = NUM2INT(val);
01733 break;
01734 default:
01735 break;
01736 }
01737 break;
01738 case T_FLOAT:
01739 switch(V_VT(var)) {
01740 case (VT_I2 | VT_BYREF) :
01741 *V_I2REF(var) = (short)NUM2INT(val);
01742 break;
01743 case (VT_I4 | VT_BYREF) :
01744 *V_I4REF(var) = NUM2INT(val);
01745 break;
01746 case (VT_R4 | VT_BYREF) :
01747 *V_R4REF(var) = (float)NUM2DBL(val);
01748 break;
01749 case (VT_R8 | VT_BYREF) :
01750 *V_R8REF(var) = NUM2DBL(val);
01751 break;
01752 default:
01753 break;
01754 }
01755 break;
01756 case T_BIGNUM:
01757 if (V_VT(var) == (VT_R8 | VT_BYREF)) {
01758 *V_R8REF(var) = rb_big2dbl(val);
01759 }
01760 break;
01761 case T_TRUE:
01762 if (V_VT(var) == (VT_BOOL | VT_BYREF)) {
01763 *V_BOOLREF(var) = VARIANT_TRUE;
01764 }
01765 break;
01766 case T_FALSE:
01767 if (V_VT(var) == (VT_BOOL | VT_BYREF)) {
01768 *V_BOOLREF(var) = VARIANT_FALSE;
01769 }
01770 break;
01771 default:
01772 break;
01773 }
01774 }
01775
01776 static void
01777 ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt)
01778 {
01779 V_VT(var) = vt;
01780 if (vt == (VT_VARIANT|VT_BYREF)) {
01781 V_VARIANTREF(var) = realvar;
01782 } else {
01783 if (V_VT(realvar) != (vt & ~VT_BYREF)) {
01784 rb_raise(eWIN32OLERuntimeError, "variant type mismatch");
01785 }
01786 switch(vt & ~VT_BYREF) {
01787 case VT_I1:
01788 V_I1REF(var) = &V_I1(realvar);
01789 break;
01790 case VT_UI1:
01791 V_UI1REF(var) = &V_UI1(realvar);
01792 break;
01793 case VT_I2:
01794 V_I2REF(var) = &V_I2(realvar);
01795 break;
01796 case VT_UI2:
01797 V_UI2REF(var) = &V_UI2(realvar);
01798 break;
01799 case VT_I4:
01800 V_I4REF(var) = &V_I4(realvar);
01801 break;
01802 case VT_UI4:
01803 V_UI4REF(var) = &V_UI4(realvar);
01804 break;
01805 case VT_R4:
01806 V_R4REF(var) = &V_R4(realvar);
01807 break;
01808 case VT_R8:
01809 V_R8REF(var) = &V_R8(realvar);
01810 break;
01811
01812 #if (_MSC_VER >= 1300)
01813 case VT_I8:
01814 V_I8REF(var) = &V_I8(realvar);
01815 break;
01816 case VT_UI8:
01817 V_UI8REF(var) = &V_UI8(realvar);
01818 break;
01819 #endif
01820 case VT_INT:
01821 V_INTREF(var) = &V_INT(realvar);
01822 break;
01823
01824 case VT_UINT:
01825 V_UINTREF(var) = &V_UINT(realvar);
01826 break;
01827
01828 case VT_CY:
01829 V_CYREF(var) = &V_CY(realvar);
01830 break;
01831 case VT_DATE:
01832 V_DATEREF(var) = &V_DATE(realvar);
01833 break;
01834 case VT_BSTR:
01835 V_BSTRREF(var) = &V_BSTR(realvar);
01836 break;
01837 case VT_DISPATCH:
01838 V_DISPATCHREF(var) = &V_DISPATCH(realvar);
01839 break;
01840 case VT_ERROR:
01841 V_ERRORREF(var) = &V_ERROR(realvar);
01842 break;
01843 case VT_BOOL:
01844 V_BOOLREF(var) = &V_BOOL(realvar);
01845 break;
01846 case VT_UNKNOWN:
01847 V_UNKNOWNREF(var) = &V_UNKNOWN(realvar);
01848 break;
01849 case VT_ARRAY:
01850 V_ARRAYREF(var) = &V_ARRAY(realvar);
01851 break;
01852 default:
01853 rb_raise(eWIN32OLERuntimeError, "unknown type specified(setting BYREF):%d", vt);
01854 break;
01855 }
01856 }
01857 }
01858
01859 static void
01860 ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar)
01861 {
01862 HRESULT hr = S_OK;
01863
01864 if (((vt & ~VT_BYREF) == (VT_ARRAY | VT_UI1)) && TYPE(val) == T_STRING) {
01865 long len = RSTRING_LEN(val);
01866 void *pdest = NULL;
01867 SAFEARRAY *p = NULL;
01868 SAFEARRAY *psa = SafeArrayCreateVector(VT_UI1, 0, len);
01869 if (!psa) {
01870 rb_raise(rb_eRuntimeError, "fail to SafeArrayCreateVector");
01871 }
01872 hr = SafeArrayAccessData(psa, &pdest);
01873 if (SUCCEEDED(hr)) {
01874 memcpy(pdest, RSTRING_PTR(val), len);
01875 SafeArrayUnaccessData(psa);
01876 V_VT(&(pvar->realvar)) = (vt & ~VT_BYREF);
01877 p = V_ARRAY(&(pvar->realvar));
01878 if (p != NULL) {
01879 SafeArrayDestroy(p);
01880 }
01881 V_ARRAY(&(pvar->realvar)) = psa;
01882 if (vt & VT_BYREF) {
01883 V_VT(&(pvar->var)) = vt;
01884 V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
01885 } else {
01886 hr = VariantCopy(&(pvar->var), &(pvar->realvar));
01887 }
01888 } else {
01889 if (psa)
01890 SafeArrayDestroy(psa);
01891 }
01892 } else if (vt & VT_ARRAY) {
01893 if (val == Qnil) {
01894 V_VT(&(pvar->var)) = vt;
01895 if (vt & VT_BYREF) {
01896 V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
01897 }
01898 } else {
01899 hr = ole_val_ary2variant_ary(val, &(pvar->realvar), (VARTYPE)(vt & ~VT_BYREF));
01900 if (SUCCEEDED(hr)) {
01901 if (vt & VT_BYREF) {
01902 V_VT(&(pvar->var)) = vt;
01903 V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
01904 } else {
01905 hr = VariantCopy(&(pvar->var), &(pvar->realvar));
01906 }
01907 }
01908 }
01909 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
01910 } else if ( (vt & ~VT_BYREF) == VT_I8 || (vt & ~VT_BYREF) == VT_UI8) {
01911 ole_val2variant_ex(val, &(pvar->realvar), (vt & ~VT_BYREF));
01912 ole_val2variant_ex(val, &(pvar->var), (vt & ~VT_BYREF));
01913 V_VT(&(pvar->var)) = vt;
01914 if (vt & VT_BYREF) {
01915 ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
01916 }
01917 #endif
01918 } else {
01919 if (val == Qnil) {
01920 V_VT(&(pvar->var)) = vt;
01921 if (vt == (VT_BYREF | VT_VARIANT)) {
01922 ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
01923 } else {
01924 V_VT(&(pvar->realvar)) = vt & ~VT_BYREF;
01925 if (vt & VT_BYREF) {
01926 ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
01927 }
01928 }
01929 } else {
01930 ole_val2variant_ex(val, &(pvar->realvar), (VARTYPE)(vt & ~VT_BYREF));
01931 if (vt == (VT_BYREF | VT_VARIANT)) {
01932 ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
01933 } else if (vt & VT_BYREF) {
01934 if ( (vt & ~VT_BYREF) != V_VT(&(pvar->realvar))) {
01935 hr = VariantChangeTypeEx(&(pvar->realvar), &(pvar->realvar),
01936 cWIN32OLE_lcid, 0, (VARTYPE)(vt & ~VT_BYREF));
01937 }
01938 if (SUCCEEDED(hr)) {
01939 ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
01940 }
01941 } else {
01942 if (vt == V_VT(&(pvar->realvar))) {
01943 hr = VariantCopy(&(pvar->var), &(pvar->realvar));
01944 } else {
01945 hr = VariantChangeTypeEx(&(pvar->var), &(pvar->realvar),
01946 cWIN32OLE_lcid, 0, vt);
01947 }
01948 }
01949 }
01950 }
01951 if (FAILED(hr)) {
01952 ole_raise(hr, eWIN32OLERuntimeError, "failed to change type");
01953 }
01954 }
01955
01956 static void
01957 ole_val2variant2(VALUE val, VARIANT *var)
01958 {
01959 g_nil_to = VT_EMPTY;
01960 ole_val2variant(val, var);
01961 g_nil_to = VT_ERROR;
01962 }
01963
01964 static VALUE
01965 make_inspect(const char *class_name, VALUE detail)
01966 {
01967 VALUE str;
01968 str = rb_str_new2("#<");
01969 rb_str_cat2(str, class_name);
01970 rb_str_cat2(str, ":");
01971 rb_str_concat(str, detail);
01972 rb_str_cat2(str, ">");
01973 return str;
01974 }
01975
01976 static VALUE
01977 default_inspect(VALUE self, const char *class_name)
01978 {
01979 VALUE detail = rb_funcall(self, rb_intern("to_s"), 0);
01980 return make_inspect(class_name, detail);
01981 }
01982
01983 static VALUE
01984 ole_set_member(VALUE self, IDispatch *dispatch)
01985 {
01986 struct oledata *pole;
01987 Data_Get_Struct(self, struct oledata, pole);
01988 if (pole->pDispatch) {
01989 OLE_RELEASE(pole->pDispatch);
01990 pole->pDispatch = NULL;
01991 }
01992 pole->pDispatch = dispatch;
01993 return self;
01994 }
01995
01996
01997 static VALUE
01998 fole_s_allocate(VALUE klass)
01999 {
02000 struct oledata *pole;
02001 VALUE obj;
02002 ole_initialize();
02003 obj = Data_Make_Struct(klass,struct oledata,0,ole_free,pole);
02004 pole->pDispatch = NULL;
02005 return obj;
02006 }
02007
02008 static VALUE
02009 create_win32ole_object(VALUE klass, IDispatch *pDispatch, int argc, VALUE *argv)
02010 {
02011 VALUE obj = fole_s_allocate(klass);
02012 ole_set_member(obj, pDispatch);
02013 return obj;
02014 }
02015
02016 static VALUE
02017 ary_new_dim(VALUE myary, long *pid, long *plb, long dim) {
02018 long i;
02019 VALUE obj = Qnil;
02020 VALUE pobj = Qnil;
02021 long *ids = ALLOC_N(long, dim);
02022 if (!ids) {
02023 rb_raise(rb_eRuntimeError, "memory allocation error");
02024 }
02025 for(i = 0; i < dim; i++) {
02026 ids[i] = pid[i] - plb[i];
02027 }
02028 obj = myary;
02029 pobj = myary;
02030 for(i = 0; i < dim-1; i++) {
02031 obj = rb_ary_entry(pobj, ids[i]);
02032 if (obj == Qnil) {
02033 rb_ary_store(pobj, ids[i], rb_ary_new());
02034 }
02035 obj = rb_ary_entry(pobj, ids[i]);
02036 pobj = obj;
02037 }
02038 if (ids) free(ids);
02039 return obj;
02040 }
02041
02042 static void
02043 ary_store_dim(VALUE myary, long *pid, long *plb, long dim, VALUE val) {
02044 long id = pid[dim - 1] - plb[dim - 1];
02045 VALUE obj = ary_new_dim(myary, pid, plb, dim);
02046 rb_ary_store(obj, id, val);
02047 }
02048
02049 static VALUE
02050 ole_variant2val(VARIANT *pvar)
02051 {
02052 VALUE obj = Qnil;
02053 HRESULT hr;
02054 while ( V_VT(pvar) == (VT_BYREF | VT_VARIANT) )
02055 pvar = V_VARIANTREF(pvar);
02056
02057 if(V_ISARRAY(pvar)) {
02058 SAFEARRAY *psa = V_ISBYREF(pvar) ? *V_ARRAYREF(pvar) : V_ARRAY(pvar);
02059 UINT i = 0;
02060 long *pid, *plb, *pub;
02061 VARIANT variant;
02062 VALUE val;
02063 UINT dim = 0;
02064 if (!psa) {
02065 return obj;
02066 }
02067 dim = SafeArrayGetDim(psa);
02068 VariantInit(&variant);
02069 V_VT(&variant) = (V_VT(pvar) & ~VT_ARRAY) | VT_BYREF;
02070
02071 pid = ALLOC_N(long, dim);
02072 plb = ALLOC_N(long, dim);
02073 pub = ALLOC_N(long, dim);
02074
02075 if(!pid || !plb || !pub) {
02076 if(pid) free(pid);
02077 if(plb) free(plb);
02078 if(pub) free(pub);
02079 rb_raise(rb_eRuntimeError, "memory allocation error");
02080 }
02081
02082 for(i = 0; i < dim; ++i) {
02083 SafeArrayGetLBound(psa, i+1, &plb[i]);
02084 SafeArrayGetLBound(psa, i+1, &pid[i]);
02085 SafeArrayGetUBound(psa, i+1, &pub[i]);
02086 }
02087 hr = SafeArrayLock(psa);
02088 if (SUCCEEDED(hr)) {
02089 obj = rb_ary_new();
02090 i = 0;
02091 while (i < dim) {
02092 ary_new_dim(obj, pid, plb, dim);
02093 hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant));
02094 if (SUCCEEDED(hr)) {
02095 val = ole_variant2val(&variant);
02096 ary_store_dim(obj, pid, plb, dim, val);
02097 }
02098 for (i = 0; i < dim; ++i) {
02099 if (++pid[i] <= pub[i])
02100 break;
02101 pid[i] = plb[i];
02102 }
02103 }
02104 SafeArrayUnlock(psa);
02105 }
02106 if(pid) free(pid);
02107 if(plb) free(plb);
02108 if(pub) free(pub);
02109 return obj;
02110 }
02111 switch(V_VT(pvar) & ~VT_BYREF){
02112 case VT_EMPTY:
02113 break;
02114 case VT_NULL:
02115 break;
02116 case VT_I1:
02117 if(V_ISBYREF(pvar))
02118 obj = INT2NUM((long)*V_I1REF(pvar));
02119 else
02120 obj = INT2NUM((long)V_I1(pvar));
02121 break;
02122
02123 case VT_UI1:
02124 if(V_ISBYREF(pvar))
02125 obj = INT2NUM((long)*V_UI1REF(pvar));
02126 else
02127 obj = INT2NUM((long)V_UI1(pvar));
02128 break;
02129
02130 case VT_I2:
02131 if(V_ISBYREF(pvar))
02132 obj = INT2NUM((long)*V_I2REF(pvar));
02133 else
02134 obj = INT2NUM((long)V_I2(pvar));
02135 break;
02136
02137 case VT_UI2:
02138 if(V_ISBYREF(pvar))
02139 obj = INT2NUM((long)*V_UI2REF(pvar));
02140 else
02141 obj = INT2NUM((long)V_UI2(pvar));
02142 break;
02143
02144 case VT_I4:
02145 if(V_ISBYREF(pvar))
02146 obj = INT2NUM((long)*V_I4REF(pvar));
02147 else
02148 obj = INT2NUM((long)V_I4(pvar));
02149 break;
02150
02151 case VT_UI4:
02152 if(V_ISBYREF(pvar))
02153 obj = INT2NUM((long)*V_UI4REF(pvar));
02154 else
02155 obj = INT2NUM((long)V_UI4(pvar));
02156 break;
02157
02158 case VT_INT:
02159 if(V_ISBYREF(pvar))
02160 obj = INT2NUM((long)*V_INTREF(pvar));
02161 else
02162 obj = INT2NUM((long)V_INT(pvar));
02163 break;
02164
02165 case VT_UINT:
02166 if(V_ISBYREF(pvar))
02167 obj = INT2NUM((long)*V_UINTREF(pvar));
02168 else
02169 obj = INT2NUM((long)V_UINT(pvar));
02170 break;
02171
02172 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
02173 case VT_I8:
02174 if(V_ISBYREF(pvar))
02175 #if (_MSC_VER >= 1300)
02176 obj = I8_2_NUM(*V_I8REF(pvar));
02177 #else
02178 obj = Qnil;
02179 #endif
02180 else
02181 obj = I8_2_NUM(V_I8(pvar));
02182 break;
02183 case VT_UI8:
02184 if(V_ISBYREF(pvar))
02185 #if (_MSC_VER >= 1300)
02186 obj = UI8_2_NUM(*V_UI8REF(pvar));
02187 #else
02188 obj = Qnil;
02189 #endif
02190 else
02191 obj = UI8_2_NUM(V_UI8(pvar));
02192 break;
02193 #endif
02194
02195 case VT_R4:
02196 if(V_ISBYREF(pvar))
02197 obj = rb_float_new(*V_R4REF(pvar));
02198 else
02199 obj = rb_float_new(V_R4(pvar));
02200 break;
02201
02202 case VT_R8:
02203 if(V_ISBYREF(pvar))
02204 obj = rb_float_new(*V_R8REF(pvar));
02205 else
02206 obj = rb_float_new(V_R8(pvar));
02207 break;
02208
02209 case VT_BSTR:
02210 {
02211 if(V_ISBYREF(pvar))
02212 obj = ole_wc2vstr(*V_BSTRREF(pvar), FALSE);
02213 else
02214 obj = ole_wc2vstr(V_BSTR(pvar), FALSE);
02215 break;
02216 }
02217
02218 case VT_ERROR:
02219 if(V_ISBYREF(pvar))
02220 obj = INT2NUM(*V_ERRORREF(pvar));
02221 else
02222 obj = INT2NUM(V_ERROR(pvar));
02223 break;
02224
02225 case VT_BOOL:
02226 if (V_ISBYREF(pvar))
02227 obj = (*V_BOOLREF(pvar) ? Qtrue : Qfalse);
02228 else
02229 obj = (V_BOOL(pvar) ? Qtrue : Qfalse);
02230 break;
02231
02232 case VT_DISPATCH:
02233 {
02234 IDispatch *pDispatch;
02235
02236 if (V_ISBYREF(pvar))
02237 pDispatch = *V_DISPATCHREF(pvar);
02238 else
02239 pDispatch = V_DISPATCH(pvar);
02240
02241 if (pDispatch != NULL ) {
02242 OLE_ADDREF(pDispatch);
02243 obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
02244 }
02245 break;
02246 }
02247
02248 case VT_UNKNOWN:
02249 {
02250
02251 IUnknown *punk;
02252 IDispatch *pDispatch;
02253 void *p;
02254 HRESULT hr;
02255
02256 if (V_ISBYREF(pvar))
02257 punk = *V_UNKNOWNREF(pvar);
02258 else
02259 punk = V_UNKNOWN(pvar);
02260
02261 if(punk != NULL) {
02262 hr = punk->lpVtbl->QueryInterface(punk, &IID_IDispatch, &p);
02263 if(SUCCEEDED(hr)) {
02264 pDispatch = p;
02265 obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
02266 }
02267 }
02268 break;
02269 }
02270
02271 case VT_DATE:
02272 {
02273 DATE date;
02274 if(V_ISBYREF(pvar))
02275 date = *V_DATEREF(pvar);
02276 else
02277 date = V_DATE(pvar);
02278
02279 obj = vtdate2rbtime(date);
02280 break;
02281 }
02282 case VT_CY:
02283 default:
02284 {
02285 HRESULT hr;
02286 VARIANT variant;
02287 VariantInit(&variant);
02288 hr = VariantChangeTypeEx(&variant, pvar,
02289 cWIN32OLE_lcid, 0, VT_BSTR);
02290 if (SUCCEEDED(hr) && V_VT(&variant) == VT_BSTR) {
02291 obj = ole_wc2vstr(V_BSTR(&variant), FALSE);
02292 }
02293 VariantClear(&variant);
02294 break;
02295 }
02296 }
02297 return obj;
02298 }
02299
02300 static LONG
02301 reg_open_key(HKEY hkey, const char *name, HKEY *phkey)
02302 {
02303 return RegOpenKeyEx(hkey, name, 0, KEY_READ, phkey);
02304 }
02305
02306 static LONG
02307 reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey)
02308 {
02309 return reg_open_key(hkey, StringValuePtr(key), phkey);
02310 }
02311
02312 static VALUE
02313 reg_enum_key(HKEY hkey, DWORD i)
02314 {
02315 char buf[BUFSIZ + 1];
02316 DWORD size_buf = sizeof(buf);
02317 FILETIME ft;
02318 LONG err = RegEnumKeyEx(hkey, i, buf, &size_buf,
02319 NULL, NULL, NULL, &ft);
02320 if(err == ERROR_SUCCESS) {
02321 buf[BUFSIZ] = '\0';
02322 return rb_str_new2(buf);
02323 }
02324 return Qnil;
02325 }
02326
02327 static VALUE
02328 reg_get_val(HKEY hkey, const char *subkey)
02329 {
02330 char *pbuf;
02331 DWORD dwtype = 0;
02332 LONG size = 0;
02333 VALUE val = Qnil;
02334 LONG err = RegQueryValueEx(hkey, subkey, NULL, &dwtype, NULL, &size);
02335
02336 if (err == ERROR_SUCCESS) {
02337 pbuf = ALLOC_N(char, size + 1);
02338 err = RegQueryValueEx(hkey, subkey, NULL, &dwtype, pbuf, &size);
02339 if (err == ERROR_SUCCESS) {
02340 pbuf[size] = '\0';
02341 if (dwtype == REG_EXPAND_SZ) {
02342 char* pbuf2 = pbuf;
02343 DWORD len = ExpandEnvironmentStrings(pbuf2, NULL, 0);
02344 pbuf = ALLOC_N(char, len + 1);
02345 ExpandEnvironmentStrings(pbuf2, pbuf, len + 1);
02346 free(pbuf2);
02347 }
02348 val = rb_str_new2(pbuf);
02349 }
02350 free(pbuf);
02351 }
02352 return val;
02353 }
02354
02355 static VALUE
02356 reg_get_val2(HKEY hkey, const char *subkey)
02357 {
02358 HKEY hsubkey;
02359 LONG err;
02360 VALUE val = Qnil;
02361 err = RegOpenKeyEx(hkey, subkey, 0, KEY_READ, &hsubkey);
02362 if (err == ERROR_SUCCESS) {
02363 val = reg_get_val(hsubkey, NULL);
02364 RegCloseKey(hsubkey);
02365 }
02366 if (val == Qnil) {
02367 val = reg_get_val(hkey, subkey);
02368 }
02369 return val;
02370 }
02371
02372 static VALUE
02373 reg_get_typelib_file_path(HKEY hkey)
02374 {
02375 VALUE path = Qnil;
02376 path = reg_get_val2(hkey, "win64");
02377 if (path != Qnil) {
02378 return path;
02379 }
02380 path = reg_get_val2(hkey, "win32");
02381 if (path != Qnil) {
02382 return path;
02383 }
02384 path = reg_get_val2(hkey, "win16");
02385 return path;
02386 }
02387
02388 static VALUE
02389 typelib_file_from_clsid(VALUE ole)
02390 {
02391 HKEY hroot, hclsid;
02392 LONG err;
02393 VALUE typelib;
02394 char path[MAX_PATH + 1];
02395
02396 err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hroot);
02397 if (err != ERROR_SUCCESS) {
02398 return Qnil;
02399 }
02400 err = reg_open_key(hroot, StringValuePtr(ole), &hclsid);
02401 if (err != ERROR_SUCCESS) {
02402 RegCloseKey(hroot);
02403 return Qnil;
02404 }
02405 typelib = reg_get_val2(hclsid, "InprocServer32");
02406 RegCloseKey(hroot);
02407 RegCloseKey(hclsid);
02408 if (typelib != Qnil) {
02409 ExpandEnvironmentStrings(StringValuePtr(typelib), path, sizeof(path));
02410 path[MAX_PATH] = '\0';
02411 typelib = rb_str_new2(path);
02412 }
02413 return typelib;
02414 }
02415
02416 static VALUE
02417 typelib_file_from_typelib(VALUE ole)
02418 {
02419 HKEY htypelib, hclsid, hversion, hlang;
02420 double fver;
02421 DWORD i, j, k;
02422 LONG err;
02423 BOOL found = FALSE;
02424 VALUE typelib;
02425 VALUE file = Qnil;
02426 VALUE clsid;
02427 VALUE ver;
02428 VALUE lang;
02429
02430 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
02431 if(err != ERROR_SUCCESS) {
02432 return Qnil;
02433 }
02434 for(i = 0; !found; i++) {
02435 clsid = reg_enum_key(htypelib, i);
02436 if (clsid == Qnil)
02437 break;
02438 err = reg_open_vkey(htypelib, clsid, &hclsid);
02439 if (err != ERROR_SUCCESS)
02440 continue;
02441 fver = 0;
02442 for(j = 0; !found; j++) {
02443 ver = reg_enum_key(hclsid, j);
02444 if (ver == Qnil)
02445 break;
02446 err = reg_open_vkey(hclsid, ver, &hversion);
02447 if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver)))
02448 continue;
02449 fver = atof(StringValuePtr(ver));
02450 typelib = reg_get_val(hversion, NULL);
02451 if (typelib == Qnil)
02452 continue;
02453 if (rb_str_cmp(typelib, ole) == 0) {
02454 for(k = 0; !found; k++) {
02455 lang = reg_enum_key(hversion, k);
02456 if (lang == Qnil)
02457 break;
02458 err = reg_open_vkey(hversion, lang, &hlang);
02459 if (err == ERROR_SUCCESS) {
02460 if ((file = reg_get_typelib_file_path(hlang)) != Qnil)
02461 found = TRUE;
02462 RegCloseKey(hlang);
02463 }
02464 }
02465 }
02466 RegCloseKey(hversion);
02467 }
02468 RegCloseKey(hclsid);
02469 }
02470 RegCloseKey(htypelib);
02471 return file;
02472 }
02473
02474 static VALUE
02475 typelib_file(VALUE ole)
02476 {
02477 VALUE file = typelib_file_from_clsid(ole);
02478 if (file != Qnil) {
02479 return file;
02480 }
02481 return typelib_file_from_typelib(ole);
02482 }
02483
02484 static void
02485 ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self)
02486 {
02487 unsigned int count;
02488 unsigned int index;
02489 int iVar;
02490 ITypeInfo *pTypeInfo;
02491 TYPEATTR *pTypeAttr;
02492 VARDESC *pVarDesc;
02493 HRESULT hr;
02494 unsigned int len;
02495 BSTR bstr;
02496 char *pName = NULL;
02497 VALUE val;
02498 VALUE constant;
02499 ID id;
02500 constant = rb_hash_new();
02501 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
02502 for (index = 0; index < count; index++) {
02503 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, index, &pTypeInfo);
02504 if (FAILED(hr))
02505 continue;
02506 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
02507 if(FAILED(hr)) {
02508 OLE_RELEASE(pTypeInfo);
02509 continue;
02510 }
02511 for(iVar = 0; iVar < pTypeAttr->cVars; iVar++) {
02512 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, iVar, &pVarDesc);
02513 if(FAILED(hr))
02514 continue;
02515 if(pVarDesc->varkind == VAR_CONST &&
02516 !(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
02517 VARFLAG_FRESTRICTED |
02518 VARFLAG_FNONBROWSABLE))) {
02519 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
02520 1, &len);
02521 if(FAILED(hr) || len == 0 || !bstr)
02522 continue;
02523 pName = ole_wc2mb(bstr);
02524 val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));
02525 *pName = toupper((int)*pName);
02526 id = rb_intern(pName);
02527 if (rb_is_const_id(id)) {
02528 rb_define_const(klass, pName, val);
02529 }
02530 else {
02531 rb_hash_aset(constant, rb_str_new2(pName), val);
02532 }
02533 SysFreeString(bstr);
02534 if(pName) {
02535 free(pName);
02536 pName = NULL;
02537 }
02538 }
02539 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
02540 }
02541 pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
02542 OLE_RELEASE(pTypeInfo);
02543 }
02544 rb_define_const(klass, "CONSTANTS", constant);
02545 }
02546
02547 static HRESULT
02548 clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid)
02549 {
02550 HKEY hlm;
02551 HKEY hpid;
02552 VALUE subkey;
02553 LONG err;
02554 char clsid[100];
02555 OLECHAR *pbuf;
02556 DWORD len;
02557 DWORD dwtype;
02558 HRESULT hr = S_OK;
02559 err = RegConnectRegistry(StringValuePtr(host), HKEY_LOCAL_MACHINE, &hlm);
02560 if (err != ERROR_SUCCESS)
02561 return HRESULT_FROM_WIN32(err);
02562 subkey = rb_str_new2("SOFTWARE\\Classes\\");
02563 rb_str_concat(subkey, com);
02564 rb_str_cat2(subkey, "\\CLSID");
02565 err = RegOpenKeyEx(hlm, StringValuePtr(subkey), 0, KEY_READ, &hpid);
02566 if (err != ERROR_SUCCESS)
02567 hr = HRESULT_FROM_WIN32(err);
02568 else {
02569 len = sizeof(clsid);
02570 err = RegQueryValueEx(hpid, (LPBYTE)"", NULL, &dwtype, clsid, &len);
02571 if (err == ERROR_SUCCESS && dwtype == REG_SZ) {
02572 pbuf = ole_mb2wc(clsid, -1);
02573 hr = CLSIDFromString(pbuf, pclsid);
02574 SysFreeString(pbuf);
02575 }
02576 else {
02577 hr = HRESULT_FROM_WIN32(err);
02578 }
02579 RegCloseKey(hpid);
02580 }
02581 RegCloseKey(hlm);
02582 return hr;
02583 }
02584
02585 static VALUE
02586 ole_create_dcom(int argc, VALUE *argv, VALUE self)
02587 {
02588 VALUE ole, host, others;
02589 HRESULT hr;
02590 CLSID clsid;
02591 OLECHAR *pbuf;
02592
02593 COSERVERINFO serverinfo;
02594 MULTI_QI multi_qi;
02595 DWORD clsctx = CLSCTX_REMOTE_SERVER;
02596
02597 if (!gole32)
02598 gole32 = LoadLibrary("OLE32");
02599 if (!gole32)
02600 rb_raise(rb_eRuntimeError, "failed to load OLE32");
02601 if (!gCoCreateInstanceEx)
02602 gCoCreateInstanceEx = (FNCOCREATEINSTANCEEX*)
02603 GetProcAddress(gole32, "CoCreateInstanceEx");
02604 if (!gCoCreateInstanceEx)
02605 rb_raise(rb_eRuntimeError, "CoCreateInstanceEx is not supported in this environment");
02606 rb_scan_args(argc, argv, "2*", &ole, &host, &others);
02607
02608 pbuf = ole_vstr2wc(ole);
02609 hr = CLSIDFromProgID(pbuf, &clsid);
02610 if (FAILED(hr))
02611 hr = clsid_from_remote(host, ole, &clsid);
02612 if (FAILED(hr))
02613 hr = CLSIDFromString(pbuf, &clsid);
02614 SysFreeString(pbuf);
02615 if (FAILED(hr))
02616 ole_raise(hr, eWIN32OLERuntimeError,
02617 "unknown OLE server: `%s'",
02618 StringValuePtr(ole));
02619 memset(&serverinfo, 0, sizeof(COSERVERINFO));
02620 serverinfo.pwszName = ole_vstr2wc(host);
02621 memset(&multi_qi, 0, sizeof(MULTI_QI));
02622 multi_qi.pIID = &IID_IDispatch;
02623 hr = gCoCreateInstanceEx(&clsid, NULL, clsctx, &serverinfo, 1, &multi_qi);
02624 SysFreeString(serverinfo.pwszName);
02625 if (FAILED(hr))
02626 ole_raise(hr, eWIN32OLERuntimeError,
02627 "failed to create DCOM server `%s' in `%s'",
02628 StringValuePtr(ole),
02629 StringValuePtr(host));
02630
02631 ole_set_member(self, (IDispatch*)multi_qi.pItf);
02632 return self;
02633 }
02634
02635 static VALUE
02636 ole_bind_obj(VALUE moniker, int argc, VALUE *argv, VALUE self)
02637 {
02638 IBindCtx *pBindCtx;
02639 IMoniker *pMoniker;
02640 IDispatch *pDispatch;
02641 void *p;
02642 HRESULT hr;
02643 OLECHAR *pbuf;
02644 ULONG eaten = 0;
02645
02646 ole_initialize();
02647
02648 hr = CreateBindCtx(0, &pBindCtx);
02649 if(FAILED(hr)) {
02650 ole_raise(hr, eWIN32OLERuntimeError,
02651 "failed to create bind context");
02652 }
02653
02654 pbuf = ole_vstr2wc(moniker);
02655 hr = MkParseDisplayName(pBindCtx, pbuf, &eaten, &pMoniker);
02656 SysFreeString(pbuf);
02657 if(FAILED(hr)) {
02658 OLE_RELEASE(pBindCtx);
02659 ole_raise(hr, eWIN32OLERuntimeError,
02660 "failed to parse display name of moniker `%s'",
02661 StringValuePtr(moniker));
02662 }
02663 hr = pMoniker->lpVtbl->BindToObject(pMoniker, pBindCtx, NULL,
02664 &IID_IDispatch, &p);
02665 pDispatch = p;
02666 OLE_RELEASE(pMoniker);
02667 OLE_RELEASE(pBindCtx);
02668
02669 if(FAILED(hr)) {
02670 ole_raise(hr, eWIN32OLERuntimeError,
02671 "failed to bind moniker `%s'",
02672 StringValuePtr(moniker));
02673 }
02674 return create_win32ole_object(self, pDispatch, argc, argv);
02675 }
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686 static VALUE
02687 fole_s_connect(int argc, VALUE *argv, VALUE self)
02688 {
02689 VALUE svr_name;
02690 VALUE others;
02691 HRESULT hr;
02692 CLSID clsid;
02693 OLECHAR *pBuf;
02694 IDispatch *pDispatch;
02695 void *p;
02696 IUnknown *pUnknown;
02697
02698 rb_secure(4);
02699
02700 ole_initialize();
02701
02702 rb_scan_args(argc, argv, "1*", &svr_name, &others);
02703 SafeStringValue(svr_name);
02704 if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
02705 rb_raise(rb_eSecurityError, "Insecure Object Connection - %s",
02706 StringValuePtr(svr_name));
02707 }
02708
02709
02710 pBuf = ole_vstr2wc(svr_name);
02711 hr = CLSIDFromProgID(pBuf, &clsid);
02712 if(FAILED(hr)) {
02713 hr = CLSIDFromString(pBuf, &clsid);
02714 }
02715 SysFreeString(pBuf);
02716 if(FAILED(hr)) {
02717 return ole_bind_obj(svr_name, argc, argv, self);
02718 }
02719
02720 hr = GetActiveObject(&clsid, 0, &pUnknown);
02721 if (FAILED(hr)) {
02722 ole_raise(hr, eWIN32OLERuntimeError,
02723 "OLE server `%s' not running", StringValuePtr(svr_name));
02724 }
02725 hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch, &p);
02726 pDispatch = p;
02727 if(FAILED(hr)) {
02728 OLE_RELEASE(pUnknown);
02729 ole_raise(hr, eWIN32OLERuntimeError,
02730 "failed to create WIN32OLE server `%s'",
02731 StringValuePtr(svr_name));
02732 }
02733
02734 OLE_RELEASE(pUnknown);
02735
02736 return create_win32ole_object(self, pDispatch, argc, argv);
02737 }
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768 static VALUE
02769 fole_s_const_load(int argc, VALUE *argv, VALUE self)
02770 {
02771 VALUE ole;
02772 VALUE klass;
02773 struct oledata *pole;
02774 ITypeInfo *pTypeInfo;
02775 ITypeLib *pTypeLib;
02776 unsigned int index;
02777 HRESULT hr;
02778 OLECHAR *pBuf;
02779 VALUE file;
02780 LCID lcid = cWIN32OLE_lcid;
02781
02782 rb_secure(4);
02783 rb_scan_args(argc, argv, "11", &ole, &klass);
02784 if (TYPE(klass) != T_CLASS &&
02785 TYPE(klass) != T_MODULE &&
02786 TYPE(klass) != T_NIL) {
02787 rb_raise(rb_eTypeError, "2nd parameter must be Class or Module");
02788 }
02789 if (rb_obj_is_kind_of(ole, cWIN32OLE)) {
02790 OLEData_Get_Struct(ole, pole);
02791 hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
02792 0, lcid, &pTypeInfo);
02793 if(FAILED(hr)) {
02794 ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
02795 }
02796 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
02797 if(FAILED(hr)) {
02798 OLE_RELEASE(pTypeInfo);
02799 ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib");
02800 }
02801 OLE_RELEASE(pTypeInfo);
02802 if(TYPE(klass) != T_NIL) {
02803 ole_const_load(pTypeLib, klass, self);
02804 }
02805 else {
02806 ole_const_load(pTypeLib, cWIN32OLE, self);
02807 }
02808 OLE_RELEASE(pTypeLib);
02809 }
02810 else if(TYPE(ole) == T_STRING) {
02811 file = typelib_file(ole);
02812 if (file == Qnil) {
02813 file = ole;
02814 }
02815 pBuf = ole_vstr2wc(file);
02816 hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib);
02817 SysFreeString(pBuf);
02818 if (FAILED(hr))
02819 ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
02820 if(TYPE(klass) != T_NIL) {
02821 ole_const_load(pTypeLib, klass, self);
02822 }
02823 else {
02824 ole_const_load(pTypeLib, cWIN32OLE, self);
02825 }
02826 OLE_RELEASE(pTypeLib);
02827 }
02828 else {
02829 rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE instance");
02830 }
02831 return Qnil;
02832 }
02833
02834 static VALUE
02835 ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes)
02836 {
02837
02838 long count;
02839 int i;
02840 HRESULT hr;
02841 BSTR bstr;
02842 ITypeInfo *pTypeInfo;
02843 VALUE type;
02844
02845 rb_secure(4);
02846 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
02847 for (i = 0; i < count; i++) {
02848 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
02849 &bstr, NULL, NULL, NULL);
02850 if (FAILED(hr))
02851 continue;
02852
02853 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
02854 if (FAILED(hr))
02855 continue;
02856
02857 type = foletype_s_allocate(cWIN32OLE_TYPE);
02858 oletype_set_member(type, pTypeInfo, WC2VSTR(bstr));
02859
02860 rb_ary_push(classes, type);
02861 OLE_RELEASE(pTypeInfo);
02862 }
02863 return classes;
02864 }
02865
02866 static ULONG
02867 reference_count(struct oledata * pole)
02868 {
02869 ULONG n = 0;
02870 if(pole->pDispatch) {
02871 OLE_ADDREF(pole->pDispatch);
02872 n = OLE_RELEASE(pole->pDispatch);
02873 }
02874 return n;
02875 }
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885 static VALUE
02886 fole_s_reference_count(VALUE self, VALUE obj)
02887 {
02888 struct oledata * pole;
02889 OLEData_Get_Struct(obj, pole);
02890 return INT2NUM(reference_count(pole));
02891 }
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902 static VALUE
02903 fole_s_free(VALUE self, VALUE obj)
02904 {
02905 ULONG n = 0;
02906 struct oledata * pole;
02907 OLEData_Get_Struct(obj, pole);
02908 if(pole->pDispatch) {
02909 if (reference_count(pole) > 0) {
02910 n = OLE_RELEASE(pole->pDispatch);
02911 }
02912 }
02913 return INT2NUM(n);
02914 }
02915
02916 static HWND
02917 ole_show_help(VALUE helpfile, VALUE helpcontext)
02918 {
02919 FNHTMLHELP *pfnHtmlHelp;
02920 HWND hwnd = 0;
02921
02922 if(!ghhctrl)
02923 ghhctrl = LoadLibrary("HHCTRL.OCX");
02924 if (!ghhctrl)
02925 return hwnd;
02926 pfnHtmlHelp = (FNHTMLHELP*)GetProcAddress(ghhctrl, "HtmlHelpA");
02927 if (!pfnHtmlHelp)
02928 return hwnd;
02929 hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile),
02930 0x0f, NUM2INT(helpcontext));
02931 if (hwnd == 0)
02932 hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile),
02933 0, NUM2INT(helpcontext));
02934 return hwnd;
02935 }
02936
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948 static VALUE
02949 fole_s_show_help(int argc, VALUE *argv, VALUE self)
02950 {
02951 VALUE target;
02952 VALUE helpcontext;
02953 VALUE helpfile;
02954 VALUE name;
02955 HWND hwnd;
02956 rb_scan_args(argc, argv, "11", &target, &helpcontext);
02957 if (rb_obj_is_kind_of(target, cWIN32OLE_TYPE) ||
02958 rb_obj_is_kind_of(target, cWIN32OLE_METHOD)) {
02959 helpfile = rb_funcall(target, rb_intern("helpfile"), 0);
02960 if(strlen(StringValuePtr(helpfile)) == 0) {
02961 name = rb_ivar_get(target, rb_intern("name"));
02962 rb_raise(rb_eRuntimeError, "no helpfile of `%s'",
02963 StringValuePtr(name));
02964 }
02965 helpcontext = rb_funcall(target, rb_intern("helpcontext"), 0);
02966 } else {
02967 helpfile = target;
02968 }
02969 if (TYPE(helpfile) != T_STRING) {
02970 rb_raise(rb_eTypeError, "1st parameter must be (String|WIN32OLE_TYPE|WIN32OLE_METHOD)");
02971 }
02972 hwnd = ole_show_help(helpfile, helpcontext);
02973 if(hwnd == 0) {
02974 rb_raise(rb_eRuntimeError, "failed to open help file `%s'",
02975 StringValuePtr(helpfile));
02976 }
02977 return Qnil;
02978 }
02979
02980
02981
02982
02983
02984
02985
02986
02987 static VALUE
02988 fole_s_get_code_page(VALUE self)
02989 {
02990 return INT2FIX(cWIN32OLE_cp);
02991 }
02992
02993 static BOOL CALLBACK
02994 installed_code_page_proc(LPTSTR str) {
02995 if (strtoul(str, NULL, 10) == g_cp_to_check) {
02996 g_cp_installed = TRUE;
02997 return FALSE;
02998 }
02999 return TRUE;
03000 }
03001
03002 static BOOL
03003 code_page_installed(UINT cp)
03004 {
03005 g_cp_installed = FALSE;
03006 g_cp_to_check = cp;
03007 EnumSystemCodePages(installed_code_page_proc, CP_INSTALLED);
03008 return g_cp_installed;
03009 }
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024 static VALUE
03025 fole_s_set_code_page(VALUE self, VALUE vcp)
03026 {
03027 UINT cp = FIX2INT(vcp);
03028 set_ole_codepage(cp);
03029
03030
03031
03032 return Qnil;
03033 }
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044 static VALUE
03045 fole_s_get_locale(VALUE self)
03046 {
03047 return INT2FIX(cWIN32OLE_lcid);
03048 }
03049
03050 static BOOL
03051 CALLBACK installed_lcid_proc(LPTSTR str)
03052 {
03053 if (strcmp(str, g_lcid_to_check) == 0) {
03054 g_lcid_installed = TRUE;
03055 return FALSE;
03056 }
03057 return TRUE;
03058 }
03059
03060 static BOOL
03061 lcid_installed(LCID lcid)
03062 {
03063 g_lcid_installed = FALSE;
03064 snprintf(g_lcid_to_check, sizeof(g_lcid_to_check), "%08lx", lcid);
03065 EnumSystemLocales(installed_lcid_proc, LCID_INSTALLED);
03066 return g_lcid_installed;
03067 }
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079 static VALUE
03080 fole_s_set_locale(VALUE self, VALUE vlcid)
03081 {
03082 LCID lcid = FIX2INT(vlcid);
03083 if (lcid_installed(lcid)) {
03084 cWIN32OLE_lcid = lcid;
03085 } else {
03086 switch (lcid) {
03087 case LOCALE_SYSTEM_DEFAULT:
03088 case LOCALE_USER_DEFAULT:
03089 cWIN32OLE_lcid = lcid;
03090 break;
03091 default:
03092 rb_raise(eWIN32OLERuntimeError, "not installed locale: %u", (unsigned int)lcid);
03093 }
03094 }
03095 return Qnil;
03096 }
03097
03098
03099
03100
03101
03102
03103
03104
03105 static VALUE
03106 fole_s_create_guid(VALUE self)
03107 {
03108 GUID guid;
03109 HRESULT hr;
03110 OLECHAR bstr[80];
03111 int len = 0;
03112 hr = CoCreateGuid(&guid);
03113 if (FAILED(hr)) {
03114 ole_raise(hr, eWIN32OLERuntimeError, "failed to create GUID");
03115 }
03116 len = StringFromGUID2(&guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
03117 if (len == 0) {
03118 rb_raise(rb_eRuntimeError, "failed to create GUID(buffer over)");
03119 }
03120 return ole_wc2vstr(bstr, FALSE);
03121 }
03122
03123
03124
03125
03126
03127
03128
03129 static void ole_pure_initialize()
03130 {
03131 HRESULT hr;
03132 hr = OleInitialize(NULL);
03133 if(FAILED(hr)) {
03134 ole_raise(hr, rb_eRuntimeError, "fail: OLE initialize");
03135 }
03136 }
03137
03138 static void ole_pure_uninitialize()
03139 {
03140 OleUninitialize();
03141 }
03142
03143
03144 static VALUE
03145 fole_s_ole_initialize(VALUE self)
03146 {
03147 ole_pure_initialize();
03148 return Qnil;
03149 }
03150
03151
03152 static VALUE
03153 fole_s_ole_uninitialize(VALUE self)
03154 {
03155 ole_pure_uninitialize();
03156 return Qnil;
03157 }
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212 static VALUE
03213 fole_initialize(int argc, VALUE *argv, VALUE self)
03214 {
03215 VALUE svr_name;
03216 VALUE host;
03217 VALUE others;
03218 HRESULT hr;
03219 CLSID clsid;
03220 OLECHAR *pBuf;
03221 IDispatch *pDispatch;
03222 void *p;
03223 rb_secure(4);
03224 rb_call_super(0, 0);
03225 rb_scan_args(argc, argv, "11*", &svr_name, &host, &others);
03226
03227 SafeStringValue(svr_name);
03228 if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
03229 rb_raise(rb_eSecurityError, "Insecure Object Creation - %s",
03230 StringValuePtr(svr_name));
03231 }
03232 if (!NIL_P(host)) {
03233 SafeStringValue(host);
03234 if (rb_safe_level() > 0 && OBJ_TAINTED(host)) {
03235 rb_raise(rb_eSecurityError, "Insecure Object Creation - %s",
03236 StringValuePtr(svr_name));
03237 }
03238 return ole_create_dcom(argc, argv, self);
03239 }
03240
03241
03242 pBuf = ole_vstr2wc(svr_name);
03243 hr = CLSIDFromProgID(pBuf, &clsid);
03244 if(FAILED(hr)) {
03245 hr = CLSIDFromString(pBuf, &clsid);
03246 }
03247 SysFreeString(pBuf);
03248 if(FAILED(hr)) {
03249 ole_raise(hr, eWIN32OLERuntimeError,
03250 "unknown OLE server: `%s'",
03251 StringValuePtr(svr_name));
03252 }
03253
03254
03255 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
03256 &IID_IDispatch, &p);
03257 pDispatch = p;
03258 if(FAILED(hr)) {
03259 ole_raise(hr, eWIN32OLERuntimeError,
03260 "failed to create WIN32OLE object from `%s'",
03261 StringValuePtr(svr_name));
03262 }
03263
03264 ole_set_member(self, pDispatch);
03265 return self;
03266 }
03267
03268 static VALUE
03269 hash2named_arg(VALUE pair, struct oleparam* pOp)
03270 {
03271 unsigned int index, i;
03272 VALUE key, value;
03273 index = pOp->dp.cNamedArgs;
03274
03275
03276
03277
03278 key = rb_ary_entry(pair, 0);
03279 if(TYPE(key) != T_STRING && TYPE(key) != T_SYMBOL) {
03280
03281 for(i = 1; i < index + 1; i++) {
03282 SysFreeString(pOp->pNamedArgs[i]);
03283 }
03284
03285 for(i = 0; i < index; i++ ) {
03286 VariantClear(&(pOp->dp.rgvarg[i]));
03287 }
03288
03289 rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
03290 }
03291 if (TYPE(key) == T_SYMBOL) {
03292 key = rb_sym_to_s(key);
03293 }
03294
03295
03296 pOp->pNamedArgs[index + 1] = ole_vstr2wc(key);
03297
03298 value = rb_ary_entry(pair, 1);
03299 VariantInit(&(pOp->dp.rgvarg[index]));
03300 ole_val2variant(value, &(pOp->dp.rgvarg[index]));
03301
03302 pOp->dp.cNamedArgs += 1;
03303 return Qnil;
03304 }
03305
03306 static VALUE
03307 set_argv(VARIANTARG* realargs, unsigned int beg, unsigned int end)
03308 {
03309 VALUE argv = rb_const_get(cWIN32OLE, rb_intern("ARGV"));
03310
03311 Check_Type(argv, T_ARRAY);
03312 rb_ary_clear(argv);
03313 while (end-- > beg) {
03314 rb_ary_push(argv, ole_variant2val(&realargs[end]));
03315 VariantClear(&realargs[end]);
03316 }
03317 return argv;
03318 }
03319
03320 static VALUE
03321 ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket)
03322 {
03323 LCID lcid = cWIN32OLE_lcid;
03324 struct oledata *pole;
03325 HRESULT hr;
03326 VALUE cmd;
03327 VALUE paramS;
03328 VALUE param;
03329 VALUE obj;
03330 VALUE v;
03331
03332 BSTR wcmdname;
03333
03334 DISPID DispID;
03335 DISPID* pDispID;
03336 EXCEPINFO excepinfo;
03337 VARIANT result;
03338 VARIANTARG* realargs = NULL;
03339 unsigned int argErr = 0;
03340 unsigned int i;
03341 unsigned int cNamedArgs;
03342 int n;
03343 struct oleparam op;
03344 struct olevariantdata *pvar;
03345 memset(&excepinfo, 0, sizeof(EXCEPINFO));
03346
03347 VariantInit(&result);
03348
03349 op.dp.rgvarg = NULL;
03350 op.dp.rgdispidNamedArgs = NULL;
03351 op.dp.cNamedArgs = 0;
03352 op.dp.cArgs = 0;
03353
03354 rb_scan_args(argc, argv, "1*", &cmd, ¶mS);
03355 if(TYPE(cmd) != T_STRING && TYPE(cmd) != T_SYMBOL && !is_bracket) {
03356 rb_raise(rb_eTypeError, "method is wrong type (expected String or Symbol)");
03357 }
03358 if (TYPE(cmd) == T_SYMBOL) {
03359 cmd = rb_sym_to_s(cmd);
03360 }
03361 OLEData_Get_Struct(self, pole);
03362 if(!pole->pDispatch) {
03363 rb_raise(rb_eRuntimeError, "failed to get dispatch interface");
03364 }
03365 if (is_bracket) {
03366 DispID = DISPID_VALUE;
03367 argc += 1;
03368 rb_ary_unshift(paramS, cmd);
03369 } else {
03370 wcmdname = ole_vstr2wc(cmd);
03371 hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
03372 &wcmdname, 1, lcid, &DispID);
03373 SysFreeString(wcmdname);
03374 if(FAILED(hr)) {
03375 ole_raise(hr, rb_eNoMethodError,
03376 "unknown property or method: `%s'",
03377 StringValuePtr(cmd));
03378 }
03379 }
03380
03381
03382 param = rb_ary_entry(paramS, argc-2);
03383
03384 op.dp.cNamedArgs = 0;
03385
03386
03387 if(TYPE(param) == T_HASH) {
03388
03389
03390
03391 cNamedArgs = NUM2INT(rb_funcall(param, rb_intern("length"), 0));
03392 op.dp.cArgs = cNamedArgs + argc - 2;
03393 op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);
03394 op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs);
03395 rb_block_call(param, rb_intern("each"), 0, 0, hash2named_arg, (VALUE)&op);
03396
03397 pDispID = ALLOCA_N(DISPID, cNamedArgs + 1);
03398 op.pNamedArgs[0] = ole_vstr2wc(cmd);
03399 hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch,
03400 &IID_NULL,
03401 op.pNamedArgs,
03402 op.dp.cNamedArgs + 1,
03403 lcid, pDispID);
03404 for(i = 0; i < op.dp.cNamedArgs + 1; i++) {
03405 SysFreeString(op.pNamedArgs[i]);
03406 op.pNamedArgs[i] = NULL;
03407 }
03408 if(FAILED(hr)) {
03409
03410 for(i = 0; i < op.dp.cArgs; i++ ) {
03411 VariantClear(&op.dp.rgvarg[i]);
03412 }
03413 ole_raise(hr, eWIN32OLERuntimeError,
03414 "failed to get named argument info: `%s'",
03415 StringValuePtr(cmd));
03416 }
03417 op.dp.rgdispidNamedArgs = &(pDispID[1]);
03418 }
03419 else {
03420 cNamedArgs = 0;
03421 op.dp.cArgs = argc - 1;
03422 op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);
03423 if (op.dp.cArgs > 0) {
03424 op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs);
03425 }
03426 }
03427
03428
03429
03430 if(op.dp.cArgs > cNamedArgs) {
03431 realargs = ALLOCA_N(VARIANTARG, op.dp.cArgs-cNamedArgs+1);
03432 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
03433 n = op.dp.cArgs - i + cNamedArgs - 1;
03434 VariantInit(&realargs[n]);
03435 VariantInit(&op.dp.rgvarg[n]);
03436 param = rb_ary_entry(paramS, i-cNamedArgs);
03437 if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) {
03438 Data_Get_Struct(param, struct olevariantdata, pvar);
03439 VariantCopy(&op.dp.rgvarg[n], &(pvar->var));
03440 } else {
03441 ole_val2variant(param, &realargs[n]);
03442 V_VT(&op.dp.rgvarg[n]) = VT_VARIANT | VT_BYREF;
03443 V_VARIANTREF(&op.dp.rgvarg[n]) = &realargs[n];
03444 }
03445 }
03446 }
03447
03448 if (wFlags & DISPATCH_PROPERTYPUT) {
03449 if (op.dp.cArgs == 0)
03450 ole_raise(ResultFromScode(E_INVALIDARG), eWIN32OLERuntimeError, "argument error");
03451
03452 op.dp.cNamedArgs = 1;
03453 op.dp.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 );
03454 op.dp.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
03455 }
03456
03457 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
03458 &IID_NULL, lcid, wFlags, &op.dp,
03459 &result, &excepinfo, &argErr);
03460
03461 if (FAILED(hr)) {
03462
03463 if(op.dp.cArgs >= cNamedArgs) {
03464 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
03465 n = op.dp.cArgs - i + cNamedArgs - 1;
03466 param = rb_ary_entry(paramS, i-cNamedArgs);
03467 ole_val2variant(param, &op.dp.rgvarg[n]);
03468 }
03469 if (hr == DISP_E_EXCEPTION) {
03470 ole_freeexceptinfo(&excepinfo);
03471 }
03472 memset(&excepinfo, 0, sizeof(EXCEPINFO));
03473 VariantInit(&result);
03474 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
03475 &IID_NULL, lcid, wFlags,
03476 &op.dp, &result,
03477 &excepinfo, &argErr);
03478
03479
03480
03481
03482
03483 if ((hr == DISP_E_EXCEPTION || hr == DISP_E_MEMBERNOTFOUND) && DispID > 0x8000) {
03484 if (hr == DISP_E_EXCEPTION) {
03485 ole_freeexceptinfo(&excepinfo);
03486 }
03487 memset(&excepinfo, 0, sizeof(EXCEPINFO));
03488 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
03489 &IID_NULL, lcid, wFlags,
03490 &op.dp, NULL,
03491 &excepinfo, &argErr);
03492
03493 }
03494 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
03495 n = op.dp.cArgs - i + cNamedArgs - 1;
03496 VariantClear(&op.dp.rgvarg[n]);
03497 }
03498 }
03499
03500 if (FAILED(hr)) {
03501
03502 if (op.dp.cArgs > cNamedArgs) {
03503 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
03504 n = op.dp.cArgs - i + cNamedArgs - 1;
03505 param = rb_ary_entry(paramS, i-cNamedArgs);
03506 ole_val2variant2(param, &op.dp.rgvarg[n]);
03507 }
03508 if (hr == DISP_E_EXCEPTION) {
03509 ole_freeexceptinfo(&excepinfo);
03510 }
03511 memset(&excepinfo, 0, sizeof(EXCEPINFO));
03512 VariantInit(&result);
03513 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
03514 &IID_NULL, lcid, wFlags,
03515 &op.dp, &result,
03516 &excepinfo, &argErr);
03517 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
03518 n = op.dp.cArgs - i + cNamedArgs - 1;
03519 VariantClear(&op.dp.rgvarg[n]);
03520 }
03521 }
03522 }
03523
03524 }
03525
03526 if(op.dp.cArgs > cNamedArgs) {
03527 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
03528 n = op.dp.cArgs - i + cNamedArgs - 1;
03529 param = rb_ary_entry(paramS, i-cNamedArgs);
03530 if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) {
03531 ole_val2variant(param, &realargs[n]);
03532 }
03533 }
03534 set_argv(realargs, cNamedArgs, op.dp.cArgs);
03535 }
03536 else {
03537 for(i = 0; i < op.dp.cArgs; i++) {
03538 VariantClear(&op.dp.rgvarg[i]);
03539 }
03540 }
03541
03542 if (FAILED(hr)) {
03543 v = ole_excepinfo2msg(&excepinfo);
03544 ole_raise(hr, eWIN32OLERuntimeError, "(in OLE method `%s': )%s",
03545 StringValuePtr(cmd),
03546 StringValuePtr(v));
03547 }
03548 obj = ole_variant2val(&result);
03549 VariantClear(&result);
03550 return obj;
03551 }
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561
03562
03563
03564
03565
03566 static VALUE
03567 fole_invoke(int argc, VALUE *argv, VALUE self)
03568 {
03569 return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
03570 }
03571
03572 static VALUE
03573 ole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types, USHORT dispkind)
03574 {
03575 HRESULT hr;
03576 struct oledata *pole;
03577 unsigned int argErr = 0;
03578 EXCEPINFO excepinfo;
03579 VARIANT result;
03580 DISPPARAMS dispParams;
03581 VARIANTARG* realargs = NULL;
03582 int i, j;
03583 VALUE obj = Qnil;
03584 VALUE tp, param;
03585 VALUE v;
03586 VARTYPE vt;
03587
03588 Check_Type(args, T_ARRAY);
03589 Check_Type(types, T_ARRAY);
03590
03591 memset(&excepinfo, 0, sizeof(EXCEPINFO));
03592 memset(&dispParams, 0, sizeof(DISPPARAMS));
03593 VariantInit(&result);
03594 OLEData_Get_Struct(self, pole);
03595
03596 dispParams.cArgs = RARRAY_LEN(args);
03597 dispParams.rgvarg = ALLOCA_N(VARIANTARG, dispParams.cArgs);
03598 realargs = ALLOCA_N(VARIANTARG, dispParams.cArgs);
03599 for (i = 0, j = dispParams.cArgs - 1; i < (int)dispParams.cArgs; i++, j--)
03600 {
03601 VariantInit(&realargs[i]);
03602 VariantInit(&dispParams.rgvarg[i]);
03603 tp = rb_ary_entry(types, j);
03604 vt = (VARTYPE)FIX2INT(tp);
03605 V_VT(&dispParams.rgvarg[i]) = vt;
03606 param = rb_ary_entry(args, j);
03607 if (param == Qnil)
03608 {
03609
03610 V_VT(&dispParams.rgvarg[i]) = V_VT(&realargs[i]) = VT_ERROR;
03611 V_ERROR(&dispParams.rgvarg[i]) = V_ERROR(&realargs[i]) = DISP_E_PARAMNOTFOUND;
03612 }
03613 else
03614 {
03615 if (vt & VT_ARRAY)
03616 {
03617 int ent;
03618 LPBYTE pb;
03619 short* ps;
03620 LPLONG pl;
03621 VARIANT* pv;
03622 CY *py;
03623 VARTYPE v;
03624 SAFEARRAYBOUND rgsabound[1];
03625 Check_Type(param, T_ARRAY);
03626 rgsabound[0].lLbound = 0;
03627 rgsabound[0].cElements = RARRAY_LEN(param);
03628 v = vt & ~(VT_ARRAY | VT_BYREF);
03629 V_ARRAY(&realargs[i]) = SafeArrayCreate(v, 1, rgsabound);
03630 V_VT(&realargs[i]) = VT_ARRAY | v;
03631 SafeArrayLock(V_ARRAY(&realargs[i]));
03632 pb = V_ARRAY(&realargs[i])->pvData;
03633 ps = V_ARRAY(&realargs[i])->pvData;
03634 pl = V_ARRAY(&realargs[i])->pvData;
03635 py = V_ARRAY(&realargs[i])->pvData;
03636 pv = V_ARRAY(&realargs[i])->pvData;
03637 for (ent = 0; ent < (int)rgsabound[0].cElements; ent++)
03638 {
03639 VARIANT velem;
03640 VALUE elem = rb_ary_entry(param, ent);
03641 ole_val2variant(elem, &velem);
03642 if (v != VT_VARIANT)
03643 {
03644 VariantChangeTypeEx(&velem, &velem,
03645 cWIN32OLE_lcid, 0, v);
03646 }
03647 switch (v)
03648 {
03649
03650 case VT_VARIANT:
03651 *pv++ = velem;
03652 break;
03653
03654 case VT_R8:
03655 case VT_CY:
03656 case VT_DATE:
03657 *py++ = V_CY(&velem);
03658 break;
03659
03660 case VT_BOOL:
03661 case VT_I2:
03662 case VT_UI2:
03663 *ps++ = V_I2(&velem);
03664 break;
03665
03666 case VT_UI1:
03667 case VT_I1:
03668 *pb++ = V_UI1(&velem);
03669 break;
03670
03671 default:
03672 *pl++ = V_I4(&velem);
03673 break;
03674 }
03675 }
03676 SafeArrayUnlock(V_ARRAY(&realargs[i]));
03677 }
03678 else
03679 {
03680 ole_val2variant(param, &realargs[i]);
03681 if ((vt & (~VT_BYREF)) != VT_VARIANT)
03682 {
03683 hr = VariantChangeTypeEx(&realargs[i], &realargs[i],
03684 cWIN32OLE_lcid, 0,
03685 (VARTYPE)(vt & (~VT_BYREF)));
03686 if (hr != S_OK)
03687 {
03688 rb_raise(rb_eTypeError, "not valid value");
03689 }
03690 }
03691 }
03692 if ((vt & VT_BYREF) || vt == VT_VARIANT)
03693 {
03694 if (vt == VT_VARIANT)
03695 V_VT(&dispParams.rgvarg[i]) = VT_VARIANT | VT_BYREF;
03696 switch (vt & (~VT_BYREF))
03697 {
03698
03699 case VT_VARIANT:
03700 V_VARIANTREF(&dispParams.rgvarg[i]) = &realargs[i];
03701 break;
03702
03703 case VT_R8:
03704 case VT_CY:
03705 case VT_DATE:
03706 V_CYREF(&dispParams.rgvarg[i]) = &V_CY(&realargs[i]);
03707 break;
03708
03709 case VT_BOOL:
03710 case VT_I2:
03711 case VT_UI2:
03712 V_I2REF(&dispParams.rgvarg[i]) = &V_I2(&realargs[i]);
03713 break;
03714
03715 case VT_UI1:
03716 case VT_I1:
03717 V_UI1REF(&dispParams.rgvarg[i]) = &V_UI1(&realargs[i]);
03718 break;
03719
03720 default:
03721 V_I4REF(&dispParams.rgvarg[i]) = &V_I4(&realargs[i]);
03722 break;
03723 }
03724 }
03725 else
03726 {
03727
03728 V_CY(&dispParams.rgvarg[i]) = V_CY(&realargs[i]);
03729 }
03730 }
03731 }
03732
03733 if (dispkind & DISPATCH_PROPERTYPUT) {
03734 dispParams.cNamedArgs = 1;
03735 dispParams.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 );
03736 dispParams.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
03737 }
03738
03739 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, NUM2INT(dispid),
03740 &IID_NULL, cWIN32OLE_lcid,
03741 dispkind,
03742 &dispParams, &result,
03743 &excepinfo, &argErr);
03744
03745 if (FAILED(hr)) {
03746 v = ole_excepinfo2msg(&excepinfo);
03747 ole_raise(hr, eWIN32OLERuntimeError, "(in OLE method `<dispatch id:%d>': )%s",
03748 NUM2INT(dispid),
03749 StringValuePtr(v));
03750 }
03751
03752
03753 if(dispParams.cArgs > 0) {
03754 set_argv(realargs, 0, dispParams.cArgs);
03755 }
03756
03757 obj = ole_variant2val(&result);
03758 VariantClear(&result);
03759 return obj;
03760 }
03761
03762
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774 static VALUE
03775 fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types)
03776 {
03777 return ole_invoke2(self, dispid, args, types, DISPATCH_METHOD);
03778 }
03779
03780
03781
03782
03783
03784
03785
03786
03787
03788
03789
03790
03791
03792 static VALUE
03793 fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
03794 {
03795 return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYGET);
03796 }
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810 static VALUE
03811 fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
03812 {
03813 return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYPUT);
03814 }
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834 static VALUE
03835 fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self)
03836 {
03837 return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, TRUE);
03838 }
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851
03852
03853 static VALUE
03854 fole_setproperty(int argc, VALUE *argv, VALUE self)
03855 {
03856 return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, FALSE);
03857 }
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875 static VALUE
03876 fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self)
03877 {
03878 return ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET, TRUE);
03879 }
03880
03881 static VALUE
03882 ole_propertyput(VALUE self, VALUE property, VALUE value)
03883 {
03884 struct oledata *pole;
03885 unsigned argErr;
03886 unsigned int index;
03887 HRESULT hr;
03888 EXCEPINFO excepinfo;
03889 DISPID dispID = DISPID_VALUE;
03890 DISPID dispIDParam = DISPID_PROPERTYPUT;
03891 USHORT wFlags = DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF;
03892 DISPPARAMS dispParams;
03893 VARIANTARG propertyValue[2];
03894 OLECHAR* pBuf[1];
03895 VALUE v;
03896 LCID lcid = cWIN32OLE_lcid;
03897 dispParams.rgdispidNamedArgs = &dispIDParam;
03898 dispParams.rgvarg = propertyValue;
03899 dispParams.cNamedArgs = 1;
03900 dispParams.cArgs = 1;
03901
03902 VariantInit(&propertyValue[0]);
03903 VariantInit(&propertyValue[1]);
03904 memset(&excepinfo, 0, sizeof(excepinfo));
03905
03906 OLEData_Get_Struct(self, pole);
03907
03908
03909 pBuf[0] = ole_vstr2wc(property);
03910 hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch, &IID_NULL,
03911 pBuf, 1, lcid, &dispID);
03912 SysFreeString(pBuf[0]);
03913 pBuf[0] = NULL;
03914
03915 if(FAILED(hr)) {
03916 ole_raise(hr, eWIN32OLERuntimeError,
03917 "unknown property or method: `%s'",
03918 StringValuePtr(property));
03919 }
03920
03921 ole_val2variant(value, &propertyValue[0]);
03922 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, dispID, &IID_NULL,
03923 lcid, wFlags, &dispParams,
03924 NULL, &excepinfo, &argErr);
03925
03926 for(index = 0; index < dispParams.cArgs; ++index) {
03927 VariantClear(&propertyValue[index]);
03928 }
03929 if (FAILED(hr)) {
03930 v = ole_excepinfo2msg(&excepinfo);
03931 ole_raise(hr, eWIN32OLERuntimeError, "(in setting property `%s': )%s",
03932 StringValuePtr(property),
03933 StringValuePtr(v));
03934 }
03935 return Qnil;
03936 }
03937
03938
03939
03940
03941
03942
03943
03944
03945
03946
03947 static VALUE
03948 fole_free(VALUE self)
03949 {
03950 struct oledata *pole;
03951 rb_secure(4);
03952 OLEData_Get_Struct(self, pole);
03953 OLE_FREE(pole->pDispatch);
03954 pole->pDispatch = NULL;
03955 return Qnil;
03956 }
03957
03958 static VALUE
03959 ole_each_sub(VALUE pEnumV)
03960 {
03961 VARIANT variant;
03962 VALUE obj = Qnil;
03963 IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
03964 VariantInit(&variant);
03965 while(pEnum->lpVtbl->Next(pEnum, 1, &variant, NULL) == S_OK) {
03966 obj = ole_variant2val(&variant);
03967 VariantClear(&variant);
03968 VariantInit(&variant);
03969 rb_yield(obj);
03970 }
03971 return Qnil;
03972 }
03973
03974 static VALUE
03975 ole_ienum_free(VALUE pEnumV)
03976 {
03977 IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
03978 OLE_RELEASE(pEnum);
03979 return Qnil;
03980 }
03981
03982
03983
03984
03985
03986
03987
03988
03989
03990
03991
03992
03993
03994
03995
03996 static VALUE
03997 fole_each(VALUE self)
03998 {
03999 LCID lcid = cWIN32OLE_lcid;
04000
04001 struct oledata *pole;
04002
04003 unsigned int argErr;
04004 EXCEPINFO excepinfo;
04005 DISPPARAMS dispParams;
04006 VARIANT result;
04007 HRESULT hr;
04008 IEnumVARIANT *pEnum = NULL;
04009 void *p;
04010
04011 RETURN_ENUMERATOR(self, 0, 0);
04012
04013 VariantInit(&result);
04014 dispParams.rgvarg = NULL;
04015 dispParams.rgdispidNamedArgs = NULL;
04016 dispParams.cNamedArgs = 0;
04017 dispParams.cArgs = 0;
04018 memset(&excepinfo, 0, sizeof(excepinfo));
04019
04020 OLEData_Get_Struct(self, pole);
04021 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DISPID_NEWENUM,
04022 &IID_NULL, lcid,
04023 DISPATCH_METHOD | DISPATCH_PROPERTYGET,
04024 &dispParams, &result,
04025 &excepinfo, &argErr);
04026
04027 if (FAILED(hr)) {
04028 VariantClear(&result);
04029 ole_raise(hr, eWIN32OLERuntimeError, "failed to get IEnum Interface");
04030 }
04031
04032 if (V_VT(&result) == VT_UNKNOWN) {
04033 hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result),
04034 &IID_IEnumVARIANT,
04035 &p);
04036 pEnum = p;
04037 } else if (V_VT(&result) == VT_DISPATCH) {
04038 hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result),
04039 &IID_IEnumVARIANT,
04040 &p);
04041 pEnum = p;
04042 }
04043 if (FAILED(hr) || !pEnum) {
04044 VariantClear(&result);
04045 ole_raise(hr, rb_eRuntimeError, "failed to get IEnum Interface");
04046 }
04047
04048 VariantClear(&result);
04049 rb_ensure(ole_each_sub, (VALUE)pEnum, ole_ienum_free, (VALUE)pEnum);
04050 return Qnil;
04051 }
04052
04053
04054
04055
04056
04057
04058
04059 static VALUE
04060 fole_missing(int argc, VALUE *argv, VALUE self)
04061 {
04062 ID id;
04063 const char* mname;
04064 int n;
04065 id = rb_to_id(argv[0]);
04066 mname = rb_id2name(id);
04067 if(!mname) {
04068 rb_raise(rb_eRuntimeError, "fail: unknown method or property");
04069 }
04070 n = strlen(mname);
04071 if(mname[n-1] == '=') {
04072 argv[0] = rb_enc_str_new(mname, n-1, cWIN32OLE_enc);
04073
04074 return ole_propertyput(self, argv[0], argv[1]);
04075 }
04076 else {
04077 argv[0] = rb_enc_str_new(mname, n, cWIN32OLE_enc);
04078 return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
04079 }
04080 }
04081
04082 static VALUE
04083 ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name)
04084 {
04085 HRESULT hr;
04086 TYPEATTR *pTypeAttr;
04087 BSTR bstr;
04088 FUNCDESC *pFuncDesc;
04089 WORD i;
04090 VALUE fname;
04091 VALUE method = Qnil;
04092 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
04093 if (FAILED(hr)) {
04094 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
04095 }
04096 for(i = 0; i < pTypeAttr->cFuncs && method == Qnil; i++) {
04097 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
04098 if (FAILED(hr))
04099 continue;
04100
04101 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
04102 &bstr, NULL, NULL, NULL);
04103 if (FAILED(hr)) {
04104 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
04105 continue;
04106 }
04107 fname = WC2VSTR(bstr);
04108 if (strcasecmp(StringValuePtr(name), StringValuePtr(fname)) == 0) {
04109 olemethod_set_member(self, pTypeInfo, pOwnerTypeInfo, i, fname);
04110 method = self;
04111 }
04112 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
04113 pFuncDesc=NULL;
04114 }
04115 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
04116 return method;
04117 }
04118
04119 static VALUE
04120 olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
04121 {
04122 HRESULT hr;
04123 TYPEATTR *pTypeAttr;
04124 WORD i;
04125 HREFTYPE href;
04126 ITypeInfo *pRefTypeInfo;
04127 VALUE method = Qnil;
04128 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
04129 if (FAILED(hr)) {
04130 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
04131 }
04132 method = ole_method_sub(self, 0, pTypeInfo, name);
04133 if (method != Qnil) {
04134 return method;
04135 }
04136 for(i=0; i < pTypeAttr->cImplTypes && method == Qnil; i++){
04137 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
04138 if(FAILED(hr))
04139 continue;
04140 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
04141 if (FAILED(hr))
04142 continue;
04143 method = ole_method_sub(self, pTypeInfo, pRefTypeInfo, name);
04144 OLE_RELEASE(pRefTypeInfo);
04145 }
04146 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
04147 return method;
04148 }
04149
04150 static VALUE
04151 ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask)
04152 {
04153 HRESULT hr;
04154 TYPEATTR *pTypeAttr;
04155 BSTR bstr;
04156 char *pstr;
04157 FUNCDESC *pFuncDesc;
04158 VALUE method;
04159 WORD i;
04160 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
04161 if (FAILED(hr)) {
04162 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
04163 }
04164 for(i = 0; i < pTypeAttr->cFuncs; i++) {
04165 pstr = NULL;
04166 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
04167 if (FAILED(hr))
04168 continue;
04169
04170 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
04171 &bstr, NULL, NULL, NULL);
04172 if (FAILED(hr)) {
04173 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
04174 continue;
04175 }
04176 if(pFuncDesc->invkind & mask) {
04177 method = folemethod_s_allocate(cWIN32OLE_METHOD);
04178 olemethod_set_member(method, pTypeInfo, pOwnerTypeInfo,
04179 i, WC2VSTR(bstr));
04180 rb_ary_push(methods, method);
04181 }
04182 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
04183 pFuncDesc=NULL;
04184 }
04185 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
04186
04187 return methods;
04188 }
04189
04190 static VALUE
04191 ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask)
04192 {
04193 HRESULT hr;
04194 TYPEATTR *pTypeAttr;
04195 WORD i;
04196 HREFTYPE href;
04197 ITypeInfo *pRefTypeInfo;
04198 VALUE methods = rb_ary_new();
04199 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
04200 if (FAILED(hr)) {
04201 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
04202 }
04203
04204 ole_methods_sub(0, pTypeInfo, methods, mask);
04205 for(i=0; i < pTypeAttr->cImplTypes; i++){
04206 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
04207 if(FAILED(hr))
04208 continue;
04209 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
04210 if (FAILED(hr))
04211 continue;
04212 ole_methods_sub(pTypeInfo, pRefTypeInfo, methods, mask);
04213 OLE_RELEASE(pRefTypeInfo);
04214 }
04215 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
04216 return methods;
04217 }
04218
04219 static HRESULT
04220 typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti)
04221 {
04222 ITypeInfo *pTypeInfo;
04223 ITypeLib *pTypeLib;
04224 BSTR bstr;
04225 VALUE type;
04226 UINT i;
04227 UINT count;
04228 LCID lcid = cWIN32OLE_lcid;
04229 HRESULT hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
04230 0, lcid, &pTypeInfo);
04231 if(FAILED(hr)) {
04232 ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
04233 }
04234 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo,
04235 -1,
04236 &bstr,
04237 NULL, NULL, NULL);
04238 type = WC2VSTR(bstr);
04239 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
04240 OLE_RELEASE(pTypeInfo);
04241 if (FAILED(hr)) {
04242 ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib");
04243 }
04244 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
04245 for (i = 0; i < count; i++) {
04246 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
04247 &bstr, NULL, NULL, NULL);
04248 if (SUCCEEDED(hr) && rb_str_cmp(WC2VSTR(bstr), type) == 0) {
04249 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
04250 if (SUCCEEDED(hr)) {
04251 *ppti = pTypeInfo;
04252 break;
04253 }
04254 }
04255 }
04256 OLE_RELEASE(pTypeLib);
04257 return hr;
04258 }
04259
04260 static VALUE
04261 ole_methods(VALUE self, int mask)
04262 {
04263 ITypeInfo *pTypeInfo;
04264 HRESULT hr;
04265 VALUE methods;
04266 struct oledata *pole;
04267
04268 OLEData_Get_Struct(self, pole);
04269 methods = rb_ary_new();
04270
04271 hr = typeinfo_from_ole(pole, &pTypeInfo);
04272 if(FAILED(hr))
04273 return methods;
04274 rb_ary_concat(methods, ole_methods_from_typeinfo(pTypeInfo, mask));
04275 OLE_RELEASE(pTypeInfo);
04276 return methods;
04277 }
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288
04289
04290 static VALUE
04291 fole_methods(VALUE self)
04292 {
04293 return ole_methods( self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
04294 }
04295
04296
04297
04298
04299
04300
04301
04302
04303
04304
04305
04306 static VALUE
04307 fole_get_methods(VALUE self)
04308 {
04309 return ole_methods( self, INVOKE_PROPERTYGET);
04310 }
04311
04312
04313
04314
04315
04316
04317
04318
04319
04320
04321
04322 static VALUE
04323 fole_put_methods(VALUE self)
04324 {
04325 return ole_methods( self, INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF);
04326 }
04327
04328
04329
04330
04331
04332
04333
04334
04335
04336
04337
04338
04339 static VALUE
04340 fole_func_methods(VALUE self)
04341 {
04342 return ole_methods( self, INVOKE_FUNC);
04343 }
04344
04345 static VALUE
04346 ole_type_from_itypeinfo(ITypeInfo *pTypeInfo)
04347 {
04348 ITypeLib *pTypeLib;
04349 VALUE type = Qnil;
04350 HRESULT hr;
04351 unsigned int index;
04352 BSTR bstr;
04353
04354 hr = pTypeInfo->lpVtbl->GetContainingTypeLib( pTypeInfo, &pTypeLib, &index );
04355 if(FAILED(hr)) {
04356 return Qnil;
04357 }
04358 hr = pTypeLib->lpVtbl->GetDocumentation( pTypeLib, index,
04359 &bstr, NULL, NULL, NULL);
04360 OLE_RELEASE(pTypeLib);
04361 if (FAILED(hr)) {
04362 return Qnil;
04363 }
04364 type = foletype_s_allocate(cWIN32OLE_TYPE);
04365 oletype_set_member(type, pTypeInfo, WC2VSTR(bstr));
04366 return type;
04367 }
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378 static VALUE
04379 fole_type(VALUE self)
04380 {
04381 ITypeInfo *pTypeInfo;
04382 HRESULT hr;
04383 struct oledata *pole;
04384 LCID lcid = cWIN32OLE_lcid;
04385 VALUE type = Qnil;
04386
04387 OLEData_Get_Struct(self, pole);
04388
04389 hr = pole->pDispatch->lpVtbl->GetTypeInfo( pole->pDispatch, 0, lcid, &pTypeInfo );
04390 if(FAILED(hr)) {
04391 ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
04392 }
04393 type = ole_type_from_itypeinfo(pTypeInfo);
04394 OLE_RELEASE(pTypeInfo);
04395 if (type == Qnil) {
04396 rb_raise(rb_eRuntimeError, "failed to create WIN32OLE_TYPE obj from ITypeInfo");
04397 }
04398 return type;
04399 }
04400
04401 static VALUE
04402 ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo)
04403 {
04404 HRESULT hr;
04405 ITypeLib *pTypeLib;
04406 unsigned int index;
04407 VALUE retval = Qnil;
04408
04409 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
04410 if(FAILED(hr)) {
04411 return Qnil;
04412 }
04413 retval = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("allocate"), 0);
04414 oletypelib_set_member(retval, pTypeLib);
04415 return retval;
04416 }
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429 static VALUE
04430 fole_typelib(VALUE self)
04431 {
04432 struct oledata *pole;
04433 HRESULT hr;
04434 ITypeInfo *pTypeInfo;
04435 LCID lcid = cWIN32OLE_lcid;
04436 VALUE vtlib = Qnil;
04437
04438 OLEData_Get_Struct(self, pole);
04439 hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
04440 0, lcid, &pTypeInfo);
04441 if(FAILED(hr)) {
04442 ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
04443 }
04444 vtlib = ole_typelib_from_itypeinfo(pTypeInfo);
04445 OLE_RELEASE(pTypeInfo);
04446 if (vtlib == Qnil) {
04447 rb_raise(rb_eRuntimeError, "failed to get type library info.");
04448 }
04449 return vtlib;
04450 }
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462 static VALUE
04463 fole_query_interface(VALUE self, VALUE str_iid)
04464 {
04465 HRESULT hr;
04466 OLECHAR *pBuf;
04467 IID iid;
04468 struct oledata *pole;
04469 IDispatch *pDispatch;
04470 void *p;
04471
04472 pBuf = ole_vstr2wc(str_iid);
04473 hr = CLSIDFromString(pBuf, &iid);
04474 SysFreeString(pBuf);
04475 if(FAILED(hr)) {
04476 ole_raise(hr, eWIN32OLERuntimeError,
04477 "invalid iid: `%s'",
04478 StringValuePtr(str_iid));
04479 }
04480
04481 OLEData_Get_Struct(self, pole);
04482 if(!pole->pDispatch) {
04483 rb_raise(rb_eRuntimeError, "failed to get dispatch interface");
04484 }
04485
04486 hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &iid,
04487 &p);
04488 if(FAILED(hr)) {
04489 ole_raise(hr, eWIN32OLERuntimeError,
04490 "failed to get interface `%s'",
04491 StringValuePtr(str_iid));
04492 }
04493
04494 pDispatch = p;
04495 return create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
04496 }
04497
04498
04499
04500
04501
04502
04503
04504
04505
04506
04507 static VALUE
04508 fole_respond_to(VALUE self, VALUE method)
04509 {
04510 struct oledata *pole;
04511 BSTR wcmdname;
04512 DISPID DispID;
04513 HRESULT hr;
04514 rb_secure(4);
04515 if(TYPE(method) != T_STRING && TYPE(method) != T_SYMBOL) {
04516 rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
04517 }
04518 if (TYPE(method) == T_SYMBOL) {
04519 method = rb_sym_to_s(method);
04520 }
04521 OLEData_Get_Struct(self, pole);
04522 wcmdname = ole_vstr2wc(method);
04523 hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
04524 &wcmdname, 1, cWIN32OLE_lcid, &DispID);
04525 SysFreeString(wcmdname);
04526 return SUCCEEDED(hr) ? Qtrue : Qfalse;
04527 }
04528
04529 static HRESULT
04530 ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile)
04531 {
04532 HRESULT hr;
04533 ITypeLib *pTypeLib;
04534 UINT i;
04535
04536 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
04537 if (FAILED(hr)) {
04538 return hr;
04539 }
04540
04541 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
04542 name, helpstr,
04543 helpcontext, helpfile);
04544 if (FAILED(hr)) {
04545 OLE_RELEASE(pTypeLib);
04546 return hr;
04547 }
04548 OLE_RELEASE(pTypeLib);
04549 return hr;
04550 }
04551
04552 static VALUE
04553 ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
04554 {
04555 HRESULT hr;
04556 BSTR bstr;
04557 ITypeInfo *pRefTypeInfo;
04558 VALUE type = Qnil;
04559
04560 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
04561 V_UNION1(pTypeDesc, hreftype),
04562 &pRefTypeInfo);
04563 if(FAILED(hr))
04564 return Qnil;
04565 hr = ole_docinfo_from_type(pRefTypeInfo, &bstr, NULL, NULL, NULL);
04566 if(FAILED(hr)) {
04567 OLE_RELEASE(pRefTypeInfo);
04568 return Qnil;
04569 }
04570 OLE_RELEASE(pRefTypeInfo);
04571 type = WC2VSTR(bstr);
04572 if(typedetails != Qnil)
04573 rb_ary_push(typedetails, type);
04574 return type;
04575 }
04576
04577 static VALUE
04578 ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
04579 {
04580 TYPEDESC *p = pTypeDesc;
04581 VALUE type = rb_str_new2("");
04582
04583 if (p->vt == VT_PTR || p->vt == VT_SAFEARRAY) {
04584 p = V_UNION1(p, lptdesc);
04585 type = ole_typedesc2val(pTypeInfo, p, typedetails);
04586 }
04587 return type;
04588 }
04589
04590 static VALUE
04591 ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
04592 {
04593 VALUE str;
04594 VALUE typestr = Qnil;
04595 switch(pTypeDesc->vt) {
04596 case VT_I2:
04597 typestr = rb_str_new2("I2");
04598 break;
04599 case VT_I4:
04600 typestr = rb_str_new2("I4");
04601 break;
04602 case VT_R4:
04603 typestr = rb_str_new2("R4");
04604 break;
04605 case VT_R8:
04606 typestr = rb_str_new2("R8");
04607 break;
04608 case VT_CY:
04609 typestr = rb_str_new2("CY");
04610 break;
04611 case VT_DATE:
04612 typestr = rb_str_new2("DATE");
04613 break;
04614 case VT_BSTR:
04615 typestr = rb_str_new2("BSTR");
04616 break;
04617 case VT_BOOL:
04618 typestr = rb_str_new2("BOOL");
04619 break;
04620 case VT_VARIANT:
04621 typestr = rb_str_new2("VARIANT");
04622 break;
04623 case VT_DECIMAL:
04624 typestr = rb_str_new2("DECIMAL");
04625 break;
04626 case VT_I1:
04627 typestr = rb_str_new2("I1");
04628 break;
04629 case VT_UI1:
04630 typestr = rb_str_new2("UI1");
04631 break;
04632 case VT_UI2:
04633 typestr = rb_str_new2("UI2");
04634 break;
04635 case VT_UI4:
04636 typestr = rb_str_new2("UI4");
04637 break;
04638 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
04639 case VT_I8:
04640 typestr = rb_str_new2("I8");
04641 break;
04642 case VT_UI8:
04643 typestr = rb_str_new2("UI8");
04644 break;
04645 #endif
04646 case VT_INT:
04647 typestr = rb_str_new2("INT");
04648 break;
04649 case VT_UINT:
04650 typestr = rb_str_new2("UINT");
04651 break;
04652 case VT_VOID:
04653 typestr = rb_str_new2("VOID");
04654 break;
04655 case VT_HRESULT:
04656 typestr = rb_str_new2("HRESULT");
04657 break;
04658 case VT_PTR:
04659 typestr = rb_str_new2("PTR");
04660 if(typedetails != Qnil)
04661 rb_ary_push(typedetails, typestr);
04662 return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
04663 case VT_SAFEARRAY:
04664 typestr = rb_str_new2("SAFEARRAY");
04665 if(typedetails != Qnil)
04666 rb_ary_push(typedetails, typestr);
04667 return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
04668 case VT_CARRAY:
04669 typestr = rb_str_new2("CARRAY");
04670 break;
04671 case VT_USERDEFINED:
04672 typestr = rb_str_new2("USERDEFINED");
04673 if (typedetails != Qnil)
04674 rb_ary_push(typedetails, typestr);
04675 str = ole_usertype2val(pTypeInfo, pTypeDesc, typedetails);
04676 if (str != Qnil) {
04677 return str;
04678 }
04679 return typestr;
04680 case VT_UNKNOWN:
04681 typestr = rb_str_new2("UNKNOWN");
04682 break;
04683 case VT_DISPATCH:
04684 typestr = rb_str_new2("DISPATCH");
04685 break;
04686 case VT_ERROR:
04687 typestr = rb_str_new2("ERROR");
04688 break;
04689 case VT_LPWSTR:
04690 typestr = rb_str_new2("LPWSTR");
04691 break;
04692 case VT_LPSTR:
04693 typestr = rb_str_new2("LPSTR");
04694 break;
04695 default:
04696 typestr = rb_str_new2("Unknown Type ");
04697 rb_str_concat(typestr, rb_fix2str(INT2FIX(pTypeDesc->vt), 10));
04698 break;
04699 }
04700 if (typedetails != Qnil)
04701 rb_ary_push(typedetails, typestr);
04702 return typestr;
04703 }
04704
04705
04706
04707
04708
04709
04710
04711
04712
04713
04714
04715
04716 static VALUE
04717 fole_method_help(VALUE self, VALUE cmdname)
04718 {
04719 ITypeInfo *pTypeInfo;
04720 HRESULT hr;
04721 struct oledata *pole;
04722 VALUE method, obj;
04723
04724 SafeStringValue(cmdname);
04725 OLEData_Get_Struct(self, pole);
04726 hr = typeinfo_from_ole(pole, &pTypeInfo);
04727 if(FAILED(hr))
04728 ole_raise(hr, rb_eRuntimeError, "failed to get ITypeInfo");
04729 method = folemethod_s_allocate(cWIN32OLE_METHOD);
04730 obj = olemethod_from_typeinfo(method, pTypeInfo, cmdname);
04731 OLE_RELEASE(pTypeInfo);
04732 if (obj == Qnil)
04733 rb_raise(eWIN32OLERuntimeError, "not found %s",
04734 StringValuePtr(cmdname));
04735 return obj;
04736 }
04737
04738
04739
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751
04752
04753
04754
04755
04756
04757
04758 static VALUE
04759 fole_activex_initialize(VALUE self)
04760 {
04761 struct oledata *pole;
04762 IPersistMemory *pPersistMemory;
04763 void *p;
04764
04765 HRESULT hr = S_OK;
04766
04767 OLEData_Get_Struct(self, pole);
04768
04769 hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &IID_IPersistMemory, &p);
04770 pPersistMemory = p;
04771 if (SUCCEEDED(hr)) {
04772 hr = pPersistMemory->lpVtbl->InitNew(pPersistMemory);
04773 OLE_RELEASE(pPersistMemory);
04774 if (SUCCEEDED(hr)) {
04775 return Qnil;
04776 }
04777 }
04778
04779 if (FAILED(hr)) {
04780 ole_raise(hr, eWIN32OLERuntimeError, "fail to initialize ActiveX control");
04781 }
04782
04783 return Qnil;
04784 }
04785
04786
04787
04788
04789
04790
04791
04792
04793 static VALUE
04794 foletype_s_ole_classes(VALUE self, VALUE typelib)
04795 {
04796 VALUE obj;
04797
04798
04799
04800
04801
04802
04803 obj = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("new"), 1, typelib);
04804 return rb_funcall(obj, rb_intern("ole_types"), 0);
04805 }
04806
04807
04808
04809
04810
04811
04812
04813
04814
04815 static VALUE
04816 foletype_s_typelibs(VALUE self)
04817 {
04818
04819
04820
04821
04822
04823 return rb_eval_string("WIN32OLE_TYPELIB.typelibs.collect{|t|t.name}");
04824 }
04825
04826
04827
04828
04829
04830
04831
04832 static VALUE
04833 foletype_s_progids(VALUE self)
04834 {
04835 HKEY hclsids, hclsid;
04836 DWORD i;
04837 LONG err;
04838 VALUE clsid;
04839 VALUE v = rb_str_new2("");
04840 VALUE progids = rb_ary_new();
04841
04842 err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hclsids);
04843 if(err != ERROR_SUCCESS) {
04844 return progids;
04845 }
04846 for(i = 0; ; i++) {
04847 clsid = reg_enum_key(hclsids, i);
04848 if (clsid == Qnil)
04849 break;
04850 err = reg_open_vkey(hclsids, clsid, &hclsid);
04851 if (err != ERROR_SUCCESS)
04852 continue;
04853 if ((v = reg_get_val2(hclsid, "ProgID")) != Qnil)
04854 rb_ary_push(progids, v);
04855 if ((v = reg_get_val2(hclsid, "VersionIndependentProgID")) != Qnil)
04856 rb_ary_push(progids, v);
04857 RegCloseKey(hclsid);
04858 }
04859 RegCloseKey(hclsids);
04860 return progids;
04861 }
04862
04863 static VALUE
04864 foletype_s_allocate(VALUE klass)
04865 {
04866 struct oletypedata *poletype;
04867 VALUE obj;
04868 ole_initialize();
04869 obj = Data_Make_Struct(klass,struct oletypedata,0,oletype_free,poletype);
04870 poletype->pTypeInfo = NULL;
04871 return obj;
04872 }
04873
04874 static VALUE
04875 oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
04876 {
04877 struct oletypedata *ptype;
04878 Data_Get_Struct(self, struct oletypedata, ptype);
04879 rb_ivar_set(self, rb_intern("name"), name);
04880 ptype->pTypeInfo = pTypeInfo;
04881 if(pTypeInfo) OLE_ADDREF(pTypeInfo);
04882 return self;
04883 }
04884
04885 static VALUE
04886 oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass)
04887 {
04888
04889 long count;
04890 int i;
04891 HRESULT hr;
04892 BSTR bstr;
04893 VALUE typelib;
04894 ITypeInfo *pTypeInfo;
04895
04896 VALUE found = Qfalse;
04897
04898 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
04899 for (i = 0; i < count && found == Qfalse; i++) {
04900 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
04901 if (FAILED(hr))
04902 continue;
04903 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
04904 &bstr, NULL, NULL, NULL);
04905 if (FAILED(hr))
04906 continue;
04907 typelib = WC2VSTR(bstr);
04908 if (rb_str_cmp(oleclass, typelib) == 0) {
04909 oletype_set_member(self, pTypeInfo, typelib);
04910 found = Qtrue;
04911 }
04912 OLE_RELEASE(pTypeInfo);
04913 }
04914 return found;
04915 }
04916
04917
04918
04919
04920
04921
04922
04923 static VALUE
04924 oletypelib_set_member(VALUE self, ITypeLib *pTypeLib)
04925 {
04926 struct oletypelibdata *ptlib;
04927 Data_Get_Struct(self, struct oletypelibdata, ptlib);
04928 ptlib->pTypeLib = pTypeLib;
04929 return self;
04930 }
04931
04932 static ITypeLib *
04933 oletypelib_get_typelib(VALUE self)
04934 {
04935 struct oletypelibdata *ptlib;
04936 Data_Get_Struct(self, struct oletypelibdata, ptlib);
04937 return ptlib->pTypeLib;
04938 }
04939
04940 static void
04941 oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr)
04942 {
04943 HRESULT hr;
04944 hr = pTypeLib->lpVtbl->GetLibAttr(pTypeLib, ppTLibAttr);
04945 if (FAILED(hr)) {
04946 ole_raise(hr, eWIN32OLERuntimeError,
04947 "failed to get library attribute(TLIBATTR) from ITypeLib");
04948 }
04949 }
04950
04951
04952
04953
04954
04955
04956
04957
04958
04959
04960
04961 static VALUE
04962 foletypelib_s_typelibs(VALUE self)
04963 {
04964 HKEY htypelib, hguid;
04965 DWORD i, j;
04966 LONG err;
04967 VALUE guid;
04968 VALUE version;
04969 VALUE name = Qnil;
04970 VALUE typelibs = rb_ary_new();
04971 VALUE typelib = Qnil;
04972 HRESULT hr;
04973 ITypeLib *pTypeLib;
04974
04975 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
04976 if(err != ERROR_SUCCESS) {
04977 return typelibs;
04978 }
04979 for(i = 0; ; i++) {
04980 guid = reg_enum_key(htypelib, i);
04981 if (guid == Qnil)
04982 break;
04983 err = reg_open_vkey(htypelib, guid, &hguid);
04984 if (err != ERROR_SUCCESS)
04985 continue;
04986 for(j = 0; ; j++) {
04987 version = reg_enum_key(hguid, j);
04988 if (version == Qnil)
04989 break;
04990 if ( (name = reg_get_val2(hguid, StringValuePtr(version))) != Qnil ) {
04991 hr = oletypelib_from_guid(guid, version, &pTypeLib);
04992 if (SUCCEEDED(hr)) {
04993 typelib = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("allocate"), 0);
04994 oletypelib_set_member(typelib, pTypeLib);
04995 rb_ary_push(typelibs, typelib);
04996 }
04997 }
04998 }
04999 RegCloseKey(hguid);
05000 }
05001 RegCloseKey(htypelib);
05002 return typelibs;
05003 }
05004
05005 static VALUE
05006 make_version_str(VALUE major, VALUE minor)
05007 {
05008 VALUE version_str = Qnil;
05009 VALUE minor_str = Qnil;
05010 if (major == Qnil) {
05011 return Qnil;
05012 }
05013 version_str = rb_String(major);
05014 if (minor != Qnil) {
05015 minor_str = rb_String(minor);
05016 rb_str_cat2(version_str, ".");
05017 rb_str_append(version_str, minor_str);
05018 }
05019 return version_str;
05020 }
05021
05022 static VALUE
05023 oletypelib_search_registry2(VALUE self, VALUE args)
05024 {
05025 HKEY htypelib, hguid, hversion;
05026 double fver;
05027 DWORD j;
05028 LONG err;
05029 VALUE found = Qfalse;
05030 VALUE tlib;
05031 VALUE ver;
05032 VALUE version_str;
05033 VALUE version = Qnil;
05034 VALUE typelib = Qnil;
05035 HRESULT hr;
05036 ITypeLib *pTypeLib;
05037
05038 VALUE guid = rb_ary_entry(args, 0);
05039 version_str = make_version_str(rb_ary_entry(args, 1), rb_ary_entry(args, 2));
05040
05041 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
05042 if(err != ERROR_SUCCESS) {
05043 return Qfalse;
05044 }
05045 err = reg_open_vkey(htypelib, guid, &hguid);
05046 if (err != ERROR_SUCCESS) {
05047 RegCloseKey(htypelib);
05048 return Qfalse;
05049 }
05050 if (version_str != Qnil) {
05051 err = reg_open_vkey(hguid, version_str, &hversion);
05052 if (err == ERROR_SUCCESS) {
05053 tlib = reg_get_val(hversion, NULL);
05054 if (tlib != Qnil) {
05055 typelib = tlib;
05056 version = version_str;
05057 }
05058 }
05059 RegCloseKey(hversion);
05060 } else {
05061 fver = 0.0;
05062 for(j = 0; ;j++) {
05063 ver = reg_enum_key(hguid, j);
05064 if (ver == Qnil)
05065 break;
05066 err = reg_open_vkey(hguid, ver, &hversion);
05067 if (err != ERROR_SUCCESS)
05068 continue;
05069 tlib = reg_get_val(hversion, NULL);
05070 if (tlib == Qnil) {
05071 RegCloseKey(hversion);
05072 continue;
05073 }
05074 if (fver < atof(StringValuePtr(ver))) {
05075 fver = atof(StringValuePtr(ver));
05076 version = ver;
05077 typelib = tlib;
05078 }
05079 RegCloseKey(hversion);
05080 }
05081 }
05082 RegCloseKey(hguid);
05083 RegCloseKey(htypelib);
05084 if (typelib != Qnil) {
05085 hr = oletypelib_from_guid(guid, version, &pTypeLib);
05086 if (SUCCEEDED(hr)) {
05087 found = Qtrue;
05088 oletypelib_set_member(self, pTypeLib);
05089 }
05090 }
05091 return found;
05092 }
05093
05094 static VALUE
05095 oletypelib_search_registry(VALUE self, VALUE typelib)
05096 {
05097 HKEY htypelib, hguid, hversion;
05098 DWORD i, j;
05099 LONG err;
05100 VALUE found = Qfalse;
05101 VALUE tlib;
05102 VALUE guid;
05103 VALUE ver;
05104 HRESULT hr;
05105 ITypeLib *pTypeLib;
05106
05107 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
05108 if(err != ERROR_SUCCESS) {
05109 return Qfalse;
05110 }
05111 for(i = 0; !found; i++) {
05112 guid = reg_enum_key(htypelib, i);
05113 if (guid == Qnil)
05114 break;
05115 err = reg_open_vkey(htypelib, guid, &hguid);
05116 if (err != ERROR_SUCCESS)
05117 continue;
05118 for(j = 0; found == Qfalse; j++) {
05119 ver = reg_enum_key(hguid, j);
05120 if (ver == Qnil)
05121 break;
05122 err = reg_open_vkey(hguid, ver, &hversion);
05123 if (err != ERROR_SUCCESS)
05124 continue;
05125 tlib = reg_get_val(hversion, NULL);
05126 if (tlib == Qnil) {
05127 RegCloseKey(hversion);
05128 continue;
05129 }
05130 if (rb_str_cmp(typelib, tlib) == 0) {
05131 hr = oletypelib_from_guid(guid, ver, &pTypeLib);
05132 if (SUCCEEDED(hr)) {
05133 oletypelib_set_member(self, pTypeLib);
05134 found = Qtrue;
05135 }
05136 }
05137 RegCloseKey(hversion);
05138 }
05139 RegCloseKey(hguid);
05140 }
05141 RegCloseKey(htypelib);
05142 return found;
05143 }
05144
05145 static VALUE
05146 foletypelib_s_allocate(VALUE klass)
05147 {
05148 struct oletypelibdata *poletypelib;
05149 VALUE obj;
05150 ole_initialize();
05151 obj = Data_Make_Struct(klass, struct oletypelibdata, 0, oletypelib_free, poletypelib);
05152 poletypelib->pTypeLib = NULL;
05153 return obj;
05154 }
05155
05156
05157
05158
05159
05160
05161
05162
05163
05164
05165
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180
05181
05182 static VALUE
05183 foletypelib_initialize(VALUE self, VALUE args)
05184 {
05185 VALUE found = Qfalse;
05186 VALUE typelib = Qnil;
05187 int len = 0;
05188 OLECHAR * pbuf;
05189 ITypeLib *pTypeLib;
05190 HRESULT hr = S_OK;
05191
05192 len = RARRAY_LEN(args);
05193 if (len < 1 || len > 3) {
05194 rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", len);
05195 }
05196
05197 typelib = rb_ary_entry(args, 0);
05198
05199 SafeStringValue(typelib);
05200
05201 found = oletypelib_search_registry(self, typelib);
05202 if (found == Qfalse) {
05203 found = oletypelib_search_registry2(self, args);
05204 }
05205 if (found == Qfalse) {
05206 pbuf = ole_vstr2wc(typelib);
05207 hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
05208 SysFreeString(pbuf);
05209 if (SUCCEEDED(hr)) {
05210 found = Qtrue;
05211 oletypelib_set_member(self, pTypeLib);
05212 }
05213 }
05214
05215 if (found == Qfalse) {
05216 rb_raise(eWIN32OLERuntimeError, "not found type library `%s`",
05217 StringValuePtr(typelib));
05218 }
05219 return self;
05220 }
05221
05222
05223
05224
05225
05226
05227
05228
05229
05230
05231 static VALUE
05232 foletypelib_guid(VALUE self)
05233 {
05234 ITypeLib *pTypeLib;
05235 OLECHAR bstr[80];
05236 VALUE guid = Qnil;
05237 int len;
05238 TLIBATTR *pTLibAttr;
05239
05240 pTypeLib = oletypelib_get_typelib(self);
05241 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
05242 len = StringFromGUID2(&pTLibAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
05243 if (len > 3) {
05244 guid = ole_wc2vstr(bstr, FALSE);
05245 }
05246 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05247 return guid;
05248 }
05249
05250
05251
05252
05253
05254
05255
05256
05257
05258
05259 static VALUE
05260 foletypelib_name(VALUE self)
05261 {
05262 ITypeLib *pTypeLib;
05263 HRESULT hr;
05264 BSTR bstr;
05265 VALUE name;
05266 pTypeLib = oletypelib_get_typelib(self);
05267 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
05268 NULL, &bstr, NULL, NULL);
05269
05270 if (FAILED(hr)) {
05271 ole_raise(hr, eWIN32OLERuntimeError, "failed to get name from ITypeLib");
05272 }
05273 name = WC2VSTR(bstr);
05274 return rb_enc_str_new(StringValuePtr(name), strlen(StringValuePtr(name)), cWIN32OLE_enc);
05275 }
05276
05277
05278
05279
05280
05281
05282
05283
05284
05285
05286 static VALUE
05287 foletypelib_version(VALUE self)
05288 {
05289 TLIBATTR *pTLibAttr;
05290 VALUE major;
05291 VALUE minor;
05292 ITypeLib *pTypeLib;
05293
05294 pTypeLib = oletypelib_get_typelib(self);
05295 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
05296 major = INT2NUM(pTLibAttr->wMajorVerNum);
05297 minor = INT2NUM(pTLibAttr->wMinorVerNum);
05298 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05299 return rb_Float(make_version_str(major, minor));
05300 }
05301
05302
05303
05304
05305
05306
05307
05308
05309
05310
05311 static VALUE
05312 foletypelib_major_version(VALUE self)
05313 {
05314 TLIBATTR *pTLibAttr;
05315 VALUE major;
05316 ITypeLib *pTypeLib;
05317 pTypeLib = oletypelib_get_typelib(self);
05318 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
05319
05320 major = INT2NUM(pTLibAttr->wMajorVerNum);
05321 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05322 return major;
05323 }
05324
05325
05326
05327
05328
05329
05330
05331
05332
05333
05334 static VALUE
05335 foletypelib_minor_version(VALUE self)
05336 {
05337 TLIBATTR *pTLibAttr;
05338 VALUE minor;
05339 ITypeLib *pTypeLib;
05340 pTypeLib = oletypelib_get_typelib(self);
05341 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
05342 minor = INT2NUM(pTLibAttr->wMinorVerNum);
05343 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05344 return minor;
05345 }
05346
05347 static VALUE
05348 oletypelib_path(VALUE guid, VALUE version)
05349 {
05350 int k;
05351 LONG err;
05352 HKEY hkey;
05353 HKEY hlang;
05354 VALUE lang;
05355 VALUE path = Qnil;
05356
05357 VALUE key = rb_str_new2("TypeLib\\");
05358 rb_str_concat(key, guid);
05359 rb_str_cat2(key, "\\");
05360 rb_str_concat(key, version);
05361
05362 err = reg_open_vkey(HKEY_CLASSES_ROOT, key, &hkey);
05363 if (err != ERROR_SUCCESS) {
05364 return Qnil;
05365 }
05366 for(k = 0; path == Qnil; k++) {
05367 lang = reg_enum_key(hkey, k);
05368 if (lang == Qnil)
05369 break;
05370 err = reg_open_vkey(hkey, lang, &hlang);
05371 if (err == ERROR_SUCCESS) {
05372 path = reg_get_typelib_file_path(hlang);
05373 RegCloseKey(hlang);
05374 }
05375 }
05376 RegCloseKey(hkey);
05377 return path;
05378 }
05379
05380 static HRESULT
05381 oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib)
05382 {
05383 VALUE path;
05384 OLECHAR *pBuf;
05385 HRESULT hr;
05386 path = oletypelib_path(guid, version);
05387 if (path == Qnil) {
05388 return E_UNEXPECTED;
05389 }
05390 pBuf = ole_vstr2wc(path);
05391 hr = LoadTypeLibEx(pBuf, REGKIND_NONE, ppTypeLib);
05392 SysFreeString(pBuf);
05393 return hr;
05394 }
05395
05396
05397
05398
05399
05400
05401
05402
05403
05404
05405 static VALUE
05406 foletypelib_path(VALUE self)
05407 {
05408 TLIBATTR *pTLibAttr;
05409 HRESULT hr = S_OK;
05410 BSTR bstr;
05411 LCID lcid = cWIN32OLE_lcid;
05412 VALUE path;
05413 ITypeLib *pTypeLib;
05414
05415 pTypeLib = oletypelib_get_typelib(self);
05416 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
05417 hr = QueryPathOfRegTypeLib(&pTLibAttr->guid,
05418 pTLibAttr->wMajorVerNum,
05419 pTLibAttr->wMinorVerNum,
05420 lcid,
05421 &bstr);
05422 if (FAILED(hr)) {
05423 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05424 ole_raise(hr, eWIN32OLERuntimeError, "failed to QueryPathOfRegTypeTypeLib");
05425 }
05426
05427 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05428 path = WC2VSTR(bstr);
05429 return rb_enc_str_new(StringValuePtr(path), strlen(StringValuePtr(path)), cWIN32OLE_enc);
05430 }
05431
05432
05433
05434
05435
05436
05437
05438
05439
05440
05441
05442
05443
05444
05445 static VALUE
05446 foletypelib_visible(VALUE self)
05447 {
05448 ITypeLib *pTypeLib = NULL;
05449 VALUE visible = Qtrue;
05450 TLIBATTR *pTLibAttr;
05451
05452 pTypeLib = oletypelib_get_typelib(self);
05453 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
05454
05455 if ((pTLibAttr->wLibFlags == 0) ||
05456 (pTLibAttr->wLibFlags & LIBFLAG_FRESTRICTED) ||
05457 (pTLibAttr->wLibFlags & LIBFLAG_FHIDDEN)) {
05458 visible = Qfalse;
05459 }
05460 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05461 return visible;
05462 }
05463
05464
05465
05466
05467
05468
05469
05470
05471
05472
05473
05474 static VALUE
05475 foletypelib_library_name(VALUE self)
05476 {
05477 HRESULT hr;
05478 ITypeLib *pTypeLib = NULL;
05479 VALUE libname = Qnil;
05480 BSTR bstr;
05481
05482 pTypeLib = oletypelib_get_typelib(self);
05483 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
05484 &bstr, NULL, NULL, NULL);
05485 if (FAILED(hr)) {
05486 ole_raise(hr, eWIN32OLERuntimeError, "failed to get library name");
05487 }
05488 libname = WC2VSTR(bstr);
05489 return libname;
05490 }
05491
05492
05493
05494
05495
05496
05497
05498
05499
05500
05501
05502 static VALUE
05503 foletypelib_ole_types(VALUE self)
05504 {
05505 ITypeLib *pTypeLib = NULL;
05506 VALUE classes = rb_ary_new();
05507 pTypeLib = oletypelib_get_typelib(self);
05508 ole_types_from_typelib(pTypeLib, classes);
05509 return classes;
05510 }
05511
05512
05513
05514
05515
05516
05517
05518
05519
05520
05521 static VALUE
05522 foletypelib_inspect(VALUE self)
05523 {
05524 return default_inspect(self, "WIN32OLE_TYPELIB");
05525 }
05526
05527
05528
05529
05530
05531
05532
05533
05534
05535
05536
05537
05538
05539
05540
05541
05542
05543
05544 static VALUE
05545 foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass)
05546 {
05547 VALUE file;
05548 OLECHAR * pbuf;
05549 ITypeLib *pTypeLib;
05550 HRESULT hr;
05551
05552 SafeStringValue(oleclass);
05553 SafeStringValue(typelib);
05554 file = typelib_file(typelib);
05555 if (file == Qnil) {
05556 file = typelib;
05557 }
05558 pbuf = ole_vstr2wc(file);
05559 hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
05560 if (FAILED(hr))
05561 ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
05562 SysFreeString(pbuf);
05563 if (oleclass_from_typelib(self, pTypeLib, oleclass) == Qfalse) {
05564 OLE_RELEASE(pTypeLib);
05565 rb_raise(eWIN32OLERuntimeError, "not found `%s` in `%s`",
05566 StringValuePtr(oleclass), StringValuePtr(typelib));
05567 }
05568 OLE_RELEASE(pTypeLib);
05569 return self;
05570 }
05571
05572
05573
05574
05575
05576
05577
05578
05579
05580 static VALUE
05581 foletype_name(VALUE self)
05582 {
05583 return rb_ivar_get(self, rb_intern("name"));
05584 }
05585
05586 static VALUE
05587 ole_ole_type(ITypeInfo *pTypeInfo)
05588 {
05589 HRESULT hr;
05590 TYPEATTR *pTypeAttr;
05591 VALUE type = Qnil;
05592 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05593 if(FAILED(hr)){
05594 return type;
05595 }
05596 switch(pTypeAttr->typekind) {
05597 case TKIND_ENUM:
05598 type = rb_str_new2("Enum");
05599 break;
05600 case TKIND_RECORD:
05601 type = rb_str_new2("Record");
05602 break;
05603 case TKIND_MODULE:
05604 type = rb_str_new2("Module");
05605 break;
05606 case TKIND_INTERFACE:
05607 type = rb_str_new2("Interface");
05608 break;
05609 case TKIND_DISPATCH:
05610 type = rb_str_new2("Dispatch");
05611 break;
05612 case TKIND_COCLASS:
05613 type = rb_str_new2("Class");
05614 break;
05615 case TKIND_ALIAS:
05616 type = rb_str_new2("Alias");
05617 break;
05618 case TKIND_UNION:
05619 type = rb_str_new2("Union");
05620 break;
05621 case TKIND_MAX:
05622 type = rb_str_new2("Max");
05623 break;
05624 default:
05625 type = Qnil;
05626 break;
05627 }
05628 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05629 return type;
05630 }
05631
05632
05633
05634
05635
05636
05637
05638
05639
05640 static VALUE
05641 foletype_ole_type(VALUE self)
05642 {
05643 struct oletypedata *ptype;
05644 Data_Get_Struct(self, struct oletypedata, ptype);
05645 return ole_ole_type(ptype->pTypeInfo);
05646 }
05647
05648 static VALUE
05649 ole_type_guid(ITypeInfo *pTypeInfo)
05650 {
05651 HRESULT hr;
05652 TYPEATTR *pTypeAttr;
05653 int len;
05654 OLECHAR bstr[80];
05655 VALUE guid = Qnil;
05656 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05657 if (FAILED(hr))
05658 return guid;
05659 len = StringFromGUID2(&pTypeAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
05660 if (len > 3) {
05661 guid = ole_wc2vstr(bstr, FALSE);
05662 }
05663 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05664 return guid;
05665 }
05666
05667
05668
05669
05670
05671
05672
05673
05674
05675 static VALUE
05676 foletype_guid(VALUE self)
05677 {
05678 struct oletypedata *ptype;
05679 Data_Get_Struct(self, struct oletypedata, ptype);
05680 return ole_type_guid(ptype->pTypeInfo);
05681 }
05682
05683 static VALUE
05684 ole_type_progid(ITypeInfo *pTypeInfo)
05685 {
05686 HRESULT hr;
05687 TYPEATTR *pTypeAttr;
05688 OLECHAR *pbuf;
05689 VALUE progid = Qnil;
05690 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05691 if (FAILED(hr))
05692 return progid;
05693 hr = ProgIDFromCLSID(&pTypeAttr->guid, &pbuf);
05694 if (SUCCEEDED(hr)) {
05695 progid = ole_wc2vstr(pbuf, FALSE);
05696 CoTaskMemFree(pbuf);
05697 }
05698 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05699 return progid;
05700 }
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710 static VALUE
05711 foletype_progid(VALUE self)
05712 {
05713 struct oletypedata *ptype;
05714 Data_Get_Struct(self, struct oletypedata, ptype);
05715 return ole_type_progid(ptype->pTypeInfo);
05716 }
05717
05718
05719 static VALUE
05720 ole_type_visible(ITypeInfo *pTypeInfo)
05721 {
05722 HRESULT hr;
05723 TYPEATTR *pTypeAttr;
05724 VALUE visible;
05725 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05726 if (FAILED(hr))
05727 return Qtrue;
05728 if (pTypeAttr->wTypeFlags & (TYPEFLAG_FHIDDEN | TYPEFLAG_FRESTRICTED)) {
05729 visible = Qfalse;
05730 } else {
05731 visible = Qtrue;
05732 }
05733 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05734 return visible;
05735 }
05736
05737
05738
05739
05740
05741
05742
05743
05744
05745 static VALUE
05746 foletype_visible(VALUE self)
05747 {
05748 struct oletypedata *ptype;
05749 Data_Get_Struct(self, struct oletypedata, ptype);
05750 return ole_type_visible(ptype->pTypeInfo);
05751 }
05752
05753 static VALUE
05754 ole_type_major_version(ITypeInfo *pTypeInfo)
05755 {
05756 VALUE ver;
05757 TYPEATTR *pTypeAttr;
05758 HRESULT hr;
05759 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05760 if (FAILED(hr))
05761 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
05762 ver = INT2FIX(pTypeAttr->wMajorVerNum);
05763 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05764 return ver;
05765 }
05766
05767
05768
05769
05770
05771
05772
05773
05774
05775 static VALUE
05776 foletype_major_version(VALUE self)
05777 {
05778 struct oletypedata *ptype;
05779 Data_Get_Struct(self, struct oletypedata, ptype);
05780 return ole_type_major_version(ptype->pTypeInfo);
05781 }
05782
05783 static VALUE
05784 ole_type_minor_version(ITypeInfo *pTypeInfo)
05785 {
05786 VALUE ver;
05787 TYPEATTR *pTypeAttr;
05788 HRESULT hr;
05789 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05790 if (FAILED(hr))
05791 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
05792 ver = INT2FIX(pTypeAttr->wMinorVerNum);
05793 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05794 return ver;
05795 }
05796
05797
05798
05799
05800
05801
05802
05803
05804
05805 static VALUE
05806 foletype_minor_version(VALUE self)
05807 {
05808 struct oletypedata *ptype;
05809 Data_Get_Struct(self, struct oletypedata, ptype);
05810 return ole_type_minor_version(ptype->pTypeInfo);
05811 }
05812
05813 static VALUE
05814 ole_type_typekind(ITypeInfo *pTypeInfo)
05815 {
05816 VALUE typekind;
05817 TYPEATTR *pTypeAttr;
05818 HRESULT hr;
05819 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05820 if (FAILED(hr))
05821 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
05822 typekind = INT2FIX(pTypeAttr->typekind);
05823 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05824 return typekind;
05825 }
05826
05827
05828
05829
05830
05831
05832
05833
05834
05835
05836 static VALUE
05837 foletype_typekind(VALUE self)
05838 {
05839 struct oletypedata *ptype;
05840 Data_Get_Struct(self, struct oletypedata, ptype);
05841 return ole_type_typekind(ptype->pTypeInfo);
05842 }
05843
05844 static VALUE
05845 ole_type_helpstring(ITypeInfo *pTypeInfo)
05846 {
05847 HRESULT hr;
05848 BSTR bhelpstr;
05849 hr = ole_docinfo_from_type(pTypeInfo, NULL, &bhelpstr, NULL, NULL);
05850 if(FAILED(hr)) {
05851 return Qnil;
05852 }
05853 return WC2VSTR(bhelpstr);
05854 }
05855
05856
05857
05858
05859
05860
05861
05862
05863
05864 static VALUE
05865 foletype_helpstring(VALUE self)
05866 {
05867 struct oletypedata *ptype;
05868 Data_Get_Struct(self, struct oletypedata, ptype);
05869 return ole_type_helpstring(ptype->pTypeInfo);
05870 }
05871
05872 static VALUE
05873 ole_type_src_type(ITypeInfo *pTypeInfo)
05874 {
05875 HRESULT hr;
05876 TYPEATTR *pTypeAttr;
05877 VALUE alias = Qnil;
05878 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05879 if (FAILED(hr))
05880 return alias;
05881 if(pTypeAttr->typekind != TKIND_ALIAS) {
05882 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05883 return alias;
05884 }
05885 alias = ole_typedesc2val(pTypeInfo, &(pTypeAttr->tdescAlias), Qnil);
05886 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05887 return alias;
05888 }
05889
05890
05891
05892
05893
05894
05895
05896
05897
05898
05899 static VALUE
05900 foletype_src_type(VALUE self)
05901 {
05902 struct oletypedata *ptype;
05903 Data_Get_Struct(self, struct oletypedata, ptype);
05904 return ole_type_src_type(ptype->pTypeInfo);
05905 }
05906
05907 static VALUE
05908 ole_type_helpfile(ITypeInfo *pTypeInfo)
05909 {
05910 HRESULT hr;
05911 BSTR bhelpfile;
05912 hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL, NULL, &bhelpfile);
05913 if(FAILED(hr)) {
05914 return Qnil;
05915 }
05916 return WC2VSTR(bhelpfile);
05917 }
05918
05919
05920
05921
05922
05923
05924
05925
05926
05927
05928 static VALUE
05929 foletype_helpfile(VALUE self)
05930 {
05931 struct oletypedata *ptype;
05932 Data_Get_Struct(self, struct oletypedata, ptype);
05933 return ole_type_helpfile(ptype->pTypeInfo);
05934 }
05935
05936 static VALUE
05937 ole_type_helpcontext(ITypeInfo *pTypeInfo)
05938 {
05939 HRESULT hr;
05940 DWORD helpcontext;
05941 hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL,
05942 &helpcontext, NULL);
05943 if(FAILED(hr))
05944 return Qnil;
05945 return INT2FIX(helpcontext);
05946 }
05947
05948
05949
05950
05951
05952
05953
05954
05955
05956 static VALUE
05957 foletype_helpcontext(VALUE self)
05958 {
05959 struct oletypedata *ptype;
05960 Data_Get_Struct(self, struct oletypedata, ptype);
05961 return ole_type_helpcontext(ptype->pTypeInfo);
05962 }
05963
05964
05965
05966
05967
05968
05969
05970
05971
05972
05973 static VALUE
05974 foletype_ole_typelib(VALUE self)
05975 {
05976 struct oletypedata *ptype;
05977 Data_Get_Struct(self, struct oletypedata, ptype);
05978 return ole_typelib_from_itypeinfo(ptype->pTypeInfo);
05979 }
05980
05981 static VALUE
05982 ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags)
05983 {
05984 HRESULT hr;
05985 ITypeInfo *pRefTypeInfo;
05986 HREFTYPE href;
05987 WORD i;
05988 VALUE type;
05989 TYPEATTR *pTypeAttr;
05990 int flags;
05991
05992 VALUE types = rb_ary_new();
05993 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05994 if (FAILED(hr)) {
05995 return types;
05996 }
05997 for (i = 0; i < pTypeAttr->cImplTypes; i++) {
05998 hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
05999 if (FAILED(hr))
06000 continue;
06001
06002 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
06003 if (FAILED(hr))
06004 continue;
06005 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
06006 if (FAILED(hr))
06007 continue;
06008
06009 if ((flags & implflags) == implflags) {
06010 type = ole_type_from_itypeinfo(pRefTypeInfo);
06011 if (type != Qnil) {
06012 rb_ary_push(types, type);
06013 }
06014 }
06015
06016 OLE_RELEASE(pRefTypeInfo);
06017 }
06018 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
06019 return types;
06020 }
06021
06022
06023
06024
06025
06026
06027
06028
06029
06030
06031 static VALUE
06032 foletype_impl_ole_types(VALUE self)
06033 {
06034 struct oletypedata *ptype;
06035 Data_Get_Struct(self, struct oletypedata, ptype);
06036 return ole_type_impl_ole_types(ptype->pTypeInfo, 0);
06037 }
06038
06039
06040
06041
06042
06043
06044
06045
06046
06047
06048
06049 static VALUE
06050 foletype_source_ole_types(VALUE self)
06051 {
06052 struct oletypedata *ptype;
06053 Data_Get_Struct(self, struct oletypedata, ptype);
06054 return ole_type_impl_ole_types(ptype->pTypeInfo, IMPLTYPEFLAG_FSOURCE);
06055 }
06056
06057
06058
06059
06060
06061
06062
06063
06064
06065
06066 static VALUE
06067 foletype_default_event_sources(VALUE self)
06068 {
06069 struct oletypedata *ptype;
06070 Data_Get_Struct(self, struct oletypedata, ptype);
06071 return ole_type_impl_ole_types(ptype->pTypeInfo, IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT);
06072 }
06073
06074
06075
06076
06077
06078
06079
06080
06081
06082
06083
06084 static VALUE
06085 foletype_default_ole_types(VALUE self)
06086 {
06087 struct oletypedata *ptype;
06088 Data_Get_Struct(self, struct oletypedata, ptype);
06089 return ole_type_impl_ole_types(ptype->pTypeInfo, IMPLTYPEFLAG_FDEFAULT);
06090 }
06091
06092
06093
06094
06095
06096
06097
06098
06099
06100
06101 static VALUE
06102 foletype_inspect(VALUE self)
06103 {
06104 return default_inspect(self, "WIN32OLE_TYPE");
06105 }
06106
06107 static VALUE
06108 ole_variables(ITypeInfo *pTypeInfo)
06109 {
06110 HRESULT hr;
06111 TYPEATTR *pTypeAttr;
06112 WORD i;
06113 UINT len;
06114 BSTR bstr;
06115 char *pstr;
06116 VARDESC *pVarDesc;
06117 struct olevariabledata *pvar;
06118 VALUE var;
06119 VALUE variables = rb_ary_new();
06120 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
06121 if (FAILED(hr)) {
06122 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
06123 }
06124
06125 for(i = 0; i < pTypeAttr->cVars; i++) {
06126 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, i, &pVarDesc);
06127 if(FAILED(hr))
06128 continue;
06129 len = 0;
06130 pstr = NULL;
06131 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
06132 1, &len);
06133 if(FAILED(hr) || len == 0 || !bstr)
06134 continue;
06135
06136 var = Data_Make_Struct(cWIN32OLE_VARIABLE, struct olevariabledata,
06137 0,olevariable_free,pvar);
06138 pvar->pTypeInfo = pTypeInfo;
06139 OLE_ADDREF(pTypeInfo);
06140 pvar->index = i;
06141 rb_ivar_set(var, rb_intern("name"), WC2VSTR(bstr));
06142 rb_ary_push(variables, var);
06143
06144 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06145 pVarDesc = NULL;
06146 }
06147 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
06148 return variables;
06149 }
06150
06151
06152
06153
06154
06155
06156
06157
06158
06159
06160
06161
06162
06163
06164
06165
06166
06167
06168
06169
06170
06171 static VALUE
06172 foletype_variables(VALUE self)
06173 {
06174 struct oletypedata *ptype;
06175 Data_Get_Struct(self, struct oletypedata, ptype);
06176 return ole_variables(ptype->pTypeInfo);
06177 }
06178
06179
06180
06181
06182
06183
06184
06185
06186
06187
06188
06189
06190
06191 static VALUE
06192 foletype_methods(VALUE self)
06193 {
06194 struct oletypedata *ptype;
06195 Data_Get_Struct(self, struct oletypedata, ptype);
06196 return ole_methods_from_typeinfo(ptype->pTypeInfo, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
06197 }
06198
06199
06200
06201
06202
06203
06204
06205
06206
06207
06208
06209
06210
06211
06212
06213
06214
06215
06216
06217
06218
06219
06220
06221
06222
06223
06224
06225 static VALUE
06226 folevariable_name(VALUE self)
06227 {
06228 return rb_ivar_get(self, rb_intern("name"));
06229 }
06230
06231 static VALUE
06232 ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index)
06233 {
06234 VARDESC *pVarDesc;
06235 HRESULT hr;
06236 VALUE type;
06237 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
06238 if (FAILED(hr))
06239 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc");
06240 type = ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), Qnil);
06241 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06242 return type;
06243 }
06244
06245
06246
06247
06248
06249
06250
06251
06252
06253
06254
06255
06256
06257
06258
06259
06260
06261
06262
06263
06264
06265 static VALUE
06266 folevariable_ole_type(VALUE self)
06267 {
06268 struct olevariabledata *pvar;
06269 Data_Get_Struct(self, struct olevariabledata, pvar);
06270 return ole_variable_ole_type(pvar->pTypeInfo, pvar->index);
06271 }
06272
06273 static VALUE
06274 ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index)
06275 {
06276 VARDESC *pVarDesc;
06277 HRESULT hr;
06278 VALUE type = rb_ary_new();
06279 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
06280 if (FAILED(hr))
06281 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc");
06282 ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), type);
06283 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06284 return type;
06285 }
06286
06287
06288
06289
06290
06291
06292
06293
06294
06295
06296
06297
06298
06299 static VALUE
06300 folevariable_ole_type_detail(VALUE self)
06301 {
06302 struct olevariabledata *pvar;
06303 Data_Get_Struct(self, struct olevariabledata, pvar);
06304 return ole_variable_ole_type_detail(pvar->pTypeInfo, pvar->index);
06305 }
06306
06307 static VALUE
06308 ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index)
06309 {
06310 VARDESC *pVarDesc;
06311 HRESULT hr;
06312 VALUE val = Qnil;
06313 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
06314 if (FAILED(hr))
06315 return Qnil;
06316 if(pVarDesc->varkind == VAR_CONST)
06317 val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));
06318 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06319 return val;
06320 }
06321
06322
06323
06324
06325
06326
06327
06328
06329
06330
06331
06332
06333
06334
06335
06336
06337
06338
06339
06340
06341
06342
06343 static VALUE
06344 folevariable_value(VALUE self)
06345 {
06346 struct olevariabledata *pvar;
06347 Data_Get_Struct(self, struct olevariabledata, pvar);
06348 return ole_variable_value(pvar->pTypeInfo, pvar->index);
06349 }
06350
06351 static VALUE
06352 ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index)
06353 {
06354 VARDESC *pVarDesc;
06355 HRESULT hr;
06356 VALUE visible = Qfalse;
06357 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
06358 if (FAILED(hr))
06359 return visible;
06360 if (!(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
06361 VARFLAG_FRESTRICTED |
06362 VARFLAG_FNONBROWSABLE))) {
06363 visible = Qtrue;
06364 }
06365 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06366 return visible;
06367 }
06368
06369
06370
06371
06372
06373
06374
06375
06376
06377
06378
06379
06380
06381
06382
06383
06384
06385
06386
06387
06388
06389 static VALUE
06390 folevariable_visible(VALUE self)
06391 {
06392 struct olevariabledata *pvar;
06393 Data_Get_Struct(self, struct olevariabledata, pvar);
06394 return ole_variable_visible(pvar->pTypeInfo, pvar->index);
06395 }
06396
06397 static VALUE
06398 ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index)
06399 {
06400 VARDESC *pVarDesc;
06401 HRESULT hr;
06402 VALUE kind = rb_str_new2("UNKNOWN");
06403 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
06404 if (FAILED(hr))
06405 return kind;
06406 switch(pVarDesc->varkind) {
06407 case VAR_PERINSTANCE:
06408 kind = rb_str_new2("PERINSTANCE");
06409 break;
06410 case VAR_STATIC:
06411 kind = rb_str_new2("STATIC");
06412 break;
06413 case VAR_CONST:
06414 kind = rb_str_new2("CONSTANT");
06415 break;
06416 case VAR_DISPATCH:
06417 kind = rb_str_new2("DISPATCH");
06418 break;
06419 default:
06420 break;
06421 }
06422 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06423 return kind;
06424 }
06425
06426
06427
06428
06429
06430
06431
06432
06433
06434
06435
06436
06437
06438
06439
06440
06441
06442
06443
06444
06445 static VALUE
06446 folevariable_variable_kind(VALUE self)
06447 {
06448 struct olevariabledata *pvar;
06449 Data_Get_Struct(self, struct olevariabledata, pvar);
06450 return ole_variable_kind(pvar->pTypeInfo, pvar->index);
06451 }
06452
06453 static VALUE
06454 ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index)
06455 {
06456 VARDESC *pVarDesc;
06457 HRESULT hr;
06458 VALUE kind = Qnil;
06459 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
06460 if (FAILED(hr))
06461 return kind;
06462 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06463 kind = INT2FIX(pVarDesc->varkind);
06464 return kind;
06465 }
06466
06467
06468
06469
06470
06471
06472
06473
06474
06475
06476
06477
06478
06479
06480
06481
06482
06483
06484
06485 static VALUE
06486 folevariable_varkind(VALUE self)
06487 {
06488 struct olevariabledata *pvar;
06489 Data_Get_Struct(self, struct olevariabledata, pvar);
06490 return ole_variable_varkind(pvar->pTypeInfo, pvar->index);
06491 }
06492
06493
06494
06495
06496
06497
06498
06499
06500 static VALUE
06501 folevariable_inspect(VALUE self)
06502 {
06503 VALUE detail = rb_funcall(self, rb_intern("to_s"), 0);
06504 rb_str_cat2(detail, "=");
06505 rb_str_concat(detail, rb_funcall(rb_funcall(self, rb_intern("value"), 0), rb_intern("inspect"), 0));
06506 return make_inspect("WIN32OLE_VARIABLE", detail);
06507 }
06508
06509
06510
06511
06512
06513
06514
06515 static VALUE
06516 olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name)
06517 {
06518 struct olemethoddata *pmethod;
06519 Data_Get_Struct(self, struct olemethoddata, pmethod);
06520 pmethod->pTypeInfo = pTypeInfo;
06521 OLE_ADDREF(pTypeInfo);
06522 pmethod->pOwnerTypeInfo = pOwnerTypeInfo;
06523 if(pOwnerTypeInfo) OLE_ADDREF(pOwnerTypeInfo);
06524 pmethod->index = index;
06525 rb_ivar_set(self, rb_intern("name"), name);
06526 return self;
06527 }
06528
06529 static VALUE
06530 folemethod_s_allocate(VALUE klass)
06531 {
06532 struct olemethoddata *pmethod;
06533 VALUE obj;
06534 obj = Data_Make_Struct(klass,
06535 struct olemethoddata,
06536 0, olemethod_free, pmethod);
06537 pmethod->pTypeInfo = NULL;
06538 pmethod->pOwnerTypeInfo = NULL;
06539 pmethod->index = 0;
06540 return obj;
06541 }
06542
06543
06544
06545
06546
06547
06548
06549
06550
06551
06552
06553
06554
06555
06556 static VALUE
06557 folemethod_initialize(VALUE self, VALUE oletype, VALUE method)
06558 {
06559 struct oletypedata *ptype;
06560 VALUE obj = Qnil;
06561 if (rb_obj_is_kind_of(oletype, cWIN32OLE_TYPE)) {
06562 SafeStringValue(method);
06563 Data_Get_Struct(oletype, struct oletypedata, ptype);
06564 obj = olemethod_from_typeinfo(self, ptype->pTypeInfo, method);
06565 if (obj == Qnil) {
06566 rb_raise(eWIN32OLERuntimeError, "not found %s",
06567 StringValuePtr(method));
06568 }
06569 }
06570 else {
06571 rb_raise(rb_eTypeError, "1st argument should be WIN32OLE_TYPE object");
06572 }
06573 return obj;
06574 }
06575
06576
06577
06578
06579
06580
06581
06582
06583
06584
06585
06586
06587 static VALUE
06588 folemethod_name(VALUE self)
06589 {
06590 return rb_ivar_get(self, rb_intern("name"));
06591 }
06592
06593 static VALUE
06594 ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index)
06595 {
06596 FUNCDESC *pFuncDesc;
06597 HRESULT hr;
06598 VALUE type;
06599
06600 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
06601 if (FAILED(hr))
06602 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
06603
06604 type = ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), Qnil);
06605 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
06606 return type;
06607 }
06608
06609
06610
06611
06612
06613
06614
06615
06616
06617
06618
06619 static VALUE
06620 folemethod_return_type(VALUE self)
06621 {
06622 struct olemethoddata *pmethod;
06623 Data_Get_Struct(self, struct olemethoddata, pmethod);
06624 return ole_method_return_type(pmethod->pTypeInfo, pmethod->index);
06625 }
06626
06627 static VALUE
06628 ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index)
06629 {
06630 FUNCDESC *pFuncDesc;
06631 HRESULT hr;
06632 VALUE vvt;
06633
06634 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
06635 if (FAILED(hr))
06636 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
06637
06638 vvt = INT2FIX(pFuncDesc->elemdescFunc.tdesc.vt);
06639 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
06640 return vvt;
06641 }
06642
06643
06644
06645
06646
06647
06648
06649
06650
06651
06652
06653 static VALUE
06654 folemethod_return_vtype(VALUE self)
06655 {
06656 struct olemethoddata *pmethod;
06657 Data_Get_Struct(self, struct olemethoddata, pmethod);
06658 return ole_method_return_vtype(pmethod->pTypeInfo, pmethod->index);
06659 }
06660
06661 static VALUE
06662 ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index)
06663 {
06664 FUNCDESC *pFuncDesc;
06665 HRESULT hr;
06666 VALUE type = rb_ary_new();
06667
06668 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
06669 if (FAILED(hr))
06670 return type;
06671
06672 ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), type);
06673 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
06674 return type;
06675 }
06676
06677
06678
06679
06680
06681
06682
06683
06684
06685
06686
06687 static VALUE
06688 folemethod_return_type_detail(VALUE self)
06689 {
06690 struct olemethoddata *pmethod;
06691 Data_Get_Struct(self, struct olemethoddata, pmethod);
06692 return ole_method_return_type_detail(pmethod->pTypeInfo, pmethod->index);
06693 }
06694
06695 static VALUE
06696 ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index)
06697 {
06698 FUNCDESC *pFuncDesc;
06699 HRESULT hr;
06700 VALUE invkind;
06701 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
06702 if(FAILED(hr))
06703 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
06704 invkind = INT2FIX(pFuncDesc->invkind);
06705 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
06706 return invkind;
06707 }
06708
06709 static VALUE
06710 ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index)
06711 {
06712 VALUE type = rb_str_new2("UNKNOWN");
06713 VALUE invkind = ole_method_invkind(pTypeInfo, method_index);
06714 if((FIX2INT(invkind) & INVOKE_PROPERTYGET) &&
06715 (FIX2INT(invkind) & INVOKE_PROPERTYPUT) ) {
06716 type = rb_str_new2("PROPERTY");
06717 } else if(FIX2INT(invkind) & INVOKE_PROPERTYGET) {
06718 type = rb_str_new2("PROPERTYGET");
06719 } else if(FIX2INT(invkind) & INVOKE_PROPERTYPUT) {
06720 type = rb_str_new2("PROPERTYPUT");
06721 } else if(FIX2INT(invkind) & INVOKE_PROPERTYPUTREF) {
06722 type = rb_str_new2("PROPERTYPUTREF");
06723 } else if(FIX2INT(invkind) & INVOKE_FUNC) {
06724 type = rb_str_new2("FUNC");
06725 }
06726 return type;
06727 }
06728
06729
06730
06731
06732
06733
06734
06735
06736
06737
06738
06739 static VALUE
06740 folemethod_invkind(VALUE self)
06741 {
06742 struct olemethoddata *pmethod;
06743 Data_Get_Struct(self, struct olemethoddata, pmethod);
06744 return ole_method_invkind(pmethod->pTypeInfo, pmethod->index);
06745 }
06746
06747
06748
06749
06750
06751
06752
06753
06754
06755
06756
06757
06758 static VALUE
06759 folemethod_invoke_kind(VALUE self)
06760 {
06761 struct olemethoddata *pmethod;
06762 Data_Get_Struct(self, struct olemethoddata, pmethod);
06763 return ole_method_invoke_kind(pmethod->pTypeInfo, pmethod->index);
06764 }
06765
06766 static VALUE
06767 ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index)
06768 {
06769 FUNCDESC *pFuncDesc;
06770 HRESULT hr;
06771 VALUE visible;
06772 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
06773 if(FAILED(hr))
06774 return Qfalse;
06775 if (pFuncDesc->wFuncFlags & (FUNCFLAG_FRESTRICTED |
06776 FUNCFLAG_FHIDDEN |
06777 FUNCFLAG_FNONBROWSABLE)) {
06778 visible = Qfalse;
06779 } else {
06780 visible = Qtrue;
06781 }
06782 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
06783 return visible;
06784 }
06785
06786
06787
06788
06789
06790
06791
06792
06793
06794
06795 static VALUE
06796 folemethod_visible(VALUE self)
06797 {
06798 struct olemethoddata *pmethod;
06799 Data_Get_Struct(self, struct olemethoddata, pmethod);
06800 return ole_method_visible(pmethod->pTypeInfo, pmethod->index);
06801 }
06802
06803 static VALUE
06804 ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name)
06805 {
06806 TYPEATTR *pTypeAttr;
06807 HRESULT hr;
06808 WORD i;
06809 int flags;
06810 HREFTYPE href;
06811 ITypeInfo *pRefTypeInfo;
06812 FUNCDESC *pFuncDesc;
06813 BSTR bstr;
06814 VALUE name;
06815 VALUE event = Qfalse;
06816
06817 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
06818 if (FAILED(hr))
06819 return event;
06820 if(pTypeAttr->typekind != TKIND_COCLASS) {
06821 pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
06822 return event;
06823 }
06824 for (i = 0; i < pTypeAttr->cImplTypes; i++) {
06825 hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
06826 if (FAILED(hr))
06827 continue;
06828
06829 if (flags & IMPLTYPEFLAG_FSOURCE) {
06830 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
06831 i, &href);
06832 if (FAILED(hr))
06833 continue;
06834 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
06835 href, &pRefTypeInfo);
06836 if (FAILED(hr))
06837 continue;
06838 hr = pRefTypeInfo->lpVtbl->GetFuncDesc(pRefTypeInfo, method_index,
06839 &pFuncDesc);
06840 if (FAILED(hr)) {
06841 OLE_RELEASE(pRefTypeInfo);
06842 continue;
06843 }
06844
06845 hr = pRefTypeInfo->lpVtbl->GetDocumentation(pRefTypeInfo,
06846 pFuncDesc->memid,
06847 &bstr, NULL, NULL, NULL);
06848 if (FAILED(hr)) {
06849 pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);
06850 OLE_RELEASE(pRefTypeInfo);
06851 continue;
06852 }
06853
06854 name = WC2VSTR(bstr);
06855 pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);
06856 OLE_RELEASE(pRefTypeInfo);
06857 if (rb_str_cmp(method_name, name) == 0) {
06858 event = Qtrue;
06859 break;
06860 }
06861 }
06862 }
06863 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
06864 return event;
06865 }
06866
06867
06868
06869
06870
06871
06872
06873
06874
06875
06876
06877 static VALUE
06878 folemethod_event(VALUE self)
06879 {
06880 struct olemethoddata *pmethod;
06881 Data_Get_Struct(self, struct olemethoddata, pmethod);
06882 if (!pmethod->pOwnerTypeInfo)
06883 return Qfalse;
06884 return ole_method_event(pmethod->pOwnerTypeInfo,
06885 pmethod->index,
06886 rb_ivar_get(self, rb_intern("name")));
06887 }
06888
06889
06890
06891
06892
06893
06894
06895
06896
06897
06898 static VALUE
06899 folemethod_event_interface(VALUE self)
06900 {
06901 BSTR name;
06902 struct olemethoddata *pmethod;
06903 HRESULT hr;
06904 Data_Get_Struct(self, struct olemethoddata, pmethod);
06905 if(folemethod_event(self) == Qtrue) {
06906 hr = ole_docinfo_from_type(pmethod->pTypeInfo, &name, NULL, NULL, NULL);
06907 if(SUCCEEDED(hr))
06908 return WC2VSTR(name);
06909 }
06910 return Qnil;
06911 }
06912
06913 static VALUE
06914 ole_method_docinfo_from_type(
06915 ITypeInfo *pTypeInfo,
06916 UINT method_index,
06917 BSTR *name,
06918 BSTR *helpstr,
06919 DWORD *helpcontext,
06920 BSTR *helpfile
06921 )
06922 {
06923 FUNCDESC *pFuncDesc;
06924 HRESULT hr;
06925 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
06926 if (FAILED(hr))
06927 return hr;
06928 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
06929 name, helpstr,
06930 helpcontext, helpfile);
06931 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
06932 return hr;
06933 }
06934
06935 static VALUE
06936 ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index)
06937 {
06938 HRESULT hr;
06939 BSTR bhelpstring;
06940 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, &bhelpstring,
06941 NULL, NULL);
06942 if (FAILED(hr))
06943 return Qnil;
06944 return WC2VSTR(bhelpstring);
06945 }
06946
06947
06948
06949
06950
06951
06952
06953
06954
06955
06956
06957
06958 static VALUE
06959 folemethod_helpstring(VALUE self)
06960 {
06961 struct olemethoddata *pmethod;
06962 Data_Get_Struct(self, struct olemethoddata, pmethod);
06963 return ole_method_helpstring(pmethod->pTypeInfo, pmethod->index);
06964 }
06965
06966 static VALUE
06967 ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index)
06968 {
06969 HRESULT hr;
06970 BSTR bhelpfile;
06971 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,
06972 NULL, &bhelpfile);
06973 if (FAILED(hr))
06974 return Qnil;
06975 return WC2VSTR(bhelpfile);
06976 }
06977
06978
06979
06980
06981
06982
06983
06984
06985
06986
06987
06988 static VALUE
06989 folemethod_helpfile(VALUE self)
06990 {
06991 struct olemethoddata *pmethod;
06992 Data_Get_Struct(self, struct olemethoddata, pmethod);
06993
06994 return ole_method_helpfile(pmethod->pTypeInfo, pmethod->index);
06995 }
06996
06997 static VALUE
06998 ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index)
06999 {
07000 HRESULT hr;
07001 DWORD helpcontext = 0;
07002 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,
07003 &helpcontext, NULL);
07004 if (FAILED(hr))
07005 return Qnil;
07006 return INT2FIX(helpcontext);
07007 }
07008
07009
07010
07011
07012
07013
07014
07015
07016
07017
07018 static VALUE
07019 folemethod_helpcontext(VALUE self)
07020 {
07021 struct olemethoddata *pmethod;
07022 Data_Get_Struct(self, struct olemethoddata, pmethod);
07023 return ole_method_helpcontext(pmethod->pTypeInfo, pmethod->index);
07024 }
07025
07026 static VALUE
07027 ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index)
07028 {
07029 FUNCDESC *pFuncDesc;
07030 HRESULT hr;
07031 VALUE dispid = Qnil;
07032 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07033 if (FAILED(hr))
07034 return dispid;
07035 dispid = INT2NUM(pFuncDesc->memid);
07036 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07037 return dispid;
07038 }
07039
07040
07041
07042
07043
07044
07045
07046
07047
07048
07049 static VALUE
07050 folemethod_dispid(VALUE self)
07051 {
07052 struct olemethoddata *pmethod;
07053 Data_Get_Struct(self, struct olemethoddata, pmethod);
07054 return ole_method_dispid(pmethod->pTypeInfo, pmethod->index);
07055 }
07056
07057 static VALUE
07058 ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index)
07059 {
07060 FUNCDESC *pFuncDesc;
07061 HRESULT hr;
07062 VALUE offset_vtbl = Qnil;
07063 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07064 if (FAILED(hr))
07065 return offset_vtbl;
07066 offset_vtbl = INT2FIX(pFuncDesc->oVft);
07067 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07068 return offset_vtbl;
07069 }
07070
07071
07072
07073
07074
07075
07076
07077
07078
07079
07080 static VALUE
07081 folemethod_offset_vtbl(VALUE self)
07082 {
07083 struct olemethoddata *pmethod;
07084 Data_Get_Struct(self, struct olemethoddata, pmethod);
07085 return ole_method_offset_vtbl(pmethod->pTypeInfo, pmethod->index);
07086 }
07087
07088 static VALUE
07089 ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index)
07090 {
07091 FUNCDESC *pFuncDesc;
07092 HRESULT hr;
07093 VALUE size_params = Qnil;
07094 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07095 if (FAILED(hr))
07096 return size_params;
07097 size_params = INT2FIX(pFuncDesc->cParams);
07098 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07099 return size_params;
07100 }
07101
07102
07103
07104
07105
07106
07107
07108
07109
07110
07111
07112 static VALUE
07113 folemethod_size_params(VALUE self)
07114 {
07115 struct olemethoddata *pmethod;
07116 Data_Get_Struct(self, struct olemethoddata, pmethod);
07117 return ole_method_size_params(pmethod->pTypeInfo, pmethod->index);
07118 }
07119
07120 static VALUE
07121 ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index)
07122 {
07123 FUNCDESC *pFuncDesc;
07124 HRESULT hr;
07125 VALUE size_opt_params = Qnil;
07126 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07127 if (FAILED(hr))
07128 return size_opt_params;
07129 size_opt_params = INT2FIX(pFuncDesc->cParamsOpt);
07130 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07131 return size_opt_params;
07132 }
07133
07134
07135
07136
07137
07138
07139
07140
07141
07142
07143 static VALUE
07144 folemethod_size_opt_params(VALUE self)
07145 {
07146 struct olemethoddata *pmethod;
07147 Data_Get_Struct(self, struct olemethoddata, pmethod);
07148 return ole_method_size_opt_params(pmethod->pTypeInfo, pmethod->index);
07149 }
07150
07151 static VALUE
07152 ole_method_params(ITypeInfo *pTypeInfo, UINT method_index)
07153 {
07154 FUNCDESC *pFuncDesc;
07155 HRESULT hr;
07156 BSTR *bstrs;
07157 UINT len, i;
07158 struct oleparamdata *pparam;
07159 VALUE param;
07160 VALUE params = rb_ary_new();
07161 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07162 if (FAILED(hr))
07163 return params;
07164
07165 len = 0;
07166 bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1);
07167 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid,
07168 bstrs, pFuncDesc->cParams + 1,
07169 &len);
07170 if (FAILED(hr)) {
07171 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07172 return params;
07173 }
07174 SysFreeString(bstrs[0]);
07175 if (pFuncDesc->cParams > 0) {
07176 for(i = 1; i < len; i++) {
07177 param = Data_Make_Struct(cWIN32OLE_PARAM, struct oleparamdata, 0,
07178 oleparam_free, pparam);
07179 pparam->pTypeInfo = pTypeInfo;
07180 OLE_ADDREF(pTypeInfo);
07181 pparam->method_index = method_index;
07182 pparam->index = i - 1;
07183 rb_ivar_set(param, rb_intern("name"), WC2VSTR(bstrs[i]));
07184 rb_ary_push(params, param);
07185 }
07186 }
07187 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07188 return params;
07189 }
07190
07191
07192
07193
07194
07195
07196
07197
07198
07199
07200
07201
07202
07203
07204 static VALUE
07205 folemethod_params(VALUE self)
07206 {
07207 struct olemethoddata *pmethod;
07208 Data_Get_Struct(self, struct olemethoddata, pmethod);
07209 return ole_method_params(pmethod->pTypeInfo, pmethod->index);
07210 }
07211
07212
07213
07214
07215
07216
07217
07218
07219 static VALUE
07220 folemethod_inspect(VALUE self)
07221 {
07222 return default_inspect(self, "WIN32OLE_METHOD");
07223 }
07224
07225
07226
07227
07228
07229
07230
07231 static VALUE foleparam_s_allocate(VALUE klass)
07232 {
07233 struct oleparamdata *pparam;
07234 VALUE obj;
07235 obj = Data_Make_Struct(klass,
07236 struct oleparamdata,
07237 0, oleparam_free, pparam);
07238 pparam->pTypeInfo = NULL;
07239 pparam->method_index = 0;
07240 pparam->index = 0;
07241 return obj;
07242 }
07243
07244 static VALUE
07245 oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index)
07246 {
07247 FUNCDESC *pFuncDesc;
07248 HRESULT hr;
07249 BSTR *bstrs;
07250 UINT len;
07251 struct oleparamdata *pparam;
07252 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07253 if (FAILED(hr))
07254 ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetFuncDesc");
07255
07256 len = 0;
07257 bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1);
07258 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid,
07259 bstrs, pFuncDesc->cParams + 1,
07260 &len);
07261 if (FAILED(hr)) {
07262 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07263 ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetNames");
07264 }
07265 SysFreeString(bstrs[0]);
07266 if (param_index < 1 || len <= (UINT)param_index)
07267 {
07268 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07269 rb_raise(rb_eIndexError, "index of param must be in 1..%d", len);
07270 }
07271
07272 Data_Get_Struct(self, struct oleparamdata, pparam);
07273 pparam->pTypeInfo = pTypeInfo;
07274 OLE_ADDREF(pTypeInfo);
07275 pparam->method_index = method_index;
07276 pparam->index = param_index - 1;
07277 rb_ivar_set(self, rb_intern("name"), WC2VSTR(bstrs[param_index]));
07278
07279 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07280 return self;
07281 }
07282
07283 static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n)
07284 {
07285 struct olemethoddata *pmethod;
07286 Data_Get_Struct(olemethod, struct olemethoddata, pmethod);
07287 return oleparam_ole_param_from_index(self, pmethod->pTypeInfo, pmethod->index, n);
07288 }
07289
07290 static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n)
07291 {
07292 int idx;
07293 if (!rb_obj_is_kind_of(olemethod, cWIN32OLE_METHOD)) {
07294 rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE_METHOD object");
07295 }
07296 idx = FIX2INT(n);
07297 return oleparam_ole_param(self, olemethod, idx);
07298 }
07299
07300
07301
07302
07303
07304
07305
07306
07307
07308
07309
07310 static VALUE
07311 foleparam_name(VALUE self)
07312 {
07313 return rb_ivar_get(self, rb_intern("name"));
07314 }
07315
07316 static VALUE
07317 ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
07318 {
07319 FUNCDESC *pFuncDesc;
07320 HRESULT hr;
07321 VALUE type = rb_str_new2("unknown type");
07322 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07323 if (FAILED(hr))
07324 return type;
07325 type = ole_typedesc2val(pTypeInfo,
07326 &(pFuncDesc->lprgelemdescParam[index].tdesc), Qnil);
07327 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07328 return type;
07329 }
07330
07331
07332
07333
07334
07335
07336
07337
07338
07339
07340
07341 static VALUE
07342 foleparam_ole_type(VALUE self)
07343 {
07344 struct oleparamdata *pparam;
07345 Data_Get_Struct(self, struct oleparamdata, pparam);
07346 return ole_param_ole_type(pparam->pTypeInfo, pparam->method_index,
07347 pparam->index);
07348 }
07349
07350 static VALUE
07351 ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
07352 {
07353 FUNCDESC *pFuncDesc;
07354 HRESULT hr;
07355 VALUE typedetail = rb_ary_new();
07356 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07357 if (FAILED(hr))
07358 return typedetail;
07359 ole_typedesc2val(pTypeInfo,
07360 &(pFuncDesc->lprgelemdescParam[index].tdesc), typedetail);
07361 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07362 return typedetail;
07363 }
07364
07365
07366
07367
07368
07369
07370
07371
07372
07373
07374
07375 static VALUE
07376 foleparam_ole_type_detail(VALUE self)
07377 {
07378 struct oleparamdata *pparam;
07379 Data_Get_Struct(self, struct oleparamdata, pparam);
07380 return ole_param_ole_type_detail(pparam->pTypeInfo, pparam->method_index,
07381 pparam->index);
07382 }
07383
07384 static VALUE
07385 ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask)
07386 {
07387 FUNCDESC *pFuncDesc;
07388 HRESULT hr;
07389 VALUE ret = Qfalse;
07390 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07391 if(FAILED(hr))
07392 return ret;
07393 if (V_UNION1((&(pFuncDesc->lprgelemdescParam[index])), paramdesc).wParamFlags &mask)
07394 ret = Qtrue;
07395 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07396 return ret;
07397 }
07398
07399
07400
07401
07402
07403
07404
07405
07406
07407
07408
07409 static VALUE foleparam_input(VALUE self)
07410 {
07411 struct oleparamdata *pparam;
07412 Data_Get_Struct(self, struct oleparamdata, pparam);
07413 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
07414 pparam->index, PARAMFLAG_FIN);
07415 }
07416
07417
07418
07419
07420
07421
07422
07423
07424
07425
07426
07427
07428
07429
07430
07431
07432
07433
07434
07435
07436 static VALUE foleparam_output(VALUE self)
07437 {
07438 struct oleparamdata *pparam;
07439 Data_Get_Struct(self, struct oleparamdata, pparam);
07440 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
07441 pparam->index, PARAMFLAG_FOUT);
07442 }
07443
07444
07445
07446
07447
07448
07449
07450
07451
07452
07453
07454 static VALUE foleparam_optional(VALUE self)
07455 {
07456 struct oleparamdata *pparam;
07457 Data_Get_Struct(self, struct oleparamdata, pparam);
07458 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
07459 pparam->index, PARAMFLAG_FOPT);
07460 }
07461
07462
07463
07464
07465
07466
07467
07468
07469
07470
07471
07472
07473 static VALUE foleparam_retval(VALUE self)
07474 {
07475 struct oleparamdata *pparam;
07476 Data_Get_Struct(self, struct oleparamdata, pparam);
07477 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
07478 pparam->index, PARAMFLAG_FRETVAL);
07479 }
07480
07481 static VALUE
07482 ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
07483 {
07484 FUNCDESC *pFuncDesc;
07485 ELEMDESC *pElemDesc;
07486 PARAMDESCEX * pParamDescEx;
07487 HRESULT hr;
07488 USHORT wParamFlags;
07489 USHORT mask = PARAMFLAG_FOPT|PARAMFLAG_FHASDEFAULT;
07490 VALUE defval = Qnil;
07491 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07492 if (FAILED(hr))
07493 return defval;
07494 pElemDesc = &pFuncDesc->lprgelemdescParam[index];
07495 wParamFlags = V_UNION1(pElemDesc, paramdesc).wParamFlags;
07496 if ((wParamFlags & mask) == mask) {
07497 pParamDescEx = V_UNION1(pElemDesc, paramdesc).pparamdescex;
07498 defval = ole_variant2val(&pParamDescEx->varDefaultValue);
07499 }
07500 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07501 return defval;
07502 }
07503
07504
07505
07506
07507
07508
07509
07510
07511
07512
07513
07514
07515
07516
07517
07518
07519
07520
07521
07522
07523
07524
07525
07526
07527
07528
07529
07530
07531
07532
07533 static VALUE foleparam_default(VALUE self)
07534 {
07535 struct oleparamdata *pparam;
07536 Data_Get_Struct(self, struct oleparamdata, pparam);
07537 return ole_param_default(pparam->pTypeInfo, pparam->method_index,
07538 pparam->index);
07539 }
07540
07541
07542
07543
07544
07545
07546
07547
07548
07549 static VALUE
07550 foleparam_inspect(VALUE self)
07551 {
07552 VALUE detail = foleparam_name(self);
07553 VALUE defval = foleparam_default(self);
07554 if (defval != Qnil) {
07555 rb_str_cat2(detail, "=");
07556 rb_str_concat(detail, rb_funcall(defval, rb_intern("inspect"), 0));
07557 }
07558 return make_inspect("WIN32OLE_PARAM", detail);
07559 }
07560
07561
07562
07563
07564
07565
07566
07567 static IEventSinkVtbl vtEventSink;
07568 static BOOL g_IsEventSinkVtblInitialized = FALSE;
07569
07570 void EVENTSINK_Destructor(PIEVENTSINKOBJ);
07571
07572 STDMETHODIMP
07573 EVENTSINK_QueryInterface(
07574 PEVENTSINK pEV,
07575 REFIID iid,
07576 LPVOID* ppv
07577 ) {
07578 if (IsEqualIID(iid, &IID_IUnknown) ||
07579 IsEqualIID(iid, &IID_IDispatch) ||
07580 IsEqualIID(iid, &((PIEVENTSINKOBJ)pEV)->m_iid)) {
07581 *ppv = pEV;
07582 }
07583 else {
07584 *ppv = NULL;
07585 return E_NOINTERFACE;
07586 }
07587 ((LPUNKNOWN)*ppv)->lpVtbl->AddRef((LPUNKNOWN)*ppv);
07588 return NOERROR;
07589 }
07590
07591 STDMETHODIMP_(ULONG)
07592 EVENTSINK_AddRef(
07593 PEVENTSINK pEV
07594 ){
07595 PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV;
07596 return ++pEVObj->m_cRef;
07597 }
07598
07599 STDMETHODIMP_(ULONG) EVENTSINK_Release(
07600 PEVENTSINK pEV
07601 ) {
07602 PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV;
07603 --pEVObj->m_cRef;
07604 if(pEVObj->m_cRef != 0)
07605 return pEVObj->m_cRef;
07606 EVENTSINK_Destructor(pEVObj);
07607 return 0;
07608 }
07609
07610 STDMETHODIMP EVENTSINK_GetTypeInfoCount(
07611 PEVENTSINK pEV,
07612 UINT *pct
07613 ) {
07614 *pct = 0;
07615 return NOERROR;
07616 }
07617
07618 STDMETHODIMP EVENTSINK_GetTypeInfo(
07619 PEVENTSINK pEV,
07620 UINT info,
07621 LCID lcid,
07622 ITypeInfo **pInfo
07623 ) {
07624 *pInfo = NULL;
07625 return DISP_E_BADINDEX;
07626 }
07627
07628 STDMETHODIMP EVENTSINK_GetIDsOfNames(
07629 PEVENTSINK pEventSink,
07630 REFIID riid,
07631 OLECHAR **szNames,
07632 UINT cNames,
07633 LCID lcid,
07634 DISPID *pDispID
07635 ) {
07636 ITypeInfo *pTypeInfo;
07637 PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink;
07638 pTypeInfo = pEV->pTypeInfo;
07639 if (pTypeInfo) {
07640 return pTypeInfo->lpVtbl->GetIDsOfNames(pTypeInfo, szNames, cNames, pDispID);
07641 }
07642 return DISP_E_UNKNOWNNAME;
07643 }
07644
07645 static long
07646 ole_search_event_at(VALUE ary, VALUE ev)
07647 {
07648 VALUE event;
07649 VALUE def_event;
07650 VALUE event_name;
07651 long i, len;
07652 long ret = -1;
07653 def_event = Qnil;
07654 len = RARRAY_LEN(ary);
07655 for(i = 0; i < len; i++) {
07656 event = rb_ary_entry(ary, i);
07657 event_name = rb_ary_entry(event, 1);
07658 if(NIL_P(event_name) && NIL_P(ev)) {
07659 ret = i;
07660 break;
07661 }
07662 else if (TYPE(ev) == T_STRING &&
07663 TYPE(event_name) == T_STRING &&
07664 rb_str_cmp(ev, event_name) == 0) {
07665 ret = i;
07666 break;
07667 }
07668 }
07669 return ret;
07670 }
07671
07672 static VALUE
07673 ole_search_event(VALUE ary, VALUE ev, BOOL *is_default)
07674 {
07675 VALUE event;
07676 VALUE def_event;
07677 VALUE event_name;
07678 int i, len;
07679 *is_default = FALSE;
07680 def_event = Qnil;
07681 len = RARRAY_LEN(ary);
07682 for(i = 0; i < len; i++) {
07683 event = rb_ary_entry(ary, i);
07684 event_name = rb_ary_entry(event, 1);
07685 if(NIL_P(event_name)) {
07686 *is_default = TRUE;
07687 def_event = event;
07688 }
07689 else if (rb_str_cmp(ev, event_name) == 0) {
07690 *is_default = FALSE;
07691 return event;
07692 }
07693 }
07694 return def_event;
07695 }
07696 static VALUE
07697 ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler)
07698 {
07699 VALUE mid;
07700
07701 *is_default_handler = FALSE;
07702 mid = rb_to_id(rb_sprintf("on%s", StringValuePtr(ev)));
07703 if (rb_respond_to(handler, mid)) {
07704 return mid;
07705 }
07706 mid = rb_intern("method_missing");
07707 if (rb_respond_to(handler, mid)) {
07708 *is_default_handler = TRUE;
07709 return mid;
07710 }
07711 return Qnil;
07712 }
07713
07714 static void
07715 ole_delete_event(VALUE ary, VALUE ev)
07716 {
07717 long at = -1;
07718 at = ole_search_event_at(ary, ev);
07719 if (at >= 0) {
07720 rb_ary_delete_at(ary, at);
07721 }
07722 }
07723
07724 static void
07725 hash2ptr_dispparams(VALUE hash, ITypeInfo *pTypeInfo, DISPID dispid, DISPPARAMS *pdispparams)
07726 {
07727 BSTR *bstrs;
07728 HRESULT hr;
07729 UINT len, i;
07730 VARIANT *pvar;
07731 VALUE val;
07732 VALUE key;
07733 len = 0;
07734 bstrs = ALLOCA_N(BSTR, pdispparams->cArgs + 1);
07735 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid,
07736 bstrs, pdispparams->cArgs + 1,
07737 &len);
07738 if (FAILED(hr))
07739 return;
07740
07741 for (i = 0; i < len - 1; i++) {
07742 key = WC2VSTR(bstrs[i + 1]);
07743 val = rb_hash_aref(hash, INT2FIX(i));
07744 if (val == Qnil)
07745 val = rb_hash_aref(hash, key);
07746 if (val == Qnil)
07747 val = rb_hash_aref(hash, rb_str_intern(key));
07748 pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
07749 ole_val2ptr_variant(val, pvar);
07750 }
07751 }
07752
07753 static VALUE
07754 hash2result(VALUE hash)
07755 {
07756 VALUE ret = Qnil;
07757 ret = rb_hash_aref(hash, rb_str_new2("return"));
07758 if (ret == Qnil)
07759 ret = rb_hash_aref(hash, rb_str_intern(rb_str_new2("return")));
07760 return ret;
07761 }
07762
07763 static void
07764 ary2ptr_dispparams(VALUE ary, DISPPARAMS *pdispparams)
07765 {
07766 int i;
07767 VALUE v;
07768 VARIANT *pvar;
07769 for(i = 0; i < RARRAY_LEN(ary) && (unsigned int) i < pdispparams->cArgs; i++) {
07770 v = rb_ary_entry(ary, i);
07771 pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
07772 ole_val2ptr_variant(v, pvar);
07773 }
07774 }
07775
07776 static VALUE
07777 exec_callback(VALUE arg)
07778 {
07779 VALUE *parg = (VALUE *)arg;
07780 VALUE handler = parg[0];
07781 VALUE mid = parg[1];
07782 VALUE args = parg[2];
07783 return rb_apply(handler, mid, args);
07784 }
07785
07786 static VALUE
07787 rescue_callback(VALUE arg)
07788 {
07789
07790 VALUE error;
07791 VALUE e = rb_errinfo();
07792 VALUE bt = rb_funcall(e, rb_intern("backtrace"), 0);
07793 VALUE msg = rb_funcall(e, rb_intern("message"), 0);
07794 bt = rb_ary_entry(bt, 0);
07795 error = rb_sprintf("%s: %s (%s)\n", StringValuePtr(bt), StringValuePtr(msg), rb_obj_classname(e));
07796 rb_write_error(StringValuePtr(error));
07797 rb_backtrace();
07798 ruby_finalize();
07799 exit(-1);
07800
07801 return Qnil;
07802 }
07803
07804 STDMETHODIMP EVENTSINK_Invoke(
07805 PEVENTSINK pEventSink,
07806 DISPID dispid,
07807 REFIID riid,
07808 LCID lcid,
07809 WORD wFlags,
07810 DISPPARAMS *pdispparams,
07811 VARIANT *pvarResult,
07812 EXCEPINFO *pexcepinfo,
07813 UINT *puArgErr
07814 ) {
07815
07816 HRESULT hr;
07817 BSTR bstr;
07818 unsigned int count;
07819 unsigned int i;
07820 ITypeInfo *pTypeInfo;
07821 VARIANT *pvar;
07822 VALUE ary, obj, event, args, outargv, ev, result;
07823 VALUE handler = Qnil;
07824 VALUE arg[3];
07825 VALUE mid;
07826 VALUE is_outarg = Qfalse;
07827 BOOL is_default_handler = FALSE;
07828 int state;
07829
07830 PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink;
07831 pTypeInfo = pEV->pTypeInfo;
07832 obj = evs_entry(pEV->m_event_id);
07833 if (!rb_obj_is_kind_of(obj, cWIN32OLE_EVENT)) {
07834 return NOERROR;
07835 }
07836
07837 ary = rb_ivar_get(obj, id_events);
07838 if (NIL_P(ary) || TYPE(ary) != T_ARRAY) {
07839 return NOERROR;
07840 }
07841 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid,
07842 &bstr, 1, &count);
07843 if (FAILED(hr)) {
07844 return NOERROR;
07845 }
07846 ev = WC2VSTR(bstr);
07847 event = ole_search_event(ary, ev, &is_default_handler);
07848 if (TYPE(event) == T_ARRAY) {
07849 handler = rb_ary_entry(event, 0);
07850 mid = rb_intern("call");
07851 is_outarg = rb_ary_entry(event, 3);
07852 } else {
07853 handler = rb_ivar_get(obj, rb_intern("handler"));
07854 if (handler == Qnil) {
07855 return NOERROR;
07856 }
07857 mid = ole_search_handler_method(handler, ev, &is_default_handler);
07858 }
07859 if (handler == Qnil || mid == Qnil) {
07860 return NOERROR;
07861 }
07862
07863 args = rb_ary_new();
07864 if (is_default_handler) {
07865 rb_ary_push(args, ev);
07866 }
07867
07868
07869 for (i = 0; i < pdispparams->cArgs; ++i) {
07870 pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
07871 rb_ary_push(args, ole_variant2val(pvar));
07872 }
07873 outargv = Qnil;
07874 if (is_outarg == Qtrue) {
07875 outargv = rb_ary_new();
07876 rb_ary_push(args, outargv);
07877 }
07878
07879
07880
07881
07882
07883
07884
07885
07886 arg[0] = handler;
07887 arg[1] = mid;
07888 arg[2] = args;
07889 result = rb_protect(exec_callback, (VALUE)arg, &state);
07890 if (state != 0) {
07891 rescue_callback(Qnil);
07892 }
07893 if(TYPE(result) == T_HASH) {
07894 hash2ptr_dispparams(result, pTypeInfo, dispid, pdispparams);
07895 result = hash2result(result);
07896 }else if (is_outarg == Qtrue && TYPE(outargv) == T_ARRAY) {
07897 ary2ptr_dispparams(outargv, pdispparams);
07898 }
07899
07900 if (pvarResult) {
07901 VariantInit(pvarResult);
07902 ole_val2variant(result, pvarResult);
07903 }
07904
07905 return NOERROR;
07906 }
07907
07908 PIEVENTSINKOBJ
07909 EVENTSINK_Constructor() {
07910 PIEVENTSINKOBJ pEv;
07911 if (!g_IsEventSinkVtblInitialized) {
07912 vtEventSink.QueryInterface=EVENTSINK_QueryInterface;
07913 vtEventSink.AddRef = EVENTSINK_AddRef;
07914 vtEventSink.Release = EVENTSINK_Release;
07915 vtEventSink.Invoke = EVENTSINK_Invoke;
07916 vtEventSink.GetIDsOfNames = EVENTSINK_GetIDsOfNames;
07917 vtEventSink.GetTypeInfoCount = EVENTSINK_GetTypeInfoCount;
07918 vtEventSink.GetTypeInfo = EVENTSINK_GetTypeInfo;
07919
07920 g_IsEventSinkVtblInitialized = TRUE;
07921 }
07922 pEv = ALLOC_N(IEVENTSINKOBJ, 1);
07923 if(pEv == NULL) return NULL;
07924 pEv->lpVtbl = &vtEventSink;
07925 pEv->m_cRef = 0;
07926 pEv->m_event_id = 0;
07927 pEv->pTypeInfo = NULL;
07928 return pEv;
07929 }
07930
07931 void EVENTSINK_Destructor(
07932 PIEVENTSINKOBJ pEVObj
07933 ) {
07934 if(pEVObj != NULL) {
07935 OLE_RELEASE(pEVObj->pTypeInfo);
07936 free(pEVObj);
07937 pEVObj = NULL;
07938 }
07939 }
07940
07941 static HRESULT
07942 find_iid(VALUE ole, char *pitf, IID *piid, ITypeInfo **ppTypeInfo)
07943 {
07944 HRESULT hr;
07945 IDispatch *pDispatch;
07946 ITypeInfo *pTypeInfo;
07947 ITypeLib *pTypeLib;
07948 TYPEATTR *pTypeAttr;
07949 HREFTYPE RefType;
07950 ITypeInfo *pImplTypeInfo;
07951 TYPEATTR *pImplTypeAttr;
07952
07953 struct oledata *pole;
07954 unsigned int index;
07955 unsigned int count;
07956 int type;
07957 BSTR bstr;
07958 char *pstr;
07959
07960 BOOL is_found = FALSE;
07961 LCID lcid = cWIN32OLE_lcid;
07962
07963 OLEData_Get_Struct(ole, pole);
07964
07965 pDispatch = pole->pDispatch;
07966
07967 hr = pDispatch->lpVtbl->GetTypeInfo(pDispatch, 0, lcid, &pTypeInfo);
07968 if (FAILED(hr))
07969 return hr;
07970
07971 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo,
07972 &pTypeLib,
07973 &index);
07974 OLE_RELEASE(pTypeInfo);
07975 if (FAILED(hr))
07976 return hr;
07977
07978 if (!pitf) {
07979 hr = pTypeLib->lpVtbl->GetTypeInfoOfGuid(pTypeLib,
07980 piid,
07981 ppTypeInfo);
07982 OLE_RELEASE(pTypeLib);
07983 return hr;
07984 }
07985 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
07986 for (index = 0; index < count; index++) {
07987 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib,
07988 index,
07989 &pTypeInfo);
07990 if (FAILED(hr))
07991 break;
07992 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
07993
07994 if(FAILED(hr)) {
07995 OLE_RELEASE(pTypeInfo);
07996 break;
07997 }
07998 if(pTypeAttr->typekind == TKIND_COCLASS) {
07999 for (type = 0; type < pTypeAttr->cImplTypes; type++) {
08000 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
08001 type,
08002 &RefType);
08003 if (FAILED(hr))
08004 break;
08005 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
08006 RefType,
08007 &pImplTypeInfo);
08008 if (FAILED(hr))
08009 break;
08010
08011 hr = pImplTypeInfo->lpVtbl->GetDocumentation(pImplTypeInfo,
08012 -1,
08013 &bstr,
08014 NULL, NULL, NULL);
08015 if (FAILED(hr)) {
08016 OLE_RELEASE(pImplTypeInfo);
08017 break;
08018 }
08019 pstr = ole_wc2mb(bstr);
08020 if (strcmp(pitf, pstr) == 0) {
08021 hr = pImplTypeInfo->lpVtbl->GetTypeAttr(pImplTypeInfo,
08022 &pImplTypeAttr);
08023 if (SUCCEEDED(hr)) {
08024 is_found = TRUE;
08025 *piid = pImplTypeAttr->guid;
08026 if (ppTypeInfo) {
08027 *ppTypeInfo = pImplTypeInfo;
08028 (*ppTypeInfo)->lpVtbl->AddRef((*ppTypeInfo));
08029 }
08030 pImplTypeInfo->lpVtbl->ReleaseTypeAttr(pImplTypeInfo,
08031 pImplTypeAttr);
08032 }
08033 }
08034 free(pstr);
08035 OLE_RELEASE(pImplTypeInfo);
08036 if (is_found || FAILED(hr))
08037 break;
08038 }
08039 }
08040
08041 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
08042 OLE_RELEASE(pTypeInfo);
08043 if (is_found || FAILED(hr))
08044 break;
08045 }
08046 OLE_RELEASE(pTypeLib);
08047 if(!is_found)
08048 return E_NOINTERFACE;
08049 return hr;
08050 }
08051
08052 static HRESULT
08053 find_coclass(
08054 ITypeInfo *pTypeInfo,
08055 TYPEATTR *pTypeAttr,
08056 ITypeInfo **pCOTypeInfo,
08057 TYPEATTR **pCOTypeAttr)
08058 {
08059 HRESULT hr = E_NOINTERFACE;
08060 ITypeLib *pTypeLib;
08061 int count;
08062 BOOL found = FALSE;
08063 ITypeInfo *pTypeInfo2;
08064 TYPEATTR *pTypeAttr2;
08065 int flags;
08066 int i,j;
08067 HREFTYPE href;
08068 ITypeInfo *pRefTypeInfo;
08069 TYPEATTR *pRefTypeAttr;
08070
08071 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, NULL);
08072 if (FAILED(hr)) {
08073 return hr;
08074 }
08075 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
08076 for (i = 0; i < count && !found; i++) {
08077 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo2);
08078 if (FAILED(hr))
08079 continue;
08080 hr = OLE_GET_TYPEATTR(pTypeInfo2, &pTypeAttr2);
08081 if (FAILED(hr)) {
08082 OLE_RELEASE(pTypeInfo2);
08083 continue;
08084 }
08085 if (pTypeAttr2->typekind != TKIND_COCLASS) {
08086 OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
08087 OLE_RELEASE(pTypeInfo2);
08088 continue;
08089 }
08090 for (j = 0; j < pTypeAttr2->cImplTypes && !found; j++) {
08091 hr = pTypeInfo2->lpVtbl->GetImplTypeFlags(pTypeInfo2, j, &flags);
08092 if (FAILED(hr))
08093 continue;
08094 if (!(flags & IMPLTYPEFLAG_FDEFAULT))
08095 continue;
08096 hr = pTypeInfo2->lpVtbl->GetRefTypeOfImplType(pTypeInfo2, j, &href);
08097 if (FAILED(hr))
08098 continue;
08099 hr = pTypeInfo2->lpVtbl->GetRefTypeInfo(pTypeInfo2, href, &pRefTypeInfo);
08100 if (FAILED(hr))
08101 continue;
08102 hr = OLE_GET_TYPEATTR(pRefTypeInfo, &pRefTypeAttr);
08103 if (FAILED(hr)) {
08104 OLE_RELEASE(pRefTypeInfo);
08105 continue;
08106 }
08107 if (IsEqualGUID(&(pTypeAttr->guid), &(pRefTypeAttr->guid))) {
08108 found = TRUE;
08109 }
08110 }
08111 if (!found) {
08112 OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
08113 OLE_RELEASE(pTypeInfo2);
08114 }
08115 }
08116 OLE_RELEASE(pTypeLib);
08117 if (found) {
08118 *pCOTypeInfo = pTypeInfo2;
08119 *pCOTypeAttr = pTypeAttr2;
08120 hr = S_OK;
08121 } else {
08122 hr = E_NOINTERFACE;
08123 }
08124 return hr;
08125 }
08126
08127 static HRESULT
08128 find_default_source_from_typeinfo(
08129 ITypeInfo *pTypeInfo,
08130 TYPEATTR *pTypeAttr,
08131 ITypeInfo **ppTypeInfo)
08132 {
08133 int i = 0;
08134 HRESULT hr = E_NOINTERFACE;
08135 int flags;
08136 HREFTYPE hRefType;
08137
08138 for (i = 0; i < pTypeAttr->cImplTypes; i++) {
08139 hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
08140 if (FAILED(hr))
08141 continue;
08142
08143
08144
08145
08146
08147 if ((flags & IMPLTYPEFLAG_FDEFAULT) &&
08148 (flags & IMPLTYPEFLAG_FSOURCE)) {
08149
08150 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
08151 i, &hRefType);
08152 if (FAILED(hr))
08153 continue;
08154 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
08155 hRefType, ppTypeInfo);
08156 if (SUCCEEDED(hr))
08157 break;
08158 }
08159 }
08160 return hr;
08161 }
08162
08163 static HRESULT
08164 find_default_source(VALUE ole, IID *piid, ITypeInfo **ppTypeInfo)
08165 {
08166 HRESULT hr;
08167 IProvideClassInfo2 *pProvideClassInfo2;
08168 IProvideClassInfo *pProvideClassInfo;
08169 void *p;
08170
08171 IDispatch *pDispatch;
08172 ITypeInfo *pTypeInfo;
08173 ITypeInfo *pTypeInfo2 = NULL;
08174 TYPEATTR *pTypeAttr;
08175 TYPEATTR *pTypeAttr2 = NULL;
08176
08177 struct oledata *pole;
08178
08179 OLEData_Get_Struct(ole, pole);
08180 pDispatch = pole->pDispatch;
08181 hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
08182 &IID_IProvideClassInfo2,
08183 &p);
08184 if (SUCCEEDED(hr)) {
08185 pProvideClassInfo2 = p;
08186 hr = pProvideClassInfo2->lpVtbl->GetGUID(pProvideClassInfo2,
08187 GUIDKIND_DEFAULT_SOURCE_DISP_IID,
08188 piid);
08189 OLE_RELEASE(pProvideClassInfo2);
08190 if (SUCCEEDED(hr)) {
08191 hr = find_iid(ole, NULL, piid, ppTypeInfo);
08192 }
08193 }
08194 if (SUCCEEDED(hr)) {
08195 return hr;
08196 }
08197 hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
08198 &IID_IProvideClassInfo,
08199 &p);
08200 if (SUCCEEDED(hr)) {
08201 pProvideClassInfo = p;
08202 hr = pProvideClassInfo->lpVtbl->GetClassInfo(pProvideClassInfo,
08203 &pTypeInfo);
08204 OLE_RELEASE(pProvideClassInfo);
08205 }
08206 if (FAILED(hr)) {
08207 hr = pDispatch->lpVtbl->GetTypeInfo(pDispatch, 0, cWIN32OLE_lcid, &pTypeInfo );
08208 }
08209 if (FAILED(hr))
08210 return hr;
08211 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
08212 if (FAILED(hr)) {
08213 OLE_RELEASE(pTypeInfo);
08214 return hr;
08215 }
08216
08217 *ppTypeInfo = 0;
08218 hr = find_default_source_from_typeinfo(pTypeInfo, pTypeAttr, ppTypeInfo);
08219 if (!*ppTypeInfo) {
08220 hr = find_coclass(pTypeInfo, pTypeAttr, &pTypeInfo2, &pTypeAttr2);
08221 if (SUCCEEDED(hr)) {
08222 hr = find_default_source_from_typeinfo(pTypeInfo2, pTypeAttr2, ppTypeInfo);
08223 OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
08224 OLE_RELEASE(pTypeInfo2);
08225 }
08226 }
08227 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
08228 OLE_RELEASE(pTypeInfo);
08229
08230 if (!*ppTypeInfo) {
08231 if (SUCCEEDED(hr))
08232 hr = E_UNEXPECTED;
08233 return hr;
08234 }
08235
08236
08237 hr = (*ppTypeInfo)->lpVtbl->GetTypeAttr(*ppTypeInfo, &pTypeAttr);
08238 if (SUCCEEDED(hr)) {
08239 *piid = pTypeAttr->guid;
08240 (*ppTypeInfo)->lpVtbl->ReleaseTypeAttr(*ppTypeInfo, pTypeAttr);
08241 }
08242 else
08243 OLE_RELEASE(*ppTypeInfo);
08244
08245 return hr;
08246
08247 }
08248
08249 static void
08250 ole_event_free(struct oleeventdata *poleev)
08251 {
08252 if (poleev->pConnectionPoint) {
08253 poleev->pConnectionPoint->lpVtbl->Unadvise(poleev->pConnectionPoint, poleev->dwCookie);
08254 OLE_RELEASE(poleev->pConnectionPoint);
08255 poleev->pConnectionPoint = NULL;
08256 }
08257 free(poleev);
08258 }
08259
08260 static VALUE
08261 fev_s_allocate(VALUE klass)
08262 {
08263 VALUE obj;
08264 struct oleeventdata *poleev;
08265 obj = Data_Make_Struct(klass,struct oleeventdata,0,ole_event_free,poleev);
08266 poleev->dwCookie = 0;
08267 poleev->pConnectionPoint = NULL;
08268 poleev->event_id = 0;
08269 return obj;
08270 }
08271
08272 static VALUE
08273 ev_advise(int argc, VALUE *argv, VALUE self)
08274 {
08275
08276 VALUE ole, itf;
08277 struct oledata *pole;
08278 char *pitf;
08279 HRESULT hr;
08280 IID iid;
08281 ITypeInfo *pTypeInfo = 0;
08282 IDispatch *pDispatch;
08283 IConnectionPointContainer *pContainer;
08284 IConnectionPoint *pConnectionPoint;
08285 IEVENTSINKOBJ *pIEV;
08286 DWORD dwCookie;
08287 struct oleeventdata *poleev;
08288 void *p;
08289
08290 rb_secure(4);
08291 rb_scan_args(argc, argv, "11", &ole, &itf);
08292
08293 if (!rb_obj_is_kind_of(ole, cWIN32OLE)) {
08294 rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE object");
08295 }
08296
08297 if(TYPE(itf) != T_NIL) {
08298 if (rb_safe_level() > 0 && OBJ_TAINTED(itf)) {
08299 rb_raise(rb_eSecurityError, "Insecure Event Creation - %s",
08300 StringValuePtr(itf));
08301 }
08302 SafeStringValue(itf);
08303 pitf = StringValuePtr(itf);
08304 hr = find_iid(ole, pitf, &iid, &pTypeInfo);
08305 }
08306 else {
08307 hr = find_default_source(ole, &iid, &pTypeInfo);
08308 }
08309 if (FAILED(hr)) {
08310 ole_raise(hr, rb_eRuntimeError, "interface not found");
08311 }
08312
08313 OLEData_Get_Struct(ole, pole);
08314 pDispatch = pole->pDispatch;
08315 hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
08316 &IID_IConnectionPointContainer,
08317 &p);
08318 if (FAILED(hr)) {
08319 OLE_RELEASE(pTypeInfo);
08320 ole_raise(hr, rb_eRuntimeError,
08321 "failed to query IConnectionPointContainer");
08322 }
08323 pContainer = p;
08324
08325 hr = pContainer->lpVtbl->FindConnectionPoint(pContainer,
08326 &iid,
08327 &pConnectionPoint);
08328 OLE_RELEASE(pContainer);
08329 if (FAILED(hr)) {
08330 OLE_RELEASE(pTypeInfo);
08331 ole_raise(hr, rb_eRuntimeError, "failed to query IConnectionPoint");
08332 }
08333 pIEV = EVENTSINK_Constructor();
08334 pIEV->m_iid = iid;
08335 hr = pConnectionPoint->lpVtbl->Advise(pConnectionPoint,
08336 (IUnknown*)pIEV,
08337 &dwCookie);
08338 if (FAILED(hr)) {
08339 ole_raise(hr, rb_eRuntimeError, "Advise Error");
08340 }
08341
08342 Data_Get_Struct(self, struct oleeventdata, poleev);
08343 pIEV->m_event_id
08344 = NUM2INT(evs_length());
08345 pIEV->pTypeInfo = pTypeInfo;
08346 poleev->dwCookie = dwCookie;
08347 poleev->pConnectionPoint = pConnectionPoint;
08348 poleev->event_id = pIEV->m_event_id;
08349
08350 return self;
08351 }
08352
08353
08354
08355
08356
08357
08358
08359
08360
08361
08362
08363 static VALUE
08364 fev_initialize(int argc, VALUE *argv, VALUE self)
08365 {
08366 ev_advise(argc, argv, self);
08367 evs_push(self);
08368 rb_ivar_set(self, id_events, rb_ary_new());
08369 fev_set_handler(self, Qnil);
08370 return self;
08371 }
08372
08373
08374
08375
08376
08377
08378
08379 static VALUE
08380 fev_s_msg_loop(VALUE klass)
08381 {
08382 ole_msg_loop();
08383 return Qnil;
08384 }
08385
08386
08387 static void
08388 add_event_call_back(VALUE obj, VALUE event, VALUE data)
08389 {
08390 VALUE events = rb_ivar_get(obj, id_events);
08391 if (NIL_P(events) || TYPE(events) != T_ARRAY) {
08392 events = rb_ary_new();
08393 rb_ivar_set(obj, id_events, events);
08394 }
08395 ole_delete_event(events, event);
08396 rb_ary_push(events, data);
08397 }
08398
08399 static VALUE
08400 ev_on_event(int argc, VALUE *argv, VALUE self, VALUE is_ary_arg)
08401 {
08402 struct oleeventdata *poleev;
08403 VALUE event, args, data;
08404 Data_Get_Struct(self, struct oleeventdata, poleev);
08405 if (poleev->pConnectionPoint == NULL) {
08406 rb_raise(eWIN32OLERuntimeError, "IConnectionPoint not found. You must call advise at first.");
08407 }
08408 rb_scan_args(argc, argv, "01*", &event, &args);
08409 if(!NIL_P(event)) {
08410 if(TYPE(event) != T_STRING && TYPE(event) != T_SYMBOL) {
08411 rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
08412 }
08413 if (TYPE(event) == T_SYMBOL) {
08414 event = rb_sym_to_s(event);
08415 }
08416 }
08417 data = rb_ary_new3(4, rb_block_proc(), event, args, is_ary_arg);
08418 add_event_call_back(self, event, data);
08419 return Qnil;
08420 }
08421
08422
08423
08424
08425
08426
08427
08428
08429
08430
08431
08432
08433
08434
08435
08436
08437
08438
08439
08440
08441
08442
08443
08444
08445
08446
08447
08448
08449
08450
08451 static VALUE
08452 fev_on_event(int argc, VALUE *argv, VALUE self)
08453 {
08454 return ev_on_event(argc, argv, self, Qfalse);
08455 }
08456
08457
08458
08459
08460
08461
08462
08463
08464
08465
08466
08467
08468
08469
08470
08471 static VALUE
08472 fev_on_event_with_outargs(int argc, VALUE *argv, VALUE self)
08473 {
08474 return ev_on_event(argc, argv, self, Qtrue);
08475 }
08476
08477
08478
08479
08480
08481
08482
08483
08484
08485
08486
08487
08488
08489
08490
08491
08492 static VALUE
08493 fev_off_event(int argc, VALUE *argv, VALUE self)
08494 {
08495 VALUE event = Qnil;
08496 VALUE events;
08497
08498 rb_secure(4);
08499 rb_scan_args(argc, argv, "01", &event);
08500 if(!NIL_P(event)) {
08501 if(TYPE(event) != T_STRING && TYPE(event) != T_SYMBOL) {
08502 rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
08503 }
08504 if (TYPE(event) == T_SYMBOL) {
08505 event = rb_sym_to_s(event);
08506 }
08507 }
08508 events = rb_ivar_get(self, id_events);
08509 if (NIL_P(events)) {
08510 return Qnil;
08511 }
08512 ole_delete_event(events, event);
08513 return Qnil;
08514 }
08515
08516
08517
08518
08519
08520
08521
08522
08523
08524
08525
08526
08527
08528
08529
08530
08531 static VALUE
08532 fev_unadvise(VALUE self)
08533 {
08534 struct oleeventdata *poleev;
08535 Data_Get_Struct(self, struct oleeventdata, poleev);
08536 if (poleev->pConnectionPoint) {
08537 ole_msg_loop();
08538 evs_delete(poleev->event_id);
08539 poleev->pConnectionPoint->lpVtbl->Unadvise(poleev->pConnectionPoint, poleev->dwCookie);
08540 OLE_RELEASE(poleev->pConnectionPoint);
08541 poleev->pConnectionPoint = NULL;
08542 }
08543 return Qnil;
08544 }
08545
08546 static VALUE
08547 evs_push(VALUE ev)
08548 {
08549 return rb_ary_push(ary_ole_event, ev);
08550 }
08551
08552 static VALUE
08553 evs_delete(long i)
08554 {
08555 rb_ary_store(ary_ole_event, i, Qnil);
08556 return Qnil;
08557 }
08558
08559 static VALUE
08560 evs_entry(long i)
08561 {
08562 return rb_ary_entry(ary_ole_event, i);
08563 }
08564
08565 static VALUE
08566 evs_length()
08567 {
08568 return rb_funcall(ary_ole_event, rb_intern("length"), 0);
08569 }
08570
08571
08572
08573
08574
08575
08576
08577
08578
08579
08580
08581
08582
08583
08584
08585
08586
08587
08588
08589
08590
08591
08592
08593
08594
08595
08596
08597
08598
08599
08600
08601
08602
08603
08604
08605
08606
08607
08608
08609
08610 static VALUE
08611 fev_set_handler(VALUE self, VALUE val)
08612 {
08613 return rb_ivar_set(self, rb_intern("handler"), val);
08614 }
08615
08616
08617
08618
08619
08620
08621
08622
08623 static VALUE
08624 fev_get_handler(VALUE self)
08625 {
08626 return rb_ivar_get(self, rb_intern("handler"));
08627 }
08628
08629 static void
08630 olevariant_free(struct olevariantdata *pvar)
08631 {
08632 VariantClear(&(pvar->realvar));
08633 VariantClear(&(pvar->var));
08634 free(pvar);
08635 }
08636
08637 static VALUE
08638 folevariant_s_allocate(VALUE klass)
08639 {
08640 struct olevariantdata *pvar;
08641 VALUE obj;
08642 ole_initialize();
08643 obj = Data_Make_Struct(klass,struct olevariantdata,0,olevariant_free,pvar);
08644 VariantInit(&(pvar->var));
08645 VariantInit(&(pvar->realvar));
08646 return obj;
08647 }
08648
08649
08650
08651
08652
08653
08654
08655
08656
08657
08658
08659
08660
08661
08662
08663
08664
08665 static VALUE
08666 folevariant_s_array(VALUE klass, VALUE elems, VALUE vvt)
08667 {
08668 VALUE obj = Qnil;
08669 VARTYPE vt;
08670 struct olevariantdata *pvar;
08671 SAFEARRAYBOUND *psab = NULL;
08672 SAFEARRAY *psa = NULL;
08673 UINT dim = 0;
08674 UINT i = 0;
08675
08676 ole_initialize();
08677
08678 vt = NUM2UINT(vvt);
08679 vt = (vt | VT_ARRAY);
08680 Check_Type(elems, T_ARRAY);
08681 obj = folevariant_s_allocate(klass);
08682
08683 Data_Get_Struct(obj, struct olevariantdata, pvar);
08684 dim = RARRAY_LEN(elems);
08685
08686 psab = ALLOC_N(SAFEARRAYBOUND, dim);
08687
08688 if(!psab) {
08689 rb_raise(rb_eRuntimeError, "memory allocation error");
08690 }
08691
08692 for (i = 0; i < dim; i++) {
08693 psab[i].cElements = FIX2INT(rb_ary_entry(elems, i));
08694 psab[i].lLbound = 0;
08695 }
08696
08697 psa = SafeArrayCreate((VARTYPE)(vt & VT_TYPEMASK), dim, psab);
08698 if (psa == NULL) {
08699 if (psab) free(psab);
08700 rb_raise(rb_eRuntimeError, "memory allocation error(SafeArrayCreate)");
08701 }
08702
08703 V_VT(&(pvar->var)) = vt;
08704 if (vt & VT_BYREF) {
08705 V_VT(&(pvar->realvar)) = (vt & ~VT_BYREF);
08706 V_ARRAY(&(pvar->realvar)) = psa;
08707 V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
08708 } else {
08709 V_ARRAY(&(pvar->var)) = psa;
08710 }
08711 if (psab) free(psab);
08712 return obj;
08713 }
08714
08715
08716
08717
08718
08719
08720
08721
08722
08723
08724
08725
08726
08727
08728
08729
08730
08731
08732
08733 static VALUE
08734 folevariant_initialize(VALUE self, VALUE args)
08735 {
08736 int len = 0;
08737 VARIANT var;
08738 VALUE val;
08739 VALUE vvt;
08740 VARTYPE vt;
08741 struct olevariantdata *pvar;
08742
08743 len = RARRAY_LEN(args);
08744 if (len < 1 || len > 3) {
08745 rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", len);
08746 }
08747 VariantInit(&var);
08748 val = rb_ary_entry(args, 0);
08749
08750 if(!rb_obj_is_kind_of(val, cWIN32OLE) &&
08751 !rb_obj_is_kind_of(val, cWIN32OLE_VARIANT) &&
08752 !rb_obj_is_kind_of(val, rb_cTime)) {
08753 switch (TYPE(val)) {
08754 case T_ARRAY:
08755 case T_STRING:
08756 case T_FIXNUM:
08757 case T_BIGNUM:
08758 case T_FLOAT:
08759 case T_TRUE:
08760 case T_FALSE:
08761 case T_NIL:
08762 break;
08763 default:
08764 rb_raise(rb_eTypeError, "can not convert WIN32OLE_VARIANT from type %s",
08765 rb_obj_classname(val));
08766 }
08767 }
08768
08769 Data_Get_Struct(self, struct olevariantdata, pvar);
08770 if (len == 1) {
08771 ole_val2variant(val, &(pvar->var));
08772 } else {
08773 vvt = rb_ary_entry(args, 1);
08774 vt = NUM2INT(vvt);
08775 ole_val2olevariantdata(val, vt, pvar);
08776 }
08777 vt = V_VT(&pvar->var);
08778 return self;
08779 }
08780
08781 static SAFEARRAY *
08782 get_locked_safe_array(VALUE val)
08783 {
08784 struct olevariantdata *pvar;
08785 SAFEARRAY *psa = NULL;
08786 HRESULT hr;
08787 Data_Get_Struct(val, struct olevariantdata, pvar);
08788 if (!(V_VT(&(pvar->var)) & VT_ARRAY)) {
08789 rb_raise(rb_eTypeError, "variant type is not VT_ARRAY.");
08790 }
08791 psa = V_ISBYREF(&(pvar->var)) ? *V_ARRAYREF(&(pvar->var)) : V_ARRAY(&(pvar->var));
08792 if (psa == NULL) {
08793 return psa;
08794 }
08795 hr = SafeArrayLock(psa);
08796 if (FAILED(hr)) {
08797 ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayLock");
08798 }
08799 return psa;
08800 }
08801
08802 static long *
08803 ary2safe_array_index(int ary_size, VALUE *ary, SAFEARRAY *psa)
08804 {
08805 long dim;
08806 long *pid;
08807 long i;
08808 dim = SafeArrayGetDim(psa);
08809 if (dim != ary_size) {
08810 rb_raise(rb_eArgError, "unmatch number of indices");
08811 }
08812 pid = ALLOC_N(long, dim);
08813 if (pid == NULL) {
08814 rb_raise(rb_eRuntimeError, "failed to allocate memory for indices");
08815 }
08816 for (i = 0; i < dim; i++) {
08817 pid[i] = NUM2INT(ary[i]);
08818 }
08819 return pid;
08820 }
08821
08822 static void
08823 unlock_safe_array(SAFEARRAY *psa)
08824 {
08825 HRESULT hr;
08826 hr = SafeArrayUnlock(psa);
08827 if (FAILED(hr)) {
08828 ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayUnlock");
08829 }
08830 }
08831
08832
08833
08834
08835
08836
08837
08838
08839
08840
08841
08842
08843
08844
08845
08846
08847
08848
08849
08850
08851
08852 static VALUE
08853 folevariant_ary_aref(int argc, VALUE *argv, VALUE self)
08854 {
08855 struct olevariantdata *pvar;
08856 SAFEARRAY *psa;
08857 VALUE val = Qnil;
08858 VARIANT variant;
08859 long *pid;
08860 HRESULT hr;
08861
08862 Data_Get_Struct(self, struct olevariantdata, pvar);
08863 if (!V_ISARRAY(&(pvar->var))) {
08864 rb_raise(eWIN32OLERuntimeError,
08865 "`[]' is not available for this variant type object");
08866 }
08867 psa = get_locked_safe_array(self);
08868 if (psa == NULL) {
08869 return val;
08870 }
08871
08872 pid = ary2safe_array_index(argc, argv, psa);
08873
08874 VariantInit(&variant);
08875 V_VT(&variant) = (V_VT(&(pvar->var)) & ~VT_ARRAY) | VT_BYREF;
08876 hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant));
08877 if (FAILED(hr)) {
08878 ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPtrOfIndex");
08879 }
08880 val = ole_variant2val(&variant);
08881
08882 unlock_safe_array(psa);
08883 if (pid) free(pid);
08884 return val;
08885 }
08886
08887 static VOID *
08888 val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt)
08889 {
08890 VOID *p = NULL;
08891 HRESULT hr = S_OK;
08892 ole_val2variant_ex(val, var, vt);
08893 if ((vt & ~VT_BYREF) == VT_VARIANT) {
08894 p = var;
08895 } else {
08896 if ( (vt & ~VT_BYREF) != V_VT(var)) {
08897 hr = VariantChangeTypeEx(var, var,
08898 cWIN32OLE_lcid, 0, (VARTYPE)(vt & ~VT_BYREF));
08899 if (FAILED(hr)) {
08900 ole_raise(hr, rb_eRuntimeError, "failed to change type");
08901 }
08902 }
08903 p = get_ptr_of_variant(var);
08904 }
08905 if (p == NULL) {
08906 rb_raise(rb_eRuntimeError, "failed to get pointer of variant");
08907 }
08908 return p;
08909 }
08910
08911
08912
08913
08914
08915
08916
08917
08918
08919
08920
08921
08922
08923
08924
08925
08926
08927
08928
08929
08930
08931
08932 static VALUE
08933 folevariant_ary_aset(int argc, VALUE *argv, VALUE self)
08934 {
08935 struct olevariantdata *pvar;
08936 SAFEARRAY *psa;
08937 VARIANT var;
08938 VARTYPE vt;
08939 long *pid;
08940 HRESULT hr;
08941 VOID *p = NULL;
08942
08943 Data_Get_Struct(self, struct olevariantdata, pvar);
08944 if (!V_ISARRAY(&(pvar->var))) {
08945 rb_raise(eWIN32OLERuntimeError,
08946 "`[]' is not available for this variant type object");
08947 }
08948 psa = get_locked_safe_array(self);
08949 if (psa == NULL) {
08950 rb_raise(rb_eRuntimeError, "failed to get SafeArray pointer");
08951 }
08952
08953 pid = ary2safe_array_index(argc-1, argv, psa);
08954
08955 VariantInit(&var);
08956 vt = (V_VT(&(pvar->var)) & ~VT_ARRAY);
08957 p = val2variant_ptr(argv[argc-1], &var, vt);
08958 if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) ||
08959 (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) {
08960 rb_raise(eWIN32OLERuntimeError, "argument does not have IDispatch or IUnknown Interface");
08961 }
08962 hr = SafeArrayPutElement(psa, pid, p);
08963 if (FAILED(hr)) {
08964 ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPutElement");
08965 }
08966
08967 unlock_safe_array(psa);
08968 if (pid) free(pid);
08969 return argv[argc-1];
08970 }
08971
08972
08973
08974
08975
08976
08977
08978
08979
08980
08981 static VALUE
08982 folevariant_value(VALUE self)
08983 {
08984 struct olevariantdata *pvar;
08985 VALUE val = Qnil;
08986 VARTYPE vt;
08987 int dim;
08988 SAFEARRAY *psa;
08989 Data_Get_Struct(self, struct olevariantdata, pvar);
08990
08991 val = ole_variant2val(&(pvar->var));
08992 vt = V_VT(&(pvar->var));
08993
08994 if ((vt & ~VT_BYREF) == (VT_UI1|VT_ARRAY)) {
08995 if (vt & VT_BYREF) {
08996 psa = *V_ARRAYREF(&(pvar->var));
08997 } else {
08998 psa = V_ARRAY(&(pvar->var));
08999 }
09000 if (!psa) {
09001 return val;
09002 }
09003 dim = SafeArrayGetDim(psa);
09004 if (dim == 1) {
09005 val = rb_funcall(val, rb_intern("pack"), 1, rb_str_new2("C*"));
09006 }
09007 }
09008 return val;
09009 }
09010
09011
09012
09013
09014
09015
09016
09017
09018
09019
09020 static VALUE
09021 folevariant_vartype(VALUE self)
09022 {
09023 struct olevariantdata *pvar;
09024 Data_Get_Struct(self, struct olevariantdata, pvar);
09025 return INT2FIX(V_VT(&pvar->var));
09026 }
09027
09028
09029
09030
09031
09032
09033
09034
09035
09036
09037
09038
09039
09040
09041
09042 static VALUE
09043 folevariant_set_value(VALUE self, VALUE val)
09044 {
09045 struct olevariantdata *pvar;
09046 VARTYPE vt;
09047 Data_Get_Struct(self, struct olevariantdata, pvar);
09048 vt = V_VT(&(pvar->var));
09049 if (V_ISARRAY(&(pvar->var)) && ((vt & ~VT_BYREF) != (VT_UI1|VT_ARRAY) || TYPE(val) != T_STRING)) {
09050 rb_raise(eWIN32OLERuntimeError,
09051 "`value=' is not available for this variant type object");
09052 }
09053 ole_val2olevariantdata(val, vt, pvar);
09054 return Qnil;
09055 }
09056
09057 static void
09058 init_enc2cp()
09059 {
09060 enc2cp_table = st_init_numtable();
09061 }
09062
09063 static void
09064 free_enc2cp()
09065 {
09066 st_free_table(enc2cp_table);
09067 }
09068
09069 void
09070 Init_win32ole()
09071 {
09072 ary_ole_event = rb_ary_new();
09073 rb_gc_register_mark_object(ary_ole_event);
09074 id_events = rb_intern("events");
09075
09076 com_vtbl.QueryInterface = QueryInterface;
09077 com_vtbl.AddRef = AddRef;
09078 com_vtbl.Release = Release;
09079 com_vtbl.GetTypeInfoCount = GetTypeInfoCount;
09080 com_vtbl.GetTypeInfo = GetTypeInfo;
09081 com_vtbl.GetIDsOfNames = GetIDsOfNames;
09082 com_vtbl.Invoke = Invoke;
09083
09084 message_filter.QueryInterface = mf_QueryInterface;
09085 message_filter.AddRef = mf_AddRef;
09086 message_filter.Release = mf_Release;
09087 message_filter.HandleInComingCall = mf_HandleInComingCall;
09088 message_filter.RetryRejectedCall = mf_RetryRejectedCall;
09089 message_filter.MessagePending = mf_MessagePending;
09090
09091 com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable());
09092 rb_gc_register_mark_object(com_hash);
09093
09094 cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject);
09095
09096 rb_define_alloc_func(cWIN32OLE, fole_s_allocate);
09097
09098 rb_define_method(cWIN32OLE, "initialize", fole_initialize, -1);
09099
09100 rb_define_singleton_method(cWIN32OLE, "connect", fole_s_connect, -1);
09101 rb_define_singleton_method(cWIN32OLE, "const_load", fole_s_const_load, -1);
09102
09103 rb_define_singleton_method(cWIN32OLE, "ole_free", fole_s_free, 1);
09104 rb_define_singleton_method(cWIN32OLE, "ole_reference_count", fole_s_reference_count, 1);
09105 rb_define_singleton_method(cWIN32OLE, "ole_show_help", fole_s_show_help, -1);
09106 rb_define_singleton_method(cWIN32OLE, "codepage", fole_s_get_code_page, 0);
09107 rb_define_singleton_method(cWIN32OLE, "codepage=", fole_s_set_code_page, 1);
09108 rb_define_singleton_method(cWIN32OLE, "locale", fole_s_get_locale, 0);
09109 rb_define_singleton_method(cWIN32OLE, "locale=", fole_s_set_locale, 1);
09110 rb_define_singleton_method(cWIN32OLE, "create_guid", fole_s_create_guid, 0);
09111 rb_define_singleton_method(cWIN32OLE, "ole_initialize", fole_s_ole_initialize, 0);
09112 rb_define_singleton_method(cWIN32OLE, "ole_uninitialize", fole_s_ole_uninitialize, 0);
09113
09114 rb_define_method(cWIN32OLE, "invoke", fole_invoke, -1);
09115 rb_define_method(cWIN32OLE, "[]", fole_getproperty_with_bracket, -1);
09116 rb_define_method(cWIN32OLE, "_invoke", fole_invoke2, 3);
09117 rb_define_method(cWIN32OLE, "_getproperty", fole_getproperty2, 3);
09118 rb_define_method(cWIN32OLE, "_setproperty", fole_setproperty2, 3);
09119
09120
09121 rb_define_method(cWIN32OLE, "[]=", fole_setproperty_with_bracket, -1);
09122
09123 rb_define_method(cWIN32OLE, "ole_free", fole_free, 0);
09124
09125 rb_define_method(cWIN32OLE, "each", fole_each, 0);
09126 rb_define_method(cWIN32OLE, "method_missing", fole_missing, -1);
09127
09128
09129 rb_define_method(cWIN32OLE, "setproperty", fole_setproperty, -1);
09130
09131 rb_define_method(cWIN32OLE, "ole_methods", fole_methods, 0);
09132 rb_define_method(cWIN32OLE, "ole_get_methods", fole_get_methods, 0);
09133 rb_define_method(cWIN32OLE, "ole_put_methods", fole_put_methods, 0);
09134 rb_define_method(cWIN32OLE, "ole_func_methods", fole_func_methods, 0);
09135
09136 rb_define_method(cWIN32OLE, "ole_method", fole_method_help, 1);
09137 rb_define_alias(cWIN32OLE, "ole_method_help", "ole_method");
09138 rb_define_method(cWIN32OLE, "ole_activex_initialize", fole_activex_initialize, 0);
09139 rb_define_method(cWIN32OLE, "ole_type", fole_type, 0);
09140 rb_define_alias(cWIN32OLE, "ole_obj_help", "ole_type");
09141 rb_define_method(cWIN32OLE, "ole_typelib", fole_typelib, 0);
09142 rb_define_method(cWIN32OLE, "ole_query_interface", fole_query_interface, 1);
09143 rb_define_method(cWIN32OLE, "ole_respond_to?", fole_respond_to, 1);
09144
09145 rb_define_const(cWIN32OLE, "VERSION", rb_str_new2(WIN32OLE_VERSION));
09146 rb_define_const(cWIN32OLE, "ARGV", rb_ary_new());
09147
09148 rb_define_const(cWIN32OLE, "CP_ACP", INT2FIX(CP_ACP));
09149 rb_define_const(cWIN32OLE, "CP_OEMCP", INT2FIX(CP_OEMCP));
09150 rb_define_const(cWIN32OLE, "CP_MACCP", INT2FIX(CP_MACCP));
09151 rb_define_const(cWIN32OLE, "CP_THREAD_ACP", INT2FIX(CP_THREAD_ACP));
09152 rb_define_const(cWIN32OLE, "CP_SYMBOL", INT2FIX(CP_SYMBOL));
09153 rb_define_const(cWIN32OLE, "CP_UTF7", INT2FIX(CP_UTF7));
09154 rb_define_const(cWIN32OLE, "CP_UTF8", INT2FIX(CP_UTF8));
09155
09156 rb_define_const(cWIN32OLE, "LOCALE_SYSTEM_DEFAULT", INT2FIX(LOCALE_SYSTEM_DEFAULT));
09157 rb_define_const(cWIN32OLE, "LOCALE_USER_DEFAULT", INT2FIX(LOCALE_USER_DEFAULT));
09158
09159 mWIN32OLE_VARIANT = rb_define_module_under(cWIN32OLE, "VARIANT");
09160 rb_define_const(mWIN32OLE_VARIANT, "VT_EMPTY", INT2FIX(VT_EMPTY));
09161 rb_define_const(mWIN32OLE_VARIANT, "VT_NULL", INT2FIX(VT_NULL));
09162 rb_define_const(mWIN32OLE_VARIANT, "VT_I2", INT2FIX(VT_I2));
09163 rb_define_const(mWIN32OLE_VARIANT, "VT_I4", INT2FIX(VT_I4));
09164 rb_define_const(mWIN32OLE_VARIANT, "VT_R4", INT2FIX(VT_R4));
09165 rb_define_const(mWIN32OLE_VARIANT, "VT_R8", INT2FIX(VT_R8));
09166 rb_define_const(mWIN32OLE_VARIANT, "VT_CY", INT2FIX(VT_CY));
09167 rb_define_const(mWIN32OLE_VARIANT, "VT_DATE", INT2FIX(VT_DATE));
09168 rb_define_const(mWIN32OLE_VARIANT, "VT_BSTR", INT2FIX(VT_BSTR));
09169 rb_define_const(mWIN32OLE_VARIANT, "VT_USERDEFINED", INT2FIX(VT_USERDEFINED));
09170 rb_define_const(mWIN32OLE_VARIANT, "VT_PTR", INT2FIX(VT_PTR));
09171 rb_define_const(mWIN32OLE_VARIANT, "VT_DISPATCH", INT2FIX(VT_DISPATCH));
09172 rb_define_const(mWIN32OLE_VARIANT, "VT_ERROR", INT2FIX(VT_ERROR));
09173 rb_define_const(mWIN32OLE_VARIANT, "VT_BOOL", INT2FIX(VT_BOOL));
09174 rb_define_const(mWIN32OLE_VARIANT, "VT_VARIANT", INT2FIX(VT_VARIANT));
09175 rb_define_const(mWIN32OLE_VARIANT, "VT_UNKNOWN", INT2FIX(VT_UNKNOWN));
09176 rb_define_const(mWIN32OLE_VARIANT, "VT_I1", INT2FIX(VT_I1));
09177 rb_define_const(mWIN32OLE_VARIANT, "VT_UI1", INT2FIX(VT_UI1));
09178 rb_define_const(mWIN32OLE_VARIANT, "VT_UI2", INT2FIX(VT_UI2));
09179 rb_define_const(mWIN32OLE_VARIANT, "VT_UI4", INT2FIX(VT_UI4));
09180 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
09181 rb_define_const(mWIN32OLE_VARIANT, "VT_I8", INT2FIX(VT_I8));
09182 rb_define_const(mWIN32OLE_VARIANT, "VT_UI8", INT2FIX(VT_UI8));
09183 #endif
09184 rb_define_const(mWIN32OLE_VARIANT, "VT_INT", INT2FIX(VT_INT));
09185 rb_define_const(mWIN32OLE_VARIANT, "VT_UINT", INT2FIX(VT_UINT));
09186 rb_define_const(mWIN32OLE_VARIANT, "VT_ARRAY", INT2FIX(VT_ARRAY));
09187 rb_define_const(mWIN32OLE_VARIANT, "VT_BYREF", INT2FIX(VT_BYREF));
09188
09189 cWIN32OLE_TYPELIB = rb_define_class("WIN32OLE_TYPELIB", rb_cObject);
09190 rb_define_singleton_method(cWIN32OLE_TYPELIB, "typelibs", foletypelib_s_typelibs, 0);
09191 rb_define_alloc_func(cWIN32OLE_TYPELIB, foletypelib_s_allocate);
09192 rb_define_method(cWIN32OLE_TYPELIB, "initialize", foletypelib_initialize, -2);
09193 rb_define_method(cWIN32OLE_TYPELIB, "guid", foletypelib_guid, 0);
09194 rb_define_method(cWIN32OLE_TYPELIB, "name", foletypelib_name, 0);
09195 rb_define_method(cWIN32OLE_TYPELIB, "version", foletypelib_version, 0);
09196 rb_define_method(cWIN32OLE_TYPELIB, "major_version", foletypelib_major_version, 0);
09197 rb_define_method(cWIN32OLE_TYPELIB, "minor_version", foletypelib_minor_version, 0);
09198 rb_define_method(cWIN32OLE_TYPELIB, "path", foletypelib_path, 0);
09199 rb_define_method(cWIN32OLE_TYPELIB, "ole_types", foletypelib_ole_types, 0);
09200 rb_define_alias(cWIN32OLE_TYPELIB, "ole_classes", "ole_types");
09201 rb_define_method(cWIN32OLE_TYPELIB, "visible?", foletypelib_visible, 0);
09202 rb_define_method(cWIN32OLE_TYPELIB, "library_name", foletypelib_library_name, 0);
09203 rb_define_alias(cWIN32OLE_TYPELIB, "to_s", "name");
09204 rb_define_method(cWIN32OLE_TYPELIB, "inspect", foletypelib_inspect, 0);
09205
09206 cWIN32OLE_TYPE = rb_define_class("WIN32OLE_TYPE", rb_cObject);
09207 rb_define_singleton_method(cWIN32OLE_TYPE, "ole_classes", foletype_s_ole_classes, 1);
09208 rb_define_singleton_method(cWIN32OLE_TYPE, "typelibs", foletype_s_typelibs, 0);
09209 rb_define_singleton_method(cWIN32OLE_TYPE, "progids", foletype_s_progids, 0);
09210 rb_define_alloc_func(cWIN32OLE_TYPE, foletype_s_allocate);
09211 rb_define_method(cWIN32OLE_TYPE, "initialize", foletype_initialize, 2);
09212 rb_define_method(cWIN32OLE_TYPE, "name", foletype_name, 0);
09213 rb_define_method(cWIN32OLE_TYPE, "ole_type", foletype_ole_type, 0);
09214 rb_define_method(cWIN32OLE_TYPE, "guid", foletype_guid, 0);
09215 rb_define_method(cWIN32OLE_TYPE, "progid", foletype_progid, 0);
09216 rb_define_method(cWIN32OLE_TYPE, "visible?", foletype_visible, 0);
09217 rb_define_alias(cWIN32OLE_TYPE, "to_s", "name");
09218 rb_define_method(cWIN32OLE_TYPE, "major_version", foletype_major_version, 0);
09219 rb_define_method(cWIN32OLE_TYPE, "minor_version", foletype_minor_version, 0);
09220 rb_define_method(cWIN32OLE_TYPE, "typekind", foletype_typekind, 0);
09221 rb_define_method(cWIN32OLE_TYPE, "helpstring", foletype_helpstring, 0);
09222 rb_define_method(cWIN32OLE_TYPE, "src_type", foletype_src_type, 0);
09223 rb_define_method(cWIN32OLE_TYPE, "helpfile", foletype_helpfile, 0);
09224 rb_define_method(cWIN32OLE_TYPE, "helpcontext", foletype_helpcontext, 0);
09225 rb_define_method(cWIN32OLE_TYPE, "variables", foletype_variables, 0);
09226 rb_define_method(cWIN32OLE_TYPE, "ole_methods", foletype_methods, 0);
09227 rb_define_method(cWIN32OLE_TYPE, "ole_typelib", foletype_ole_typelib, 0);
09228 rb_define_method(cWIN32OLE_TYPE, "implemented_ole_types", foletype_impl_ole_types, 0);
09229 rb_define_method(cWIN32OLE_TYPE, "source_ole_types", foletype_source_ole_types, 0);
09230 rb_define_method(cWIN32OLE_TYPE, "default_event_sources", foletype_default_event_sources, 0);
09231 rb_define_method(cWIN32OLE_TYPE, "default_ole_types", foletype_default_ole_types, 0);
09232 rb_define_method(cWIN32OLE_TYPE, "inspect", foletype_inspect, 0);
09233
09234 cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject);
09235 rb_define_method(cWIN32OLE_VARIABLE, "name", folevariable_name, 0);
09236 rb_define_method(cWIN32OLE_VARIABLE, "ole_type", folevariable_ole_type, 0);
09237 rb_define_method(cWIN32OLE_VARIABLE, "ole_type_detail", folevariable_ole_type_detail, 0);
09238 rb_define_method(cWIN32OLE_VARIABLE, "value", folevariable_value, 0);
09239 rb_define_method(cWIN32OLE_VARIABLE, "visible?", folevariable_visible, 0);
09240 rb_define_method(cWIN32OLE_VARIABLE, "variable_kind", folevariable_variable_kind, 0);
09241 rb_define_method(cWIN32OLE_VARIABLE, "varkind", folevariable_varkind, 0);
09242 rb_define_method(cWIN32OLE_VARIABLE, "inspect", folevariable_inspect, 0);
09243 rb_define_alias(cWIN32OLE_VARIABLE, "to_s", "name");
09244
09245 cWIN32OLE_METHOD = rb_define_class("WIN32OLE_METHOD", rb_cObject);
09246 rb_define_alloc_func(cWIN32OLE_METHOD, folemethod_s_allocate);
09247 rb_define_method(cWIN32OLE_METHOD, "initialize", folemethod_initialize, 2);
09248 rb_define_method(cWIN32OLE_METHOD, "name", folemethod_name, 0);
09249 rb_define_method(cWIN32OLE_METHOD, "return_type", folemethod_return_type, 0);
09250 rb_define_method(cWIN32OLE_METHOD, "return_vtype", folemethod_return_vtype, 0);
09251 rb_define_method(cWIN32OLE_METHOD, "return_type_detail", folemethod_return_type_detail, 0);
09252 rb_define_method(cWIN32OLE_METHOD, "invoke_kind", folemethod_invoke_kind, 0);
09253 rb_define_method(cWIN32OLE_METHOD, "invkind", folemethod_invkind, 0);
09254 rb_define_method(cWIN32OLE_METHOD, "visible?", folemethod_visible, 0);
09255 rb_define_method(cWIN32OLE_METHOD, "event?", folemethod_event, 0);
09256 rb_define_method(cWIN32OLE_METHOD, "event_interface", folemethod_event_interface, 0);
09257 rb_define_method(cWIN32OLE_METHOD, "helpstring", folemethod_helpstring, 0);
09258 rb_define_method(cWIN32OLE_METHOD, "helpfile", folemethod_helpfile, 0);
09259 rb_define_method(cWIN32OLE_METHOD, "helpcontext", folemethod_helpcontext, 0);
09260 rb_define_method(cWIN32OLE_METHOD, "dispid", folemethod_dispid, 0);
09261 rb_define_method(cWIN32OLE_METHOD, "offset_vtbl", folemethod_offset_vtbl, 0);
09262 rb_define_method(cWIN32OLE_METHOD, "size_params", folemethod_size_params, 0);
09263 rb_define_method(cWIN32OLE_METHOD, "size_opt_params", folemethod_size_opt_params, 0);
09264 rb_define_method(cWIN32OLE_METHOD, "params", folemethod_params, 0);
09265 rb_define_alias(cWIN32OLE_METHOD, "to_s", "name");
09266 rb_define_method(cWIN32OLE_METHOD, "inspect", folemethod_inspect, 0);
09267
09268 cWIN32OLE_PARAM = rb_define_class("WIN32OLE_PARAM", rb_cObject);
09269 rb_define_alloc_func(cWIN32OLE_PARAM, foleparam_s_allocate);
09270 rb_define_method(cWIN32OLE_PARAM, "initialize", foleparam_initialize, 2);
09271 rb_define_method(cWIN32OLE_PARAM, "name", foleparam_name, 0);
09272 rb_define_method(cWIN32OLE_PARAM, "ole_type", foleparam_ole_type, 0);
09273 rb_define_method(cWIN32OLE_PARAM, "ole_type_detail", foleparam_ole_type_detail, 0);
09274 rb_define_method(cWIN32OLE_PARAM, "input?", foleparam_input, 0);
09275 rb_define_method(cWIN32OLE_PARAM, "output?", foleparam_output, 0);
09276 rb_define_method(cWIN32OLE_PARAM, "optional?", foleparam_optional, 0);
09277 rb_define_method(cWIN32OLE_PARAM, "retval?", foleparam_retval, 0);
09278 rb_define_method(cWIN32OLE_PARAM, "default", foleparam_default, 0);
09279 rb_define_alias(cWIN32OLE_PARAM, "to_s", "name");
09280 rb_define_method(cWIN32OLE_PARAM, "inspect", foleparam_inspect, 0);
09281
09282 cWIN32OLE_EVENT = rb_define_class("WIN32OLE_EVENT", rb_cObject);
09283 rb_define_singleton_method(cWIN32OLE_EVENT, "message_loop", fev_s_msg_loop, 0);
09284 rb_define_alloc_func(cWIN32OLE_EVENT, fev_s_allocate);
09285 rb_define_method(cWIN32OLE_EVENT, "initialize", fev_initialize, -1);
09286 rb_define_method(cWIN32OLE_EVENT, "on_event", fev_on_event, -1);
09287 rb_define_method(cWIN32OLE_EVENT, "on_event_with_outargs", fev_on_event_with_outargs, -1);
09288 rb_define_method(cWIN32OLE_EVENT, "off_event", fev_off_event, -1);
09289 rb_define_method(cWIN32OLE_EVENT, "unadvise", fev_unadvise, 0);
09290 rb_define_method(cWIN32OLE_EVENT, "handler=", fev_set_handler, 1);
09291 rb_define_method(cWIN32OLE_EVENT, "handler", fev_get_handler, 0);
09292
09293 cWIN32OLE_VARIANT = rb_define_class("WIN32OLE_VARIANT", rb_cObject);
09294 rb_define_alloc_func(cWIN32OLE_VARIANT, folevariant_s_allocate);
09295 rb_define_singleton_method(cWIN32OLE_VARIANT, "array", folevariant_s_array, 2);
09296 rb_define_method(cWIN32OLE_VARIANT, "initialize", folevariant_initialize, -2);
09297 rb_define_method(cWIN32OLE_VARIANT, "value", folevariant_value, 0);
09298 rb_define_method(cWIN32OLE_VARIANT, "value=", folevariant_set_value, 1);
09299 rb_define_method(cWIN32OLE_VARIANT, "vartype", folevariant_vartype, 0);
09300 rb_define_method(cWIN32OLE_VARIANT, "[]", folevariant_ary_aref, -1);
09301 rb_define_method(cWIN32OLE_VARIANT, "[]=", folevariant_ary_aset, -1);
09302 rb_define_const(cWIN32OLE_VARIANT, "Empty", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_EMPTY)));
09303 rb_define_const(cWIN32OLE_VARIANT, "Null", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_NULL)));
09304 rb_define_const(cWIN32OLE_VARIANT, "Nothing", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_DISPATCH)));
09305
09306 eWIN32OLERuntimeError = rb_define_class("WIN32OLERuntimeError", rb_eRuntimeError);
09307
09308 init_enc2cp();
09309 atexit((void (*)(void))free_enc2cp);
09310 ole_init_cp();
09311 }
09312