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", 51936);
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 val = rb_str_new2(pbuf);
02342 }
02343 free(pbuf);
02344 }
02345 return val;
02346 }
02347
02348 static VALUE
02349 reg_get_val2(HKEY hkey, const char *subkey)
02350 {
02351 HKEY hsubkey;
02352 LONG err;
02353 VALUE val = Qnil;
02354 err = RegOpenKeyEx(hkey, subkey, 0, KEY_READ, &hsubkey);
02355 if (err == ERROR_SUCCESS) {
02356 val = reg_get_val(hsubkey, NULL);
02357 RegCloseKey(hsubkey);
02358 }
02359 if (val == Qnil) {
02360 val = reg_get_val(hkey, subkey);
02361 }
02362 return val;
02363 }
02364
02365 static VALUE
02366 reg_get_typelib_file_path(HKEY hkey)
02367 {
02368 VALUE path = Qnil;
02369 path = reg_get_val2(hkey, "win64");
02370 if (path != Qnil) {
02371 return path;
02372 }
02373 path = reg_get_val2(hkey, "win32");
02374 if (path != Qnil) {
02375 return path;
02376 }
02377 path = reg_get_val2(hkey, "win16");
02378 return path;
02379 }
02380
02381 static VALUE
02382 typelib_file_from_clsid(VALUE ole)
02383 {
02384 HKEY hroot, hclsid;
02385 LONG err;
02386 VALUE typelib;
02387 char path[MAX_PATH + 1];
02388
02389 err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hroot);
02390 if (err != ERROR_SUCCESS) {
02391 return Qnil;
02392 }
02393 err = reg_open_key(hroot, StringValuePtr(ole), &hclsid);
02394 if (err != ERROR_SUCCESS) {
02395 RegCloseKey(hroot);
02396 return Qnil;
02397 }
02398 typelib = reg_get_val2(hclsid, "InprocServer32");
02399 RegCloseKey(hroot);
02400 RegCloseKey(hclsid);
02401 if (typelib != Qnil) {
02402 ExpandEnvironmentStrings(StringValuePtr(typelib), path, sizeof(path));
02403 path[MAX_PATH] = '\0';
02404 typelib = rb_str_new2(path);
02405 }
02406 return typelib;
02407 }
02408
02409 static VALUE
02410 typelib_file_from_typelib(VALUE ole)
02411 {
02412 HKEY htypelib, hclsid, hversion, hlang;
02413 double fver;
02414 DWORD i, j, k;
02415 LONG err;
02416 BOOL found = FALSE;
02417 VALUE typelib;
02418 VALUE file = Qnil;
02419 VALUE clsid;
02420 VALUE ver;
02421 VALUE lang;
02422
02423 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
02424 if(err != ERROR_SUCCESS) {
02425 return Qnil;
02426 }
02427 for(i = 0; !found; i++) {
02428 clsid = reg_enum_key(htypelib, i);
02429 if (clsid == Qnil)
02430 break;
02431 err = reg_open_vkey(htypelib, clsid, &hclsid);
02432 if (err != ERROR_SUCCESS)
02433 continue;
02434 fver = 0;
02435 for(j = 0; !found; j++) {
02436 ver = reg_enum_key(hclsid, j);
02437 if (ver == Qnil)
02438 break;
02439 err = reg_open_vkey(hclsid, ver, &hversion);
02440 if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver)))
02441 continue;
02442 fver = atof(StringValuePtr(ver));
02443 typelib = reg_get_val(hversion, NULL);
02444 if (typelib == Qnil)
02445 continue;
02446 if (rb_str_cmp(typelib, ole) == 0) {
02447 for(k = 0; !found; k++) {
02448 lang = reg_enum_key(hversion, k);
02449 if (lang == Qnil)
02450 break;
02451 err = reg_open_vkey(hversion, lang, &hlang);
02452 if (err == ERROR_SUCCESS) {
02453 if ((file = reg_get_typelib_file_path(hlang)) != Qnil)
02454 found = TRUE;
02455 RegCloseKey(hlang);
02456 }
02457 }
02458 }
02459 RegCloseKey(hversion);
02460 }
02461 RegCloseKey(hclsid);
02462 }
02463 RegCloseKey(htypelib);
02464 return file;
02465 }
02466
02467 static VALUE
02468 typelib_file(VALUE ole)
02469 {
02470 VALUE file = typelib_file_from_clsid(ole);
02471 if (file != Qnil) {
02472 return file;
02473 }
02474 return typelib_file_from_typelib(ole);
02475 }
02476
02477 static void
02478 ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self)
02479 {
02480 unsigned int count;
02481 unsigned int index;
02482 int iVar;
02483 ITypeInfo *pTypeInfo;
02484 TYPEATTR *pTypeAttr;
02485 VARDESC *pVarDesc;
02486 HRESULT hr;
02487 unsigned int len;
02488 BSTR bstr;
02489 char *pName = NULL;
02490 VALUE val;
02491 VALUE constant;
02492 ID id;
02493 constant = rb_hash_new();
02494 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
02495 for (index = 0; index < count; index++) {
02496 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, index, &pTypeInfo);
02497 if (FAILED(hr))
02498 continue;
02499 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
02500 if(FAILED(hr)) {
02501 OLE_RELEASE(pTypeInfo);
02502 continue;
02503 }
02504 for(iVar = 0; iVar < pTypeAttr->cVars; iVar++) {
02505 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, iVar, &pVarDesc);
02506 if(FAILED(hr))
02507 continue;
02508 if(pVarDesc->varkind == VAR_CONST &&
02509 !(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
02510 VARFLAG_FRESTRICTED |
02511 VARFLAG_FNONBROWSABLE))) {
02512 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
02513 1, &len);
02514 if(FAILED(hr) || len == 0 || !bstr)
02515 continue;
02516 pName = ole_wc2mb(bstr);
02517 val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));
02518 *pName = toupper((int)*pName);
02519 id = rb_intern(pName);
02520 if (rb_is_const_id(id)) {
02521 rb_define_const(klass, pName, val);
02522 }
02523 else {
02524 rb_hash_aset(constant, rb_str_new2(pName), val);
02525 }
02526 SysFreeString(bstr);
02527 if(pName) {
02528 free(pName);
02529 pName = NULL;
02530 }
02531 }
02532 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
02533 }
02534 pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
02535 OLE_RELEASE(pTypeInfo);
02536 }
02537 rb_define_const(klass, "CONSTANTS", constant);
02538 }
02539
02540 static HRESULT
02541 clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid)
02542 {
02543 HKEY hlm;
02544 HKEY hpid;
02545 VALUE subkey;
02546 LONG err;
02547 char clsid[100];
02548 OLECHAR *pbuf;
02549 DWORD len;
02550 DWORD dwtype;
02551 HRESULT hr = S_OK;
02552 err = RegConnectRegistry(StringValuePtr(host), HKEY_LOCAL_MACHINE, &hlm);
02553 if (err != ERROR_SUCCESS)
02554 return HRESULT_FROM_WIN32(err);
02555 subkey = rb_str_new2("SOFTWARE\\Classes\\");
02556 rb_str_concat(subkey, com);
02557 rb_str_cat2(subkey, "\\CLSID");
02558 err = RegOpenKeyEx(hlm, StringValuePtr(subkey), 0, KEY_READ, &hpid);
02559 if (err != ERROR_SUCCESS)
02560 hr = HRESULT_FROM_WIN32(err);
02561 else {
02562 len = sizeof(clsid);
02563 err = RegQueryValueEx(hpid, (LPBYTE)"", NULL, &dwtype, clsid, &len);
02564 if (err == ERROR_SUCCESS && dwtype == REG_SZ) {
02565 pbuf = ole_mb2wc(clsid, -1);
02566 hr = CLSIDFromString(pbuf, pclsid);
02567 SysFreeString(pbuf);
02568 }
02569 else {
02570 hr = HRESULT_FROM_WIN32(err);
02571 }
02572 RegCloseKey(hpid);
02573 }
02574 RegCloseKey(hlm);
02575 return hr;
02576 }
02577
02578 static VALUE
02579 ole_create_dcom(int argc, VALUE *argv, VALUE self)
02580 {
02581 VALUE ole, host, others;
02582 HRESULT hr;
02583 CLSID clsid;
02584 OLECHAR *pbuf;
02585
02586 COSERVERINFO serverinfo;
02587 MULTI_QI multi_qi;
02588 DWORD clsctx = CLSCTX_REMOTE_SERVER;
02589
02590 if (!gole32)
02591 gole32 = LoadLibrary("OLE32");
02592 if (!gole32)
02593 rb_raise(rb_eRuntimeError, "failed to load OLE32");
02594 if (!gCoCreateInstanceEx)
02595 gCoCreateInstanceEx = (FNCOCREATEINSTANCEEX*)
02596 GetProcAddress(gole32, "CoCreateInstanceEx");
02597 if (!gCoCreateInstanceEx)
02598 rb_raise(rb_eRuntimeError, "CoCreateInstanceEx is not supported in this environment");
02599 rb_scan_args(argc, argv, "2*", &ole, &host, &others);
02600
02601 pbuf = ole_vstr2wc(ole);
02602 hr = CLSIDFromProgID(pbuf, &clsid);
02603 if (FAILED(hr))
02604 hr = clsid_from_remote(host, ole, &clsid);
02605 if (FAILED(hr))
02606 hr = CLSIDFromString(pbuf, &clsid);
02607 SysFreeString(pbuf);
02608 if (FAILED(hr))
02609 ole_raise(hr, eWIN32OLERuntimeError,
02610 "unknown OLE server: `%s'",
02611 StringValuePtr(ole));
02612 memset(&serverinfo, 0, sizeof(COSERVERINFO));
02613 serverinfo.pwszName = ole_vstr2wc(host);
02614 memset(&multi_qi, 0, sizeof(MULTI_QI));
02615 multi_qi.pIID = &IID_IDispatch;
02616 hr = gCoCreateInstanceEx(&clsid, NULL, clsctx, &serverinfo, 1, &multi_qi);
02617 SysFreeString(serverinfo.pwszName);
02618 if (FAILED(hr))
02619 ole_raise(hr, eWIN32OLERuntimeError,
02620 "failed to create DCOM server `%s' in `%s'",
02621 StringValuePtr(ole),
02622 StringValuePtr(host));
02623
02624 ole_set_member(self, (IDispatch*)multi_qi.pItf);
02625 return self;
02626 }
02627
02628 static VALUE
02629 ole_bind_obj(VALUE moniker, int argc, VALUE *argv, VALUE self)
02630 {
02631 IBindCtx *pBindCtx;
02632 IMoniker *pMoniker;
02633 IDispatch *pDispatch;
02634 void *p;
02635 HRESULT hr;
02636 OLECHAR *pbuf;
02637 ULONG eaten = 0;
02638
02639 ole_initialize();
02640
02641 hr = CreateBindCtx(0, &pBindCtx);
02642 if(FAILED(hr)) {
02643 ole_raise(hr, eWIN32OLERuntimeError,
02644 "failed to create bind context");
02645 }
02646
02647 pbuf = ole_vstr2wc(moniker);
02648 hr = MkParseDisplayName(pBindCtx, pbuf, &eaten, &pMoniker);
02649 SysFreeString(pbuf);
02650 if(FAILED(hr)) {
02651 OLE_RELEASE(pBindCtx);
02652 ole_raise(hr, eWIN32OLERuntimeError,
02653 "failed to parse display name of moniker `%s'",
02654 StringValuePtr(moniker));
02655 }
02656 hr = pMoniker->lpVtbl->BindToObject(pMoniker, pBindCtx, NULL,
02657 &IID_IDispatch, &p);
02658 pDispatch = p;
02659 OLE_RELEASE(pMoniker);
02660 OLE_RELEASE(pBindCtx);
02661
02662 if(FAILED(hr)) {
02663 ole_raise(hr, eWIN32OLERuntimeError,
02664 "failed to bind moniker `%s'",
02665 StringValuePtr(moniker));
02666 }
02667 return create_win32ole_object(self, pDispatch, argc, argv);
02668 }
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679 static VALUE
02680 fole_s_connect(int argc, VALUE *argv, VALUE self)
02681 {
02682 VALUE svr_name;
02683 VALUE others;
02684 HRESULT hr;
02685 CLSID clsid;
02686 OLECHAR *pBuf;
02687 IDispatch *pDispatch;
02688 void *p;
02689 IUnknown *pUnknown;
02690
02691 rb_secure(4);
02692
02693 ole_initialize();
02694
02695 rb_scan_args(argc, argv, "1*", &svr_name, &others);
02696 SafeStringValue(svr_name);
02697 if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
02698 rb_raise(rb_eSecurityError, "Insecure Object Connection - %s",
02699 StringValuePtr(svr_name));
02700 }
02701
02702
02703 pBuf = ole_vstr2wc(svr_name);
02704 hr = CLSIDFromProgID(pBuf, &clsid);
02705 if(FAILED(hr)) {
02706 hr = CLSIDFromString(pBuf, &clsid);
02707 }
02708 SysFreeString(pBuf);
02709 if(FAILED(hr)) {
02710 return ole_bind_obj(svr_name, argc, argv, self);
02711 }
02712
02713 hr = GetActiveObject(&clsid, 0, &pUnknown);
02714 if (FAILED(hr)) {
02715 ole_raise(hr, eWIN32OLERuntimeError,
02716 "OLE server `%s' not running", StringValuePtr(svr_name));
02717 }
02718 hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch, &p);
02719 pDispatch = p;
02720 if(FAILED(hr)) {
02721 OLE_RELEASE(pUnknown);
02722 ole_raise(hr, eWIN32OLERuntimeError,
02723 "failed to create WIN32OLE server `%s'",
02724 StringValuePtr(svr_name));
02725 }
02726
02727 OLE_RELEASE(pUnknown);
02728
02729 return create_win32ole_object(self, pDispatch, argc, argv);
02730 }
02731
02732
02733
02734
02735
02736
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 static VALUE
02762 fole_s_const_load(int argc, VALUE *argv, VALUE self)
02763 {
02764 VALUE ole;
02765 VALUE klass;
02766 struct oledata *pole;
02767 ITypeInfo *pTypeInfo;
02768 ITypeLib *pTypeLib;
02769 unsigned int index;
02770 HRESULT hr;
02771 OLECHAR *pBuf;
02772 VALUE file;
02773 LCID lcid = cWIN32OLE_lcid;
02774
02775 rb_secure(4);
02776 rb_scan_args(argc, argv, "11", &ole, &klass);
02777 if (TYPE(klass) != T_CLASS &&
02778 TYPE(klass) != T_MODULE &&
02779 TYPE(klass) != T_NIL) {
02780 rb_raise(rb_eTypeError, "2nd parameter must be Class or Module");
02781 }
02782 if (rb_obj_is_kind_of(ole, cWIN32OLE)) {
02783 OLEData_Get_Struct(ole, pole);
02784 hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
02785 0, lcid, &pTypeInfo);
02786 if(FAILED(hr)) {
02787 ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
02788 }
02789 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
02790 if(FAILED(hr)) {
02791 OLE_RELEASE(pTypeInfo);
02792 ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib");
02793 }
02794 OLE_RELEASE(pTypeInfo);
02795 if(TYPE(klass) != T_NIL) {
02796 ole_const_load(pTypeLib, klass, self);
02797 }
02798 else {
02799 ole_const_load(pTypeLib, cWIN32OLE, self);
02800 }
02801 OLE_RELEASE(pTypeLib);
02802 }
02803 else if(TYPE(ole) == T_STRING) {
02804 file = typelib_file(ole);
02805 if (file == Qnil) {
02806 file = ole;
02807 }
02808 pBuf = ole_vstr2wc(file);
02809 hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib);
02810 SysFreeString(pBuf);
02811 if (FAILED(hr))
02812 ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
02813 if(TYPE(klass) != T_NIL) {
02814 ole_const_load(pTypeLib, klass, self);
02815 }
02816 else {
02817 ole_const_load(pTypeLib, cWIN32OLE, self);
02818 }
02819 OLE_RELEASE(pTypeLib);
02820 }
02821 else {
02822 rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE instance");
02823 }
02824 return Qnil;
02825 }
02826
02827 static VALUE
02828 ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes)
02829 {
02830
02831 long count;
02832 int i;
02833 HRESULT hr;
02834 BSTR bstr;
02835 ITypeInfo *pTypeInfo;
02836 VALUE type;
02837
02838 rb_secure(4);
02839 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
02840 for (i = 0; i < count; i++) {
02841 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
02842 &bstr, NULL, NULL, NULL);
02843 if (FAILED(hr))
02844 continue;
02845
02846 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
02847 if (FAILED(hr))
02848 continue;
02849
02850 type = foletype_s_allocate(cWIN32OLE_TYPE);
02851 oletype_set_member(type, pTypeInfo, WC2VSTR(bstr));
02852
02853 rb_ary_push(classes, type);
02854 OLE_RELEASE(pTypeInfo);
02855 }
02856 return classes;
02857 }
02858
02859 static ULONG
02860 reference_count(struct oledata * pole)
02861 {
02862 ULONG n = 0;
02863 if(pole->pDispatch) {
02864 OLE_ADDREF(pole->pDispatch);
02865 n = OLE_RELEASE(pole->pDispatch);
02866 }
02867 return n;
02868 }
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878 static VALUE
02879 fole_s_reference_count(VALUE self, VALUE obj)
02880 {
02881 struct oledata * pole;
02882 OLEData_Get_Struct(obj, pole);
02883 return INT2NUM(reference_count(pole));
02884 }
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895 static VALUE
02896 fole_s_free(VALUE self, VALUE obj)
02897 {
02898 ULONG n = 0;
02899 struct oledata * pole;
02900 OLEData_Get_Struct(obj, pole);
02901 if(pole->pDispatch) {
02902 if (reference_count(pole) > 0) {
02903 n = OLE_RELEASE(pole->pDispatch);
02904 }
02905 }
02906 return INT2NUM(n);
02907 }
02908
02909 static HWND
02910 ole_show_help(VALUE helpfile, VALUE helpcontext)
02911 {
02912 FNHTMLHELP *pfnHtmlHelp;
02913 HWND hwnd = 0;
02914
02915 if(!ghhctrl)
02916 ghhctrl = LoadLibrary("HHCTRL.OCX");
02917 if (!ghhctrl)
02918 return hwnd;
02919 pfnHtmlHelp = (FNHTMLHELP*)GetProcAddress(ghhctrl, "HtmlHelpA");
02920 if (!pfnHtmlHelp)
02921 return hwnd;
02922 hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile),
02923 0x0f, NUM2INT(helpcontext));
02924 if (hwnd == 0)
02925 hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile),
02926 0, NUM2INT(helpcontext));
02927 return hwnd;
02928 }
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941 static VALUE
02942 fole_s_show_help(int argc, VALUE *argv, VALUE self)
02943 {
02944 VALUE target;
02945 VALUE helpcontext;
02946 VALUE helpfile;
02947 VALUE name;
02948 HWND hwnd;
02949 rb_scan_args(argc, argv, "11", &target, &helpcontext);
02950 if (rb_obj_is_kind_of(target, cWIN32OLE_TYPE) ||
02951 rb_obj_is_kind_of(target, cWIN32OLE_METHOD)) {
02952 helpfile = rb_funcall(target, rb_intern("helpfile"), 0);
02953 if(strlen(StringValuePtr(helpfile)) == 0) {
02954 name = rb_ivar_get(target, rb_intern("name"));
02955 rb_raise(rb_eRuntimeError, "no helpfile of `%s'",
02956 StringValuePtr(name));
02957 }
02958 helpcontext = rb_funcall(target, rb_intern("helpcontext"), 0);
02959 } else {
02960 helpfile = target;
02961 }
02962 if (TYPE(helpfile) != T_STRING) {
02963 rb_raise(rb_eTypeError, "1st parameter must be (String|WIN32OLE_TYPE|WIN32OLE_METHOD)");
02964 }
02965 hwnd = ole_show_help(helpfile, helpcontext);
02966 if(hwnd == 0) {
02967 rb_raise(rb_eRuntimeError, "failed to open help file `%s'",
02968 StringValuePtr(helpfile));
02969 }
02970 return Qnil;
02971 }
02972
02973
02974
02975
02976
02977
02978
02979
02980 static VALUE
02981 fole_s_get_code_page(VALUE self)
02982 {
02983 return INT2FIX(cWIN32OLE_cp);
02984 }
02985
02986 static BOOL CALLBACK
02987 installed_code_page_proc(LPTSTR str) {
02988 if (strtoul(str, NULL, 10) == g_cp_to_check) {
02989 g_cp_installed = TRUE;
02990 return FALSE;
02991 }
02992 return TRUE;
02993 }
02994
02995 static BOOL
02996 code_page_installed(UINT cp)
02997 {
02998 g_cp_installed = FALSE;
02999 g_cp_to_check = cp;
03000 EnumSystemCodePages(installed_code_page_proc, CP_INSTALLED);
03001 return g_cp_installed;
03002 }
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017 static VALUE
03018 fole_s_set_code_page(VALUE self, VALUE vcp)
03019 {
03020 UINT cp = FIX2INT(vcp);
03021 set_ole_codepage(cp);
03022
03023
03024
03025 return Qnil;
03026 }
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037 static VALUE
03038 fole_s_get_locale(VALUE self)
03039 {
03040 return INT2FIX(cWIN32OLE_lcid);
03041 }
03042
03043 static BOOL
03044 CALLBACK installed_lcid_proc(LPTSTR str)
03045 {
03046 if (strcmp(str, g_lcid_to_check) == 0) {
03047 g_lcid_installed = TRUE;
03048 return FALSE;
03049 }
03050 return TRUE;
03051 }
03052
03053 static BOOL
03054 lcid_installed(LCID lcid)
03055 {
03056 g_lcid_installed = FALSE;
03057 snprintf(g_lcid_to_check, sizeof(g_lcid_to_check), "%08lx", lcid);
03058 EnumSystemLocales(installed_lcid_proc, LCID_INSTALLED);
03059 return g_lcid_installed;
03060 }
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072 static VALUE
03073 fole_s_set_locale(VALUE self, VALUE vlcid)
03074 {
03075 LCID lcid = FIX2INT(vlcid);
03076 if (lcid_installed(lcid)) {
03077 cWIN32OLE_lcid = lcid;
03078 } else {
03079 switch (lcid) {
03080 case LOCALE_SYSTEM_DEFAULT:
03081 case LOCALE_USER_DEFAULT:
03082 cWIN32OLE_lcid = lcid;
03083 break;
03084 default:
03085 rb_raise(eWIN32OLERuntimeError, "not installed locale: %u", (unsigned int)lcid);
03086 }
03087 }
03088 return Qnil;
03089 }
03090
03091
03092
03093
03094
03095
03096
03097
03098 static VALUE
03099 fole_s_create_guid(VALUE self)
03100 {
03101 GUID guid;
03102 HRESULT hr;
03103 OLECHAR bstr[80];
03104 int len = 0;
03105 hr = CoCreateGuid(&guid);
03106 if (FAILED(hr)) {
03107 ole_raise(hr, eWIN32OLERuntimeError, "failed to create GUID");
03108 }
03109 len = StringFromGUID2(&guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
03110 if (len == 0) {
03111 rb_raise(rb_eRuntimeError, "failed to create GUID(buffer over)");
03112 }
03113 return ole_wc2vstr(bstr, FALSE);
03114 }
03115
03116
03117
03118
03119
03120
03121
03122 static void ole_pure_initialize()
03123 {
03124 HRESULT hr;
03125 hr = OleInitialize(NULL);
03126 if(FAILED(hr)) {
03127 ole_raise(hr, rb_eRuntimeError, "fail: OLE initialize");
03128 }
03129 }
03130
03131 static void ole_pure_uninitialize()
03132 {
03133 OleUninitialize();
03134 }
03135
03136
03137 static VALUE
03138 fole_s_ole_initialize(VALUE self)
03139 {
03140 ole_pure_initialize();
03141 return Qnil;
03142 }
03143
03144
03145 static VALUE
03146 fole_s_ole_uninitialize(VALUE self)
03147 {
03148 ole_pure_uninitialize();
03149 return Qnil;
03150 }
03151
03152
03153
03154
03155
03156
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 static VALUE
03206 fole_initialize(int argc, VALUE *argv, VALUE self)
03207 {
03208 VALUE svr_name;
03209 VALUE host;
03210 VALUE others;
03211 HRESULT hr;
03212 CLSID clsid;
03213 OLECHAR *pBuf;
03214 IDispatch *pDispatch;
03215 void *p;
03216 rb_secure(4);
03217 rb_call_super(0, 0);
03218 rb_scan_args(argc, argv, "11*", &svr_name, &host, &others);
03219
03220 SafeStringValue(svr_name);
03221 if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
03222 rb_raise(rb_eSecurityError, "Insecure Object Creation - %s",
03223 StringValuePtr(svr_name));
03224 }
03225 if (!NIL_P(host)) {
03226 SafeStringValue(host);
03227 if (rb_safe_level() > 0 && OBJ_TAINTED(host)) {
03228 rb_raise(rb_eSecurityError, "Insecure Object Creation - %s",
03229 StringValuePtr(svr_name));
03230 }
03231 return ole_create_dcom(argc, argv, self);
03232 }
03233
03234
03235 pBuf = ole_vstr2wc(svr_name);
03236 hr = CLSIDFromProgID(pBuf, &clsid);
03237 if(FAILED(hr)) {
03238 hr = CLSIDFromString(pBuf, &clsid);
03239 }
03240 SysFreeString(pBuf);
03241 if(FAILED(hr)) {
03242 ole_raise(hr, eWIN32OLERuntimeError,
03243 "unknown OLE server: `%s'",
03244 StringValuePtr(svr_name));
03245 }
03246
03247
03248 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
03249 &IID_IDispatch, &p);
03250 pDispatch = p;
03251 if(FAILED(hr)) {
03252 ole_raise(hr, eWIN32OLERuntimeError,
03253 "failed to create WIN32OLE object from `%s'",
03254 StringValuePtr(svr_name));
03255 }
03256
03257 ole_set_member(self, pDispatch);
03258 return self;
03259 }
03260
03261 static VALUE
03262 hash2named_arg(VALUE pair, struct oleparam* pOp)
03263 {
03264 unsigned int index, i;
03265 VALUE key, value;
03266 index = pOp->dp.cNamedArgs;
03267
03268
03269
03270
03271 key = rb_ary_entry(pair, 0);
03272 if(TYPE(key) != T_STRING && TYPE(key) != T_SYMBOL) {
03273
03274 for(i = 1; i < index + 1; i++) {
03275 SysFreeString(pOp->pNamedArgs[i]);
03276 }
03277
03278 for(i = 0; i < index; i++ ) {
03279 VariantClear(&(pOp->dp.rgvarg[i]));
03280 }
03281
03282 rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
03283 }
03284 if (TYPE(key) == T_SYMBOL) {
03285 key = rb_sym_to_s(key);
03286 }
03287
03288
03289 pOp->pNamedArgs[index + 1] = ole_vstr2wc(key);
03290
03291 value = rb_ary_entry(pair, 1);
03292 VariantInit(&(pOp->dp.rgvarg[index]));
03293 ole_val2variant(value, &(pOp->dp.rgvarg[index]));
03294
03295 pOp->dp.cNamedArgs += 1;
03296 return Qnil;
03297 }
03298
03299 static VALUE
03300 set_argv(VARIANTARG* realargs, unsigned int beg, unsigned int end)
03301 {
03302 VALUE argv = rb_const_get(cWIN32OLE, rb_intern("ARGV"));
03303
03304 Check_Type(argv, T_ARRAY);
03305 rb_ary_clear(argv);
03306 while (end-- > beg) {
03307 rb_ary_push(argv, ole_variant2val(&realargs[end]));
03308 VariantClear(&realargs[end]);
03309 }
03310 return argv;
03311 }
03312
03313 static VALUE
03314 ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket)
03315 {
03316 LCID lcid = cWIN32OLE_lcid;
03317 struct oledata *pole;
03318 HRESULT hr;
03319 VALUE cmd;
03320 VALUE paramS;
03321 VALUE param;
03322 VALUE obj;
03323 VALUE v;
03324
03325 BSTR wcmdname;
03326
03327 DISPID DispID;
03328 DISPID* pDispID;
03329 EXCEPINFO excepinfo;
03330 VARIANT result;
03331 VARIANTARG* realargs = NULL;
03332 unsigned int argErr = 0;
03333 unsigned int i;
03334 unsigned int cNamedArgs;
03335 int n;
03336 struct oleparam op;
03337 struct olevariantdata *pvar;
03338 memset(&excepinfo, 0, sizeof(EXCEPINFO));
03339
03340 VariantInit(&result);
03341
03342 op.dp.rgvarg = NULL;
03343 op.dp.rgdispidNamedArgs = NULL;
03344 op.dp.cNamedArgs = 0;
03345 op.dp.cArgs = 0;
03346
03347 rb_scan_args(argc, argv, "1*", &cmd, ¶mS);
03348 if(TYPE(cmd) != T_STRING && TYPE(cmd) != T_SYMBOL && !is_bracket) {
03349 rb_raise(rb_eTypeError, "method is wrong type (expected String or Symbol)");
03350 }
03351 if (TYPE(cmd) == T_SYMBOL) {
03352 cmd = rb_sym_to_s(cmd);
03353 }
03354 OLEData_Get_Struct(self, pole);
03355 if(!pole->pDispatch) {
03356 rb_raise(rb_eRuntimeError, "failed to get dispatch interface");
03357 }
03358 if (is_bracket) {
03359 DispID = DISPID_VALUE;
03360 argc += 1;
03361 rb_ary_unshift(paramS, cmd);
03362 } else {
03363 wcmdname = ole_vstr2wc(cmd);
03364 hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
03365 &wcmdname, 1, lcid, &DispID);
03366 SysFreeString(wcmdname);
03367 if(FAILED(hr)) {
03368 ole_raise(hr, rb_eNoMethodError,
03369 "unknown property or method: `%s'",
03370 StringValuePtr(cmd));
03371 }
03372 }
03373
03374
03375 param = rb_ary_entry(paramS, argc-2);
03376
03377 op.dp.cNamedArgs = 0;
03378
03379
03380 if(TYPE(param) == T_HASH) {
03381
03382
03383
03384 cNamedArgs = NUM2INT(rb_funcall(param, rb_intern("length"), 0));
03385 op.dp.cArgs = cNamedArgs + argc - 2;
03386 op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);
03387 op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs);
03388 rb_block_call(param, rb_intern("each"), 0, 0, hash2named_arg, (VALUE)&op);
03389
03390 pDispID = ALLOCA_N(DISPID, cNamedArgs + 1);
03391 op.pNamedArgs[0] = ole_vstr2wc(cmd);
03392 hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch,
03393 &IID_NULL,
03394 op.pNamedArgs,
03395 op.dp.cNamedArgs + 1,
03396 lcid, pDispID);
03397 for(i = 0; i < op.dp.cNamedArgs + 1; i++) {
03398 SysFreeString(op.pNamedArgs[i]);
03399 op.pNamedArgs[i] = NULL;
03400 }
03401 if(FAILED(hr)) {
03402
03403 for(i = 0; i < op.dp.cArgs; i++ ) {
03404 VariantClear(&op.dp.rgvarg[i]);
03405 }
03406 ole_raise(hr, eWIN32OLERuntimeError,
03407 "failed to get named argument info: `%s'",
03408 StringValuePtr(cmd));
03409 }
03410 op.dp.rgdispidNamedArgs = &(pDispID[1]);
03411 }
03412 else {
03413 cNamedArgs = 0;
03414 op.dp.cArgs = argc - 1;
03415 op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);
03416 if (op.dp.cArgs > 0) {
03417 op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs);
03418 }
03419 }
03420
03421
03422
03423 if(op.dp.cArgs > cNamedArgs) {
03424 realargs = ALLOCA_N(VARIANTARG, op.dp.cArgs-cNamedArgs+1);
03425 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
03426 n = op.dp.cArgs - i + cNamedArgs - 1;
03427 VariantInit(&realargs[n]);
03428 VariantInit(&op.dp.rgvarg[n]);
03429 param = rb_ary_entry(paramS, i-cNamedArgs);
03430 if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) {
03431 Data_Get_Struct(param, struct olevariantdata, pvar);
03432 VariantCopy(&op.dp.rgvarg[n], &(pvar->var));
03433 } else {
03434 ole_val2variant(param, &realargs[n]);
03435 V_VT(&op.dp.rgvarg[n]) = VT_VARIANT | VT_BYREF;
03436 V_VARIANTREF(&op.dp.rgvarg[n]) = &realargs[n];
03437 }
03438 }
03439 }
03440
03441 if (wFlags & DISPATCH_PROPERTYPUT) {
03442 if (op.dp.cArgs == 0)
03443 ole_raise(ResultFromScode(E_INVALIDARG), eWIN32OLERuntimeError, "argument error");
03444
03445 op.dp.cNamedArgs = 1;
03446 op.dp.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 );
03447 op.dp.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
03448 }
03449
03450 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
03451 &IID_NULL, lcid, wFlags, &op.dp,
03452 &result, &excepinfo, &argErr);
03453
03454 if (FAILED(hr)) {
03455
03456 if(op.dp.cArgs >= cNamedArgs) {
03457 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
03458 n = op.dp.cArgs - i + cNamedArgs - 1;
03459 param = rb_ary_entry(paramS, i-cNamedArgs);
03460 ole_val2variant(param, &op.dp.rgvarg[n]);
03461 }
03462 if (hr == DISP_E_EXCEPTION) {
03463 ole_freeexceptinfo(&excepinfo);
03464 }
03465 memset(&excepinfo, 0, sizeof(EXCEPINFO));
03466 VariantInit(&result);
03467 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
03468 &IID_NULL, lcid, wFlags,
03469 &op.dp, &result,
03470 &excepinfo, &argErr);
03471
03472
03473
03474
03475
03476 if ((hr == DISP_E_EXCEPTION || hr == DISP_E_MEMBERNOTFOUND) && DispID > 0x8000) {
03477 if (hr == DISP_E_EXCEPTION) {
03478 ole_freeexceptinfo(&excepinfo);
03479 }
03480 memset(&excepinfo, 0, sizeof(EXCEPINFO));
03481 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
03482 &IID_NULL, lcid, wFlags,
03483 &op.dp, NULL,
03484 &excepinfo, &argErr);
03485
03486 }
03487 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
03488 n = op.dp.cArgs - i + cNamedArgs - 1;
03489 VariantClear(&op.dp.rgvarg[n]);
03490 }
03491 }
03492
03493 if (FAILED(hr)) {
03494
03495 if (op.dp.cArgs > cNamedArgs) {
03496 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
03497 n = op.dp.cArgs - i + cNamedArgs - 1;
03498 param = rb_ary_entry(paramS, i-cNamedArgs);
03499 ole_val2variant2(param, &op.dp.rgvarg[n]);
03500 }
03501 if (hr == DISP_E_EXCEPTION) {
03502 ole_freeexceptinfo(&excepinfo);
03503 }
03504 memset(&excepinfo, 0, sizeof(EXCEPINFO));
03505 VariantInit(&result);
03506 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
03507 &IID_NULL, lcid, wFlags,
03508 &op.dp, &result,
03509 &excepinfo, &argErr);
03510 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
03511 n = op.dp.cArgs - i + cNamedArgs - 1;
03512 VariantClear(&op.dp.rgvarg[n]);
03513 }
03514 }
03515 }
03516
03517 }
03518
03519 if(op.dp.cArgs > cNamedArgs) {
03520 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
03521 n = op.dp.cArgs - i + cNamedArgs - 1;
03522 param = rb_ary_entry(paramS, i-cNamedArgs);
03523 if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) {
03524 ole_val2variant(param, &realargs[n]);
03525 }
03526 }
03527 set_argv(realargs, cNamedArgs, op.dp.cArgs);
03528 }
03529 else {
03530 for(i = 0; i < op.dp.cArgs; i++) {
03531 VariantClear(&op.dp.rgvarg[i]);
03532 }
03533 }
03534
03535 if (FAILED(hr)) {
03536 v = ole_excepinfo2msg(&excepinfo);
03537 ole_raise(hr, eWIN32OLERuntimeError, "(in OLE method `%s': )%s",
03538 StringValuePtr(cmd),
03539 StringValuePtr(v));
03540 }
03541 obj = ole_variant2val(&result);
03542 VariantClear(&result);
03543 return obj;
03544 }
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559 static VALUE
03560 fole_invoke(int argc, VALUE *argv, VALUE self)
03561 {
03562 return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
03563 }
03564
03565 static VALUE
03566 ole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types, USHORT dispkind)
03567 {
03568 HRESULT hr;
03569 struct oledata *pole;
03570 unsigned int argErr = 0;
03571 EXCEPINFO excepinfo;
03572 VARIANT result;
03573 DISPPARAMS dispParams;
03574 VARIANTARG* realargs = NULL;
03575 int i, j;
03576 VALUE obj = Qnil;
03577 VALUE tp, param;
03578 VALUE v;
03579 VARTYPE vt;
03580
03581 Check_Type(args, T_ARRAY);
03582 Check_Type(types, T_ARRAY);
03583
03584 memset(&excepinfo, 0, sizeof(EXCEPINFO));
03585 memset(&dispParams, 0, sizeof(DISPPARAMS));
03586 VariantInit(&result);
03587 OLEData_Get_Struct(self, pole);
03588
03589 dispParams.cArgs = RARRAY_LEN(args);
03590 dispParams.rgvarg = ALLOCA_N(VARIANTARG, dispParams.cArgs);
03591 realargs = ALLOCA_N(VARIANTARG, dispParams.cArgs);
03592 for (i = 0, j = dispParams.cArgs - 1; i < (int)dispParams.cArgs; i++, j--)
03593 {
03594 VariantInit(&realargs[i]);
03595 VariantInit(&dispParams.rgvarg[i]);
03596 tp = rb_ary_entry(types, j);
03597 vt = (VARTYPE)FIX2INT(tp);
03598 V_VT(&dispParams.rgvarg[i]) = vt;
03599 param = rb_ary_entry(args, j);
03600 if (param == Qnil)
03601 {
03602
03603 V_VT(&dispParams.rgvarg[i]) = V_VT(&realargs[i]) = VT_ERROR;
03604 V_ERROR(&dispParams.rgvarg[i]) = V_ERROR(&realargs[i]) = DISP_E_PARAMNOTFOUND;
03605 }
03606 else
03607 {
03608 if (vt & VT_ARRAY)
03609 {
03610 int ent;
03611 LPBYTE pb;
03612 short* ps;
03613 LPLONG pl;
03614 VARIANT* pv;
03615 CY *py;
03616 VARTYPE v;
03617 SAFEARRAYBOUND rgsabound[1];
03618 Check_Type(param, T_ARRAY);
03619 rgsabound[0].lLbound = 0;
03620 rgsabound[0].cElements = RARRAY_LEN(param);
03621 v = vt & ~(VT_ARRAY | VT_BYREF);
03622 V_ARRAY(&realargs[i]) = SafeArrayCreate(v, 1, rgsabound);
03623 V_VT(&realargs[i]) = VT_ARRAY | v;
03624 SafeArrayLock(V_ARRAY(&realargs[i]));
03625 pb = V_ARRAY(&realargs[i])->pvData;
03626 ps = V_ARRAY(&realargs[i])->pvData;
03627 pl = V_ARRAY(&realargs[i])->pvData;
03628 py = V_ARRAY(&realargs[i])->pvData;
03629 pv = V_ARRAY(&realargs[i])->pvData;
03630 for (ent = 0; ent < (int)rgsabound[0].cElements; ent++)
03631 {
03632 VARIANT velem;
03633 VALUE elem = rb_ary_entry(param, ent);
03634 ole_val2variant(elem, &velem);
03635 if (v != VT_VARIANT)
03636 {
03637 VariantChangeTypeEx(&velem, &velem,
03638 cWIN32OLE_lcid, 0, v);
03639 }
03640 switch (v)
03641 {
03642
03643 case VT_VARIANT:
03644 *pv++ = velem;
03645 break;
03646
03647 case VT_R8:
03648 case VT_CY:
03649 case VT_DATE:
03650 *py++ = V_CY(&velem);
03651 break;
03652
03653 case VT_BOOL:
03654 case VT_I2:
03655 case VT_UI2:
03656 *ps++ = V_I2(&velem);
03657 break;
03658
03659 case VT_UI1:
03660 case VT_I1:
03661 *pb++ = V_UI1(&velem);
03662 break;
03663
03664 default:
03665 *pl++ = V_I4(&velem);
03666 break;
03667 }
03668 }
03669 SafeArrayUnlock(V_ARRAY(&realargs[i]));
03670 }
03671 else
03672 {
03673 ole_val2variant(param, &realargs[i]);
03674 if ((vt & (~VT_BYREF)) != VT_VARIANT)
03675 {
03676 hr = VariantChangeTypeEx(&realargs[i], &realargs[i],
03677 cWIN32OLE_lcid, 0,
03678 (VARTYPE)(vt & (~VT_BYREF)));
03679 if (hr != S_OK)
03680 {
03681 rb_raise(rb_eTypeError, "not valid value");
03682 }
03683 }
03684 }
03685 if ((vt & VT_BYREF) || vt == VT_VARIANT)
03686 {
03687 if (vt == VT_VARIANT)
03688 V_VT(&dispParams.rgvarg[i]) = VT_VARIANT | VT_BYREF;
03689 switch (vt & (~VT_BYREF))
03690 {
03691
03692 case VT_VARIANT:
03693 V_VARIANTREF(&dispParams.rgvarg[i]) = &realargs[i];
03694 break;
03695
03696 case VT_R8:
03697 case VT_CY:
03698 case VT_DATE:
03699 V_CYREF(&dispParams.rgvarg[i]) = &V_CY(&realargs[i]);
03700 break;
03701
03702 case VT_BOOL:
03703 case VT_I2:
03704 case VT_UI2:
03705 V_I2REF(&dispParams.rgvarg[i]) = &V_I2(&realargs[i]);
03706 break;
03707
03708 case VT_UI1:
03709 case VT_I1:
03710 V_UI1REF(&dispParams.rgvarg[i]) = &V_UI1(&realargs[i]);
03711 break;
03712
03713 default:
03714 V_I4REF(&dispParams.rgvarg[i]) = &V_I4(&realargs[i]);
03715 break;
03716 }
03717 }
03718 else
03719 {
03720
03721 V_CY(&dispParams.rgvarg[i]) = V_CY(&realargs[i]);
03722 }
03723 }
03724 }
03725
03726 if (dispkind & DISPATCH_PROPERTYPUT) {
03727 dispParams.cNamedArgs = 1;
03728 dispParams.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 );
03729 dispParams.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
03730 }
03731
03732 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, NUM2INT(dispid),
03733 &IID_NULL, cWIN32OLE_lcid,
03734 dispkind,
03735 &dispParams, &result,
03736 &excepinfo, &argErr);
03737
03738 if (FAILED(hr)) {
03739 v = ole_excepinfo2msg(&excepinfo);
03740 ole_raise(hr, eWIN32OLERuntimeError, "(in OLE method `<dispatch id:%d>': )%s",
03741 NUM2INT(dispid),
03742 StringValuePtr(v));
03743 }
03744
03745
03746 if(dispParams.cArgs > 0) {
03747 set_argv(realargs, 0, dispParams.cArgs);
03748 }
03749
03750 obj = ole_variant2val(&result);
03751 VariantClear(&result);
03752 return obj;
03753 }
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767 static VALUE
03768 fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types)
03769 {
03770 return ole_invoke2(self, dispid, args, types, DISPATCH_METHOD);
03771 }
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785 static VALUE
03786 fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
03787 {
03788 return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYGET);
03789 }
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803 static VALUE
03804 fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
03805 {
03806 return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYPUT);
03807 }
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827 static VALUE
03828 fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self)
03829 {
03830 return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, TRUE);
03831 }
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846 static VALUE
03847 fole_setproperty(int argc, VALUE *argv, VALUE self)
03848 {
03849 return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, FALSE);
03850 }
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868 static VALUE
03869 fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self)
03870 {
03871 return ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET, TRUE);
03872 }
03873
03874 static VALUE
03875 ole_propertyput(VALUE self, VALUE property, VALUE value)
03876 {
03877 struct oledata *pole;
03878 unsigned argErr;
03879 unsigned int index;
03880 HRESULT hr;
03881 EXCEPINFO excepinfo;
03882 DISPID dispID = DISPID_VALUE;
03883 DISPID dispIDParam = DISPID_PROPERTYPUT;
03884 USHORT wFlags = DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF;
03885 DISPPARAMS dispParams;
03886 VARIANTARG propertyValue[2];
03887 OLECHAR* pBuf[1];
03888 VALUE v;
03889 LCID lcid = cWIN32OLE_lcid;
03890 dispParams.rgdispidNamedArgs = &dispIDParam;
03891 dispParams.rgvarg = propertyValue;
03892 dispParams.cNamedArgs = 1;
03893 dispParams.cArgs = 1;
03894
03895 VariantInit(&propertyValue[0]);
03896 VariantInit(&propertyValue[1]);
03897 memset(&excepinfo, 0, sizeof(excepinfo));
03898
03899 OLEData_Get_Struct(self, pole);
03900
03901
03902 pBuf[0] = ole_vstr2wc(property);
03903 hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch, &IID_NULL,
03904 pBuf, 1, lcid, &dispID);
03905 SysFreeString(pBuf[0]);
03906 pBuf[0] = NULL;
03907
03908 if(FAILED(hr)) {
03909 ole_raise(hr, eWIN32OLERuntimeError,
03910 "unknown property or method: `%s'",
03911 StringValuePtr(property));
03912 }
03913
03914 ole_val2variant(value, &propertyValue[0]);
03915 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, dispID, &IID_NULL,
03916 lcid, wFlags, &dispParams,
03917 NULL, &excepinfo, &argErr);
03918
03919 for(index = 0; index < dispParams.cArgs; ++index) {
03920 VariantClear(&propertyValue[index]);
03921 }
03922 if (FAILED(hr)) {
03923 v = ole_excepinfo2msg(&excepinfo);
03924 ole_raise(hr, eWIN32OLERuntimeError, "(in setting property `%s': )%s",
03925 StringValuePtr(property),
03926 StringValuePtr(v));
03927 }
03928 return Qnil;
03929 }
03930
03931
03932
03933
03934
03935
03936
03937
03938
03939
03940 static VALUE
03941 fole_free(VALUE self)
03942 {
03943 struct oledata *pole;
03944 rb_secure(4);
03945 OLEData_Get_Struct(self, pole);
03946 OLE_FREE(pole->pDispatch);
03947 pole->pDispatch = NULL;
03948 return Qnil;
03949 }
03950
03951 static VALUE
03952 ole_each_sub(VALUE pEnumV)
03953 {
03954 VARIANT variant;
03955 VALUE obj = Qnil;
03956 IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
03957 VariantInit(&variant);
03958 while(pEnum->lpVtbl->Next(pEnum, 1, &variant, NULL) == S_OK) {
03959 obj = ole_variant2val(&variant);
03960 VariantClear(&variant);
03961 VariantInit(&variant);
03962 rb_yield(obj);
03963 }
03964 return Qnil;
03965 }
03966
03967 static VALUE
03968 ole_ienum_free(VALUE pEnumV)
03969 {
03970 IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
03971 OLE_RELEASE(pEnum);
03972 return Qnil;
03973 }
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988
03989 static VALUE
03990 fole_each(VALUE self)
03991 {
03992 LCID lcid = cWIN32OLE_lcid;
03993
03994 struct oledata *pole;
03995
03996 unsigned int argErr;
03997 EXCEPINFO excepinfo;
03998 DISPPARAMS dispParams;
03999 VARIANT result;
04000 HRESULT hr;
04001 IEnumVARIANT *pEnum = NULL;
04002 void *p;
04003
04004 RETURN_ENUMERATOR(self, 0, 0);
04005
04006 VariantInit(&result);
04007 dispParams.rgvarg = NULL;
04008 dispParams.rgdispidNamedArgs = NULL;
04009 dispParams.cNamedArgs = 0;
04010 dispParams.cArgs = 0;
04011 memset(&excepinfo, 0, sizeof(excepinfo));
04012
04013 OLEData_Get_Struct(self, pole);
04014 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DISPID_NEWENUM,
04015 &IID_NULL, lcid,
04016 DISPATCH_METHOD | DISPATCH_PROPERTYGET,
04017 &dispParams, &result,
04018 &excepinfo, &argErr);
04019
04020 if (FAILED(hr)) {
04021 VariantClear(&result);
04022 ole_raise(hr, eWIN32OLERuntimeError, "failed to get IEnum Interface");
04023 }
04024
04025 if (V_VT(&result) == VT_UNKNOWN) {
04026 hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result),
04027 &IID_IEnumVARIANT,
04028 &p);
04029 pEnum = p;
04030 } else if (V_VT(&result) == VT_DISPATCH) {
04031 hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result),
04032 &IID_IEnumVARIANT,
04033 &p);
04034 pEnum = p;
04035 }
04036 if (FAILED(hr) || !pEnum) {
04037 VariantClear(&result);
04038 ole_raise(hr, rb_eRuntimeError, "failed to get IEnum Interface");
04039 }
04040
04041 VariantClear(&result);
04042 rb_ensure(ole_each_sub, (VALUE)pEnum, ole_ienum_free, (VALUE)pEnum);
04043 return Qnil;
04044 }
04045
04046
04047
04048
04049
04050
04051
04052 static VALUE
04053 fole_missing(int argc, VALUE *argv, VALUE self)
04054 {
04055 ID id;
04056 const char* mname;
04057 int n;
04058 id = rb_to_id(argv[0]);
04059 mname = rb_id2name(id);
04060 if(!mname) {
04061 rb_raise(rb_eRuntimeError, "fail: unknown method or property");
04062 }
04063 n = strlen(mname);
04064 if(mname[n-1] == '=') {
04065 argv[0] = rb_enc_str_new(mname, n-1, cWIN32OLE_enc);
04066
04067 return ole_propertyput(self, argv[0], argv[1]);
04068 }
04069 else {
04070 argv[0] = rb_enc_str_new(mname, n, cWIN32OLE_enc);
04071 return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
04072 }
04073 }
04074
04075 static VALUE
04076 ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name)
04077 {
04078 HRESULT hr;
04079 TYPEATTR *pTypeAttr;
04080 BSTR bstr;
04081 FUNCDESC *pFuncDesc;
04082 WORD i;
04083 VALUE fname;
04084 VALUE method = Qnil;
04085 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
04086 if (FAILED(hr)) {
04087 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
04088 }
04089 for(i = 0; i < pTypeAttr->cFuncs && method == Qnil; i++) {
04090 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
04091 if (FAILED(hr))
04092 continue;
04093
04094 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
04095 &bstr, NULL, NULL, NULL);
04096 if (FAILED(hr)) {
04097 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
04098 continue;
04099 }
04100 fname = WC2VSTR(bstr);
04101 if (strcasecmp(StringValuePtr(name), StringValuePtr(fname)) == 0) {
04102 olemethod_set_member(self, pTypeInfo, pOwnerTypeInfo, i, fname);
04103 method = self;
04104 }
04105 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
04106 pFuncDesc=NULL;
04107 }
04108 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
04109 return method;
04110 }
04111
04112 static VALUE
04113 olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
04114 {
04115 HRESULT hr;
04116 TYPEATTR *pTypeAttr;
04117 WORD i;
04118 HREFTYPE href;
04119 ITypeInfo *pRefTypeInfo;
04120 VALUE method = Qnil;
04121 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
04122 if (FAILED(hr)) {
04123 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
04124 }
04125 method = ole_method_sub(self, 0, pTypeInfo, name);
04126 if (method != Qnil) {
04127 return method;
04128 }
04129 for(i=0; i < pTypeAttr->cImplTypes && method == Qnil; i++){
04130 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
04131 if(FAILED(hr))
04132 continue;
04133 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
04134 if (FAILED(hr))
04135 continue;
04136 method = ole_method_sub(self, pTypeInfo, pRefTypeInfo, name);
04137 OLE_RELEASE(pRefTypeInfo);
04138 }
04139 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
04140 return method;
04141 }
04142
04143 static VALUE
04144 ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask)
04145 {
04146 HRESULT hr;
04147 TYPEATTR *pTypeAttr;
04148 BSTR bstr;
04149 char *pstr;
04150 FUNCDESC *pFuncDesc;
04151 VALUE method;
04152 WORD i;
04153 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
04154 if (FAILED(hr)) {
04155 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
04156 }
04157 for(i = 0; i < pTypeAttr->cFuncs; i++) {
04158 pstr = NULL;
04159 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
04160 if (FAILED(hr))
04161 continue;
04162
04163 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
04164 &bstr, NULL, NULL, NULL);
04165 if (FAILED(hr)) {
04166 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
04167 continue;
04168 }
04169 if(pFuncDesc->invkind & mask) {
04170 method = folemethod_s_allocate(cWIN32OLE_METHOD);
04171 olemethod_set_member(method, pTypeInfo, pOwnerTypeInfo,
04172 i, WC2VSTR(bstr));
04173 rb_ary_push(methods, method);
04174 }
04175 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
04176 pFuncDesc=NULL;
04177 }
04178 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
04179
04180 return methods;
04181 }
04182
04183 static VALUE
04184 ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask)
04185 {
04186 HRESULT hr;
04187 TYPEATTR *pTypeAttr;
04188 WORD i;
04189 HREFTYPE href;
04190 ITypeInfo *pRefTypeInfo;
04191 VALUE methods = rb_ary_new();
04192 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
04193 if (FAILED(hr)) {
04194 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
04195 }
04196
04197 ole_methods_sub(0, pTypeInfo, methods, mask);
04198 for(i=0; i < pTypeAttr->cImplTypes; i++){
04199 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
04200 if(FAILED(hr))
04201 continue;
04202 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
04203 if (FAILED(hr))
04204 continue;
04205 ole_methods_sub(pTypeInfo, pRefTypeInfo, methods, mask);
04206 OLE_RELEASE(pRefTypeInfo);
04207 }
04208 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
04209 return methods;
04210 }
04211
04212 static HRESULT
04213 typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti)
04214 {
04215 ITypeInfo *pTypeInfo;
04216 ITypeLib *pTypeLib;
04217 BSTR bstr;
04218 VALUE type;
04219 UINT i;
04220 UINT count;
04221 LCID lcid = cWIN32OLE_lcid;
04222 HRESULT hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
04223 0, lcid, &pTypeInfo);
04224 if(FAILED(hr)) {
04225 ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
04226 }
04227 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo,
04228 -1,
04229 &bstr,
04230 NULL, NULL, NULL);
04231 type = WC2VSTR(bstr);
04232 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
04233 OLE_RELEASE(pTypeInfo);
04234 if (FAILED(hr)) {
04235 ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib");
04236 }
04237 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
04238 for (i = 0; i < count; i++) {
04239 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
04240 &bstr, NULL, NULL, NULL);
04241 if (SUCCEEDED(hr) && rb_str_cmp(WC2VSTR(bstr), type) == 0) {
04242 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
04243 if (SUCCEEDED(hr)) {
04244 *ppti = pTypeInfo;
04245 break;
04246 }
04247 }
04248 }
04249 OLE_RELEASE(pTypeLib);
04250 return hr;
04251 }
04252
04253 static VALUE
04254 ole_methods(VALUE self, int mask)
04255 {
04256 ITypeInfo *pTypeInfo;
04257 HRESULT hr;
04258 VALUE methods;
04259 struct oledata *pole;
04260
04261 OLEData_Get_Struct(self, pole);
04262 methods = rb_ary_new();
04263
04264 hr = typeinfo_from_ole(pole, &pTypeInfo);
04265 if(FAILED(hr))
04266 return methods;
04267 rb_ary_concat(methods, ole_methods_from_typeinfo(pTypeInfo, mask));
04268 OLE_RELEASE(pTypeInfo);
04269 return methods;
04270 }
04271
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283 static VALUE
04284 fole_methods(VALUE self)
04285 {
04286 return ole_methods( self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
04287 }
04288
04289
04290
04291
04292
04293
04294
04295
04296
04297
04298
04299 static VALUE
04300 fole_get_methods(VALUE self)
04301 {
04302 return ole_methods( self, INVOKE_PROPERTYGET);
04303 }
04304
04305
04306
04307
04308
04309
04310
04311
04312
04313
04314
04315 static VALUE
04316 fole_put_methods(VALUE self)
04317 {
04318 return ole_methods( self, INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF);
04319 }
04320
04321
04322
04323
04324
04325
04326
04327
04328
04329
04330
04331
04332 static VALUE
04333 fole_func_methods(VALUE self)
04334 {
04335 return ole_methods( self, INVOKE_FUNC);
04336 }
04337
04338 static VALUE
04339 ole_type_from_itypeinfo(ITypeInfo *pTypeInfo)
04340 {
04341 ITypeLib *pTypeLib;
04342 VALUE type = Qnil;
04343 HRESULT hr;
04344 unsigned int index;
04345 BSTR bstr;
04346
04347 hr = pTypeInfo->lpVtbl->GetContainingTypeLib( pTypeInfo, &pTypeLib, &index );
04348 if(FAILED(hr)) {
04349 return Qnil;
04350 }
04351 hr = pTypeLib->lpVtbl->GetDocumentation( pTypeLib, index,
04352 &bstr, NULL, NULL, NULL);
04353 OLE_RELEASE(pTypeLib);
04354 if (FAILED(hr)) {
04355 return Qnil;
04356 }
04357 type = foletype_s_allocate(cWIN32OLE_TYPE);
04358 oletype_set_member(type, pTypeInfo, WC2VSTR(bstr));
04359 return type;
04360 }
04361
04362
04363
04364
04365
04366
04367
04368
04369
04370
04371 static VALUE
04372 fole_type(VALUE self)
04373 {
04374 ITypeInfo *pTypeInfo;
04375 HRESULT hr;
04376 struct oledata *pole;
04377 LCID lcid = cWIN32OLE_lcid;
04378 VALUE type = Qnil;
04379
04380 OLEData_Get_Struct(self, pole);
04381
04382 hr = pole->pDispatch->lpVtbl->GetTypeInfo( pole->pDispatch, 0, lcid, &pTypeInfo );
04383 if(FAILED(hr)) {
04384 ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
04385 }
04386 type = ole_type_from_itypeinfo(pTypeInfo);
04387 OLE_RELEASE(pTypeInfo);
04388 if (type == Qnil) {
04389 rb_raise(rb_eRuntimeError, "failed to create WIN32OLE_TYPE obj from ITypeInfo");
04390 }
04391 return type;
04392 }
04393
04394 static VALUE
04395 ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo)
04396 {
04397 HRESULT hr;
04398 ITypeLib *pTypeLib;
04399 unsigned int index;
04400 VALUE retval = Qnil;
04401
04402 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
04403 if(FAILED(hr)) {
04404 return Qnil;
04405 }
04406 retval = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("allocate"), 0);
04407 oletypelib_set_member(retval, pTypeLib);
04408 return retval;
04409 }
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422 static VALUE
04423 fole_typelib(VALUE self)
04424 {
04425 struct oledata *pole;
04426 HRESULT hr;
04427 ITypeInfo *pTypeInfo;
04428 LCID lcid = cWIN32OLE_lcid;
04429 VALUE vtlib = Qnil;
04430
04431 OLEData_Get_Struct(self, pole);
04432 hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
04433 0, lcid, &pTypeInfo);
04434 if(FAILED(hr)) {
04435 ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
04436 }
04437 vtlib = ole_typelib_from_itypeinfo(pTypeInfo);
04438 OLE_RELEASE(pTypeInfo);
04439 if (vtlib == Qnil) {
04440 rb_raise(rb_eRuntimeError, "failed to get type library info.");
04441 }
04442 return vtlib;
04443 }
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455 static VALUE
04456 fole_query_interface(VALUE self, VALUE str_iid)
04457 {
04458 HRESULT hr;
04459 OLECHAR *pBuf;
04460 IID iid;
04461 struct oledata *pole;
04462 IDispatch *pDispatch;
04463 void *p;
04464
04465 pBuf = ole_vstr2wc(str_iid);
04466 hr = CLSIDFromString(pBuf, &iid);
04467 SysFreeString(pBuf);
04468 if(FAILED(hr)) {
04469 ole_raise(hr, eWIN32OLERuntimeError,
04470 "invalid iid: `%s'",
04471 StringValuePtr(str_iid));
04472 }
04473
04474 OLEData_Get_Struct(self, pole);
04475 if(!pole->pDispatch) {
04476 rb_raise(rb_eRuntimeError, "failed to get dispatch interface");
04477 }
04478
04479 hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &iid,
04480 &p);
04481 if(FAILED(hr)) {
04482 ole_raise(hr, eWIN32OLERuntimeError,
04483 "failed to get interface `%s'",
04484 StringValuePtr(str_iid));
04485 }
04486
04487 pDispatch = p;
04488 return create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
04489 }
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500 static VALUE
04501 fole_respond_to(VALUE self, VALUE method)
04502 {
04503 struct oledata *pole;
04504 BSTR wcmdname;
04505 DISPID DispID;
04506 HRESULT hr;
04507 rb_secure(4);
04508 if(TYPE(method) != T_STRING && TYPE(method) != T_SYMBOL) {
04509 rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
04510 }
04511 if (TYPE(method) == T_SYMBOL) {
04512 method = rb_sym_to_s(method);
04513 }
04514 OLEData_Get_Struct(self, pole);
04515 wcmdname = ole_vstr2wc(method);
04516 hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
04517 &wcmdname, 1, cWIN32OLE_lcid, &DispID);
04518 SysFreeString(wcmdname);
04519 return SUCCEEDED(hr) ? Qtrue : Qfalse;
04520 }
04521
04522 static HRESULT
04523 ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile)
04524 {
04525 HRESULT hr;
04526 ITypeLib *pTypeLib;
04527 UINT i;
04528
04529 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
04530 if (FAILED(hr)) {
04531 return hr;
04532 }
04533
04534 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
04535 name, helpstr,
04536 helpcontext, helpfile);
04537 if (FAILED(hr)) {
04538 OLE_RELEASE(pTypeLib);
04539 return hr;
04540 }
04541 OLE_RELEASE(pTypeLib);
04542 return hr;
04543 }
04544
04545 static VALUE
04546 ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
04547 {
04548 HRESULT hr;
04549 BSTR bstr;
04550 ITypeInfo *pRefTypeInfo;
04551 VALUE type = Qnil;
04552
04553 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
04554 V_UNION1(pTypeDesc, hreftype),
04555 &pRefTypeInfo);
04556 if(FAILED(hr))
04557 return Qnil;
04558 hr = ole_docinfo_from_type(pRefTypeInfo, &bstr, NULL, NULL, NULL);
04559 if(FAILED(hr)) {
04560 OLE_RELEASE(pRefTypeInfo);
04561 return Qnil;
04562 }
04563 OLE_RELEASE(pRefTypeInfo);
04564 type = WC2VSTR(bstr);
04565 if(typedetails != Qnil)
04566 rb_ary_push(typedetails, type);
04567 return type;
04568 }
04569
04570 static VALUE
04571 ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
04572 {
04573 TYPEDESC *p = pTypeDesc;
04574 VALUE type = rb_str_new2("");
04575
04576 if (p->vt == VT_PTR || p->vt == VT_SAFEARRAY) {
04577 p = V_UNION1(p, lptdesc);
04578 type = ole_typedesc2val(pTypeInfo, p, typedetails);
04579 }
04580 return type;
04581 }
04582
04583 static VALUE
04584 ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
04585 {
04586 VALUE str;
04587 VALUE typestr = Qnil;
04588 switch(pTypeDesc->vt) {
04589 case VT_I2:
04590 typestr = rb_str_new2("I2");
04591 break;
04592 case VT_I4:
04593 typestr = rb_str_new2("I4");
04594 break;
04595 case VT_R4:
04596 typestr = rb_str_new2("R4");
04597 break;
04598 case VT_R8:
04599 typestr = rb_str_new2("R8");
04600 break;
04601 case VT_CY:
04602 typestr = rb_str_new2("CY");
04603 break;
04604 case VT_DATE:
04605 typestr = rb_str_new2("DATE");
04606 break;
04607 case VT_BSTR:
04608 typestr = rb_str_new2("BSTR");
04609 break;
04610 case VT_BOOL:
04611 typestr = rb_str_new2("BOOL");
04612 break;
04613 case VT_VARIANT:
04614 typestr = rb_str_new2("VARIANT");
04615 break;
04616 case VT_DECIMAL:
04617 typestr = rb_str_new2("DECIMAL");
04618 break;
04619 case VT_I1:
04620 typestr = rb_str_new2("I1");
04621 break;
04622 case VT_UI1:
04623 typestr = rb_str_new2("UI1");
04624 break;
04625 case VT_UI2:
04626 typestr = rb_str_new2("UI2");
04627 break;
04628 case VT_UI4:
04629 typestr = rb_str_new2("UI4");
04630 break;
04631 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
04632 case VT_I8:
04633 typestr = rb_str_new2("I8");
04634 break;
04635 case VT_UI8:
04636 typestr = rb_str_new2("UI8");
04637 break;
04638 #endif
04639 case VT_INT:
04640 typestr = rb_str_new2("INT");
04641 break;
04642 case VT_UINT:
04643 typestr = rb_str_new2("UINT");
04644 break;
04645 case VT_VOID:
04646 typestr = rb_str_new2("VOID");
04647 break;
04648 case VT_HRESULT:
04649 typestr = rb_str_new2("HRESULT");
04650 break;
04651 case VT_PTR:
04652 typestr = rb_str_new2("PTR");
04653 if(typedetails != Qnil)
04654 rb_ary_push(typedetails, typestr);
04655 return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
04656 case VT_SAFEARRAY:
04657 typestr = rb_str_new2("SAFEARRAY");
04658 if(typedetails != Qnil)
04659 rb_ary_push(typedetails, typestr);
04660 return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
04661 case VT_CARRAY:
04662 typestr = rb_str_new2("CARRAY");
04663 break;
04664 case VT_USERDEFINED:
04665 typestr = rb_str_new2("USERDEFINED");
04666 if (typedetails != Qnil)
04667 rb_ary_push(typedetails, typestr);
04668 str = ole_usertype2val(pTypeInfo, pTypeDesc, typedetails);
04669 if (str != Qnil) {
04670 return str;
04671 }
04672 return typestr;
04673 case VT_UNKNOWN:
04674 typestr = rb_str_new2("UNKNOWN");
04675 break;
04676 case VT_DISPATCH:
04677 typestr = rb_str_new2("DISPATCH");
04678 break;
04679 case VT_ERROR:
04680 typestr = rb_str_new2("ERROR");
04681 break;
04682 case VT_LPWSTR:
04683 typestr = rb_str_new2("LPWSTR");
04684 break;
04685 case VT_LPSTR:
04686 typestr = rb_str_new2("LPSTR");
04687 break;
04688 default:
04689 typestr = rb_str_new2("Unknown Type ");
04690 rb_str_concat(typestr, rb_fix2str(INT2FIX(pTypeDesc->vt), 10));
04691 break;
04692 }
04693 if (typedetails != Qnil)
04694 rb_ary_push(typedetails, typestr);
04695 return typestr;
04696 }
04697
04698
04699
04700
04701
04702
04703
04704
04705
04706
04707
04708
04709 static VALUE
04710 fole_method_help(VALUE self, VALUE cmdname)
04711 {
04712 ITypeInfo *pTypeInfo;
04713 HRESULT hr;
04714 struct oledata *pole;
04715 VALUE method, obj;
04716
04717 SafeStringValue(cmdname);
04718 OLEData_Get_Struct(self, pole);
04719 hr = typeinfo_from_ole(pole, &pTypeInfo);
04720 if(FAILED(hr))
04721 ole_raise(hr, rb_eRuntimeError, "failed to get ITypeInfo");
04722 method = folemethod_s_allocate(cWIN32OLE_METHOD);
04723 obj = olemethod_from_typeinfo(method, pTypeInfo, cmdname);
04724 OLE_RELEASE(pTypeInfo);
04725 if (obj == Qnil)
04726 rb_raise(eWIN32OLERuntimeError, "not found %s",
04727 StringValuePtr(cmdname));
04728 return obj;
04729 }
04730
04731
04732
04733
04734
04735
04736
04737
04738
04739
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751 static VALUE
04752 fole_activex_initialize(VALUE self)
04753 {
04754 struct oledata *pole;
04755 IPersistMemory *pPersistMemory;
04756 void *p;
04757
04758 HRESULT hr = S_OK;
04759
04760 OLEData_Get_Struct(self, pole);
04761
04762 hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &IID_IPersistMemory, &p);
04763 pPersistMemory = p;
04764 if (SUCCEEDED(hr)) {
04765 hr = pPersistMemory->lpVtbl->InitNew(pPersistMemory);
04766 OLE_RELEASE(pPersistMemory);
04767 if (SUCCEEDED(hr)) {
04768 return Qnil;
04769 }
04770 }
04771
04772 if (FAILED(hr)) {
04773 ole_raise(hr, eWIN32OLERuntimeError, "fail to initialize ActiveX control");
04774 }
04775
04776 return Qnil;
04777 }
04778
04779
04780
04781
04782
04783
04784
04785
04786 static VALUE
04787 foletype_s_ole_classes(VALUE self, VALUE typelib)
04788 {
04789 VALUE obj;
04790
04791
04792
04793
04794
04795
04796 obj = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("new"), 1, typelib);
04797 return rb_funcall(obj, rb_intern("ole_types"), 0);
04798 }
04799
04800
04801
04802
04803
04804
04805
04806
04807
04808 static VALUE
04809 foletype_s_typelibs(VALUE self)
04810 {
04811
04812
04813
04814
04815
04816 return rb_eval_string("WIN32OLE_TYPELIB.typelibs.collect{|t|t.name}");
04817 }
04818
04819
04820
04821
04822
04823
04824
04825 static VALUE
04826 foletype_s_progids(VALUE self)
04827 {
04828 HKEY hclsids, hclsid;
04829 DWORD i;
04830 LONG err;
04831 VALUE clsid;
04832 VALUE v = rb_str_new2("");
04833 VALUE progids = rb_ary_new();
04834
04835 err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hclsids);
04836 if(err != ERROR_SUCCESS) {
04837 return progids;
04838 }
04839 for(i = 0; ; i++) {
04840 clsid = reg_enum_key(hclsids, i);
04841 if (clsid == Qnil)
04842 break;
04843 err = reg_open_vkey(hclsids, clsid, &hclsid);
04844 if (err != ERROR_SUCCESS)
04845 continue;
04846 if ((v = reg_get_val2(hclsid, "ProgID")) != Qnil)
04847 rb_ary_push(progids, v);
04848 if ((v = reg_get_val2(hclsid, "VersionIndependentProgID")) != Qnil)
04849 rb_ary_push(progids, v);
04850 RegCloseKey(hclsid);
04851 }
04852 RegCloseKey(hclsids);
04853 return progids;
04854 }
04855
04856 static VALUE
04857 foletype_s_allocate(VALUE klass)
04858 {
04859 struct oletypedata *poletype;
04860 VALUE obj;
04861 ole_initialize();
04862 obj = Data_Make_Struct(klass,struct oletypedata,0,oletype_free,poletype);
04863 poletype->pTypeInfo = NULL;
04864 return obj;
04865 }
04866
04867 static VALUE
04868 oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
04869 {
04870 struct oletypedata *ptype;
04871 Data_Get_Struct(self, struct oletypedata, ptype);
04872 rb_ivar_set(self, rb_intern("name"), name);
04873 ptype->pTypeInfo = pTypeInfo;
04874 if(pTypeInfo) OLE_ADDREF(pTypeInfo);
04875 return self;
04876 }
04877
04878 static VALUE
04879 oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass)
04880 {
04881
04882 long count;
04883 int i;
04884 HRESULT hr;
04885 BSTR bstr;
04886 VALUE typelib;
04887 ITypeInfo *pTypeInfo;
04888
04889 VALUE found = Qfalse;
04890
04891 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
04892 for (i = 0; i < count && found == Qfalse; i++) {
04893 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
04894 if (FAILED(hr))
04895 continue;
04896 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
04897 &bstr, NULL, NULL, NULL);
04898 if (FAILED(hr))
04899 continue;
04900 typelib = WC2VSTR(bstr);
04901 if (rb_str_cmp(oleclass, typelib) == 0) {
04902 oletype_set_member(self, pTypeInfo, typelib);
04903 found = Qtrue;
04904 }
04905 OLE_RELEASE(pTypeInfo);
04906 }
04907 return found;
04908 }
04909
04910
04911
04912
04913
04914
04915
04916 static VALUE
04917 oletypelib_set_member(VALUE self, ITypeLib *pTypeLib)
04918 {
04919 struct oletypelibdata *ptlib;
04920 Data_Get_Struct(self, struct oletypelibdata, ptlib);
04921 ptlib->pTypeLib = pTypeLib;
04922 return self;
04923 }
04924
04925 static ITypeLib *
04926 oletypelib_get_typelib(VALUE self)
04927 {
04928 struct oletypelibdata *ptlib;
04929 Data_Get_Struct(self, struct oletypelibdata, ptlib);
04930 return ptlib->pTypeLib;
04931 }
04932
04933 static void
04934 oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr)
04935 {
04936 HRESULT hr;
04937 hr = pTypeLib->lpVtbl->GetLibAttr(pTypeLib, ppTLibAttr);
04938 if (FAILED(hr)) {
04939 ole_raise(hr, eWIN32OLERuntimeError,
04940 "failed to get library attribute(TLIBATTR) from ITypeLib");
04941 }
04942 }
04943
04944
04945
04946
04947
04948
04949
04950
04951
04952
04953
04954 static VALUE
04955 foletypelib_s_typelibs(VALUE self)
04956 {
04957 HKEY htypelib, hguid;
04958 DWORD i, j;
04959 LONG err;
04960 VALUE guid;
04961 VALUE version;
04962 VALUE name = Qnil;
04963 VALUE typelibs = rb_ary_new();
04964 VALUE typelib = Qnil;
04965 HRESULT hr;
04966 ITypeLib *pTypeLib;
04967
04968 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
04969 if(err != ERROR_SUCCESS) {
04970 return typelibs;
04971 }
04972 for(i = 0; ; i++) {
04973 guid = reg_enum_key(htypelib, i);
04974 if (guid == Qnil)
04975 break;
04976 err = reg_open_vkey(htypelib, guid, &hguid);
04977 if (err != ERROR_SUCCESS)
04978 continue;
04979 for(j = 0; ; j++) {
04980 version = reg_enum_key(hguid, j);
04981 if (version == Qnil)
04982 break;
04983 if ( (name = reg_get_val2(hguid, StringValuePtr(version))) != Qnil ) {
04984 hr = oletypelib_from_guid(guid, version, &pTypeLib);
04985 if (SUCCEEDED(hr)) {
04986 typelib = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("allocate"), 0);
04987 oletypelib_set_member(typelib, pTypeLib);
04988 rb_ary_push(typelibs, typelib);
04989 }
04990 }
04991 }
04992 RegCloseKey(hguid);
04993 }
04994 RegCloseKey(htypelib);
04995 return typelibs;
04996 }
04997
04998 static VALUE
04999 make_version_str(VALUE major, VALUE minor)
05000 {
05001 VALUE version_str = Qnil;
05002 VALUE minor_str = Qnil;
05003 if (major == Qnil) {
05004 return Qnil;
05005 }
05006 version_str = rb_String(major);
05007 if (minor != Qnil) {
05008 minor_str = rb_String(minor);
05009 rb_str_cat2(version_str, ".");
05010 rb_str_append(version_str, minor_str);
05011 }
05012 return version_str;
05013 }
05014
05015 static VALUE
05016 oletypelib_search_registry2(VALUE self, VALUE args)
05017 {
05018 HKEY htypelib, hguid, hversion;
05019 double fver;
05020 DWORD j;
05021 LONG err;
05022 VALUE found = Qfalse;
05023 VALUE tlib;
05024 VALUE ver;
05025 VALUE version_str;
05026 VALUE version = Qnil;
05027 VALUE typelib = Qnil;
05028 HRESULT hr;
05029 ITypeLib *pTypeLib;
05030
05031 VALUE guid = rb_ary_entry(args, 0);
05032 version_str = make_version_str(rb_ary_entry(args, 1), rb_ary_entry(args, 2));
05033
05034 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
05035 if(err != ERROR_SUCCESS) {
05036 return Qfalse;
05037 }
05038 err = reg_open_vkey(htypelib, guid, &hguid);
05039 if (err != ERROR_SUCCESS) {
05040 RegCloseKey(htypelib);
05041 return Qfalse;
05042 }
05043 if (version_str != Qnil) {
05044 err = reg_open_vkey(hguid, version_str, &hversion);
05045 if (err == ERROR_SUCCESS) {
05046 tlib = reg_get_val(hversion, NULL);
05047 if (tlib != Qnil) {
05048 typelib = tlib;
05049 version = version_str;
05050 }
05051 }
05052 RegCloseKey(hversion);
05053 } else {
05054 fver = 0.0;
05055 for(j = 0; ;j++) {
05056 ver = reg_enum_key(hguid, j);
05057 if (ver == Qnil)
05058 break;
05059 err = reg_open_vkey(hguid, ver, &hversion);
05060 if (err != ERROR_SUCCESS)
05061 continue;
05062 tlib = reg_get_val(hversion, NULL);
05063 if (tlib == Qnil) {
05064 RegCloseKey(hversion);
05065 continue;
05066 }
05067 if (fver < atof(StringValuePtr(ver))) {
05068 fver = atof(StringValuePtr(ver));
05069 version = ver;
05070 typelib = tlib;
05071 }
05072 RegCloseKey(hversion);
05073 }
05074 }
05075 RegCloseKey(hguid);
05076 RegCloseKey(htypelib);
05077 if (typelib != Qnil) {
05078 hr = oletypelib_from_guid(guid, version, &pTypeLib);
05079 if (SUCCEEDED(hr)) {
05080 found = Qtrue;
05081 oletypelib_set_member(self, pTypeLib);
05082 }
05083 }
05084 return found;
05085 }
05086
05087 static VALUE
05088 oletypelib_search_registry(VALUE self, VALUE typelib)
05089 {
05090 HKEY htypelib, hguid, hversion;
05091 DWORD i, j;
05092 LONG err;
05093 VALUE found = Qfalse;
05094 VALUE tlib;
05095 VALUE guid;
05096 VALUE ver;
05097 HRESULT hr;
05098 ITypeLib *pTypeLib;
05099
05100 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
05101 if(err != ERROR_SUCCESS) {
05102 return Qfalse;
05103 }
05104 for(i = 0; !found; i++) {
05105 guid = reg_enum_key(htypelib, i);
05106 if (guid == Qnil)
05107 break;
05108 err = reg_open_vkey(htypelib, guid, &hguid);
05109 if (err != ERROR_SUCCESS)
05110 continue;
05111 for(j = 0; found == Qfalse; j++) {
05112 ver = reg_enum_key(hguid, j);
05113 if (ver == Qnil)
05114 break;
05115 err = reg_open_vkey(hguid, ver, &hversion);
05116 if (err != ERROR_SUCCESS)
05117 continue;
05118 tlib = reg_get_val(hversion, NULL);
05119 if (tlib == Qnil) {
05120 RegCloseKey(hversion);
05121 continue;
05122 }
05123 if (rb_str_cmp(typelib, tlib) == 0) {
05124 hr = oletypelib_from_guid(guid, ver, &pTypeLib);
05125 if (SUCCEEDED(hr)) {
05126 oletypelib_set_member(self, pTypeLib);
05127 found = Qtrue;
05128 }
05129 }
05130 RegCloseKey(hversion);
05131 }
05132 RegCloseKey(hguid);
05133 }
05134 RegCloseKey(htypelib);
05135 return found;
05136 }
05137
05138 static VALUE
05139 foletypelib_s_allocate(VALUE klass)
05140 {
05141 struct oletypelibdata *poletypelib;
05142 VALUE obj;
05143 ole_initialize();
05144 obj = Data_Make_Struct(klass, struct oletypelibdata, 0, oletypelib_free, poletypelib);
05145 poletypelib->pTypeLib = NULL;
05146 return obj;
05147 }
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159
05160
05161
05162
05163
05164
05165
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175 static VALUE
05176 foletypelib_initialize(VALUE self, VALUE args)
05177 {
05178 VALUE found = Qfalse;
05179 VALUE typelib = Qnil;
05180 int len = 0;
05181 OLECHAR * pbuf;
05182 ITypeLib *pTypeLib;
05183 HRESULT hr = S_OK;
05184
05185 len = RARRAY_LEN(args);
05186 if (len < 1 || len > 3) {
05187 rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", len);
05188 }
05189
05190 typelib = rb_ary_entry(args, 0);
05191
05192 SafeStringValue(typelib);
05193
05194 found = oletypelib_search_registry(self, typelib);
05195 if (found == Qfalse) {
05196 found = oletypelib_search_registry2(self, args);
05197 }
05198 if (found == Qfalse) {
05199 pbuf = ole_vstr2wc(typelib);
05200 hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
05201 SysFreeString(pbuf);
05202 if (SUCCEEDED(hr)) {
05203 found = Qtrue;
05204 oletypelib_set_member(self, pTypeLib);
05205 }
05206 }
05207
05208 if (found == Qfalse) {
05209 rb_raise(eWIN32OLERuntimeError, "not found type library `%s`",
05210 StringValuePtr(typelib));
05211 }
05212 return self;
05213 }
05214
05215
05216
05217
05218
05219
05220
05221
05222
05223
05224 static VALUE
05225 foletypelib_guid(VALUE self)
05226 {
05227 ITypeLib *pTypeLib;
05228 OLECHAR bstr[80];
05229 VALUE guid = Qnil;
05230 int len;
05231 TLIBATTR *pTLibAttr;
05232
05233 pTypeLib = oletypelib_get_typelib(self);
05234 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
05235 len = StringFromGUID2(&pTLibAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
05236 if (len > 3) {
05237 guid = ole_wc2vstr(bstr, FALSE);
05238 }
05239 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05240 return guid;
05241 }
05242
05243
05244
05245
05246
05247
05248
05249
05250
05251
05252 static VALUE
05253 foletypelib_name(VALUE self)
05254 {
05255 ITypeLib *pTypeLib;
05256 HRESULT hr;
05257 BSTR bstr;
05258 VALUE name;
05259 pTypeLib = oletypelib_get_typelib(self);
05260 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
05261 NULL, &bstr, NULL, NULL);
05262
05263 if (FAILED(hr)) {
05264 ole_raise(hr, eWIN32OLERuntimeError, "failed to get name from ITypeLib");
05265 }
05266 name = WC2VSTR(bstr);
05267 return rb_enc_str_new(StringValuePtr(name), strlen(StringValuePtr(name)), cWIN32OLE_enc);
05268 }
05269
05270
05271
05272
05273
05274
05275
05276
05277
05278
05279 static VALUE
05280 foletypelib_version(VALUE self)
05281 {
05282 TLIBATTR *pTLibAttr;
05283 VALUE major;
05284 VALUE minor;
05285 ITypeLib *pTypeLib;
05286
05287 pTypeLib = oletypelib_get_typelib(self);
05288 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
05289 major = INT2NUM(pTLibAttr->wMajorVerNum);
05290 minor = INT2NUM(pTLibAttr->wMinorVerNum);
05291 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05292 return rb_Float(make_version_str(major, minor));
05293 }
05294
05295
05296
05297
05298
05299
05300
05301
05302
05303
05304 static VALUE
05305 foletypelib_major_version(VALUE self)
05306 {
05307 TLIBATTR *pTLibAttr;
05308 VALUE major;
05309 ITypeLib *pTypeLib;
05310 pTypeLib = oletypelib_get_typelib(self);
05311 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
05312
05313 major = INT2NUM(pTLibAttr->wMajorVerNum);
05314 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05315 return major;
05316 }
05317
05318
05319
05320
05321
05322
05323
05324
05325
05326
05327 static VALUE
05328 foletypelib_minor_version(VALUE self)
05329 {
05330 TLIBATTR *pTLibAttr;
05331 VALUE minor;
05332 ITypeLib *pTypeLib;
05333 pTypeLib = oletypelib_get_typelib(self);
05334 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
05335 minor = INT2NUM(pTLibAttr->wMinorVerNum);
05336 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05337 return minor;
05338 }
05339
05340 static VALUE
05341 oletypelib_path(VALUE guid, VALUE version)
05342 {
05343 int k;
05344 LONG err;
05345 HKEY hkey;
05346 HKEY hlang;
05347 VALUE lang;
05348 VALUE path = Qnil;
05349
05350 VALUE key = rb_str_new2("TypeLib\\");
05351 rb_str_concat(key, guid);
05352 rb_str_cat2(key, "\\");
05353 rb_str_concat(key, version);
05354
05355 err = reg_open_vkey(HKEY_CLASSES_ROOT, key, &hkey);
05356 if (err != ERROR_SUCCESS) {
05357 return Qnil;
05358 }
05359 for(k = 0; path == Qnil; k++) {
05360 lang = reg_enum_key(hkey, k);
05361 if (lang == Qnil)
05362 break;
05363 err = reg_open_vkey(hkey, lang, &hlang);
05364 if (err == ERROR_SUCCESS) {
05365 path = reg_get_typelib_file_path(hlang);
05366 RegCloseKey(hlang);
05367 }
05368 }
05369 RegCloseKey(hkey);
05370 return path;
05371 }
05372
05373 static HRESULT
05374 oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib)
05375 {
05376 VALUE path;
05377 OLECHAR *pBuf;
05378 HRESULT hr;
05379 path = oletypelib_path(guid, version);
05380 if (path == Qnil) {
05381 return E_UNEXPECTED;
05382 }
05383 pBuf = ole_vstr2wc(path);
05384 hr = LoadTypeLibEx(pBuf, REGKIND_NONE, ppTypeLib);
05385 SysFreeString(pBuf);
05386 return hr;
05387 }
05388
05389
05390
05391
05392
05393
05394
05395
05396
05397
05398 static VALUE
05399 foletypelib_path(VALUE self)
05400 {
05401 TLIBATTR *pTLibAttr;
05402 HRESULT hr = S_OK;
05403 BSTR bstr;
05404 LCID lcid = cWIN32OLE_lcid;
05405 VALUE path;
05406 ITypeLib *pTypeLib;
05407
05408 pTypeLib = oletypelib_get_typelib(self);
05409 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
05410 hr = QueryPathOfRegTypeLib(&pTLibAttr->guid,
05411 pTLibAttr->wMajorVerNum,
05412 pTLibAttr->wMinorVerNum,
05413 lcid,
05414 &bstr);
05415 if (FAILED(hr)) {
05416 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05417 ole_raise(hr, eWIN32OLERuntimeError, "failed to QueryPathOfRegTypeTypeLib");
05418 }
05419
05420 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05421 path = WC2VSTR(bstr);
05422 return rb_enc_str_new(StringValuePtr(path), strlen(StringValuePtr(path)), cWIN32OLE_enc);
05423 }
05424
05425
05426
05427
05428
05429
05430
05431
05432
05433
05434
05435
05436
05437
05438 static VALUE
05439 foletypelib_visible(VALUE self)
05440 {
05441 ITypeLib *pTypeLib = NULL;
05442 VALUE visible = Qtrue;
05443 TLIBATTR *pTLibAttr;
05444
05445 pTypeLib = oletypelib_get_typelib(self);
05446 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
05447
05448 if ((pTLibAttr->wLibFlags == 0) ||
05449 (pTLibAttr->wLibFlags & LIBFLAG_FRESTRICTED) ||
05450 (pTLibAttr->wLibFlags & LIBFLAG_FHIDDEN)) {
05451 visible = Qfalse;
05452 }
05453 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
05454 return visible;
05455 }
05456
05457
05458
05459
05460
05461
05462
05463
05464
05465
05466
05467 static VALUE
05468 foletypelib_library_name(VALUE self)
05469 {
05470 HRESULT hr;
05471 ITypeLib *pTypeLib = NULL;
05472 VALUE libname = Qnil;
05473 BSTR bstr;
05474
05475 pTypeLib = oletypelib_get_typelib(self);
05476 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
05477 &bstr, NULL, NULL, NULL);
05478 if (FAILED(hr)) {
05479 ole_raise(hr, eWIN32OLERuntimeError, "failed to get library name");
05480 }
05481 libname = WC2VSTR(bstr);
05482 return libname;
05483 }
05484
05485
05486
05487
05488
05489
05490
05491
05492
05493
05494
05495 static VALUE
05496 foletypelib_ole_types(VALUE self)
05497 {
05498 ITypeLib *pTypeLib = NULL;
05499 VALUE classes = rb_ary_new();
05500 pTypeLib = oletypelib_get_typelib(self);
05501 ole_types_from_typelib(pTypeLib, classes);
05502 return classes;
05503 }
05504
05505
05506
05507
05508
05509
05510
05511
05512
05513
05514 static VALUE
05515 foletypelib_inspect(VALUE self)
05516 {
05517 return default_inspect(self, "WIN32OLE_TYPELIB");
05518 }
05519
05520
05521
05522
05523
05524
05525
05526
05527
05528
05529
05530
05531
05532
05533
05534
05535
05536
05537 static VALUE
05538 foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass)
05539 {
05540 VALUE file;
05541 OLECHAR * pbuf;
05542 ITypeLib *pTypeLib;
05543 HRESULT hr;
05544
05545 SafeStringValue(oleclass);
05546 SafeStringValue(typelib);
05547 file = typelib_file(typelib);
05548 if (file == Qnil) {
05549 file = typelib;
05550 }
05551 pbuf = ole_vstr2wc(file);
05552 hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
05553 if (FAILED(hr))
05554 ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
05555 SysFreeString(pbuf);
05556 if (oleclass_from_typelib(self, pTypeLib, oleclass) == Qfalse) {
05557 OLE_RELEASE(pTypeLib);
05558 rb_raise(eWIN32OLERuntimeError, "not found `%s` in `%s`",
05559 StringValuePtr(oleclass), StringValuePtr(typelib));
05560 }
05561 OLE_RELEASE(pTypeLib);
05562 return self;
05563 }
05564
05565
05566
05567
05568
05569
05570
05571
05572
05573 static VALUE
05574 foletype_name(VALUE self)
05575 {
05576 return rb_ivar_get(self, rb_intern("name"));
05577 }
05578
05579 static VALUE
05580 ole_ole_type(ITypeInfo *pTypeInfo)
05581 {
05582 HRESULT hr;
05583 TYPEATTR *pTypeAttr;
05584 VALUE type = Qnil;
05585 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05586 if(FAILED(hr)){
05587 return type;
05588 }
05589 switch(pTypeAttr->typekind) {
05590 case TKIND_ENUM:
05591 type = rb_str_new2("Enum");
05592 break;
05593 case TKIND_RECORD:
05594 type = rb_str_new2("Record");
05595 break;
05596 case TKIND_MODULE:
05597 type = rb_str_new2("Module");
05598 break;
05599 case TKIND_INTERFACE:
05600 type = rb_str_new2("Interface");
05601 break;
05602 case TKIND_DISPATCH:
05603 type = rb_str_new2("Dispatch");
05604 break;
05605 case TKIND_COCLASS:
05606 type = rb_str_new2("Class");
05607 break;
05608 case TKIND_ALIAS:
05609 type = rb_str_new2("Alias");
05610 break;
05611 case TKIND_UNION:
05612 type = rb_str_new2("Union");
05613 break;
05614 case TKIND_MAX:
05615 type = rb_str_new2("Max");
05616 break;
05617 default:
05618 type = Qnil;
05619 break;
05620 }
05621 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05622 return type;
05623 }
05624
05625
05626
05627
05628
05629
05630
05631
05632
05633 static VALUE
05634 foletype_ole_type(VALUE self)
05635 {
05636 struct oletypedata *ptype;
05637 Data_Get_Struct(self, struct oletypedata, ptype);
05638 return ole_ole_type(ptype->pTypeInfo);
05639 }
05640
05641 static VALUE
05642 ole_type_guid(ITypeInfo *pTypeInfo)
05643 {
05644 HRESULT hr;
05645 TYPEATTR *pTypeAttr;
05646 int len;
05647 OLECHAR bstr[80];
05648 VALUE guid = Qnil;
05649 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05650 if (FAILED(hr))
05651 return guid;
05652 len = StringFromGUID2(&pTypeAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
05653 if (len > 3) {
05654 guid = ole_wc2vstr(bstr, FALSE);
05655 }
05656 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05657 return guid;
05658 }
05659
05660
05661
05662
05663
05664
05665
05666
05667
05668 static VALUE
05669 foletype_guid(VALUE self)
05670 {
05671 struct oletypedata *ptype;
05672 Data_Get_Struct(self, struct oletypedata, ptype);
05673 return ole_type_guid(ptype->pTypeInfo);
05674 }
05675
05676 static VALUE
05677 ole_type_progid(ITypeInfo *pTypeInfo)
05678 {
05679 HRESULT hr;
05680 TYPEATTR *pTypeAttr;
05681 OLECHAR *pbuf;
05682 VALUE progid = Qnil;
05683 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05684 if (FAILED(hr))
05685 return progid;
05686 hr = ProgIDFromCLSID(&pTypeAttr->guid, &pbuf);
05687 if (SUCCEEDED(hr)) {
05688 progid = ole_wc2vstr(pbuf, FALSE);
05689 CoTaskMemFree(pbuf);
05690 }
05691 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05692 return progid;
05693 }
05694
05695
05696
05697
05698
05699
05700
05701
05702
05703 static VALUE
05704 foletype_progid(VALUE self)
05705 {
05706 struct oletypedata *ptype;
05707 Data_Get_Struct(self, struct oletypedata, ptype);
05708 return ole_type_progid(ptype->pTypeInfo);
05709 }
05710
05711
05712 static VALUE
05713 ole_type_visible(ITypeInfo *pTypeInfo)
05714 {
05715 HRESULT hr;
05716 TYPEATTR *pTypeAttr;
05717 VALUE visible;
05718 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05719 if (FAILED(hr))
05720 return Qtrue;
05721 if (pTypeAttr->wTypeFlags & (TYPEFLAG_FHIDDEN | TYPEFLAG_FRESTRICTED)) {
05722 visible = Qfalse;
05723 } else {
05724 visible = Qtrue;
05725 }
05726 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05727 return visible;
05728 }
05729
05730
05731
05732
05733
05734
05735
05736
05737
05738 static VALUE
05739 foletype_visible(VALUE self)
05740 {
05741 struct oletypedata *ptype;
05742 Data_Get_Struct(self, struct oletypedata, ptype);
05743 return ole_type_visible(ptype->pTypeInfo);
05744 }
05745
05746 static VALUE
05747 ole_type_major_version(ITypeInfo *pTypeInfo)
05748 {
05749 VALUE ver;
05750 TYPEATTR *pTypeAttr;
05751 HRESULT hr;
05752 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05753 if (FAILED(hr))
05754 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
05755 ver = INT2FIX(pTypeAttr->wMajorVerNum);
05756 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05757 return ver;
05758 }
05759
05760
05761
05762
05763
05764
05765
05766
05767
05768 static VALUE
05769 foletype_major_version(VALUE self)
05770 {
05771 struct oletypedata *ptype;
05772 Data_Get_Struct(self, struct oletypedata, ptype);
05773 return ole_type_major_version(ptype->pTypeInfo);
05774 }
05775
05776 static VALUE
05777 ole_type_minor_version(ITypeInfo *pTypeInfo)
05778 {
05779 VALUE ver;
05780 TYPEATTR *pTypeAttr;
05781 HRESULT hr;
05782 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05783 if (FAILED(hr))
05784 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
05785 ver = INT2FIX(pTypeAttr->wMinorVerNum);
05786 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05787 return ver;
05788 }
05789
05790
05791
05792
05793
05794
05795
05796
05797
05798 static VALUE
05799 foletype_minor_version(VALUE self)
05800 {
05801 struct oletypedata *ptype;
05802 Data_Get_Struct(self, struct oletypedata, ptype);
05803 return ole_type_minor_version(ptype->pTypeInfo);
05804 }
05805
05806 static VALUE
05807 ole_type_typekind(ITypeInfo *pTypeInfo)
05808 {
05809 VALUE typekind;
05810 TYPEATTR *pTypeAttr;
05811 HRESULT hr;
05812 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05813 if (FAILED(hr))
05814 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
05815 typekind = INT2FIX(pTypeAttr->typekind);
05816 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05817 return typekind;
05818 }
05819
05820
05821
05822
05823
05824
05825
05826
05827
05828
05829 static VALUE
05830 foletype_typekind(VALUE self)
05831 {
05832 struct oletypedata *ptype;
05833 Data_Get_Struct(self, struct oletypedata, ptype);
05834 return ole_type_typekind(ptype->pTypeInfo);
05835 }
05836
05837 static VALUE
05838 ole_type_helpstring(ITypeInfo *pTypeInfo)
05839 {
05840 HRESULT hr;
05841 BSTR bhelpstr;
05842 hr = ole_docinfo_from_type(pTypeInfo, NULL, &bhelpstr, NULL, NULL);
05843 if(FAILED(hr)) {
05844 return Qnil;
05845 }
05846 return WC2VSTR(bhelpstr);
05847 }
05848
05849
05850
05851
05852
05853
05854
05855
05856
05857 static VALUE
05858 foletype_helpstring(VALUE self)
05859 {
05860 struct oletypedata *ptype;
05861 Data_Get_Struct(self, struct oletypedata, ptype);
05862 return ole_type_helpstring(ptype->pTypeInfo);
05863 }
05864
05865 static VALUE
05866 ole_type_src_type(ITypeInfo *pTypeInfo)
05867 {
05868 HRESULT hr;
05869 TYPEATTR *pTypeAttr;
05870 VALUE alias = Qnil;
05871 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05872 if (FAILED(hr))
05873 return alias;
05874 if(pTypeAttr->typekind != TKIND_ALIAS) {
05875 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05876 return alias;
05877 }
05878 alias = ole_typedesc2val(pTypeInfo, &(pTypeAttr->tdescAlias), Qnil);
05879 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
05880 return alias;
05881 }
05882
05883
05884
05885
05886
05887
05888
05889
05890
05891
05892 static VALUE
05893 foletype_src_type(VALUE self)
05894 {
05895 struct oletypedata *ptype;
05896 Data_Get_Struct(self, struct oletypedata, ptype);
05897 return ole_type_src_type(ptype->pTypeInfo);
05898 }
05899
05900 static VALUE
05901 ole_type_helpfile(ITypeInfo *pTypeInfo)
05902 {
05903 HRESULT hr;
05904 BSTR bhelpfile;
05905 hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL, NULL, &bhelpfile);
05906 if(FAILED(hr)) {
05907 return Qnil;
05908 }
05909 return WC2VSTR(bhelpfile);
05910 }
05911
05912
05913
05914
05915
05916
05917
05918
05919
05920
05921 static VALUE
05922 foletype_helpfile(VALUE self)
05923 {
05924 struct oletypedata *ptype;
05925 Data_Get_Struct(self, struct oletypedata, ptype);
05926 return ole_type_helpfile(ptype->pTypeInfo);
05927 }
05928
05929 static VALUE
05930 ole_type_helpcontext(ITypeInfo *pTypeInfo)
05931 {
05932 HRESULT hr;
05933 DWORD helpcontext;
05934 hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL,
05935 &helpcontext, NULL);
05936 if(FAILED(hr))
05937 return Qnil;
05938 return INT2FIX(helpcontext);
05939 }
05940
05941
05942
05943
05944
05945
05946
05947
05948
05949 static VALUE
05950 foletype_helpcontext(VALUE self)
05951 {
05952 struct oletypedata *ptype;
05953 Data_Get_Struct(self, struct oletypedata, ptype);
05954 return ole_type_helpcontext(ptype->pTypeInfo);
05955 }
05956
05957
05958
05959
05960
05961
05962
05963
05964
05965
05966 static VALUE
05967 foletype_ole_typelib(VALUE self)
05968 {
05969 struct oletypedata *ptype;
05970 Data_Get_Struct(self, struct oletypedata, ptype);
05971 return ole_typelib_from_itypeinfo(ptype->pTypeInfo);
05972 }
05973
05974 static VALUE
05975 ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags)
05976 {
05977 HRESULT hr;
05978 ITypeInfo *pRefTypeInfo;
05979 HREFTYPE href;
05980 WORD i;
05981 VALUE type;
05982 TYPEATTR *pTypeAttr;
05983 int flags;
05984
05985 VALUE types = rb_ary_new();
05986 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
05987 if (FAILED(hr)) {
05988 return types;
05989 }
05990 for (i = 0; i < pTypeAttr->cImplTypes; i++) {
05991 hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
05992 if (FAILED(hr))
05993 continue;
05994
05995 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
05996 if (FAILED(hr))
05997 continue;
05998 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
05999 if (FAILED(hr))
06000 continue;
06001
06002 if ((flags & implflags) == implflags) {
06003 type = ole_type_from_itypeinfo(pRefTypeInfo);
06004 if (type != Qnil) {
06005 rb_ary_push(types, type);
06006 }
06007 }
06008
06009 OLE_RELEASE(pRefTypeInfo);
06010 }
06011 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
06012 return types;
06013 }
06014
06015
06016
06017
06018
06019
06020
06021
06022
06023
06024 static VALUE
06025 foletype_impl_ole_types(VALUE self)
06026 {
06027 struct oletypedata *ptype;
06028 Data_Get_Struct(self, struct oletypedata, ptype);
06029 return ole_type_impl_ole_types(ptype->pTypeInfo, 0);
06030 }
06031
06032
06033
06034
06035
06036
06037
06038
06039
06040
06041
06042 static VALUE
06043 foletype_source_ole_types(VALUE self)
06044 {
06045 struct oletypedata *ptype;
06046 Data_Get_Struct(self, struct oletypedata, ptype);
06047 return ole_type_impl_ole_types(ptype->pTypeInfo, IMPLTYPEFLAG_FSOURCE);
06048 }
06049
06050
06051
06052
06053
06054
06055
06056
06057
06058
06059 static VALUE
06060 foletype_default_event_sources(VALUE self)
06061 {
06062 struct oletypedata *ptype;
06063 Data_Get_Struct(self, struct oletypedata, ptype);
06064 return ole_type_impl_ole_types(ptype->pTypeInfo, IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT);
06065 }
06066
06067
06068
06069
06070
06071
06072
06073
06074
06075
06076
06077 static VALUE
06078 foletype_default_ole_types(VALUE self)
06079 {
06080 struct oletypedata *ptype;
06081 Data_Get_Struct(self, struct oletypedata, ptype);
06082 return ole_type_impl_ole_types(ptype->pTypeInfo, IMPLTYPEFLAG_FDEFAULT);
06083 }
06084
06085
06086
06087
06088
06089
06090
06091
06092
06093
06094 static VALUE
06095 foletype_inspect(VALUE self)
06096 {
06097 return default_inspect(self, "WIN32OLE_TYPE");
06098 }
06099
06100 static VALUE
06101 ole_variables(ITypeInfo *pTypeInfo)
06102 {
06103 HRESULT hr;
06104 TYPEATTR *pTypeAttr;
06105 WORD i;
06106 UINT len;
06107 BSTR bstr;
06108 char *pstr;
06109 VARDESC *pVarDesc;
06110 struct olevariabledata *pvar;
06111 VALUE var;
06112 VALUE variables = rb_ary_new();
06113 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
06114 if (FAILED(hr)) {
06115 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
06116 }
06117
06118 for(i = 0; i < pTypeAttr->cVars; i++) {
06119 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, i, &pVarDesc);
06120 if(FAILED(hr))
06121 continue;
06122 len = 0;
06123 pstr = NULL;
06124 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
06125 1, &len);
06126 if(FAILED(hr) || len == 0 || !bstr)
06127 continue;
06128
06129 var = Data_Make_Struct(cWIN32OLE_VARIABLE, struct olevariabledata,
06130 0,olevariable_free,pvar);
06131 pvar->pTypeInfo = pTypeInfo;
06132 OLE_ADDREF(pTypeInfo);
06133 pvar->index = i;
06134 rb_ivar_set(var, rb_intern("name"), WC2VSTR(bstr));
06135 rb_ary_push(variables, var);
06136
06137 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06138 pVarDesc = NULL;
06139 }
06140 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
06141 return variables;
06142 }
06143
06144
06145
06146
06147
06148
06149
06150
06151
06152
06153
06154
06155
06156
06157
06158
06159
06160
06161
06162
06163
06164 static VALUE
06165 foletype_variables(VALUE self)
06166 {
06167 struct oletypedata *ptype;
06168 Data_Get_Struct(self, struct oletypedata, ptype);
06169 return ole_variables(ptype->pTypeInfo);
06170 }
06171
06172
06173
06174
06175
06176
06177
06178
06179
06180
06181
06182
06183
06184 static VALUE
06185 foletype_methods(VALUE self)
06186 {
06187 struct oletypedata *ptype;
06188 Data_Get_Struct(self, struct oletypedata, ptype);
06189 return ole_methods_from_typeinfo(ptype->pTypeInfo, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
06190 }
06191
06192
06193
06194
06195
06196
06197
06198
06199
06200
06201
06202
06203
06204
06205
06206
06207
06208
06209
06210
06211
06212
06213
06214
06215
06216
06217
06218 static VALUE
06219 folevariable_name(VALUE self)
06220 {
06221 return rb_ivar_get(self, rb_intern("name"));
06222 }
06223
06224 static VALUE
06225 ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index)
06226 {
06227 VARDESC *pVarDesc;
06228 HRESULT hr;
06229 VALUE type;
06230 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
06231 if (FAILED(hr))
06232 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc");
06233 type = ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), Qnil);
06234 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06235 return type;
06236 }
06237
06238
06239
06240
06241
06242
06243
06244
06245
06246
06247
06248
06249
06250
06251
06252
06253
06254
06255
06256
06257
06258 static VALUE
06259 folevariable_ole_type(VALUE self)
06260 {
06261 struct olevariabledata *pvar;
06262 Data_Get_Struct(self, struct olevariabledata, pvar);
06263 return ole_variable_ole_type(pvar->pTypeInfo, pvar->index);
06264 }
06265
06266 static VALUE
06267 ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index)
06268 {
06269 VARDESC *pVarDesc;
06270 HRESULT hr;
06271 VALUE type = rb_ary_new();
06272 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
06273 if (FAILED(hr))
06274 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc");
06275 ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), type);
06276 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06277 return type;
06278 }
06279
06280
06281
06282
06283
06284
06285
06286
06287
06288
06289
06290
06291
06292 static VALUE
06293 folevariable_ole_type_detail(VALUE self)
06294 {
06295 struct olevariabledata *pvar;
06296 Data_Get_Struct(self, struct olevariabledata, pvar);
06297 return ole_variable_ole_type_detail(pvar->pTypeInfo, pvar->index);
06298 }
06299
06300 static VALUE
06301 ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index)
06302 {
06303 VARDESC *pVarDesc;
06304 HRESULT hr;
06305 VALUE val = Qnil;
06306 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
06307 if (FAILED(hr))
06308 return Qnil;
06309 if(pVarDesc->varkind == VAR_CONST)
06310 val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));
06311 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06312 return val;
06313 }
06314
06315
06316
06317
06318
06319
06320
06321
06322
06323
06324
06325
06326
06327
06328
06329
06330
06331
06332
06333
06334
06335
06336 static VALUE
06337 folevariable_value(VALUE self)
06338 {
06339 struct olevariabledata *pvar;
06340 Data_Get_Struct(self, struct olevariabledata, pvar);
06341 return ole_variable_value(pvar->pTypeInfo, pvar->index);
06342 }
06343
06344 static VALUE
06345 ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index)
06346 {
06347 VARDESC *pVarDesc;
06348 HRESULT hr;
06349 VALUE visible = Qfalse;
06350 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
06351 if (FAILED(hr))
06352 return visible;
06353 if (!(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
06354 VARFLAG_FRESTRICTED |
06355 VARFLAG_FNONBROWSABLE))) {
06356 visible = Qtrue;
06357 }
06358 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06359 return visible;
06360 }
06361
06362
06363
06364
06365
06366
06367
06368
06369
06370
06371
06372
06373
06374
06375
06376
06377
06378
06379
06380
06381
06382 static VALUE
06383 folevariable_visible(VALUE self)
06384 {
06385 struct olevariabledata *pvar;
06386 Data_Get_Struct(self, struct olevariabledata, pvar);
06387 return ole_variable_visible(pvar->pTypeInfo, pvar->index);
06388 }
06389
06390 static VALUE
06391 ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index)
06392 {
06393 VARDESC *pVarDesc;
06394 HRESULT hr;
06395 VALUE kind = rb_str_new2("UNKNOWN");
06396 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
06397 if (FAILED(hr))
06398 return kind;
06399 switch(pVarDesc->varkind) {
06400 case VAR_PERINSTANCE:
06401 kind = rb_str_new2("PERINSTANCE");
06402 break;
06403 case VAR_STATIC:
06404 kind = rb_str_new2("STATIC");
06405 break;
06406 case VAR_CONST:
06407 kind = rb_str_new2("CONSTANT");
06408 break;
06409 case VAR_DISPATCH:
06410 kind = rb_str_new2("DISPATCH");
06411 break;
06412 default:
06413 break;
06414 }
06415 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06416 return kind;
06417 }
06418
06419
06420
06421
06422
06423
06424
06425
06426
06427
06428
06429
06430
06431
06432
06433
06434
06435
06436
06437
06438 static VALUE
06439 folevariable_variable_kind(VALUE self)
06440 {
06441 struct olevariabledata *pvar;
06442 Data_Get_Struct(self, struct olevariabledata, pvar);
06443 return ole_variable_kind(pvar->pTypeInfo, pvar->index);
06444 }
06445
06446 static VALUE
06447 ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index)
06448 {
06449 VARDESC *pVarDesc;
06450 HRESULT hr;
06451 VALUE kind = Qnil;
06452 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
06453 if (FAILED(hr))
06454 return kind;
06455 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
06456 kind = INT2FIX(pVarDesc->varkind);
06457 return kind;
06458 }
06459
06460
06461
06462
06463
06464
06465
06466
06467
06468
06469
06470
06471
06472
06473
06474
06475
06476
06477
06478 static VALUE
06479 folevariable_varkind(VALUE self)
06480 {
06481 struct olevariabledata *pvar;
06482 Data_Get_Struct(self, struct olevariabledata, pvar);
06483 return ole_variable_varkind(pvar->pTypeInfo, pvar->index);
06484 }
06485
06486
06487
06488
06489
06490
06491
06492
06493 static VALUE
06494 folevariable_inspect(VALUE self)
06495 {
06496 VALUE detail = rb_funcall(self, rb_intern("to_s"), 0);
06497 rb_str_cat2(detail, "=");
06498 rb_str_concat(detail, rb_funcall(rb_funcall(self, rb_intern("value"), 0), rb_intern("inspect"), 0));
06499 return make_inspect("WIN32OLE_VARIABLE", detail);
06500 }
06501
06502
06503
06504
06505
06506
06507
06508 static VALUE
06509 olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name)
06510 {
06511 struct olemethoddata *pmethod;
06512 Data_Get_Struct(self, struct olemethoddata, pmethod);
06513 pmethod->pTypeInfo = pTypeInfo;
06514 OLE_ADDREF(pTypeInfo);
06515 pmethod->pOwnerTypeInfo = pOwnerTypeInfo;
06516 if(pOwnerTypeInfo) OLE_ADDREF(pOwnerTypeInfo);
06517 pmethod->index = index;
06518 rb_ivar_set(self, rb_intern("name"), name);
06519 return self;
06520 }
06521
06522 static VALUE
06523 folemethod_s_allocate(VALUE klass)
06524 {
06525 struct olemethoddata *pmethod;
06526 VALUE obj;
06527 obj = Data_Make_Struct(klass,
06528 struct olemethoddata,
06529 0, olemethod_free, pmethod);
06530 pmethod->pTypeInfo = NULL;
06531 pmethod->pOwnerTypeInfo = NULL;
06532 pmethod->index = 0;
06533 return obj;
06534 }
06535
06536
06537
06538
06539
06540
06541
06542
06543
06544
06545
06546
06547
06548
06549 static VALUE
06550 folemethod_initialize(VALUE self, VALUE oletype, VALUE method)
06551 {
06552 struct oletypedata *ptype;
06553 VALUE obj = Qnil;
06554 if (rb_obj_is_kind_of(oletype, cWIN32OLE_TYPE)) {
06555 SafeStringValue(method);
06556 Data_Get_Struct(oletype, struct oletypedata, ptype);
06557 obj = olemethod_from_typeinfo(self, ptype->pTypeInfo, method);
06558 if (obj == Qnil) {
06559 rb_raise(eWIN32OLERuntimeError, "not found %s",
06560 StringValuePtr(method));
06561 }
06562 }
06563 else {
06564 rb_raise(rb_eTypeError, "1st argument should be WIN32OLE_TYPE object");
06565 }
06566 return obj;
06567 }
06568
06569
06570
06571
06572
06573
06574
06575
06576
06577
06578
06579
06580 static VALUE
06581 folemethod_name(VALUE self)
06582 {
06583 return rb_ivar_get(self, rb_intern("name"));
06584 }
06585
06586 static VALUE
06587 ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index)
06588 {
06589 FUNCDESC *pFuncDesc;
06590 HRESULT hr;
06591 VALUE type;
06592
06593 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
06594 if (FAILED(hr))
06595 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
06596
06597 type = ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), Qnil);
06598 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
06599 return type;
06600 }
06601
06602
06603
06604
06605
06606
06607
06608
06609
06610
06611
06612 static VALUE
06613 folemethod_return_type(VALUE self)
06614 {
06615 struct olemethoddata *pmethod;
06616 Data_Get_Struct(self, struct olemethoddata, pmethod);
06617 return ole_method_return_type(pmethod->pTypeInfo, pmethod->index);
06618 }
06619
06620 static VALUE
06621 ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index)
06622 {
06623 FUNCDESC *pFuncDesc;
06624 HRESULT hr;
06625 VALUE vvt;
06626
06627 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
06628 if (FAILED(hr))
06629 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
06630
06631 vvt = INT2FIX(pFuncDesc->elemdescFunc.tdesc.vt);
06632 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
06633 return vvt;
06634 }
06635
06636
06637
06638
06639
06640
06641
06642
06643
06644
06645
06646 static VALUE
06647 folemethod_return_vtype(VALUE self)
06648 {
06649 struct olemethoddata *pmethod;
06650 Data_Get_Struct(self, struct olemethoddata, pmethod);
06651 return ole_method_return_vtype(pmethod->pTypeInfo, pmethod->index);
06652 }
06653
06654 static VALUE
06655 ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index)
06656 {
06657 FUNCDESC *pFuncDesc;
06658 HRESULT hr;
06659 VALUE type = rb_ary_new();
06660
06661 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
06662 if (FAILED(hr))
06663 return type;
06664
06665 ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), type);
06666 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
06667 return type;
06668 }
06669
06670
06671
06672
06673
06674
06675
06676
06677
06678
06679
06680 static VALUE
06681 folemethod_return_type_detail(VALUE self)
06682 {
06683 struct olemethoddata *pmethod;
06684 Data_Get_Struct(self, struct olemethoddata, pmethod);
06685 return ole_method_return_type_detail(pmethod->pTypeInfo, pmethod->index);
06686 }
06687
06688 static VALUE
06689 ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index)
06690 {
06691 FUNCDESC *pFuncDesc;
06692 HRESULT hr;
06693 VALUE invkind;
06694 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
06695 if(FAILED(hr))
06696 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
06697 invkind = INT2FIX(pFuncDesc->invkind);
06698 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
06699 return invkind;
06700 }
06701
06702 static VALUE
06703 ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index)
06704 {
06705 VALUE type = rb_str_new2("UNKNOWN");
06706 VALUE invkind = ole_method_invkind(pTypeInfo, method_index);
06707 if((FIX2INT(invkind) & INVOKE_PROPERTYGET) &&
06708 (FIX2INT(invkind) & INVOKE_PROPERTYPUT) ) {
06709 type = rb_str_new2("PROPERTY");
06710 } else if(FIX2INT(invkind) & INVOKE_PROPERTYGET) {
06711 type = rb_str_new2("PROPERTYGET");
06712 } else if(FIX2INT(invkind) & INVOKE_PROPERTYPUT) {
06713 type = rb_str_new2("PROPERTYPUT");
06714 } else if(FIX2INT(invkind) & INVOKE_PROPERTYPUTREF) {
06715 type = rb_str_new2("PROPERTYPUTREF");
06716 } else if(FIX2INT(invkind) & INVOKE_FUNC) {
06717 type = rb_str_new2("FUNC");
06718 }
06719 return type;
06720 }
06721
06722
06723
06724
06725
06726
06727
06728
06729
06730
06731
06732 static VALUE
06733 folemethod_invkind(VALUE self)
06734 {
06735 struct olemethoddata *pmethod;
06736 Data_Get_Struct(self, struct olemethoddata, pmethod);
06737 return ole_method_invkind(pmethod->pTypeInfo, pmethod->index);
06738 }
06739
06740
06741
06742
06743
06744
06745
06746
06747
06748
06749
06750
06751 static VALUE
06752 folemethod_invoke_kind(VALUE self)
06753 {
06754 struct olemethoddata *pmethod;
06755 Data_Get_Struct(self, struct olemethoddata, pmethod);
06756 return ole_method_invoke_kind(pmethod->pTypeInfo, pmethod->index);
06757 }
06758
06759 static VALUE
06760 ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index)
06761 {
06762 FUNCDESC *pFuncDesc;
06763 HRESULT hr;
06764 VALUE visible;
06765 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
06766 if(FAILED(hr))
06767 return Qfalse;
06768 if (pFuncDesc->wFuncFlags & (FUNCFLAG_FRESTRICTED |
06769 FUNCFLAG_FHIDDEN |
06770 FUNCFLAG_FNONBROWSABLE)) {
06771 visible = Qfalse;
06772 } else {
06773 visible = Qtrue;
06774 }
06775 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
06776 return visible;
06777 }
06778
06779
06780
06781
06782
06783
06784
06785
06786
06787
06788 static VALUE
06789 folemethod_visible(VALUE self)
06790 {
06791 struct olemethoddata *pmethod;
06792 Data_Get_Struct(self, struct olemethoddata, pmethod);
06793 return ole_method_visible(pmethod->pTypeInfo, pmethod->index);
06794 }
06795
06796 static VALUE
06797 ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name)
06798 {
06799 TYPEATTR *pTypeAttr;
06800 HRESULT hr;
06801 WORD i;
06802 int flags;
06803 HREFTYPE href;
06804 ITypeInfo *pRefTypeInfo;
06805 FUNCDESC *pFuncDesc;
06806 BSTR bstr;
06807 VALUE name;
06808 VALUE event = Qfalse;
06809
06810 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
06811 if (FAILED(hr))
06812 return event;
06813 if(pTypeAttr->typekind != TKIND_COCLASS) {
06814 pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
06815 return event;
06816 }
06817 for (i = 0; i < pTypeAttr->cImplTypes; i++) {
06818 hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
06819 if (FAILED(hr))
06820 continue;
06821
06822 if (flags & IMPLTYPEFLAG_FSOURCE) {
06823 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
06824 i, &href);
06825 if (FAILED(hr))
06826 continue;
06827 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
06828 href, &pRefTypeInfo);
06829 if (FAILED(hr))
06830 continue;
06831 hr = pRefTypeInfo->lpVtbl->GetFuncDesc(pRefTypeInfo, method_index,
06832 &pFuncDesc);
06833 if (FAILED(hr)) {
06834 OLE_RELEASE(pRefTypeInfo);
06835 continue;
06836 }
06837
06838 hr = pRefTypeInfo->lpVtbl->GetDocumentation(pRefTypeInfo,
06839 pFuncDesc->memid,
06840 &bstr, NULL, NULL, NULL);
06841 if (FAILED(hr)) {
06842 pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);
06843 OLE_RELEASE(pRefTypeInfo);
06844 continue;
06845 }
06846
06847 name = WC2VSTR(bstr);
06848 pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);
06849 OLE_RELEASE(pRefTypeInfo);
06850 if (rb_str_cmp(method_name, name) == 0) {
06851 event = Qtrue;
06852 break;
06853 }
06854 }
06855 }
06856 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
06857 return event;
06858 }
06859
06860
06861
06862
06863
06864
06865
06866
06867
06868
06869
06870 static VALUE
06871 folemethod_event(VALUE self)
06872 {
06873 struct olemethoddata *pmethod;
06874 Data_Get_Struct(self, struct olemethoddata, pmethod);
06875 if (!pmethod->pOwnerTypeInfo)
06876 return Qfalse;
06877 return ole_method_event(pmethod->pOwnerTypeInfo,
06878 pmethod->index,
06879 rb_ivar_get(self, rb_intern("name")));
06880 }
06881
06882
06883
06884
06885
06886
06887
06888
06889
06890
06891 static VALUE
06892 folemethod_event_interface(VALUE self)
06893 {
06894 BSTR name;
06895 struct olemethoddata *pmethod;
06896 HRESULT hr;
06897 Data_Get_Struct(self, struct olemethoddata, pmethod);
06898 if(folemethod_event(self) == Qtrue) {
06899 hr = ole_docinfo_from_type(pmethod->pTypeInfo, &name, NULL, NULL, NULL);
06900 if(SUCCEEDED(hr))
06901 return WC2VSTR(name);
06902 }
06903 return Qnil;
06904 }
06905
06906 static VALUE
06907 ole_method_docinfo_from_type(
06908 ITypeInfo *pTypeInfo,
06909 UINT method_index,
06910 BSTR *name,
06911 BSTR *helpstr,
06912 DWORD *helpcontext,
06913 BSTR *helpfile
06914 )
06915 {
06916 FUNCDESC *pFuncDesc;
06917 HRESULT hr;
06918 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
06919 if (FAILED(hr))
06920 return hr;
06921 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
06922 name, helpstr,
06923 helpcontext, helpfile);
06924 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
06925 return hr;
06926 }
06927
06928 static VALUE
06929 ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index)
06930 {
06931 HRESULT hr;
06932 BSTR bhelpstring;
06933 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, &bhelpstring,
06934 NULL, NULL);
06935 if (FAILED(hr))
06936 return Qnil;
06937 return WC2VSTR(bhelpstring);
06938 }
06939
06940
06941
06942
06943
06944
06945
06946
06947
06948
06949
06950
06951 static VALUE
06952 folemethod_helpstring(VALUE self)
06953 {
06954 struct olemethoddata *pmethod;
06955 Data_Get_Struct(self, struct olemethoddata, pmethod);
06956 return ole_method_helpstring(pmethod->pTypeInfo, pmethod->index);
06957 }
06958
06959 static VALUE
06960 ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index)
06961 {
06962 HRESULT hr;
06963 BSTR bhelpfile;
06964 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,
06965 NULL, &bhelpfile);
06966 if (FAILED(hr))
06967 return Qnil;
06968 return WC2VSTR(bhelpfile);
06969 }
06970
06971
06972
06973
06974
06975
06976
06977
06978
06979
06980
06981 static VALUE
06982 folemethod_helpfile(VALUE self)
06983 {
06984 struct olemethoddata *pmethod;
06985 Data_Get_Struct(self, struct olemethoddata, pmethod);
06986
06987 return ole_method_helpfile(pmethod->pTypeInfo, pmethod->index);
06988 }
06989
06990 static VALUE
06991 ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index)
06992 {
06993 HRESULT hr;
06994 DWORD helpcontext = 0;
06995 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,
06996 &helpcontext, NULL);
06997 if (FAILED(hr))
06998 return Qnil;
06999 return INT2FIX(helpcontext);
07000 }
07001
07002
07003
07004
07005
07006
07007
07008
07009
07010
07011 static VALUE
07012 folemethod_helpcontext(VALUE self)
07013 {
07014 struct olemethoddata *pmethod;
07015 Data_Get_Struct(self, struct olemethoddata, pmethod);
07016 return ole_method_helpcontext(pmethod->pTypeInfo, pmethod->index);
07017 }
07018
07019 static VALUE
07020 ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index)
07021 {
07022 FUNCDESC *pFuncDesc;
07023 HRESULT hr;
07024 VALUE dispid = Qnil;
07025 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07026 if (FAILED(hr))
07027 return dispid;
07028 dispid = INT2NUM(pFuncDesc->memid);
07029 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07030 return dispid;
07031 }
07032
07033
07034
07035
07036
07037
07038
07039
07040
07041
07042 static VALUE
07043 folemethod_dispid(VALUE self)
07044 {
07045 struct olemethoddata *pmethod;
07046 Data_Get_Struct(self, struct olemethoddata, pmethod);
07047 return ole_method_dispid(pmethod->pTypeInfo, pmethod->index);
07048 }
07049
07050 static VALUE
07051 ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index)
07052 {
07053 FUNCDESC *pFuncDesc;
07054 HRESULT hr;
07055 VALUE offset_vtbl = Qnil;
07056 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07057 if (FAILED(hr))
07058 return offset_vtbl;
07059 offset_vtbl = INT2FIX(pFuncDesc->oVft);
07060 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07061 return offset_vtbl;
07062 }
07063
07064
07065
07066
07067
07068
07069
07070
07071
07072
07073 static VALUE
07074 folemethod_offset_vtbl(VALUE self)
07075 {
07076 struct olemethoddata *pmethod;
07077 Data_Get_Struct(self, struct olemethoddata, pmethod);
07078 return ole_method_offset_vtbl(pmethod->pTypeInfo, pmethod->index);
07079 }
07080
07081 static VALUE
07082 ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index)
07083 {
07084 FUNCDESC *pFuncDesc;
07085 HRESULT hr;
07086 VALUE size_params = Qnil;
07087 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07088 if (FAILED(hr))
07089 return size_params;
07090 size_params = INT2FIX(pFuncDesc->cParams);
07091 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07092 return size_params;
07093 }
07094
07095
07096
07097
07098
07099
07100
07101
07102
07103
07104
07105 static VALUE
07106 folemethod_size_params(VALUE self)
07107 {
07108 struct olemethoddata *pmethod;
07109 Data_Get_Struct(self, struct olemethoddata, pmethod);
07110 return ole_method_size_params(pmethod->pTypeInfo, pmethod->index);
07111 }
07112
07113 static VALUE
07114 ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index)
07115 {
07116 FUNCDESC *pFuncDesc;
07117 HRESULT hr;
07118 VALUE size_opt_params = Qnil;
07119 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07120 if (FAILED(hr))
07121 return size_opt_params;
07122 size_opt_params = INT2FIX(pFuncDesc->cParamsOpt);
07123 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07124 return size_opt_params;
07125 }
07126
07127
07128
07129
07130
07131
07132
07133
07134
07135
07136 static VALUE
07137 folemethod_size_opt_params(VALUE self)
07138 {
07139 struct olemethoddata *pmethod;
07140 Data_Get_Struct(self, struct olemethoddata, pmethod);
07141 return ole_method_size_opt_params(pmethod->pTypeInfo, pmethod->index);
07142 }
07143
07144 static VALUE
07145 ole_method_params(ITypeInfo *pTypeInfo, UINT method_index)
07146 {
07147 FUNCDESC *pFuncDesc;
07148 HRESULT hr;
07149 BSTR *bstrs;
07150 UINT len, i;
07151 struct oleparamdata *pparam;
07152 VALUE param;
07153 VALUE params = rb_ary_new();
07154 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07155 if (FAILED(hr))
07156 return params;
07157
07158 len = 0;
07159 bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1);
07160 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid,
07161 bstrs, pFuncDesc->cParams + 1,
07162 &len);
07163 if (FAILED(hr)) {
07164 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07165 return params;
07166 }
07167 SysFreeString(bstrs[0]);
07168 if (pFuncDesc->cParams > 0) {
07169 for(i = 1; i < len; i++) {
07170 param = Data_Make_Struct(cWIN32OLE_PARAM, struct oleparamdata, 0,
07171 oleparam_free, pparam);
07172 pparam->pTypeInfo = pTypeInfo;
07173 OLE_ADDREF(pTypeInfo);
07174 pparam->method_index = method_index;
07175 pparam->index = i - 1;
07176 rb_ivar_set(param, rb_intern("name"), WC2VSTR(bstrs[i]));
07177 rb_ary_push(params, param);
07178 }
07179 }
07180 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07181 return params;
07182 }
07183
07184
07185
07186
07187
07188
07189
07190
07191
07192
07193
07194
07195
07196
07197 static VALUE
07198 folemethod_params(VALUE self)
07199 {
07200 struct olemethoddata *pmethod;
07201 Data_Get_Struct(self, struct olemethoddata, pmethod);
07202 return ole_method_params(pmethod->pTypeInfo, pmethod->index);
07203 }
07204
07205
07206
07207
07208
07209
07210
07211
07212 static VALUE
07213 folemethod_inspect(VALUE self)
07214 {
07215 return default_inspect(self, "WIN32OLE_METHOD");
07216 }
07217
07218
07219
07220
07221
07222
07223
07224 static VALUE foleparam_s_allocate(VALUE klass)
07225 {
07226 struct oleparamdata *pparam;
07227 VALUE obj;
07228 obj = Data_Make_Struct(klass,
07229 struct oleparamdata,
07230 0, oleparam_free, pparam);
07231 pparam->pTypeInfo = NULL;
07232 pparam->method_index = 0;
07233 pparam->index = 0;
07234 return obj;
07235 }
07236
07237 static VALUE
07238 oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index)
07239 {
07240 FUNCDESC *pFuncDesc;
07241 HRESULT hr;
07242 BSTR *bstrs;
07243 UINT len;
07244 struct oleparamdata *pparam;
07245 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07246 if (FAILED(hr))
07247 ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetFuncDesc");
07248
07249 len = 0;
07250 bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1);
07251 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid,
07252 bstrs, pFuncDesc->cParams + 1,
07253 &len);
07254 if (FAILED(hr)) {
07255 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07256 ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetNames");
07257 }
07258 SysFreeString(bstrs[0]);
07259 if (param_index < 1 || len <= (UINT)param_index)
07260 {
07261 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07262 rb_raise(rb_eIndexError, "index of param must be in 1..%d", len);
07263 }
07264
07265 Data_Get_Struct(self, struct oleparamdata, pparam);
07266 pparam->pTypeInfo = pTypeInfo;
07267 OLE_ADDREF(pTypeInfo);
07268 pparam->method_index = method_index;
07269 pparam->index = param_index - 1;
07270 rb_ivar_set(self, rb_intern("name"), WC2VSTR(bstrs[param_index]));
07271
07272 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07273 return self;
07274 }
07275
07276 static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n)
07277 {
07278 struct olemethoddata *pmethod;
07279 Data_Get_Struct(olemethod, struct olemethoddata, pmethod);
07280 return oleparam_ole_param_from_index(self, pmethod->pTypeInfo, pmethod->index, n);
07281 }
07282
07283 static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n)
07284 {
07285 int idx;
07286 if (!rb_obj_is_kind_of(olemethod, cWIN32OLE_METHOD)) {
07287 rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE_METHOD object");
07288 }
07289 idx = FIX2INT(n);
07290 return oleparam_ole_param(self, olemethod, idx);
07291 }
07292
07293
07294
07295
07296
07297
07298
07299
07300
07301
07302
07303 static VALUE
07304 foleparam_name(VALUE self)
07305 {
07306 return rb_ivar_get(self, rb_intern("name"));
07307 }
07308
07309 static VALUE
07310 ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
07311 {
07312 FUNCDESC *pFuncDesc;
07313 HRESULT hr;
07314 VALUE type = rb_str_new2("unknown type");
07315 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07316 if (FAILED(hr))
07317 return type;
07318 type = ole_typedesc2val(pTypeInfo,
07319 &(pFuncDesc->lprgelemdescParam[index].tdesc), Qnil);
07320 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07321 return type;
07322 }
07323
07324
07325
07326
07327
07328
07329
07330
07331
07332
07333
07334 static VALUE
07335 foleparam_ole_type(VALUE self)
07336 {
07337 struct oleparamdata *pparam;
07338 Data_Get_Struct(self, struct oleparamdata, pparam);
07339 return ole_param_ole_type(pparam->pTypeInfo, pparam->method_index,
07340 pparam->index);
07341 }
07342
07343 static VALUE
07344 ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
07345 {
07346 FUNCDESC *pFuncDesc;
07347 HRESULT hr;
07348 VALUE typedetail = rb_ary_new();
07349 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07350 if (FAILED(hr))
07351 return typedetail;
07352 ole_typedesc2val(pTypeInfo,
07353 &(pFuncDesc->lprgelemdescParam[index].tdesc), typedetail);
07354 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07355 return typedetail;
07356 }
07357
07358
07359
07360
07361
07362
07363
07364
07365
07366
07367
07368 static VALUE
07369 foleparam_ole_type_detail(VALUE self)
07370 {
07371 struct oleparamdata *pparam;
07372 Data_Get_Struct(self, struct oleparamdata, pparam);
07373 return ole_param_ole_type_detail(pparam->pTypeInfo, pparam->method_index,
07374 pparam->index);
07375 }
07376
07377 static VALUE
07378 ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask)
07379 {
07380 FUNCDESC *pFuncDesc;
07381 HRESULT hr;
07382 VALUE ret = Qfalse;
07383 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07384 if(FAILED(hr))
07385 return ret;
07386 if (V_UNION1((&(pFuncDesc->lprgelemdescParam[index])), paramdesc).wParamFlags &mask)
07387 ret = Qtrue;
07388 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07389 return ret;
07390 }
07391
07392
07393
07394
07395
07396
07397
07398
07399
07400
07401
07402 static VALUE foleparam_input(VALUE self)
07403 {
07404 struct oleparamdata *pparam;
07405 Data_Get_Struct(self, struct oleparamdata, pparam);
07406 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
07407 pparam->index, PARAMFLAG_FIN);
07408 }
07409
07410
07411
07412
07413
07414
07415
07416
07417
07418
07419
07420
07421
07422
07423
07424
07425
07426
07427
07428
07429 static VALUE foleparam_output(VALUE self)
07430 {
07431 struct oleparamdata *pparam;
07432 Data_Get_Struct(self, struct oleparamdata, pparam);
07433 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
07434 pparam->index, PARAMFLAG_FOUT);
07435 }
07436
07437
07438
07439
07440
07441
07442
07443
07444
07445
07446
07447 static VALUE foleparam_optional(VALUE self)
07448 {
07449 struct oleparamdata *pparam;
07450 Data_Get_Struct(self, struct oleparamdata, pparam);
07451 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
07452 pparam->index, PARAMFLAG_FOPT);
07453 }
07454
07455
07456
07457
07458
07459
07460
07461
07462
07463
07464
07465
07466 static VALUE foleparam_retval(VALUE self)
07467 {
07468 struct oleparamdata *pparam;
07469 Data_Get_Struct(self, struct oleparamdata, pparam);
07470 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
07471 pparam->index, PARAMFLAG_FRETVAL);
07472 }
07473
07474 static VALUE
07475 ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
07476 {
07477 FUNCDESC *pFuncDesc;
07478 ELEMDESC *pElemDesc;
07479 PARAMDESCEX * pParamDescEx;
07480 HRESULT hr;
07481 USHORT wParamFlags;
07482 USHORT mask = PARAMFLAG_FOPT|PARAMFLAG_FHASDEFAULT;
07483 VALUE defval = Qnil;
07484 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
07485 if (FAILED(hr))
07486 return defval;
07487 pElemDesc = &pFuncDesc->lprgelemdescParam[index];
07488 wParamFlags = V_UNION1(pElemDesc, paramdesc).wParamFlags;
07489 if ((wParamFlags & mask) == mask) {
07490 pParamDescEx = V_UNION1(pElemDesc, paramdesc).pparamdescex;
07491 defval = ole_variant2val(&pParamDescEx->varDefaultValue);
07492 }
07493 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
07494 return defval;
07495 }
07496
07497
07498
07499
07500
07501
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 static VALUE foleparam_default(VALUE self)
07527 {
07528 struct oleparamdata *pparam;
07529 Data_Get_Struct(self, struct oleparamdata, pparam);
07530 return ole_param_default(pparam->pTypeInfo, pparam->method_index,
07531 pparam->index);
07532 }
07533
07534
07535
07536
07537
07538
07539
07540
07541
07542 static VALUE
07543 foleparam_inspect(VALUE self)
07544 {
07545 VALUE detail = foleparam_name(self);
07546 VALUE defval = foleparam_default(self);
07547 if (defval != Qnil) {
07548 rb_str_cat2(detail, "=");
07549 rb_str_concat(detail, rb_funcall(defval, rb_intern("inspect"), 0));
07550 }
07551 return make_inspect("WIN32OLE_PARAM", detail);
07552 }
07553
07554
07555
07556
07557
07558
07559
07560 static IEventSinkVtbl vtEventSink;
07561 static BOOL g_IsEventSinkVtblInitialized = FALSE;
07562
07563 void EVENTSINK_Destructor(PIEVENTSINKOBJ);
07564
07565 STDMETHODIMP
07566 EVENTSINK_QueryInterface(
07567 PEVENTSINK pEV,
07568 REFIID iid,
07569 LPVOID* ppv
07570 ) {
07571 if (IsEqualIID(iid, &IID_IUnknown) ||
07572 IsEqualIID(iid, &IID_IDispatch) ||
07573 IsEqualIID(iid, &((PIEVENTSINKOBJ)pEV)->m_iid)) {
07574 *ppv = pEV;
07575 }
07576 else {
07577 *ppv = NULL;
07578 return E_NOINTERFACE;
07579 }
07580 ((LPUNKNOWN)*ppv)->lpVtbl->AddRef((LPUNKNOWN)*ppv);
07581 return NOERROR;
07582 }
07583
07584 STDMETHODIMP_(ULONG)
07585 EVENTSINK_AddRef(
07586 PEVENTSINK pEV
07587 ){
07588 PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV;
07589 return ++pEVObj->m_cRef;
07590 }
07591
07592 STDMETHODIMP_(ULONG) EVENTSINK_Release(
07593 PEVENTSINK pEV
07594 ) {
07595 PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV;
07596 --pEVObj->m_cRef;
07597 if(pEVObj->m_cRef != 0)
07598 return pEVObj->m_cRef;
07599 EVENTSINK_Destructor(pEVObj);
07600 return 0;
07601 }
07602
07603 STDMETHODIMP EVENTSINK_GetTypeInfoCount(
07604 PEVENTSINK pEV,
07605 UINT *pct
07606 ) {
07607 *pct = 0;
07608 return NOERROR;
07609 }
07610
07611 STDMETHODIMP EVENTSINK_GetTypeInfo(
07612 PEVENTSINK pEV,
07613 UINT info,
07614 LCID lcid,
07615 ITypeInfo **pInfo
07616 ) {
07617 *pInfo = NULL;
07618 return DISP_E_BADINDEX;
07619 }
07620
07621 STDMETHODIMP EVENTSINK_GetIDsOfNames(
07622 PEVENTSINK pEventSink,
07623 REFIID riid,
07624 OLECHAR **szNames,
07625 UINT cNames,
07626 LCID lcid,
07627 DISPID *pDispID
07628 ) {
07629 ITypeInfo *pTypeInfo;
07630 PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink;
07631 pTypeInfo = pEV->pTypeInfo;
07632 if (pTypeInfo) {
07633 return pTypeInfo->lpVtbl->GetIDsOfNames(pTypeInfo, szNames, cNames, pDispID);
07634 }
07635 return DISP_E_UNKNOWNNAME;
07636 }
07637
07638 static long
07639 ole_search_event_at(VALUE ary, VALUE ev)
07640 {
07641 VALUE event;
07642 VALUE def_event;
07643 VALUE event_name;
07644 long i, len;
07645 long ret = -1;
07646 def_event = Qnil;
07647 len = RARRAY_LEN(ary);
07648 for(i = 0; i < len; i++) {
07649 event = rb_ary_entry(ary, i);
07650 event_name = rb_ary_entry(event, 1);
07651 if(NIL_P(event_name) && NIL_P(ev)) {
07652 ret = i;
07653 break;
07654 }
07655 else if (TYPE(ev) == T_STRING &&
07656 TYPE(event_name) == T_STRING &&
07657 rb_str_cmp(ev, event_name) == 0) {
07658 ret = i;
07659 break;
07660 }
07661 }
07662 return ret;
07663 }
07664
07665 static VALUE
07666 ole_search_event(VALUE ary, VALUE ev, BOOL *is_default)
07667 {
07668 VALUE event;
07669 VALUE def_event;
07670 VALUE event_name;
07671 int i, len;
07672 *is_default = FALSE;
07673 def_event = Qnil;
07674 len = RARRAY_LEN(ary);
07675 for(i = 0; i < len; i++) {
07676 event = rb_ary_entry(ary, i);
07677 event_name = rb_ary_entry(event, 1);
07678 if(NIL_P(event_name)) {
07679 *is_default = TRUE;
07680 def_event = event;
07681 }
07682 else if (rb_str_cmp(ev, event_name) == 0) {
07683 *is_default = FALSE;
07684 return event;
07685 }
07686 }
07687 return def_event;
07688 }
07689 static VALUE
07690 ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler)
07691 {
07692 VALUE mid;
07693
07694 *is_default_handler = FALSE;
07695 mid = rb_to_id(rb_sprintf("on%s", StringValuePtr(ev)));
07696 if (rb_respond_to(handler, mid)) {
07697 return mid;
07698 }
07699 mid = rb_intern("method_missing");
07700 if (rb_respond_to(handler, mid)) {
07701 *is_default_handler = TRUE;
07702 return mid;
07703 }
07704 return Qnil;
07705 }
07706
07707 static void
07708 ole_delete_event(VALUE ary, VALUE ev)
07709 {
07710 long at = -1;
07711 at = ole_search_event_at(ary, ev);
07712 if (at >= 0) {
07713 rb_ary_delete_at(ary, at);
07714 }
07715 }
07716
07717 static void
07718 hash2ptr_dispparams(VALUE hash, ITypeInfo *pTypeInfo, DISPID dispid, DISPPARAMS *pdispparams)
07719 {
07720 BSTR *bstrs;
07721 HRESULT hr;
07722 UINT len, i;
07723 VARIANT *pvar;
07724 VALUE val;
07725 VALUE key;
07726 len = 0;
07727 bstrs = ALLOCA_N(BSTR, pdispparams->cArgs + 1);
07728 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid,
07729 bstrs, pdispparams->cArgs + 1,
07730 &len);
07731 if (FAILED(hr))
07732 return;
07733
07734 for (i = 0; i < len - 1; i++) {
07735 key = WC2VSTR(bstrs[i + 1]);
07736 val = rb_hash_aref(hash, INT2FIX(i));
07737 if (val == Qnil)
07738 val = rb_hash_aref(hash, key);
07739 if (val == Qnil)
07740 val = rb_hash_aref(hash, rb_str_intern(key));
07741 pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
07742 ole_val2ptr_variant(val, pvar);
07743 }
07744 }
07745
07746 static VALUE
07747 hash2result(VALUE hash)
07748 {
07749 VALUE ret = Qnil;
07750 ret = rb_hash_aref(hash, rb_str_new2("return"));
07751 if (ret == Qnil)
07752 ret = rb_hash_aref(hash, rb_str_intern(rb_str_new2("return")));
07753 return ret;
07754 }
07755
07756 static void
07757 ary2ptr_dispparams(VALUE ary, DISPPARAMS *pdispparams)
07758 {
07759 int i;
07760 VALUE v;
07761 VARIANT *pvar;
07762 for(i = 0; i < RARRAY_LEN(ary) && (unsigned int) i < pdispparams->cArgs; i++) {
07763 v = rb_ary_entry(ary, i);
07764 pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
07765 ole_val2ptr_variant(v, pvar);
07766 }
07767 }
07768
07769 static VALUE
07770 exec_callback(VALUE arg)
07771 {
07772 VALUE *parg = (VALUE *)arg;
07773 VALUE handler = parg[0];
07774 VALUE mid = parg[1];
07775 VALUE args = parg[2];
07776 return rb_apply(handler, mid, args);
07777 }
07778
07779 static VALUE
07780 rescue_callback(VALUE arg)
07781 {
07782
07783 VALUE error;
07784 VALUE e = rb_errinfo();
07785 VALUE bt = rb_funcall(e, rb_intern("backtrace"), 0);
07786 VALUE msg = rb_funcall(e, rb_intern("message"), 0);
07787 bt = rb_ary_entry(bt, 0);
07788 error = rb_sprintf("%s: %s (%s)\n", StringValuePtr(bt), StringValuePtr(msg), rb_obj_classname(e));
07789 rb_write_error(StringValuePtr(error));
07790 rb_backtrace();
07791 ruby_finalize();
07792 exit(-1);
07793
07794 return Qnil;
07795 }
07796
07797 STDMETHODIMP EVENTSINK_Invoke(
07798 PEVENTSINK pEventSink,
07799 DISPID dispid,
07800 REFIID riid,
07801 LCID lcid,
07802 WORD wFlags,
07803 DISPPARAMS *pdispparams,
07804 VARIANT *pvarResult,
07805 EXCEPINFO *pexcepinfo,
07806 UINT *puArgErr
07807 ) {
07808
07809 HRESULT hr;
07810 BSTR bstr;
07811 unsigned int count;
07812 unsigned int i;
07813 ITypeInfo *pTypeInfo;
07814 VARIANT *pvar;
07815 VALUE ary, obj, event, args, outargv, ev, result;
07816 VALUE handler = Qnil;
07817 VALUE arg[3];
07818 VALUE mid;
07819 VALUE is_outarg = Qfalse;
07820 BOOL is_default_handler = FALSE;
07821 int state;
07822
07823 PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink;
07824 pTypeInfo = pEV->pTypeInfo;
07825 obj = evs_entry(pEV->m_event_id);
07826 if (!rb_obj_is_kind_of(obj, cWIN32OLE_EVENT)) {
07827 return NOERROR;
07828 }
07829
07830 ary = rb_ivar_get(obj, id_events);
07831 if (NIL_P(ary) || TYPE(ary) != T_ARRAY) {
07832 return NOERROR;
07833 }
07834 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid,
07835 &bstr, 1, &count);
07836 if (FAILED(hr)) {
07837 return NOERROR;
07838 }
07839 ev = WC2VSTR(bstr);
07840 event = ole_search_event(ary, ev, &is_default_handler);
07841 if (TYPE(event) == T_ARRAY) {
07842 handler = rb_ary_entry(event, 0);
07843 mid = rb_intern("call");
07844 is_outarg = rb_ary_entry(event, 3);
07845 } else {
07846 handler = rb_ivar_get(obj, rb_intern("handler"));
07847 if (handler == Qnil) {
07848 return NOERROR;
07849 }
07850 mid = ole_search_handler_method(handler, ev, &is_default_handler);
07851 }
07852 if (handler == Qnil || mid == Qnil) {
07853 return NOERROR;
07854 }
07855
07856 args = rb_ary_new();
07857 if (is_default_handler) {
07858 rb_ary_push(args, ev);
07859 }
07860
07861
07862 for (i = 0; i < pdispparams->cArgs; ++i) {
07863 pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
07864 rb_ary_push(args, ole_variant2val(pvar));
07865 }
07866 outargv = Qnil;
07867 if (is_outarg == Qtrue) {
07868 outargv = rb_ary_new();
07869 rb_ary_push(args, outargv);
07870 }
07871
07872
07873
07874
07875
07876
07877
07878
07879 arg[0] = handler;
07880 arg[1] = mid;
07881 arg[2] = args;
07882 result = rb_protect(exec_callback, (VALUE)arg, &state);
07883 if (state != 0) {
07884 rescue_callback(Qnil);
07885 }
07886 if(TYPE(result) == T_HASH) {
07887 hash2ptr_dispparams(result, pTypeInfo, dispid, pdispparams);
07888 result = hash2result(result);
07889 }else if (is_outarg == Qtrue && TYPE(outargv) == T_ARRAY) {
07890 ary2ptr_dispparams(outargv, pdispparams);
07891 }
07892
07893 if (pvarResult) {
07894 VariantInit(pvarResult);
07895 ole_val2variant(result, pvarResult);
07896 }
07897
07898 return NOERROR;
07899 }
07900
07901 PIEVENTSINKOBJ
07902 EVENTSINK_Constructor() {
07903 PIEVENTSINKOBJ pEv;
07904 if (!g_IsEventSinkVtblInitialized) {
07905 vtEventSink.QueryInterface=EVENTSINK_QueryInterface;
07906 vtEventSink.AddRef = EVENTSINK_AddRef;
07907 vtEventSink.Release = EVENTSINK_Release;
07908 vtEventSink.Invoke = EVENTSINK_Invoke;
07909 vtEventSink.GetIDsOfNames = EVENTSINK_GetIDsOfNames;
07910 vtEventSink.GetTypeInfoCount = EVENTSINK_GetTypeInfoCount;
07911 vtEventSink.GetTypeInfo = EVENTSINK_GetTypeInfo;
07912
07913 g_IsEventSinkVtblInitialized = TRUE;
07914 }
07915 pEv = ALLOC_N(IEVENTSINKOBJ, 1);
07916 if(pEv == NULL) return NULL;
07917 pEv->lpVtbl = &vtEventSink;
07918 pEv->m_cRef = 0;
07919 pEv->m_event_id = 0;
07920 pEv->pTypeInfo = NULL;
07921 return pEv;
07922 }
07923
07924 void EVENTSINK_Destructor(
07925 PIEVENTSINKOBJ pEVObj
07926 ) {
07927 if(pEVObj != NULL) {
07928 OLE_RELEASE(pEVObj->pTypeInfo);
07929 free(pEVObj);
07930 pEVObj = NULL;
07931 }
07932 }
07933
07934 static HRESULT
07935 find_iid(VALUE ole, char *pitf, IID *piid, ITypeInfo **ppTypeInfo)
07936 {
07937 HRESULT hr;
07938 IDispatch *pDispatch;
07939 ITypeInfo *pTypeInfo;
07940 ITypeLib *pTypeLib;
07941 TYPEATTR *pTypeAttr;
07942 HREFTYPE RefType;
07943 ITypeInfo *pImplTypeInfo;
07944 TYPEATTR *pImplTypeAttr;
07945
07946 struct oledata *pole;
07947 unsigned int index;
07948 unsigned int count;
07949 int type;
07950 BSTR bstr;
07951 char *pstr;
07952
07953 BOOL is_found = FALSE;
07954 LCID lcid = cWIN32OLE_lcid;
07955
07956 OLEData_Get_Struct(ole, pole);
07957
07958 pDispatch = pole->pDispatch;
07959
07960 hr = pDispatch->lpVtbl->GetTypeInfo(pDispatch, 0, lcid, &pTypeInfo);
07961 if (FAILED(hr))
07962 return hr;
07963
07964 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo,
07965 &pTypeLib,
07966 &index);
07967 OLE_RELEASE(pTypeInfo);
07968 if (FAILED(hr))
07969 return hr;
07970
07971 if (!pitf) {
07972 hr = pTypeLib->lpVtbl->GetTypeInfoOfGuid(pTypeLib,
07973 piid,
07974 ppTypeInfo);
07975 OLE_RELEASE(pTypeLib);
07976 return hr;
07977 }
07978 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
07979 for (index = 0; index < count; index++) {
07980 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib,
07981 index,
07982 &pTypeInfo);
07983 if (FAILED(hr))
07984 break;
07985 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
07986
07987 if(FAILED(hr)) {
07988 OLE_RELEASE(pTypeInfo);
07989 break;
07990 }
07991 if(pTypeAttr->typekind == TKIND_COCLASS) {
07992 for (type = 0; type < pTypeAttr->cImplTypes; type++) {
07993 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
07994 type,
07995 &RefType);
07996 if (FAILED(hr))
07997 break;
07998 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
07999 RefType,
08000 &pImplTypeInfo);
08001 if (FAILED(hr))
08002 break;
08003
08004 hr = pImplTypeInfo->lpVtbl->GetDocumentation(pImplTypeInfo,
08005 -1,
08006 &bstr,
08007 NULL, NULL, NULL);
08008 if (FAILED(hr)) {
08009 OLE_RELEASE(pImplTypeInfo);
08010 break;
08011 }
08012 pstr = ole_wc2mb(bstr);
08013 if (strcmp(pitf, pstr) == 0) {
08014 hr = pImplTypeInfo->lpVtbl->GetTypeAttr(pImplTypeInfo,
08015 &pImplTypeAttr);
08016 if (SUCCEEDED(hr)) {
08017 is_found = TRUE;
08018 *piid = pImplTypeAttr->guid;
08019 if (ppTypeInfo) {
08020 *ppTypeInfo = pImplTypeInfo;
08021 (*ppTypeInfo)->lpVtbl->AddRef((*ppTypeInfo));
08022 }
08023 pImplTypeInfo->lpVtbl->ReleaseTypeAttr(pImplTypeInfo,
08024 pImplTypeAttr);
08025 }
08026 }
08027 free(pstr);
08028 OLE_RELEASE(pImplTypeInfo);
08029 if (is_found || FAILED(hr))
08030 break;
08031 }
08032 }
08033
08034 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
08035 OLE_RELEASE(pTypeInfo);
08036 if (is_found || FAILED(hr))
08037 break;
08038 }
08039 OLE_RELEASE(pTypeLib);
08040 if(!is_found)
08041 return E_NOINTERFACE;
08042 return hr;
08043 }
08044
08045 static HRESULT
08046 find_coclass(
08047 ITypeInfo *pTypeInfo,
08048 TYPEATTR *pTypeAttr,
08049 ITypeInfo **pCOTypeInfo,
08050 TYPEATTR **pCOTypeAttr)
08051 {
08052 HRESULT hr = E_NOINTERFACE;
08053 ITypeLib *pTypeLib;
08054 int count;
08055 BOOL found = FALSE;
08056 ITypeInfo *pTypeInfo2;
08057 TYPEATTR *pTypeAttr2;
08058 int flags;
08059 int i,j;
08060 HREFTYPE href;
08061 ITypeInfo *pRefTypeInfo;
08062 TYPEATTR *pRefTypeAttr;
08063
08064 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, NULL);
08065 if (FAILED(hr)) {
08066 return hr;
08067 }
08068 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
08069 for (i = 0; i < count && !found; i++) {
08070 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo2);
08071 if (FAILED(hr))
08072 continue;
08073 hr = OLE_GET_TYPEATTR(pTypeInfo2, &pTypeAttr2);
08074 if (FAILED(hr)) {
08075 OLE_RELEASE(pTypeInfo2);
08076 continue;
08077 }
08078 if (pTypeAttr2->typekind != TKIND_COCLASS) {
08079 OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
08080 OLE_RELEASE(pTypeInfo2);
08081 continue;
08082 }
08083 for (j = 0; j < pTypeAttr2->cImplTypes && !found; j++) {
08084 hr = pTypeInfo2->lpVtbl->GetImplTypeFlags(pTypeInfo2, j, &flags);
08085 if (FAILED(hr))
08086 continue;
08087 if (!(flags & IMPLTYPEFLAG_FDEFAULT))
08088 continue;
08089 hr = pTypeInfo2->lpVtbl->GetRefTypeOfImplType(pTypeInfo2, j, &href);
08090 if (FAILED(hr))
08091 continue;
08092 hr = pTypeInfo2->lpVtbl->GetRefTypeInfo(pTypeInfo2, href, &pRefTypeInfo);
08093 if (FAILED(hr))
08094 continue;
08095 hr = OLE_GET_TYPEATTR(pRefTypeInfo, &pRefTypeAttr);
08096 if (FAILED(hr)) {
08097 OLE_RELEASE(pRefTypeInfo);
08098 continue;
08099 }
08100 if (IsEqualGUID(&(pTypeAttr->guid), &(pRefTypeAttr->guid))) {
08101 found = TRUE;
08102 }
08103 }
08104 if (!found) {
08105 OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
08106 OLE_RELEASE(pTypeInfo2);
08107 }
08108 }
08109 OLE_RELEASE(pTypeLib);
08110 if (found) {
08111 *pCOTypeInfo = pTypeInfo2;
08112 *pCOTypeAttr = pTypeAttr2;
08113 hr = S_OK;
08114 } else {
08115 hr = E_NOINTERFACE;
08116 }
08117 return hr;
08118 }
08119
08120 static HRESULT
08121 find_default_source_from_typeinfo(
08122 ITypeInfo *pTypeInfo,
08123 TYPEATTR *pTypeAttr,
08124 ITypeInfo **ppTypeInfo)
08125 {
08126 int i = 0;
08127 HRESULT hr = E_NOINTERFACE;
08128 int flags;
08129 HREFTYPE hRefType;
08130
08131 for (i = 0; i < pTypeAttr->cImplTypes; i++) {
08132 hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
08133 if (FAILED(hr))
08134 continue;
08135
08136
08137
08138
08139
08140 if ((flags & IMPLTYPEFLAG_FDEFAULT) &&
08141 (flags & IMPLTYPEFLAG_FSOURCE)) {
08142
08143 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
08144 i, &hRefType);
08145 if (FAILED(hr))
08146 continue;
08147 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
08148 hRefType, ppTypeInfo);
08149 if (SUCCEEDED(hr))
08150 break;
08151 }
08152 }
08153 return hr;
08154 }
08155
08156 static HRESULT
08157 find_default_source(VALUE ole, IID *piid, ITypeInfo **ppTypeInfo)
08158 {
08159 HRESULT hr;
08160 IProvideClassInfo2 *pProvideClassInfo2;
08161 IProvideClassInfo *pProvideClassInfo;
08162 void *p;
08163
08164 IDispatch *pDispatch;
08165 ITypeInfo *pTypeInfo;
08166 ITypeInfo *pTypeInfo2 = NULL;
08167 TYPEATTR *pTypeAttr;
08168 TYPEATTR *pTypeAttr2 = NULL;
08169
08170 struct oledata *pole;
08171
08172 OLEData_Get_Struct(ole, pole);
08173 pDispatch = pole->pDispatch;
08174 hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
08175 &IID_IProvideClassInfo2,
08176 &p);
08177 if (SUCCEEDED(hr)) {
08178 pProvideClassInfo2 = p;
08179 hr = pProvideClassInfo2->lpVtbl->GetGUID(pProvideClassInfo2,
08180 GUIDKIND_DEFAULT_SOURCE_DISP_IID,
08181 piid);
08182 OLE_RELEASE(pProvideClassInfo2);
08183 if (SUCCEEDED(hr)) {
08184 hr = find_iid(ole, NULL, piid, ppTypeInfo);
08185 }
08186 }
08187 if (SUCCEEDED(hr)) {
08188 return hr;
08189 }
08190 hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
08191 &IID_IProvideClassInfo,
08192 &p);
08193 if (SUCCEEDED(hr)) {
08194 pProvideClassInfo = p;
08195 hr = pProvideClassInfo->lpVtbl->GetClassInfo(pProvideClassInfo,
08196 &pTypeInfo);
08197 OLE_RELEASE(pProvideClassInfo);
08198 }
08199 if (FAILED(hr)) {
08200 hr = pDispatch->lpVtbl->GetTypeInfo(pDispatch, 0, cWIN32OLE_lcid, &pTypeInfo );
08201 }
08202 if (FAILED(hr))
08203 return hr;
08204 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
08205 if (FAILED(hr)) {
08206 OLE_RELEASE(pTypeInfo);
08207 return hr;
08208 }
08209
08210 *ppTypeInfo = 0;
08211 hr = find_default_source_from_typeinfo(pTypeInfo, pTypeAttr, ppTypeInfo);
08212 if (!*ppTypeInfo) {
08213 hr = find_coclass(pTypeInfo, pTypeAttr, &pTypeInfo2, &pTypeAttr2);
08214 if (SUCCEEDED(hr)) {
08215 hr = find_default_source_from_typeinfo(pTypeInfo2, pTypeAttr2, ppTypeInfo);
08216 OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
08217 OLE_RELEASE(pTypeInfo2);
08218 }
08219 }
08220 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
08221 OLE_RELEASE(pTypeInfo);
08222
08223 if (!*ppTypeInfo) {
08224 if (SUCCEEDED(hr))
08225 hr = E_UNEXPECTED;
08226 return hr;
08227 }
08228
08229
08230 hr = (*ppTypeInfo)->lpVtbl->GetTypeAttr(*ppTypeInfo, &pTypeAttr);
08231 if (SUCCEEDED(hr)) {
08232 *piid = pTypeAttr->guid;
08233 (*ppTypeInfo)->lpVtbl->ReleaseTypeAttr(*ppTypeInfo, pTypeAttr);
08234 }
08235 else
08236 OLE_RELEASE(*ppTypeInfo);
08237
08238 return hr;
08239
08240 }
08241
08242 static void
08243 ole_event_free(struct oleeventdata *poleev)
08244 {
08245 if (poleev->pConnectionPoint) {
08246 poleev->pConnectionPoint->lpVtbl->Unadvise(poleev->pConnectionPoint, poleev->dwCookie);
08247 OLE_RELEASE(poleev->pConnectionPoint);
08248 poleev->pConnectionPoint = NULL;
08249 }
08250 free(poleev);
08251 }
08252
08253 static VALUE
08254 fev_s_allocate(VALUE klass)
08255 {
08256 VALUE obj;
08257 struct oleeventdata *poleev;
08258 obj = Data_Make_Struct(klass,struct oleeventdata,0,ole_event_free,poleev);
08259 poleev->dwCookie = 0;
08260 poleev->pConnectionPoint = NULL;
08261 poleev->event_id = 0;
08262 return obj;
08263 }
08264
08265 static VALUE
08266 ev_advise(int argc, VALUE *argv, VALUE self)
08267 {
08268
08269 VALUE ole, itf;
08270 struct oledata *pole;
08271 char *pitf;
08272 HRESULT hr;
08273 IID iid;
08274 ITypeInfo *pTypeInfo = 0;
08275 IDispatch *pDispatch;
08276 IConnectionPointContainer *pContainer;
08277 IConnectionPoint *pConnectionPoint;
08278 IEVENTSINKOBJ *pIEV;
08279 DWORD dwCookie;
08280 struct oleeventdata *poleev;
08281 void *p;
08282
08283 rb_secure(4);
08284 rb_scan_args(argc, argv, "11", &ole, &itf);
08285
08286 if (!rb_obj_is_kind_of(ole, cWIN32OLE)) {
08287 rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE object");
08288 }
08289
08290 if(TYPE(itf) != T_NIL) {
08291 if (rb_safe_level() > 0 && OBJ_TAINTED(itf)) {
08292 rb_raise(rb_eSecurityError, "Insecure Event Creation - %s",
08293 StringValuePtr(itf));
08294 }
08295 SafeStringValue(itf);
08296 pitf = StringValuePtr(itf);
08297 hr = find_iid(ole, pitf, &iid, &pTypeInfo);
08298 }
08299 else {
08300 hr = find_default_source(ole, &iid, &pTypeInfo);
08301 }
08302 if (FAILED(hr)) {
08303 ole_raise(hr, rb_eRuntimeError, "interface not found");
08304 }
08305
08306 OLEData_Get_Struct(ole, pole);
08307 pDispatch = pole->pDispatch;
08308 hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
08309 &IID_IConnectionPointContainer,
08310 &p);
08311 if (FAILED(hr)) {
08312 OLE_RELEASE(pTypeInfo);
08313 ole_raise(hr, rb_eRuntimeError,
08314 "failed to query IConnectionPointContainer");
08315 }
08316 pContainer = p;
08317
08318 hr = pContainer->lpVtbl->FindConnectionPoint(pContainer,
08319 &iid,
08320 &pConnectionPoint);
08321 OLE_RELEASE(pContainer);
08322 if (FAILED(hr)) {
08323 OLE_RELEASE(pTypeInfo);
08324 ole_raise(hr, rb_eRuntimeError, "failed to query IConnectionPoint");
08325 }
08326 pIEV = EVENTSINK_Constructor();
08327 pIEV->m_iid = iid;
08328 hr = pConnectionPoint->lpVtbl->Advise(pConnectionPoint,
08329 (IUnknown*)pIEV,
08330 &dwCookie);
08331 if (FAILED(hr)) {
08332 ole_raise(hr, rb_eRuntimeError, "Advise Error");
08333 }
08334
08335 Data_Get_Struct(self, struct oleeventdata, poleev);
08336 pIEV->m_event_id
08337 = NUM2INT(evs_length());
08338 pIEV->pTypeInfo = pTypeInfo;
08339 poleev->dwCookie = dwCookie;
08340 poleev->pConnectionPoint = pConnectionPoint;
08341 poleev->event_id = pIEV->m_event_id;
08342
08343 return self;
08344 }
08345
08346
08347
08348
08349
08350
08351
08352
08353
08354
08355
08356 static VALUE
08357 fev_initialize(int argc, VALUE *argv, VALUE self)
08358 {
08359 ev_advise(argc, argv, self);
08360 evs_push(self);
08361 rb_ivar_set(self, id_events, rb_ary_new());
08362 fev_set_handler(self, Qnil);
08363 return self;
08364 }
08365
08366
08367
08368
08369
08370
08371
08372 static VALUE
08373 fev_s_msg_loop(VALUE klass)
08374 {
08375 ole_msg_loop();
08376 return Qnil;
08377 }
08378
08379
08380 static void
08381 add_event_call_back(VALUE obj, VALUE event, VALUE data)
08382 {
08383 VALUE events = rb_ivar_get(obj, id_events);
08384 if (NIL_P(events) || TYPE(events) != T_ARRAY) {
08385 events = rb_ary_new();
08386 rb_ivar_set(obj, id_events, events);
08387 }
08388 ole_delete_event(events, event);
08389 rb_ary_push(events, data);
08390 }
08391
08392 static VALUE
08393 ev_on_event(int argc, VALUE *argv, VALUE self, VALUE is_ary_arg)
08394 {
08395 struct oleeventdata *poleev;
08396 VALUE event, args, data;
08397 Data_Get_Struct(self, struct oleeventdata, poleev);
08398 if (poleev->pConnectionPoint == NULL) {
08399 rb_raise(eWIN32OLERuntimeError, "IConnectionPoint not found. You must call advise at first.");
08400 }
08401 rb_scan_args(argc, argv, "01*", &event, &args);
08402 if(!NIL_P(event)) {
08403 if(TYPE(event) != T_STRING && TYPE(event) != T_SYMBOL) {
08404 rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
08405 }
08406 if (TYPE(event) == T_SYMBOL) {
08407 event = rb_sym_to_s(event);
08408 }
08409 }
08410 data = rb_ary_new3(4, rb_block_proc(), event, args, is_ary_arg);
08411 add_event_call_back(self, event, data);
08412 return Qnil;
08413 }
08414
08415
08416
08417
08418
08419
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 static VALUE
08445 fev_on_event(int argc, VALUE *argv, VALUE self)
08446 {
08447 return ev_on_event(argc, argv, self, Qfalse);
08448 }
08449
08450
08451
08452
08453
08454
08455
08456
08457
08458
08459
08460
08461
08462
08463
08464 static VALUE
08465 fev_on_event_with_outargs(int argc, VALUE *argv, VALUE self)
08466 {
08467 return ev_on_event(argc, argv, self, Qtrue);
08468 }
08469
08470
08471
08472
08473
08474
08475
08476
08477
08478
08479
08480
08481
08482
08483
08484
08485 static VALUE
08486 fev_off_event(int argc, VALUE *argv, VALUE self)
08487 {
08488 VALUE event = Qnil;
08489 VALUE events;
08490
08491 rb_secure(4);
08492 rb_scan_args(argc, argv, "01", &event);
08493 if(!NIL_P(event)) {
08494 if(TYPE(event) != T_STRING && TYPE(event) != T_SYMBOL) {
08495 rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
08496 }
08497 if (TYPE(event) == T_SYMBOL) {
08498 event = rb_sym_to_s(event);
08499 }
08500 }
08501 events = rb_ivar_get(self, id_events);
08502 if (NIL_P(events)) {
08503 return Qnil;
08504 }
08505 ole_delete_event(events, event);
08506 return Qnil;
08507 }
08508
08509
08510
08511
08512
08513
08514
08515
08516
08517
08518
08519
08520
08521
08522
08523
08524 static VALUE
08525 fev_unadvise(VALUE self)
08526 {
08527 struct oleeventdata *poleev;
08528 Data_Get_Struct(self, struct oleeventdata, poleev);
08529 if (poleev->pConnectionPoint) {
08530 ole_msg_loop();
08531 evs_delete(poleev->event_id);
08532 poleev->pConnectionPoint->lpVtbl->Unadvise(poleev->pConnectionPoint, poleev->dwCookie);
08533 OLE_RELEASE(poleev->pConnectionPoint);
08534 poleev->pConnectionPoint = NULL;
08535 }
08536 return Qnil;
08537 }
08538
08539 static VALUE
08540 evs_push(VALUE ev)
08541 {
08542 return rb_ary_push(ary_ole_event, ev);
08543 }
08544
08545 static VALUE
08546 evs_delete(long i)
08547 {
08548 rb_ary_store(ary_ole_event, i, Qnil);
08549 return Qnil;
08550 }
08551
08552 static VALUE
08553 evs_entry(long i)
08554 {
08555 return rb_ary_entry(ary_ole_event, i);
08556 }
08557
08558 static VALUE
08559 evs_length()
08560 {
08561 return rb_funcall(ary_ole_event, rb_intern("length"), 0);
08562 }
08563
08564
08565
08566
08567
08568
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 static VALUE
08604 fev_set_handler(VALUE self, VALUE val)
08605 {
08606 return rb_ivar_set(self, rb_intern("handler"), val);
08607 }
08608
08609
08610
08611
08612
08613
08614
08615
08616 static VALUE
08617 fev_get_handler(VALUE self)
08618 {
08619 return rb_ivar_get(self, rb_intern("handler"));
08620 }
08621
08622 static void
08623 olevariant_free(struct olevariantdata *pvar)
08624 {
08625 VariantClear(&(pvar->realvar));
08626 VariantClear(&(pvar->var));
08627 free(pvar);
08628 }
08629
08630 static VALUE
08631 folevariant_s_allocate(VALUE klass)
08632 {
08633 struct olevariantdata *pvar;
08634 VALUE obj;
08635 ole_initialize();
08636 obj = Data_Make_Struct(klass,struct olevariantdata,0,olevariant_free,pvar);
08637 VariantInit(&(pvar->var));
08638 VariantInit(&(pvar->realvar));
08639 return obj;
08640 }
08641
08642
08643
08644
08645
08646
08647
08648
08649
08650
08651
08652
08653
08654
08655
08656
08657
08658 static VALUE
08659 folevariant_s_array(VALUE klass, VALUE elems, VALUE vvt)
08660 {
08661 VALUE obj = Qnil;
08662 VARTYPE vt;
08663 struct olevariantdata *pvar;
08664 SAFEARRAYBOUND *psab = NULL;
08665 SAFEARRAY *psa = NULL;
08666 UINT dim = 0;
08667 UINT i = 0;
08668
08669 ole_initialize();
08670
08671 vt = NUM2UINT(vvt);
08672 vt = (vt | VT_ARRAY);
08673 Check_Type(elems, T_ARRAY);
08674 obj = folevariant_s_allocate(klass);
08675
08676 Data_Get_Struct(obj, struct olevariantdata, pvar);
08677 dim = RARRAY_LEN(elems);
08678
08679 psab = ALLOC_N(SAFEARRAYBOUND, dim);
08680
08681 if(!psab) {
08682 rb_raise(rb_eRuntimeError, "memory allocation error");
08683 }
08684
08685 for (i = 0; i < dim; i++) {
08686 psab[i].cElements = FIX2INT(rb_ary_entry(elems, i));
08687 psab[i].lLbound = 0;
08688 }
08689
08690 psa = SafeArrayCreate((VARTYPE)(vt & VT_TYPEMASK), dim, psab);
08691 if (psa == NULL) {
08692 if (psab) free(psab);
08693 rb_raise(rb_eRuntimeError, "memory allocation error(SafeArrayCreate)");
08694 }
08695
08696 V_VT(&(pvar->var)) = vt;
08697 if (vt & VT_BYREF) {
08698 V_VT(&(pvar->realvar)) = (vt & ~VT_BYREF);
08699 V_ARRAY(&(pvar->realvar)) = psa;
08700 V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
08701 } else {
08702 V_ARRAY(&(pvar->var)) = psa;
08703 }
08704 if (psab) free(psab);
08705 return obj;
08706 }
08707
08708
08709
08710
08711
08712
08713
08714
08715
08716
08717
08718
08719
08720
08721
08722
08723
08724
08725
08726 static VALUE
08727 folevariant_initialize(VALUE self, VALUE args)
08728 {
08729 int len = 0;
08730 VARIANT var;
08731 VALUE val;
08732 VALUE vvt;
08733 VARTYPE vt;
08734 struct olevariantdata *pvar;
08735
08736 len = RARRAY_LEN(args);
08737 if (len < 1 || len > 3) {
08738 rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", len);
08739 }
08740 VariantInit(&var);
08741 val = rb_ary_entry(args, 0);
08742
08743 if(!rb_obj_is_kind_of(val, cWIN32OLE) &&
08744 !rb_obj_is_kind_of(val, cWIN32OLE_VARIANT) &&
08745 !rb_obj_is_kind_of(val, rb_cTime)) {
08746 switch (TYPE(val)) {
08747 case T_ARRAY:
08748 case T_STRING:
08749 case T_FIXNUM:
08750 case T_BIGNUM:
08751 case T_FLOAT:
08752 case T_TRUE:
08753 case T_FALSE:
08754 case T_NIL:
08755 break;
08756 default:
08757 rb_raise(rb_eTypeError, "can not convert WIN32OLE_VARIANT from type %s",
08758 rb_obj_classname(val));
08759 }
08760 }
08761
08762 Data_Get_Struct(self, struct olevariantdata, pvar);
08763 if (len == 1) {
08764 ole_val2variant(val, &(pvar->var));
08765 } else {
08766 vvt = rb_ary_entry(args, 1);
08767 vt = NUM2INT(vvt);
08768 ole_val2olevariantdata(val, vt, pvar);
08769 }
08770 vt = V_VT(&pvar->var);
08771 return self;
08772 }
08773
08774 static SAFEARRAY *
08775 get_locked_safe_array(VALUE val)
08776 {
08777 struct olevariantdata *pvar;
08778 SAFEARRAY *psa = NULL;
08779 HRESULT hr;
08780 Data_Get_Struct(val, struct olevariantdata, pvar);
08781 if (!(V_VT(&(pvar->var)) & VT_ARRAY)) {
08782 rb_raise(rb_eTypeError, "variant type is not VT_ARRAY.");
08783 }
08784 psa = V_ISBYREF(&(pvar->var)) ? *V_ARRAYREF(&(pvar->var)) : V_ARRAY(&(pvar->var));
08785 if (psa == NULL) {
08786 return psa;
08787 }
08788 hr = SafeArrayLock(psa);
08789 if (FAILED(hr)) {
08790 ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayLock");
08791 }
08792 return psa;
08793 }
08794
08795 static long *
08796 ary2safe_array_index(int ary_size, VALUE *ary, SAFEARRAY *psa)
08797 {
08798 long dim;
08799 long *pid;
08800 long i;
08801 dim = SafeArrayGetDim(psa);
08802 if (dim != ary_size) {
08803 rb_raise(rb_eArgError, "unmatch number of indices");
08804 }
08805 pid = ALLOC_N(long, dim);
08806 if (pid == NULL) {
08807 rb_raise(rb_eRuntimeError, "failed to allocate memory for indices");
08808 }
08809 for (i = 0; i < dim; i++) {
08810 pid[i] = NUM2INT(ary[i]);
08811 }
08812 return pid;
08813 }
08814
08815 static void
08816 unlock_safe_array(SAFEARRAY *psa)
08817 {
08818 HRESULT hr;
08819 hr = SafeArrayUnlock(psa);
08820 if (FAILED(hr)) {
08821 ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayUnlock");
08822 }
08823 }
08824
08825
08826
08827
08828
08829
08830
08831
08832
08833
08834
08835
08836
08837
08838
08839
08840
08841
08842
08843
08844
08845 static VALUE
08846 folevariant_ary_aref(int argc, VALUE *argv, VALUE self)
08847 {
08848 struct olevariantdata *pvar;
08849 SAFEARRAY *psa;
08850 VALUE val = Qnil;
08851 VARIANT variant;
08852 long *pid;
08853 HRESULT hr;
08854
08855 Data_Get_Struct(self, struct olevariantdata, pvar);
08856 if (!V_ISARRAY(&(pvar->var))) {
08857 rb_raise(eWIN32OLERuntimeError,
08858 "`[]' is not available for this variant type object");
08859 }
08860 psa = get_locked_safe_array(self);
08861 if (psa == NULL) {
08862 return val;
08863 }
08864
08865 pid = ary2safe_array_index(argc, argv, psa);
08866
08867 VariantInit(&variant);
08868 V_VT(&variant) = (V_VT(&(pvar->var)) & ~VT_ARRAY) | VT_BYREF;
08869 hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant));
08870 if (FAILED(hr)) {
08871 ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPtrOfIndex");
08872 }
08873 val = ole_variant2val(&variant);
08874
08875 unlock_safe_array(psa);
08876 if (pid) free(pid);
08877 return val;
08878 }
08879
08880 static VOID *
08881 val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt)
08882 {
08883 VOID *p = NULL;
08884 HRESULT hr = S_OK;
08885 ole_val2variant_ex(val, var, vt);
08886 if ((vt & ~VT_BYREF) == VT_VARIANT) {
08887 p = var;
08888 } else {
08889 if ( (vt & ~VT_BYREF) != V_VT(var)) {
08890 hr = VariantChangeTypeEx(var, var,
08891 cWIN32OLE_lcid, 0, (VARTYPE)(vt & ~VT_BYREF));
08892 if (FAILED(hr)) {
08893 ole_raise(hr, rb_eRuntimeError, "failed to change type");
08894 }
08895 }
08896 p = get_ptr_of_variant(var);
08897 }
08898 if (p == NULL) {
08899 rb_raise(rb_eRuntimeError, "failed to get pointer of variant");
08900 }
08901 return p;
08902 }
08903
08904
08905
08906
08907
08908
08909
08910
08911
08912
08913
08914
08915
08916
08917
08918
08919
08920
08921
08922
08923
08924
08925 static VALUE
08926 folevariant_ary_aset(int argc, VALUE *argv, VALUE self)
08927 {
08928 struct olevariantdata *pvar;
08929 SAFEARRAY *psa;
08930 VARIANT var;
08931 VARTYPE vt;
08932 long *pid;
08933 HRESULT hr;
08934 VOID *p = NULL;
08935
08936 Data_Get_Struct(self, struct olevariantdata, pvar);
08937 if (!V_ISARRAY(&(pvar->var))) {
08938 rb_raise(eWIN32OLERuntimeError,
08939 "`[]' is not available for this variant type object");
08940 }
08941 psa = get_locked_safe_array(self);
08942 if (psa == NULL) {
08943 rb_raise(rb_eRuntimeError, "failed to get SafeArray pointer");
08944 }
08945
08946 pid = ary2safe_array_index(argc-1, argv, psa);
08947
08948 VariantInit(&var);
08949 vt = (V_VT(&(pvar->var)) & ~VT_ARRAY);
08950 p = val2variant_ptr(argv[argc-1], &var, vt);
08951 if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) ||
08952 (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) {
08953 rb_raise(eWIN32OLERuntimeError, "argument does not have IDispatch or IUnknown Interface");
08954 }
08955 hr = SafeArrayPutElement(psa, pid, p);
08956 if (FAILED(hr)) {
08957 ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPutElement");
08958 }
08959
08960 unlock_safe_array(psa);
08961 if (pid) free(pid);
08962 return argv[argc-1];
08963 }
08964
08965
08966
08967
08968
08969
08970
08971
08972
08973
08974 static VALUE
08975 folevariant_value(VALUE self)
08976 {
08977 struct olevariantdata *pvar;
08978 VALUE val = Qnil;
08979 VARTYPE vt;
08980 int dim;
08981 SAFEARRAY *psa;
08982 Data_Get_Struct(self, struct olevariantdata, pvar);
08983
08984 val = ole_variant2val(&(pvar->var));
08985 vt = V_VT(&(pvar->var));
08986
08987 if ((vt & ~VT_BYREF) == (VT_UI1|VT_ARRAY)) {
08988 if (vt & VT_BYREF) {
08989 psa = *V_ARRAYREF(&(pvar->var));
08990 } else {
08991 psa = V_ARRAY(&(pvar->var));
08992 }
08993 if (!psa) {
08994 return val;
08995 }
08996 dim = SafeArrayGetDim(psa);
08997 if (dim == 1) {
08998 val = rb_funcall(val, rb_intern("pack"), 1, rb_str_new2("C*"));
08999 }
09000 }
09001 return val;
09002 }
09003
09004
09005
09006
09007
09008
09009
09010
09011
09012
09013 static VALUE
09014 folevariant_vartype(VALUE self)
09015 {
09016 struct olevariantdata *pvar;
09017 Data_Get_Struct(self, struct olevariantdata, pvar);
09018 return INT2FIX(V_VT(&pvar->var));
09019 }
09020
09021
09022
09023
09024
09025
09026
09027
09028
09029
09030
09031
09032
09033
09034
09035 static VALUE
09036 folevariant_set_value(VALUE self, VALUE val)
09037 {
09038 struct olevariantdata *pvar;
09039 VARTYPE vt;
09040 Data_Get_Struct(self, struct olevariantdata, pvar);
09041 vt = V_VT(&(pvar->var));
09042 if (V_ISARRAY(&(pvar->var)) && ((vt & ~VT_BYREF) != (VT_UI1|VT_ARRAY) || TYPE(val) != T_STRING)) {
09043 rb_raise(eWIN32OLERuntimeError,
09044 "`value=' is not available for this variant type object");
09045 }
09046 ole_val2olevariantdata(val, vt, pvar);
09047 return Qnil;
09048 }
09049
09050 static void
09051 init_enc2cp()
09052 {
09053 enc2cp_table = st_init_numtable();
09054 }
09055
09056 static void
09057 free_enc2cp()
09058 {
09059 st_free_table(enc2cp_table);
09060 }
09061
09062 void
09063 Init_win32ole()
09064 {
09065 ary_ole_event = rb_ary_new();
09066 rb_gc_register_mark_object(ary_ole_event);
09067 id_events = rb_intern("events");
09068
09069 com_vtbl.QueryInterface = QueryInterface;
09070 com_vtbl.AddRef = AddRef;
09071 com_vtbl.Release = Release;
09072 com_vtbl.GetTypeInfoCount = GetTypeInfoCount;
09073 com_vtbl.GetTypeInfo = GetTypeInfo;
09074 com_vtbl.GetIDsOfNames = GetIDsOfNames;
09075 com_vtbl.Invoke = Invoke;
09076
09077 message_filter.QueryInterface = mf_QueryInterface;
09078 message_filter.AddRef = mf_AddRef;
09079 message_filter.Release = mf_Release;
09080 message_filter.HandleInComingCall = mf_HandleInComingCall;
09081 message_filter.RetryRejectedCall = mf_RetryRejectedCall;
09082 message_filter.MessagePending = mf_MessagePending;
09083
09084 com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable());
09085 rb_gc_register_mark_object(com_hash);
09086
09087 cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject);
09088
09089 rb_define_alloc_func(cWIN32OLE, fole_s_allocate);
09090
09091 rb_define_method(cWIN32OLE, "initialize", fole_initialize, -1);
09092
09093 rb_define_singleton_method(cWIN32OLE, "connect", fole_s_connect, -1);
09094 rb_define_singleton_method(cWIN32OLE, "const_load", fole_s_const_load, -1);
09095
09096 rb_define_singleton_method(cWIN32OLE, "ole_free", fole_s_free, 1);
09097 rb_define_singleton_method(cWIN32OLE, "ole_reference_count", fole_s_reference_count, 1);
09098 rb_define_singleton_method(cWIN32OLE, "ole_show_help", fole_s_show_help, -1);
09099 rb_define_singleton_method(cWIN32OLE, "codepage", fole_s_get_code_page, 0);
09100 rb_define_singleton_method(cWIN32OLE, "codepage=", fole_s_set_code_page, 1);
09101 rb_define_singleton_method(cWIN32OLE, "locale", fole_s_get_locale, 0);
09102 rb_define_singleton_method(cWIN32OLE, "locale=", fole_s_set_locale, 1);
09103 rb_define_singleton_method(cWIN32OLE, "create_guid", fole_s_create_guid, 0);
09104 rb_define_singleton_method(cWIN32OLE, "ole_initialize", fole_s_ole_initialize, 0);
09105 rb_define_singleton_method(cWIN32OLE, "ole_uninitialize", fole_s_ole_uninitialize, 0);
09106
09107 rb_define_method(cWIN32OLE, "invoke", fole_invoke, -1);
09108 rb_define_method(cWIN32OLE, "[]", fole_getproperty_with_bracket, -1);
09109 rb_define_method(cWIN32OLE, "_invoke", fole_invoke2, 3);
09110 rb_define_method(cWIN32OLE, "_getproperty", fole_getproperty2, 3);
09111 rb_define_method(cWIN32OLE, "_setproperty", fole_setproperty2, 3);
09112
09113
09114 rb_define_method(cWIN32OLE, "[]=", fole_setproperty_with_bracket, -1);
09115
09116 rb_define_method(cWIN32OLE, "ole_free", fole_free, 0);
09117
09118 rb_define_method(cWIN32OLE, "each", fole_each, 0);
09119 rb_define_method(cWIN32OLE, "method_missing", fole_missing, -1);
09120
09121
09122 rb_define_method(cWIN32OLE, "setproperty", fole_setproperty, -1);
09123
09124 rb_define_method(cWIN32OLE, "ole_methods", fole_methods, 0);
09125 rb_define_method(cWIN32OLE, "ole_get_methods", fole_get_methods, 0);
09126 rb_define_method(cWIN32OLE, "ole_put_methods", fole_put_methods, 0);
09127 rb_define_method(cWIN32OLE, "ole_func_methods", fole_func_methods, 0);
09128
09129 rb_define_method(cWIN32OLE, "ole_method", fole_method_help, 1);
09130 rb_define_alias(cWIN32OLE, "ole_method_help", "ole_method");
09131 rb_define_method(cWIN32OLE, "ole_activex_initialize", fole_activex_initialize, 0);
09132 rb_define_method(cWIN32OLE, "ole_type", fole_type, 0);
09133 rb_define_alias(cWIN32OLE, "ole_obj_help", "ole_type");
09134 rb_define_method(cWIN32OLE, "ole_typelib", fole_typelib, 0);
09135 rb_define_method(cWIN32OLE, "ole_query_interface", fole_query_interface, 1);
09136 rb_define_method(cWIN32OLE, "ole_respond_to?", fole_respond_to, 1);
09137
09138 rb_define_const(cWIN32OLE, "VERSION", rb_str_new2(WIN32OLE_VERSION));
09139 rb_define_const(cWIN32OLE, "ARGV", rb_ary_new());
09140
09141 rb_define_const(cWIN32OLE, "CP_ACP", INT2FIX(CP_ACP));
09142 rb_define_const(cWIN32OLE, "CP_OEMCP", INT2FIX(CP_OEMCP));
09143 rb_define_const(cWIN32OLE, "CP_MACCP", INT2FIX(CP_MACCP));
09144 rb_define_const(cWIN32OLE, "CP_THREAD_ACP", INT2FIX(CP_THREAD_ACP));
09145 rb_define_const(cWIN32OLE, "CP_SYMBOL", INT2FIX(CP_SYMBOL));
09146 rb_define_const(cWIN32OLE, "CP_UTF7", INT2FIX(CP_UTF7));
09147 rb_define_const(cWIN32OLE, "CP_UTF8", INT2FIX(CP_UTF8));
09148
09149 rb_define_const(cWIN32OLE, "LOCALE_SYSTEM_DEFAULT", INT2FIX(LOCALE_SYSTEM_DEFAULT));
09150 rb_define_const(cWIN32OLE, "LOCALE_USER_DEFAULT", INT2FIX(LOCALE_USER_DEFAULT));
09151
09152 mWIN32OLE_VARIANT = rb_define_module_under(cWIN32OLE, "VARIANT");
09153 rb_define_const(mWIN32OLE_VARIANT, "VT_EMPTY", INT2FIX(VT_EMPTY));
09154 rb_define_const(mWIN32OLE_VARIANT, "VT_NULL", INT2FIX(VT_NULL));
09155 rb_define_const(mWIN32OLE_VARIANT, "VT_I2", INT2FIX(VT_I2));
09156 rb_define_const(mWIN32OLE_VARIANT, "VT_I4", INT2FIX(VT_I4));
09157 rb_define_const(mWIN32OLE_VARIANT, "VT_R4", INT2FIX(VT_R4));
09158 rb_define_const(mWIN32OLE_VARIANT, "VT_R8", INT2FIX(VT_R8));
09159 rb_define_const(mWIN32OLE_VARIANT, "VT_CY", INT2FIX(VT_CY));
09160 rb_define_const(mWIN32OLE_VARIANT, "VT_DATE", INT2FIX(VT_DATE));
09161 rb_define_const(mWIN32OLE_VARIANT, "VT_BSTR", INT2FIX(VT_BSTR));
09162 rb_define_const(mWIN32OLE_VARIANT, "VT_USERDEFINED", INT2FIX(VT_USERDEFINED));
09163 rb_define_const(mWIN32OLE_VARIANT, "VT_PTR", INT2FIX(VT_PTR));
09164 rb_define_const(mWIN32OLE_VARIANT, "VT_DISPATCH", INT2FIX(VT_DISPATCH));
09165 rb_define_const(mWIN32OLE_VARIANT, "VT_ERROR", INT2FIX(VT_ERROR));
09166 rb_define_const(mWIN32OLE_VARIANT, "VT_BOOL", INT2FIX(VT_BOOL));
09167 rb_define_const(mWIN32OLE_VARIANT, "VT_VARIANT", INT2FIX(VT_VARIANT));
09168 rb_define_const(mWIN32OLE_VARIANT, "VT_UNKNOWN", INT2FIX(VT_UNKNOWN));
09169 rb_define_const(mWIN32OLE_VARIANT, "VT_I1", INT2FIX(VT_I1));
09170 rb_define_const(mWIN32OLE_VARIANT, "VT_UI1", INT2FIX(VT_UI1));
09171 rb_define_const(mWIN32OLE_VARIANT, "VT_UI2", INT2FIX(VT_UI2));
09172 rb_define_const(mWIN32OLE_VARIANT, "VT_UI4", INT2FIX(VT_UI4));
09173 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
09174 rb_define_const(mWIN32OLE_VARIANT, "VT_I8", INT2FIX(VT_I8));
09175 rb_define_const(mWIN32OLE_VARIANT, "VT_UI8", INT2FIX(VT_UI8));
09176 #endif
09177 rb_define_const(mWIN32OLE_VARIANT, "VT_INT", INT2FIX(VT_INT));
09178 rb_define_const(mWIN32OLE_VARIANT, "VT_UINT", INT2FIX(VT_UINT));
09179 rb_define_const(mWIN32OLE_VARIANT, "VT_ARRAY", INT2FIX(VT_ARRAY));
09180 rb_define_const(mWIN32OLE_VARIANT, "VT_BYREF", INT2FIX(VT_BYREF));
09181
09182 cWIN32OLE_TYPELIB = rb_define_class("WIN32OLE_TYPELIB", rb_cObject);
09183 rb_define_singleton_method(cWIN32OLE_TYPELIB, "typelibs", foletypelib_s_typelibs, 0);
09184 rb_define_alloc_func(cWIN32OLE_TYPELIB, foletypelib_s_allocate);
09185 rb_define_method(cWIN32OLE_TYPELIB, "initialize", foletypelib_initialize, -2);
09186 rb_define_method(cWIN32OLE_TYPELIB, "guid", foletypelib_guid, 0);
09187 rb_define_method(cWIN32OLE_TYPELIB, "name", foletypelib_name, 0);
09188 rb_define_method(cWIN32OLE_TYPELIB, "version", foletypelib_version, 0);
09189 rb_define_method(cWIN32OLE_TYPELIB, "major_version", foletypelib_major_version, 0);
09190 rb_define_method(cWIN32OLE_TYPELIB, "minor_version", foletypelib_minor_version, 0);
09191 rb_define_method(cWIN32OLE_TYPELIB, "path", foletypelib_path, 0);
09192 rb_define_method(cWIN32OLE_TYPELIB, "ole_types", foletypelib_ole_types, 0);
09193 rb_define_alias(cWIN32OLE_TYPELIB, "ole_classes", "ole_types");
09194 rb_define_method(cWIN32OLE_TYPELIB, "visible?", foletypelib_visible, 0);
09195 rb_define_method(cWIN32OLE_TYPELIB, "library_name", foletypelib_library_name, 0);
09196 rb_define_alias(cWIN32OLE_TYPELIB, "to_s", "name");
09197 rb_define_method(cWIN32OLE_TYPELIB, "inspect", foletypelib_inspect, 0);
09198
09199 cWIN32OLE_TYPE = rb_define_class("WIN32OLE_TYPE", rb_cObject);
09200 rb_define_singleton_method(cWIN32OLE_TYPE, "ole_classes", foletype_s_ole_classes, 1);
09201 rb_define_singleton_method(cWIN32OLE_TYPE, "typelibs", foletype_s_typelibs, 0);
09202 rb_define_singleton_method(cWIN32OLE_TYPE, "progids", foletype_s_progids, 0);
09203 rb_define_alloc_func(cWIN32OLE_TYPE, foletype_s_allocate);
09204 rb_define_method(cWIN32OLE_TYPE, "initialize", foletype_initialize, 2);
09205 rb_define_method(cWIN32OLE_TYPE, "name", foletype_name, 0);
09206 rb_define_method(cWIN32OLE_TYPE, "ole_type", foletype_ole_type, 0);
09207 rb_define_method(cWIN32OLE_TYPE, "guid", foletype_guid, 0);
09208 rb_define_method(cWIN32OLE_TYPE, "progid", foletype_progid, 0);
09209 rb_define_method(cWIN32OLE_TYPE, "visible?", foletype_visible, 0);
09210 rb_define_alias(cWIN32OLE_TYPE, "to_s", "name");
09211 rb_define_method(cWIN32OLE_TYPE, "major_version", foletype_major_version, 0);
09212 rb_define_method(cWIN32OLE_TYPE, "minor_version", foletype_minor_version, 0);
09213 rb_define_method(cWIN32OLE_TYPE, "typekind", foletype_typekind, 0);
09214 rb_define_method(cWIN32OLE_TYPE, "helpstring", foletype_helpstring, 0);
09215 rb_define_method(cWIN32OLE_TYPE, "src_type", foletype_src_type, 0);
09216 rb_define_method(cWIN32OLE_TYPE, "helpfile", foletype_helpfile, 0);
09217 rb_define_method(cWIN32OLE_TYPE, "helpcontext", foletype_helpcontext, 0);
09218 rb_define_method(cWIN32OLE_TYPE, "variables", foletype_variables, 0);
09219 rb_define_method(cWIN32OLE_TYPE, "ole_methods", foletype_methods, 0);
09220 rb_define_method(cWIN32OLE_TYPE, "ole_typelib", foletype_ole_typelib, 0);
09221 rb_define_method(cWIN32OLE_TYPE, "implemented_ole_types", foletype_impl_ole_types, 0);
09222 rb_define_method(cWIN32OLE_TYPE, "source_ole_types", foletype_source_ole_types, 0);
09223 rb_define_method(cWIN32OLE_TYPE, "default_event_sources", foletype_default_event_sources, 0);
09224 rb_define_method(cWIN32OLE_TYPE, "default_ole_types", foletype_default_ole_types, 0);
09225 rb_define_method(cWIN32OLE_TYPE, "inspect", foletype_inspect, 0);
09226
09227 cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject);
09228 rb_define_method(cWIN32OLE_VARIABLE, "name", folevariable_name, 0);
09229 rb_define_method(cWIN32OLE_VARIABLE, "ole_type", folevariable_ole_type, 0);
09230 rb_define_method(cWIN32OLE_VARIABLE, "ole_type_detail", folevariable_ole_type_detail, 0);
09231 rb_define_method(cWIN32OLE_VARIABLE, "value", folevariable_value, 0);
09232 rb_define_method(cWIN32OLE_VARIABLE, "visible?", folevariable_visible, 0);
09233 rb_define_method(cWIN32OLE_VARIABLE, "variable_kind", folevariable_variable_kind, 0);
09234 rb_define_method(cWIN32OLE_VARIABLE, "varkind", folevariable_varkind, 0);
09235 rb_define_method(cWIN32OLE_VARIABLE, "inspect", folevariable_inspect, 0);
09236 rb_define_alias(cWIN32OLE_VARIABLE, "to_s", "name");
09237
09238 cWIN32OLE_METHOD = rb_define_class("WIN32OLE_METHOD", rb_cObject);
09239 rb_define_alloc_func(cWIN32OLE_METHOD, folemethod_s_allocate);
09240 rb_define_method(cWIN32OLE_METHOD, "initialize", folemethod_initialize, 2);
09241 rb_define_method(cWIN32OLE_METHOD, "name", folemethod_name, 0);
09242 rb_define_method(cWIN32OLE_METHOD, "return_type", folemethod_return_type, 0);
09243 rb_define_method(cWIN32OLE_METHOD, "return_vtype", folemethod_return_vtype, 0);
09244 rb_define_method(cWIN32OLE_METHOD, "return_type_detail", folemethod_return_type_detail, 0);
09245 rb_define_method(cWIN32OLE_METHOD, "invoke_kind", folemethod_invoke_kind, 0);
09246 rb_define_method(cWIN32OLE_METHOD, "invkind", folemethod_invkind, 0);
09247 rb_define_method(cWIN32OLE_METHOD, "visible?", folemethod_visible, 0);
09248 rb_define_method(cWIN32OLE_METHOD, "event?", folemethod_event, 0);
09249 rb_define_method(cWIN32OLE_METHOD, "event_interface", folemethod_event_interface, 0);
09250 rb_define_method(cWIN32OLE_METHOD, "helpstring", folemethod_helpstring, 0);
09251 rb_define_method(cWIN32OLE_METHOD, "helpfile", folemethod_helpfile, 0);
09252 rb_define_method(cWIN32OLE_METHOD, "helpcontext", folemethod_helpcontext, 0);
09253 rb_define_method(cWIN32OLE_METHOD, "dispid", folemethod_dispid, 0);
09254 rb_define_method(cWIN32OLE_METHOD, "offset_vtbl", folemethod_offset_vtbl, 0);
09255 rb_define_method(cWIN32OLE_METHOD, "size_params", folemethod_size_params, 0);
09256 rb_define_method(cWIN32OLE_METHOD, "size_opt_params", folemethod_size_opt_params, 0);
09257 rb_define_method(cWIN32OLE_METHOD, "params", folemethod_params, 0);
09258 rb_define_alias(cWIN32OLE_METHOD, "to_s", "name");
09259 rb_define_method(cWIN32OLE_METHOD, "inspect", folemethod_inspect, 0);
09260
09261 cWIN32OLE_PARAM = rb_define_class("WIN32OLE_PARAM", rb_cObject);
09262 rb_define_alloc_func(cWIN32OLE_PARAM, foleparam_s_allocate);
09263 rb_define_method(cWIN32OLE_PARAM, "initialize", foleparam_initialize, 2);
09264 rb_define_method(cWIN32OLE_PARAM, "name", foleparam_name, 0);
09265 rb_define_method(cWIN32OLE_PARAM, "ole_type", foleparam_ole_type, 0);
09266 rb_define_method(cWIN32OLE_PARAM, "ole_type_detail", foleparam_ole_type_detail, 0);
09267 rb_define_method(cWIN32OLE_PARAM, "input?", foleparam_input, 0);
09268 rb_define_method(cWIN32OLE_PARAM, "output?", foleparam_output, 0);
09269 rb_define_method(cWIN32OLE_PARAM, "optional?", foleparam_optional, 0);
09270 rb_define_method(cWIN32OLE_PARAM, "retval?", foleparam_retval, 0);
09271 rb_define_method(cWIN32OLE_PARAM, "default", foleparam_default, 0);
09272 rb_define_alias(cWIN32OLE_PARAM, "to_s", "name");
09273 rb_define_method(cWIN32OLE_PARAM, "inspect", foleparam_inspect, 0);
09274
09275 cWIN32OLE_EVENT = rb_define_class("WIN32OLE_EVENT", rb_cObject);
09276 rb_define_singleton_method(cWIN32OLE_EVENT, "message_loop", fev_s_msg_loop, 0);
09277 rb_define_alloc_func(cWIN32OLE_EVENT, fev_s_allocate);
09278 rb_define_method(cWIN32OLE_EVENT, "initialize", fev_initialize, -1);
09279 rb_define_method(cWIN32OLE_EVENT, "on_event", fev_on_event, -1);
09280 rb_define_method(cWIN32OLE_EVENT, "on_event_with_outargs", fev_on_event_with_outargs, -1);
09281 rb_define_method(cWIN32OLE_EVENT, "off_event", fev_off_event, -1);
09282 rb_define_method(cWIN32OLE_EVENT, "unadvise", fev_unadvise, 0);
09283 rb_define_method(cWIN32OLE_EVENT, "handler=", fev_set_handler, 1);
09284 rb_define_method(cWIN32OLE_EVENT, "handler", fev_get_handler, 0);
09285
09286 cWIN32OLE_VARIANT = rb_define_class("WIN32OLE_VARIANT", rb_cObject);
09287 rb_define_alloc_func(cWIN32OLE_VARIANT, folevariant_s_allocate);
09288 rb_define_singleton_method(cWIN32OLE_VARIANT, "array", folevariant_s_array, 2);
09289 rb_define_method(cWIN32OLE_VARIANT, "initialize", folevariant_initialize, -2);
09290 rb_define_method(cWIN32OLE_VARIANT, "value", folevariant_value, 0);
09291 rb_define_method(cWIN32OLE_VARIANT, "value=", folevariant_set_value, 1);
09292 rb_define_method(cWIN32OLE_VARIANT, "vartype", folevariant_vartype, 0);
09293 rb_define_method(cWIN32OLE_VARIANT, "[]", folevariant_ary_aref, -1);
09294 rb_define_method(cWIN32OLE_VARIANT, "[]=", folevariant_ary_aset, -1);
09295 rb_define_const(cWIN32OLE_VARIANT, "Empty", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_EMPTY)));
09296 rb_define_const(cWIN32OLE_VARIANT, "Null", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_NULL)));
09297 rb_define_const(cWIN32OLE_VARIANT, "Nothing", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_DISPATCH)));
09298
09299 eWIN32OLERuntimeError = rb_define_class("WIN32OLERuntimeError", rb_eRuntimeError);
09300
09301 init_enc2cp();
09302 atexit((void (*)(void))free_enc2cp);
09303 ole_init_cp();
09304 }
09305