Ruby 2.0.0p353(2013-11-22revision43784)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

win32ole.c
Go to the documentation of this file.
1 /*
2 * (c) 1995 Microsoft Corporation. All rights reserved.
3 * Developed by ActiveWare Internet Corp., http://www.ActiveWare.com
4 *
5 * Other modifications Copyright (c) 1997, 1998 by Gurusamy Sarathy
6 * <gsar@umich.edu> and Jan Dubois <jan.dubois@ibm.net>
7 *
8 * You may distribute under the terms of either the GNU General Public
9 * License or the Artistic License, as specified in the README file
10 * of the Perl distribution.
11 *
12 */
13
14 /*
15 modified for win32ole (ruby) by Masaki.Suketa <masaki.suketa@nifty.ne.jp>
16 */
17
18 #include "ruby/ruby.h"
19 #include "ruby/st.h"
20 #include "ruby/encoding.h"
21
22 #define GNUC_OLDER_3_4_4 \
23 ((__GNUC__ < 3) || \
24 ((__GNUC__ <= 3) && (__GNUC_MINOR__ < 4)) || \
25 ((__GNUC__ <= 3) && (__GNUC_MINOR__ <= 4) && (__GNUC_PATCHLEVEL__ <= 4)))
26
27 #if (defined(__GNUC__)) && (GNUC_OLDER_3_4_4)
28 #ifndef NONAMELESSUNION
29 #define NONAMELESSUNION 1
30 #endif
31 #endif
32
33 #include <ctype.h>
34
35 #include <windows.h>
36 #include <ocidl.h>
37 #include <olectl.h>
38 #include <ole2.h>
39 #if defined(HAVE_TYPE_IMULTILANGUAGE2) || defined(HAVE_TYPE_IMULTILANGUAGE)
40 #include <mlang.h>
41 #endif
42 #include <stdlib.h>
43 #include <math.h>
44 #ifdef HAVE_STDARG_PROTOTYPES
45 #include <stdarg.h>
46 #define va_init_list(a,b) va_start(a,b)
47 #else
48 #include <varargs.h>
49 #define va_init_list(a,b) va_start(a)
50 #endif
51 #include <objidl.h>
52
53 #define DOUT fprintf(stderr,"[%d]\n",__LINE__)
54 #define DOUTS(x) fprintf(stderr,"[%d]:" #x "=%s\n",__LINE__,x)
55 #define DOUTMSG(x) fprintf(stderr, "[%d]:" #x "\n",__LINE__)
56 #define DOUTI(x) fprintf(stderr, "[%ld]:" #x "=%d\n",__LINE__,x)
57 #define DOUTD(x) fprintf(stderr, "[%d]:" #x "=%f\n",__LINE__,x)
58
59 #if (defined(__GNUC__)) && (GNUC_OLDER_3_4_4)
60 #define V_UNION1(X, Y) ((X)->u.Y)
61 #else
62 #define V_UNION1(X, Y) ((X)->Y)
63 #endif
64
65 #if (defined(__GNUC__)) && (GNUC_OLDER_3_4_4)
66 #undef V_UNION
67 #define V_UNION(X,Y) ((X)->n1.n2.n3.Y)
68
69 #undef V_VT
70 #define V_VT(X) ((X)->n1.n2.vt)
71
72 #undef V_BOOL
73 #define V_BOOL(X) V_UNION(X,boolVal)
74 #endif
75
76 #ifndef V_I1REF
77 #define V_I1REF(X) V_UNION(X, pcVal)
78 #endif
79
80 #ifndef V_UI2REF
81 #define V_UI2REF(X) V_UNION(X, puiVal)
82 #endif
83
84 #ifndef V_INT
85 #define V_INT(X) V_UNION(X, intVal)
86 #endif
87
88 #ifndef V_INTREF
89 #define V_INTREF(X) V_UNION(X, pintVal)
90 #endif
91
92 #ifndef V_UINT
93 #define V_UINT(X) V_UNION(X, uintVal)
94 #endif
95
96 #ifndef V_UINTREF
97 #define V_UINTREF(X) V_UNION(X, puintVal)
98 #endif
99
100 /*
101 * unfortunately IID_IMultiLanguage2 is not included in any libXXX.a
102 * in Cygwin(mingw32).
103 */
104 #if defined(__CYGWIN__) || defined(__MINGW32__)
105 #undef IID_IMultiLanguage2
106 const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A}};
107 #endif
108
109 #define OLE_RELEASE(X) (X) ? ((X)->lpVtbl->Release(X)) : 0
110
111 #define OLE_ADDREF(X) (X) ? ((X)->lpVtbl->AddRef(X)) : 0
112
113 #define OLE_GET_TYPEATTR(X, Y) ((X)->lpVtbl->GetTypeAttr((X), (Y)))
114 #define OLE_RELEASE_TYPEATTR(X, Y) ((X)->lpVtbl->ReleaseTypeAttr((X), (Y)))
115
116 #define OLE_FREE(x) {\
117 if(g_ole_initialized == TRUE) {\
118 if(x) {\
119 OLE_RELEASE(x);\
120 (x) = 0;\
121 }\
122 }\
123 }
124
125 #define OLEData_Get_Struct(obj, pole) {\
126 Data_Get_Struct(obj, struct oledata, pole);\
127 if(!pole->pDispatch) {\
128 rb_raise(rb_eRuntimeError, "failed to get Dispatch Interface");\
129 }\
130 }
131
132 #ifdef HAVE_LONG_LONG
133 #define I8_2_NUM LL2NUM
134 #define UI8_2_NUM ULL2NUM
135 #define NUM2I8 NUM2LL
136 #define NUM2UI8 NUM2ULL
137 #else
138 #define I8_2_NUM INT2NUM
139 #define UI8_2_NUM UINT2NUM
140 #define NUM2I8 NUM2INT
141 #define NUM2UI8 NUM2UINT
142 #endif
143
144 #define WC2VSTR(x) ole_wc2vstr((x), TRUE)
145
146 #define WIN32OLE_VERSION "1.5.4"
147
148 typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
149 (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
150
151 typedef HWND (WINAPI FNHTMLHELP)(HWND hwndCaller, LPCSTR pszFile,
152 UINT uCommand, DWORD dwData);
153 typedef BOOL (FNENUMSYSEMCODEPAGES) (CODEPAGE_ENUMPROC, DWORD);
154 typedef struct {
155 struct IEventSinkVtbl * lpVtbl;
156 } IEventSink, *PEVENTSINK;
157
158 typedef struct IEventSinkVtbl IEventSinkVtbl;
159
160 struct IEventSinkVtbl {
161 STDMETHOD(QueryInterface)(
162 PEVENTSINK,
163 REFIID,
164 LPVOID *);
165 STDMETHOD_(ULONG, AddRef)(PEVENTSINK);
166 STDMETHOD_(ULONG, Release)(PEVENTSINK);
167
168 STDMETHOD(GetTypeInfoCount)(
169 PEVENTSINK,
170 UINT *);
171 STDMETHOD(GetTypeInfo)(
172 PEVENTSINK,
173 UINT,
174 LCID,
175 ITypeInfo **);
176 STDMETHOD(GetIDsOfNames)(
177 PEVENTSINK,
178 REFIID,
179 OLECHAR **,
180 UINT,
181 LCID,
182 DISPID *);
183 STDMETHOD(Invoke)(
184 PEVENTSINK,
185 DISPID,
186 REFIID,
187 LCID,
188 WORD,
189 DISPPARAMS *,
190 VARIANT *,
191 EXCEPINFO *,
192 UINT *);
193 };
194
195 typedef struct tagIEVENTSINKOBJ {
196 IEventSinkVtbl *lpVtbl;
197 DWORD m_cRef;
198 IID m_iid;
199 int m_event_id;
200 ITypeInfo *pTypeInfo;
201 }IEVENTSINKOBJ, *PIEVENTSINKOBJ;
202
203 VALUE cWIN32OLE;
204 VALUE cWIN32OLE_TYPELIB;
205 VALUE cWIN32OLE_TYPE;
206 VALUE cWIN32OLE_VARIABLE;
207 VALUE cWIN32OLE_METHOD;
208 VALUE cWIN32OLE_PARAM;
209 VALUE cWIN32OLE_EVENT;
210 VALUE cWIN32OLE_VARIANT;
211 VALUE eWIN32OLERuntimeError;
212 VALUE mWIN32OLE_VARIANT;
213 VALUE cWIN32OLE_PROPERTY;
214
215 static VALUE ary_ole_event;
216 static ID id_events;
217 #if defined(RB_THREAD_SPECIFIC) && (defined(__CYGWIN__) || defined(__MINGW32__))
218 static RB_THREAD_SPECIFIC BOOL g_ole_initialized;
219 # define g_ole_initialized_init() ((void)0)
220 # define g_ole_initialized_set(val) (g_ole_initialized = (val))
221 #else
222 static volatile DWORD g_ole_initialized_key = TLS_OUT_OF_INDEXES;
223 # define g_ole_initialized (BOOL)TlsGetValue(g_ole_initialized_key)
224 # define g_ole_initialized_init() (g_ole_initialized_key = TlsAlloc())
225 # define g_ole_initialized_set(val) TlsSetValue(g_ole_initialized_key, (void*)(val))
226 #endif
227 static BOOL g_uninitialize_hooked = FALSE;
228 static BOOL g_cp_installed = FALSE;
229 static BOOL g_lcid_installed = FALSE;
230 static HINSTANCE ghhctrl = NULL;
231 static HINSTANCE gole32 = NULL;
232 static FNCOCREATEINSTANCEEX *gCoCreateInstanceEx = NULL;
233 static VALUE com_hash;
234 static IDispatchVtbl com_vtbl;
235 static UINT cWIN32OLE_cp = CP_ACP;
236 static LCID cWIN32OLE_lcid = LOCALE_SYSTEM_DEFAULT;
237 static rb_encoding *cWIN32OLE_enc;
238 static UINT g_cp_to_check = CP_ACP;
239 static char g_lcid_to_check[8 + 1];
240 static VARTYPE g_nil_to = VT_ERROR;
241 static st_table *enc2cp_table;
242 static IMessageFilterVtbl message_filter;
243 static IMessageFilter imessage_filter = { &message_filter };
244 static IMessageFilter* previous_filter;
245
246 #if defined(HAVE_TYPE_IMULTILANGUAGE2)
247 static IMultiLanguage2 *pIMultiLanguage = NULL;
248 #elif defined(HAVE_TYPE_IMULTILANGUAGE)
249 static IMultiLanguage *pIMultiLanguage = NULL;
250 #else
251 #define pIMultiLanguage NULL /* dummy */
252 #endif
253
254 struct oledata {
255 IDispatch *pDispatch;
256 };
257
258 struct oletypelibdata {
259 ITypeLib *pTypeLib;
260 };
261
262 struct oletypedata {
263 ITypeInfo *pTypeInfo;
264 };
265
266 struct olemethoddata {
267 ITypeInfo *pOwnerTypeInfo;
268 ITypeInfo *pTypeInfo;
269 UINT index;
270 };
271
272 struct olevariabledata {
273 ITypeInfo *pTypeInfo;
274 UINT index;
275 };
276
277 struct oleparamdata {
278 ITypeInfo *pTypeInfo;
279 UINT method_index;
280 UINT index;
281 };
282
283 struct oleeventdata {
284 DWORD dwCookie;
285 IConnectionPoint *pConnectionPoint;
286 long event_id;
287 };
288
289 struct oleparam {
290 DISPPARAMS dp;
291 OLECHAR** pNamedArgs;
292 };
293
294 struct olevariantdata {
295 VARIANT realvar;
296 VARIANT var;
297 };
298
299
300 static HRESULT ( STDMETHODCALLTYPE QueryInterface )(IDispatch __RPC_FAR *, REFIID riid, void __RPC_FAR *__RPC_FAR *ppvObject);
301 static ULONG ( STDMETHODCALLTYPE AddRef )(IDispatch __RPC_FAR * This);
302 static ULONG ( STDMETHODCALLTYPE Release )(IDispatch __RPC_FAR * This);
303 static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )(IDispatch __RPC_FAR * This, UINT __RPC_FAR *pctinfo);
304 static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )(IDispatch __RPC_FAR * This, UINT iTInfo, LCID lcid, ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo);
305 static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )(IDispatch __RPC_FAR * This, REFIID riid, LPOLESTR __RPC_FAR *rgszNames, UINT cNames, LCID lcid, DISPID __RPC_FAR *rgDispId);
306 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);
307 static IDispatch* val2dispatch(VALUE val);
308 static double rbtime2vtdate(VALUE tmobj);
309 static VALUE vtdate2rbtime(double date);
310 static rb_encoding *ole_cp2encoding(UINT cp);
311 static UINT ole_encoding2cp(rb_encoding *enc);
312 NORETURN(static void failed_load_conv51932(void));
313 #ifndef pIMultiLanguage
314 static void load_conv_function51932(void);
315 #endif
316 static UINT ole_init_cp(void);
317 static char *ole_wc2mb(LPWSTR pw);
318 static VALUE ole_hresult2msg(HRESULT hr);
319 static void ole_freeexceptinfo(EXCEPINFO *pExInfo);
320 static VALUE ole_excepinfo2msg(EXCEPINFO *pExInfo);
321 static void ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...);
322 static void ole_initialize(void);
323 static void ole_msg_loop(void);
324 static void ole_free(struct oledata *pole);
325 static void oletypelib_free(struct oletypelibdata *poletypelib);
326 static void oletype_free(struct oletypedata *poletype);
327 static void olemethod_free(struct olemethoddata *polemethod);
328 static void olevariable_free(struct olevariabledata *polevar);
329 static void oleparam_free(struct oleparamdata *pole);
330 static LPWSTR ole_vstr2wc(VALUE vstr);
331 static LPWSTR ole_mb2wc(char *pm, int len);
332 static VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree);
333 static VALUE ole_ary_m_entry(VALUE val, long *pid);
334 static void * get_ptr_of_variant(VARIANT *pvar);
335 static VALUE is_all_index_under(long *pid, long *pub, long dim);
336 static void ole_set_safe_array(long n, SAFEARRAY *psa, long *pid, long *pub, VALUE val, long dim, VARTYPE vt);
337 static long dimension(VALUE val);
338 static long ary_len_of_dim(VALUE ary, long dim);
339 static HRESULT ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt);
340 static void ole_val2variant(VALUE val, VARIANT *var);
341 static void ole_val2variant_ex(VALUE val, VARIANT *var, VARTYPE vt);
342 static void ole_val2ptr_variant(VALUE val, VARIANT *var);
343 static void ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt);
344 static void ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar);
345 static void ole_val2variant2(VALUE val, VARIANT *var);
346 static VALUE make_inspect(const char *class_name, VALUE detail);
347 static VALUE default_inspect(VALUE self, const char *class_name);
348 static VALUE ole_set_member(VALUE self, IDispatch *dispatch);
349 static VALUE fole_s_allocate(VALUE klass);
350 static VALUE create_win32ole_object(VALUE klass, IDispatch *pDispatch, int argc, VALUE *argv);
351 static VALUE ary_new_dim(VALUE myary, long *pid, long *plb, long dim);
352 static void ary_store_dim(VALUE myary, long *pid, long *plb, long dim, VALUE val);
353 static VALUE ole_variant2val(VARIANT *pvar);
354 static LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey);
355 static LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey);
356 static VALUE reg_enum_key(HKEY hkey, DWORD i);
357 static VALUE reg_get_val(HKEY hkey, const char *subkey);
358 static VALUE reg_get_typelib_file_path(HKEY hkey);
359 static VALUE typelib_file_from_clsid(VALUE ole);
360 static VALUE typelib_file_from_typelib(VALUE ole);
361 static VALUE typelib_file(VALUE ole);
362 static void ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self);
363 static HRESULT clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid);
364 static VALUE ole_create_dcom(int argc, VALUE *argv, VALUE self);
365 static VALUE ole_bind_obj(VALUE moniker, int argc, VALUE *argv, VALUE self);
366 static VALUE fole_s_connect(int argc, VALUE *argv, VALUE self);
367 static VALUE fole_s_const_load(int argc, VALUE *argv, VALUE self);
368 static VALUE ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes);
369 static ULONG reference_count(struct oledata * pole);
370 static VALUE fole_s_reference_count(VALUE self, VALUE obj);
371 static VALUE fole_s_free(VALUE self, VALUE obj);
372 static HWND ole_show_help(VALUE helpfile, VALUE helpcontext);
373 static VALUE fole_s_show_help(int argc, VALUE *argv, VALUE self);
374 static VALUE fole_s_get_code_page(VALUE self);
375 static BOOL CALLBACK installed_code_page_proc(LPTSTR str);
376 static BOOL code_page_installed(UINT cp);
377 static VALUE fole_s_set_code_page(VALUE self, VALUE vcp);
378 static VALUE fole_s_get_locale(VALUE self);
379 static BOOL CALLBACK installed_lcid_proc(LPTSTR str);
380 static BOOL lcid_installed(LCID lcid);
381 static VALUE fole_s_set_locale(VALUE self, VALUE vlcid);
382 static VALUE fole_s_create_guid(VALUE self);
383 static VALUE fole_s_ole_initialize(VALUE self);
384 static VALUE fole_s_ole_uninitialize(VALUE self);
385 static VALUE fole_initialize(int argc, VALUE *argv, VALUE self);
386 static VALUE hash2named_arg(VALUE pair, struct oleparam* pOp);
387 static VALUE set_argv(VARIANTARG* realargs, unsigned int beg, unsigned int end);
388 static VALUE ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket);
389 static VALUE fole_invoke(int argc, VALUE *argv, VALUE self);
390 static VALUE ole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types, USHORT dispkind);
391 static VALUE fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types);
392 static VALUE fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types);
393 static VALUE fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types);
394 static VALUE fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self);
395 static VALUE fole_setproperty(int argc, VALUE *argv, VALUE self);
396 static VALUE fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self);
397 static VALUE ole_propertyput(VALUE self, VALUE property, VALUE value);
398 static VALUE fole_free(VALUE self);
399 static VALUE ole_each_sub(VALUE pEnumV);
400 static VALUE ole_ienum_free(VALUE pEnumV);
401 static VALUE fole_each(VALUE self);
402 static VALUE fole_missing(int argc, VALUE *argv, VALUE self);
403 static VALUE ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name);
404 static VALUE olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name);
405 static VALUE ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask);
406 static VALUE ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask);
407 static HRESULT typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti);
408 static VALUE ole_methods(VALUE self, int mask);
409 static VALUE fole_methods(VALUE self);
410 static VALUE fole_get_methods(VALUE self);
411 static VALUE fole_put_methods(VALUE self);
412 static VALUE fole_func_methods(VALUE self);
413 static VALUE ole_type_from_itypeinfo(ITypeInfo *pTypeInfo);
414 static VALUE fole_type(VALUE self);
415 static VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo);
416 static VALUE fole_typelib(VALUE self);
417 static VALUE fole_query_interface(VALUE self, VALUE str_iid);
418 static VALUE fole_respond_to(VALUE self, VALUE method);
419 static HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile);
420 static VALUE ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails);
421 static VALUE ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails);
422 static VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails);
423 static VALUE fole_method_help(VALUE self, VALUE cmdname);
424 static VALUE fole_activex_initialize(VALUE self);
425 static VALUE foletype_s_ole_classes(VALUE self, VALUE typelib);
426 static VALUE foletype_s_typelibs(VALUE self);
427 static VALUE foletype_s_progids(VALUE self);
428 static VALUE foletype_s_allocate(VALUE klass);
429 static VALUE oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name);
430 static VALUE oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass);
431 static VALUE oletypelib_set_member(VALUE self, ITypeLib *pTypeLib);
432 static ITypeLib * oletypelib_get_typelib(VALUE self);
433 static void oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr);
434 static VALUE foletypelib_s_typelibs(VALUE self);
435 static VALUE make_version_str(VALUE major, VALUE minor);
436 static VALUE oletypelib_search_registry2(VALUE self, VALUE args);
437 static VALUE oletypelib_search_registry(VALUE self, VALUE typelib);
438 static VALUE foletypelib_s_allocate(VALUE klass);
439 static VALUE foletypelib_initialize(VALUE self, VALUE args);
440 static VALUE foletypelib_guid(VALUE self);
441 static VALUE foletypelib_name(VALUE self);
442 static VALUE foletypelib_version(VALUE self);
443 static VALUE foletypelib_major_version(VALUE self);
444 static VALUE foletypelib_minor_version(VALUE self);
445 static VALUE oletypelib_path(VALUE guid, VALUE version);
446 static HRESULT oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib);
447 static VALUE foletypelib_path(VALUE self);
448 static VALUE foletypelib_visible(VALUE self);
449 static VALUE foletypelib_library_name(VALUE self);
450 static VALUE foletypelib_ole_types(VALUE self);
451 static VALUE foletypelib_inspect(VALUE self);
452 static VALUE foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass);
453 static VALUE foletype_name(VALUE self);
454 static VALUE ole_ole_type(ITypeInfo *pTypeInfo);
455 static VALUE foletype_ole_type(VALUE self);
456 static VALUE ole_type_guid(ITypeInfo *pTypeInfo);
457 static VALUE foletype_guid(VALUE self);
458 static VALUE ole_type_progid(ITypeInfo *pTypeInfo);
459 static VALUE foletype_progid(VALUE self);
460 static VALUE ole_type_visible(ITypeInfo *pTypeInfo);
461 static VALUE foletype_visible(VALUE self);
462 static VALUE ole_type_major_version(ITypeInfo *pTypeInfo);
463 static VALUE foletype_major_version(VALUE self);
464 static VALUE ole_type_minor_version(ITypeInfo *pTypeInfo);
465 static VALUE foletype_minor_version(VALUE self);
466 static VALUE ole_type_typekind(ITypeInfo *pTypeInfo);
467 static VALUE foletype_typekind(VALUE self);
468 static VALUE ole_type_helpstring(ITypeInfo *pTypeInfo);
469 static VALUE foletype_helpstring(VALUE self);
470 static VALUE ole_type_src_type(ITypeInfo *pTypeInfo);
471 static VALUE foletype_src_type(VALUE self);
472 static VALUE ole_type_helpfile(ITypeInfo *pTypeInfo);
473 static VALUE foletype_helpfile(VALUE self);
474 static VALUE ole_type_helpcontext(ITypeInfo *pTypeInfo);
475 static VALUE foletype_helpcontext(VALUE self);
476 static VALUE foletype_ole_typelib(VALUE self);
477 static VALUE ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags);
478 static VALUE foletype_impl_ole_types(VALUE self);
479 static VALUE foletype_source_ole_types(VALUE self);
480 static VALUE foletype_default_event_sources(VALUE self);
481 static VALUE foletype_default_ole_types(VALUE self);
482 static VALUE foletype_inspect(VALUE self);
483 static VALUE ole_variables(ITypeInfo *pTypeInfo);
484 static VALUE foletype_variables(VALUE self);
485 static VALUE foletype_methods(VALUE self);
486 static VALUE folevariable_name(VALUE self);
487 static VALUE ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index);
488 static VALUE folevariable_ole_type(VALUE self);
489 static VALUE ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index);
490 static VALUE folevariable_ole_type_detail(VALUE self);
491 static VALUE ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index);
492 static VALUE folevariable_value(VALUE self);
493 static VALUE ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index);
494 static VALUE folevariable_visible(VALUE self);
495 static VALUE ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index);
496 static VALUE folevariable_variable_kind(VALUE self);
497 static VALUE ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index);
498 static VALUE folevariable_varkind(VALUE self);
499 static VALUE folevariable_inspect(VALUE self);
500 static VALUE olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name);
501 static VALUE folemethod_s_allocate(VALUE klass);
502 static VALUE folemethod_initialize(VALUE self, VALUE oletype, VALUE method);
503 static VALUE folemethod_name(VALUE self);
504 static VALUE ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index);
505 static VALUE folemethod_return_type(VALUE self);
506 static VALUE ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index);
507 static VALUE folemethod_return_vtype(VALUE self);
508 static VALUE ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index);
509 static VALUE folemethod_return_type_detail(VALUE self);
510 static VALUE ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index);
511 static VALUE ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index);
512 static VALUE folemethod_invkind(VALUE self);
513 static VALUE folemethod_invoke_kind(VALUE self);
514 static VALUE ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index);
515 static VALUE folemethod_visible(VALUE self);
516 static VALUE ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name);
517 static VALUE folemethod_event(VALUE self);
518 static VALUE folemethod_event_interface(VALUE self);
519 static VALUE ole_method_docinfo_from_type(ITypeInfo *pTypeInfo, UINT method_index, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile);
520 static VALUE ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index);
521 static VALUE folemethod_helpstring(VALUE self);
522 static VALUE ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index);
523 static VALUE folemethod_helpfile(VALUE self);
524 static VALUE ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index);
525 static VALUE folemethod_helpcontext(VALUE self);
526 static VALUE ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index);
527 static VALUE folemethod_dispid(VALUE self);
528 static VALUE ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index);
529 static VALUE folemethod_offset_vtbl(VALUE self);
530 static VALUE ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index);
531 static VALUE folemethod_size_params(VALUE self);
532 static VALUE ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index);
533 static VALUE folemethod_size_opt_params(VALUE self);
534 static VALUE ole_method_params(ITypeInfo *pTypeInfo, UINT method_index);
535 static VALUE folemethod_params(VALUE self);
536 static VALUE folemethod_inspect(VALUE self);
537 static VALUE foleparam_s_allocate(VALUE klass);
538 static VALUE oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index);
539 static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n);
540 static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n);
541 static VALUE foleparam_name(VALUE self);
542 static VALUE ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index);
543 static VALUE foleparam_ole_type(VALUE self);
544 static VALUE ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index);
545 static VALUE foleparam_ole_type_detail(VALUE self);
546 static VALUE ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask);
547 static VALUE foleparam_input(VALUE self);
548 static VALUE foleparam_output(VALUE self);
549 static VALUE foleparam_optional(VALUE self);
550 static VALUE foleparam_retval(VALUE self);
551 static VALUE ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index);
552 static VALUE foleparam_default(VALUE self);
553 static VALUE foleparam_inspect(VALUE self);
554 static long ole_search_event_at(VALUE ary, VALUE ev);
555 static VALUE ole_search_event(VALUE ary, VALUE ev, BOOL *is_default);
556 static VALUE ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler);
557 static void ole_delete_event(VALUE ary, VALUE ev);
558 static void hash2ptr_dispparams(VALUE hash, ITypeInfo *pTypeInfo, DISPID dispid, DISPPARAMS *pdispparams);
559 static VALUE hash2result(VALUE hash);
560 static void ary2ptr_dispparams(VALUE ary, DISPPARAMS *pdispparams);
561 static VALUE exec_callback(VALUE arg);
562 static VALUE rescue_callback(VALUE arg);
563 static HRESULT find_iid(VALUE ole, char *pitf, IID *piid, ITypeInfo **ppTypeInfo);
564 static HRESULT find_coclass(ITypeInfo *pTypeInfo, TYPEATTR *pTypeAttr, ITypeInfo **pTypeInfo2, TYPEATTR **pTypeAttr2);
565 static HRESULT find_default_source_from_typeinfo(ITypeInfo *pTypeInfo, TYPEATTR *pTypeAttr, ITypeInfo **ppTypeInfo);
566 static HRESULT find_default_source(VALUE ole, IID *piid, ITypeInfo **ppTypeInfo);
567 static void ole_event_free(struct oleeventdata *poleev);
568 static VALUE fev_s_allocate(VALUE klass);
569 static VALUE ev_advise(int argc, VALUE *argv, VALUE self);
570 static VALUE fev_initialize(int argc, VALUE *argv, VALUE self);
571 static VALUE fev_s_msg_loop(VALUE klass);
572 static void add_event_call_back(VALUE obj, VALUE event, VALUE data);
573 static VALUE ev_on_event(int argc, VALUE *argv, VALUE self, VALUE is_ary_arg);
574 static VALUE fev_on_event(int argc, VALUE *argv, VALUE self);
575 static VALUE fev_on_event_with_outargs(int argc, VALUE *argv, VALUE self);
576 static VALUE fev_off_event(int argc, VALUE *argv, VALUE self);
577 static VALUE fev_unadvise(VALUE self);
578 static VALUE fev_set_handler(VALUE self, VALUE val);
579 static VALUE fev_get_handler(VALUE self);
580 static VALUE evs_push(VALUE ev);
581 static VALUE evs_delete(long i);
582 static VALUE evs_entry(long i);
583 static VALUE evs_length(void);
584 static void olevariant_free(struct olevariantdata *pvar);
585 static VALUE folevariant_s_allocate(VALUE klass);
586 static VALUE folevariant_s_array(VALUE klass, VALUE dims, VALUE vvt);
587 static VALUE folevariant_initialize(VALUE self, VALUE args);
588 static long *ary2safe_array_index(int ary_size, VALUE *ary, SAFEARRAY *psa);
589 static void unlock_safe_array(SAFEARRAY *psa);
590 static SAFEARRAY *get_locked_safe_array(VALUE val);
591 static VALUE folevariant_ary_aref(int argc, VALUE *argv, VALUE self);
592 static VOID * val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt);
593 static VALUE folevariant_ary_aset(int argc, VALUE *argv, VALUE self);
594 static VALUE folevariant_value(VALUE self);
595 static VALUE folevariant_vartype(VALUE self);
596 static VALUE folevariant_set_value(VALUE self, VALUE val);
597 static void init_enc2cp(void);
598 static void free_enc2cp(void);
599
600 static HRESULT (STDMETHODCALLTYPE mf_QueryInterface)(
601 IMessageFilter __RPC_FAR * This,
602 /* [in] */ REFIID riid,
603 /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
604 {
605 if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0
606 || MEMCMP(riid, &IID_IMessageFilter, GUID, 1) == 0)
607 {
608 *ppvObject = &message_filter;
609 return S_OK;
610 }
611 return E_NOINTERFACE;
612 }
613
614 static ULONG (STDMETHODCALLTYPE mf_AddRef)(
615 IMessageFilter __RPC_FAR * This)
616 {
617 return 1;
618 }
619
620 static ULONG (STDMETHODCALLTYPE mf_Release)(
621 IMessageFilter __RPC_FAR * This)
622 {
623 return 1;
624 }
625
626 static DWORD (STDMETHODCALLTYPE mf_HandleInComingCall)(
627 IMessageFilter __RPC_FAR * pThis,
628 DWORD dwCallType, //Type of incoming call
629 HTASK threadIDCaller, //Task handle calling this task
630 DWORD dwTickCount, //Elapsed tick count
631 LPINTERFACEINFO lpInterfaceInfo //Pointer to INTERFACEINFO structure
632 )
633 {
634 #ifdef DEBUG_MESSAGEFILTER
635 printf("incoming %08X, %08X, %d\n", dwCallType, threadIDCaller, dwTickCount);
636 fflush(stdout);
637 #endif
638 switch (dwCallType)
639 {
640 case CALLTYPE_ASYNC:
641 case CALLTYPE_TOPLEVEL_CALLPENDING:
642 case CALLTYPE_ASYNC_CALLPENDING:
643 if (rb_during_gc()) {
644 return SERVERCALL_RETRYLATER;
645 }
646 break;
647 default:
648 break;
649 }
650 if (previous_filter) {
651 return previous_filter->lpVtbl->HandleInComingCall(previous_filter,
652 dwCallType,
653 threadIDCaller,
654 dwTickCount,
655 lpInterfaceInfo);
656 }
657 return SERVERCALL_ISHANDLED;
658 }
659
660 static DWORD (STDMETHODCALLTYPE mf_RetryRejectedCall)(
661 IMessageFilter* pThis,
662 HTASK threadIDCallee, //Server task handle
663 DWORD dwTickCount, //Elapsed tick count
664 DWORD dwRejectType //Returned rejection message
665 )
666 {
667 if (previous_filter) {
668 return previous_filter->lpVtbl->RetryRejectedCall(previous_filter,
669 threadIDCallee,
670 dwTickCount,
671 dwRejectType);
672 }
673 return 1000;
674 }
675
676 static DWORD (STDMETHODCALLTYPE mf_MessagePending)(
677 IMessageFilter* pThis,
678 HTASK threadIDCallee, //Called applications task handle
679 DWORD dwTickCount, //Elapsed tick count
680 DWORD dwPendingType //Call type
681 )
682 {
683 if (rb_during_gc()) {
684 return PENDINGMSG_WAITNOPROCESS;
685 }
686 if (previous_filter) {
687 return previous_filter->lpVtbl->MessagePending(previous_filter,
688 threadIDCallee,
689 dwTickCount,
690 dwPendingType);
691 }
692 return PENDINGMSG_WAITNOPROCESS;
693 }
694
695 typedef struct _Win32OLEIDispatch
696 {
697 IDispatch dispatch;
698 ULONG refcount;
699 VALUE obj;
700 } Win32OLEIDispatch;
701
702 static HRESULT ( STDMETHODCALLTYPE QueryInterface )(
703 IDispatch __RPC_FAR * This,
704 /* [in] */ REFIID riid,
705 /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
706 {
707 if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0
708 || MEMCMP(riid, &IID_IDispatch, GUID, 1) == 0)
709 {
710 Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
711 p->refcount++;
712 *ppvObject = This;
713 return S_OK;
714 }
715 return E_NOINTERFACE;
716 }
717
718 static ULONG ( STDMETHODCALLTYPE AddRef )(
719 IDispatch __RPC_FAR * This)
720 {
721 Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
722 return ++(p->refcount);
723 }
724
725 static ULONG ( STDMETHODCALLTYPE Release )(
726 IDispatch __RPC_FAR * This)
727 {
728 Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
729 ULONG u = --(p->refcount);
730 if (u == 0) {
731 st_data_t key = p->obj;
732 st_delete(DATA_PTR(com_hash), &key, 0);
733 free(p);
734 }
735 return u;
736 }
737
738 static HRESULT ( STDMETHODCALLTYPE GetTypeInfoCount )(
739 IDispatch __RPC_FAR * This,
740 /* [out] */ UINT __RPC_FAR *pctinfo)
741 {
742 return E_NOTIMPL;
743 }
744
745 static HRESULT ( STDMETHODCALLTYPE GetTypeInfo )(
746 IDispatch __RPC_FAR * This,
747 /* [in] */ UINT iTInfo,
748 /* [in] */ LCID lcid,
749 /* [out] */ ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
750 {
751 return E_NOTIMPL;
752 }
753
754
755 static HRESULT ( STDMETHODCALLTYPE GetIDsOfNames )(
756 IDispatch __RPC_FAR * This,
757 /* [in] */ REFIID riid,
758 /* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
759 /* [in] */ UINT cNames,
760 /* [in] */ LCID lcid,
761 /* [size_is][out] */ DISPID __RPC_FAR *rgDispId)
762 {
763 /*
764 Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
765 */
766 char* psz = ole_wc2mb(*rgszNames); // support only one method
767 *rgDispId = rb_intern(psz);
768 free(psz);
769 return S_OK;
770 }
771
772 static /* [local] */ HRESULT ( STDMETHODCALLTYPE Invoke )(
773 IDispatch __RPC_FAR * This,
774 /* [in] */ DISPID dispIdMember,
775 /* [in] */ REFIID riid,
776 /* [in] */ LCID lcid,
777 /* [in] */ WORD wFlags,
778 /* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
779 /* [out] */ VARIANT __RPC_FAR *pVarResult,
780 /* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
781 /* [out] */ UINT __RPC_FAR *puArgErr)
782 {
783 VALUE v;
784 int i;
785 int args = pDispParams->cArgs;
786 Win32OLEIDispatch* p = (Win32OLEIDispatch*)This;
787 VALUE* parg = ALLOCA_N(VALUE, args);
788 for (i = 0; i < args; i++) {
789 *(parg + i) = ole_variant2val(&pDispParams->rgvarg[args - i - 1]);
790 }
791 if (dispIdMember == DISPID_VALUE) {
792 if (wFlags == DISPATCH_METHOD) {
793 dispIdMember = rb_intern("call");
794 } else if (wFlags & DISPATCH_PROPERTYGET) {
795 dispIdMember = rb_intern("value");
796 }
797 }
798 v = rb_funcall2(p->obj, dispIdMember, args, parg);
799 ole_val2variant(v, pVarResult);
800 return S_OK;
801 }
802
803 static IDispatch*
804 val2dispatch(VALUE val)
805 {
806 struct st_table *tbl = DATA_PTR(com_hash);
807 Win32OLEIDispatch* pdisp;
808 st_data_t data;
809
810 if (st_lookup(tbl, val, &data)) {
811 pdisp = (Win32OLEIDispatch *)(data & ~FIXNUM_FLAG);
812 pdisp->refcount++;
813 }
814 else {
815 pdisp = ALLOC(Win32OLEIDispatch);
816 pdisp->dispatch.lpVtbl = &com_vtbl;
817 pdisp->refcount = 1;
818 pdisp->obj = val;
819 st_insert(tbl, val, (VALUE)pdisp | FIXNUM_FLAG);
820 }
821 return &pdisp->dispatch;
822 }
823
824 static double
825 rbtime2vtdate(VALUE tmobj)
826 {
827 SYSTEMTIME st;
828 double t = 0;
829 memset(&st, 0, sizeof(SYSTEMTIME));
830 st.wYear = FIX2INT(rb_funcall(tmobj, rb_intern("year"), 0));
831 st.wMonth = FIX2INT(rb_funcall(tmobj, rb_intern("month"), 0));
832 st.wDay = FIX2INT(rb_funcall(tmobj, rb_intern("mday"), 0));
833 st.wHour = FIX2INT(rb_funcall(tmobj, rb_intern("hour"), 0));
834 st.wMinute = FIX2INT(rb_funcall(tmobj, rb_intern("min"), 0));
835 st.wSecond = FIX2INT(rb_funcall(tmobj, rb_intern("sec"), 0));
836 st.wMilliseconds = FIX2INT(rb_funcall(tmobj, rb_intern("nsec"), 0)) / 1000000;
837 SystemTimeToVariantTime(&st, &t);
838 return t;
839 }
840
841 static VALUE
842 vtdate2rbtime(double date)
843 {
844 SYSTEMTIME st;
845 VALUE v;
846 VariantTimeToSystemTime(date, &st);
847
848 v = rb_funcall(rb_cTime, rb_intern("new"), 6,
849 INT2FIX(st.wYear),
850 INT2FIX(st.wMonth),
851 INT2FIX(st.wDay),
852 INT2FIX(st.wHour),
853 INT2FIX(st.wMinute),
854 INT2FIX(st.wSecond));
855 if (st.wMilliseconds > 0) {
856 return rb_funcall(v, rb_intern("+"), 1, rb_float_new((double)(st.wMilliseconds / 1000.0)));
857 }
858 return v;
859 }
860
861 #define ENC_MACHING_CP(enc,encname,cp) if(strcasecmp(rb_enc_name((enc)),(encname)) == 0) return cp
862
863 static UINT ole_encoding2cp(rb_encoding *enc)
864 {
865 /*
866 * Is there any better solution to convert
867 * Ruby encoding to Windows codepage???
868 */
869 ENC_MACHING_CP(enc, "Big5", 950);
870 ENC_MACHING_CP(enc, "CP51932", 51932);
871 ENC_MACHING_CP(enc, "CP850", 850);
872 ENC_MACHING_CP(enc, "CP852", 852);
873 ENC_MACHING_CP(enc, "CP855", 855);
874 ENC_MACHING_CP(enc, "CP949", 949);
875 ENC_MACHING_CP(enc, "EUC-JP", 20932);
876 ENC_MACHING_CP(enc, "EUC-KR", 51949);
877 ENC_MACHING_CP(enc, "EUC-TW", 51950);
878 ENC_MACHING_CP(enc, "GB18030", 54936);
879 ENC_MACHING_CP(enc, "GB2312", 20936);
880 ENC_MACHING_CP(enc, "GBK", 936);
881 ENC_MACHING_CP(enc, "IBM437", 437);
882 ENC_MACHING_CP(enc, "IBM737", 737);
883 ENC_MACHING_CP(enc, "IBM775", 775);
884 ENC_MACHING_CP(enc, "IBM852", 852);
885 ENC_MACHING_CP(enc, "IBM855", 855);
886 ENC_MACHING_CP(enc, "IBM857", 857);
887 ENC_MACHING_CP(enc, "IBM860", 860);
888 ENC_MACHING_CP(enc, "IBM861", 861);
889 ENC_MACHING_CP(enc, "IBM862", 862);
890 ENC_MACHING_CP(enc, "IBM863", 863);
891 ENC_MACHING_CP(enc, "IBM864", 864);
892 ENC_MACHING_CP(enc, "IBM865", 865);
893 ENC_MACHING_CP(enc, "IBM866", 866);
894 ENC_MACHING_CP(enc, "IBM869", 869);
895 ENC_MACHING_CP(enc, "ISO-2022-JP", 50220);
896 ENC_MACHING_CP(enc, "ISO-8859-1", 28591);
897 ENC_MACHING_CP(enc, "ISO-8859-15", 28605);
898 ENC_MACHING_CP(enc, "ISO-8859-2", 28592);
899 ENC_MACHING_CP(enc, "ISO-8859-3", 28593);
900 ENC_MACHING_CP(enc, "ISO-8859-4", 28594);
901 ENC_MACHING_CP(enc, "ISO-8859-5", 28595);
902 ENC_MACHING_CP(enc, "ISO-8859-6", 28596);
903 ENC_MACHING_CP(enc, "ISO-8859-7", 28597);
904 ENC_MACHING_CP(enc, "ISO-8859-8", 28598);
905 ENC_MACHING_CP(enc, "ISO-8859-9", 28599);
906 ENC_MACHING_CP(enc, "KOI8-R", 20866);
907 ENC_MACHING_CP(enc, "KOI8-U", 21866);
908 ENC_MACHING_CP(enc, "Shift_JIS", 932);
909 ENC_MACHING_CP(enc, "UTF-16BE", 1201);
910 ENC_MACHING_CP(enc, "UTF-16LE", 1200);
911 ENC_MACHING_CP(enc, "UTF-7", 65000);
912 ENC_MACHING_CP(enc, "UTF-8", 65001);
913 ENC_MACHING_CP(enc, "Windows-1250", 1250);
914 ENC_MACHING_CP(enc, "Windows-1251", 1251);
915 ENC_MACHING_CP(enc, "Windows-1252", 1252);
916 ENC_MACHING_CP(enc, "Windows-1253", 1253);
917 ENC_MACHING_CP(enc, "Windows-1254", 1254);
918 ENC_MACHING_CP(enc, "Windows-1255", 1255);
919 ENC_MACHING_CP(enc, "Windows-1256", 1256);
920 ENC_MACHING_CP(enc, "Windows-1257", 1257);
921 ENC_MACHING_CP(enc, "Windows-1258", 1258);
922 ENC_MACHING_CP(enc, "Windows-31J", 932);
923 ENC_MACHING_CP(enc, "Windows-874", 874);
924 ENC_MACHING_CP(enc, "eucJP-ms", 20932);
925 return CP_ACP;
926 }
927
928 static void
929 failed_load_conv51932(void)
930 {
931 rb_raise(eWIN32OLERuntimeError, "fail to load convert function for CP51932");
932 }
933
934 #ifndef pIMultiLanguage
935 static void
936 load_conv_function51932(void)
937 {
938 HRESULT hr = E_NOINTERFACE;
939 void *p;
940 if (!pIMultiLanguage) {
941 #if defined(HAVE_TYPE_IMULTILANGUAGE2)
942 hr = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER,
943 &IID_IMultiLanguage2, &p);
944 #elif defined(HAVE_TYPE_IMULTILANGUAGE)
945 hr = CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER,
946 &IID_IMultiLanguage, &p);
947 #endif
948 if (FAILED(hr)) {
949 failed_load_conv51932();
950 }
951 pIMultiLanguage = p;
952 }
953 }
954 #else
955 #define load_conv_function51932() failed_load_conv51932()
956 #endif
957
958 #define conv_51932(cp) ((cp) == 51932 && (load_conv_function51932(), 1))
959
960 static void
961 set_ole_codepage(UINT cp)
962 {
963 if (code_page_installed(cp)) {
964 cWIN32OLE_cp = cp;
965 } else {
966 switch(cp) {
967 case CP_ACP:
968 case CP_OEMCP:
969 case CP_MACCP:
970 case CP_THREAD_ACP:
971 case CP_SYMBOL:
972 case CP_UTF7:
973 case CP_UTF8:
974 cWIN32OLE_cp = cp;
975 break;
976 case 51932:
977 cWIN32OLE_cp = cp;
978 load_conv_function51932();
979 break;
980 default:
981 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.");
982 break;
983 }
984 }
985 cWIN32OLE_enc = ole_cp2encoding(cWIN32OLE_cp);
986 }
987
988
989 static UINT
990 ole_init_cp(void)
991 {
992 UINT cp;
993 rb_encoding *encdef;
994 encdef = rb_default_internal_encoding();
995 if (!encdef) {
996 encdef = rb_default_external_encoding();
997 }
998 cp = ole_encoding2cp(encdef);
999 set_ole_codepage(cp);
1000 return cp;
1001 }
1002
1003 struct myCPINFOEX {
1004 UINT MaxCharSize;
1005 BYTE DefaultChar[2];
1006 BYTE LeadByte[12];
1007 WCHAR UnicodeDefaultChar;
1008 UINT CodePage;
1009 char CodePageName[MAX_PATH];
1010 };
1011
1012 static rb_encoding *
1013 ole_cp2encoding(UINT cp)
1014 {
1015 static BOOL (*pGetCPInfoEx)(UINT, DWORD, struct myCPINFOEX *) = NULL;
1016 struct myCPINFOEX* buf;
1017 VALUE enc_name;
1018 char *enc_cstr;
1019 int idx;
1020
1021 if (!code_page_installed(cp)) {
1022 switch(cp) {
1023 case CP_ACP:
1024 cp = GetACP();
1025 break;
1026 case CP_OEMCP:
1027 cp = GetOEMCP();
1028 break;
1029 case CP_MACCP:
1030 case CP_THREAD_ACP:
1031 if (!pGetCPInfoEx) {
1032 pGetCPInfoEx = (BOOL (*)(UINT, DWORD, struct myCPINFOEX *))
1033 GetProcAddress(GetModuleHandle("kernel32"), "GetCPInfoEx");
1034 if (!pGetCPInfoEx) {
1035 pGetCPInfoEx = (void*)-1;
1036 }
1037 }
1038 buf = ALLOCA_N(struct myCPINFOEX, 1);
1039 ZeroMemory(buf, sizeof(struct myCPINFOEX));
1040 if (pGetCPInfoEx == (void*)-1 || !pGetCPInfoEx(cp, 0, buf)) {
1041 rb_raise(eWIN32OLERuntimeError, "cannot map codepage to encoding.");
1042 break; /* never reach here */
1043 }
1044 cp = buf->CodePage;
1045 break;
1046 case CP_SYMBOL:
1047 case CP_UTF7:
1048 case CP_UTF8:
1049 break;
1050 case 51932:
1051 load_conv_function51932();
1052 break;
1053 default:
1054 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.");
1055 break;
1056 }
1057 }
1058
1059 enc_name = rb_sprintf("CP%d", cp);
1060 idx = rb_enc_find_index(enc_cstr = StringValueCStr(enc_name));
1061 if (idx < 0)
1062 idx = rb_define_dummy_encoding(enc_cstr);
1063 return rb_enc_from_index(idx);
1064 }
1065
1066 static char *
1067 ole_wc2mb(LPWSTR pw)
1068 {
1069 LPSTR pm;
1070 UINT size = 0;
1071 if (conv_51932(cWIN32OLE_cp)) {
1072 #ifndef pIMultiLanguage
1073 DWORD dw = 0;
1074 HRESULT hr = pIMultiLanguage->lpVtbl->ConvertStringFromUnicode(pIMultiLanguage,
1075 &dw, cWIN32OLE_cp, pw, NULL, NULL, &size);
1076 if (FAILED(hr)) {
1077 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert Unicode to CP%d", cWIN32OLE_cp);
1078 }
1079 pm = ALLOC_N(char, size + 1);
1080 hr = pIMultiLanguage->lpVtbl->ConvertStringFromUnicode(pIMultiLanguage,
1081 &dw, cWIN32OLE_cp, pw, NULL, pm, &size);
1082 if (FAILED(hr)) {
1083 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert Unicode to CP%d", cWIN32OLE_cp);
1084 }
1085 pm[size] = '\0';
1086 #endif
1087 return pm;
1088 }
1089 size = WideCharToMultiByte(cWIN32OLE_cp, 0, pw, -1, NULL, 0, NULL, NULL);
1090 if (size) {
1091 pm = ALLOC_N(char, size + 1);
1092 WideCharToMultiByte(cWIN32OLE_cp, 0, pw, -1, pm, size, NULL, NULL);
1093 pm[size] = '\0';
1094 }
1095 else {
1096 pm = ALLOC_N(char, 1);
1097 *pm = '\0';
1098 }
1099 return pm;
1100 }
1101
1102 static VALUE
1103 ole_hresult2msg(HRESULT hr)
1104 {
1105 VALUE msg = Qnil;
1106 char *p_msg = NULL;
1107 char *term = NULL;
1108 DWORD dwCount;
1109
1110 char strhr[100];
1111 sprintf(strhr, " HRESULT error code:0x%08x\n ", (unsigned)hr);
1112 msg = rb_str_new2(strhr);
1113 dwCount = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
1114 FORMAT_MESSAGE_FROM_SYSTEM |
1115 FORMAT_MESSAGE_IGNORE_INSERTS,
1116 NULL, hr,
1117 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
1118 (LPTSTR)&p_msg, 0, NULL);
1119 if (dwCount == 0) {
1120 dwCount = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
1121 FORMAT_MESSAGE_FROM_SYSTEM |
1122 FORMAT_MESSAGE_IGNORE_INSERTS,
1123 NULL, hr, cWIN32OLE_lcid,
1124 (LPTSTR)&p_msg, 0, NULL);
1125 }
1126 if (dwCount > 0) {
1127 term = p_msg + strlen(p_msg);
1128 while (p_msg < term) {
1129 term--;
1130 if (*term == '\r' || *term == '\n')
1131 *term = '\0';
1132 else break;
1133 }
1134 if (p_msg[0] != '\0') {
1135 rb_str_cat2(msg, p_msg);
1136 }
1137 }
1138 LocalFree(p_msg);
1139 return msg;
1140 }
1141
1142 static void
1143 ole_freeexceptinfo(EXCEPINFO *pExInfo)
1144 {
1145 SysFreeString(pExInfo->bstrDescription);
1146 SysFreeString(pExInfo->bstrSource);
1147 SysFreeString(pExInfo->bstrHelpFile);
1148 }
1149
1150 static VALUE
1151 ole_excepinfo2msg(EXCEPINFO *pExInfo)
1152 {
1153 char error_code[40];
1154 char *pSource = NULL;
1155 char *pDescription = NULL;
1156 VALUE error_msg;
1157 if(pExInfo->pfnDeferredFillIn != NULL) {
1158 (*pExInfo->pfnDeferredFillIn)(pExInfo);
1159 }
1160 if (pExInfo->bstrSource != NULL) {
1161 pSource = ole_wc2mb(pExInfo->bstrSource);
1162 }
1163 if (pExInfo->bstrDescription != NULL) {
1164 pDescription = ole_wc2mb(pExInfo->bstrDescription);
1165 }
1166 if(pExInfo->wCode == 0) {
1167 sprintf(error_code, "\n OLE error code:%lX in ", pExInfo->scode);
1168 }
1169 else{
1170 sprintf(error_code, "\n OLE error code:%u in ", pExInfo->wCode);
1171 }
1172 error_msg = rb_str_new2(error_code);
1173 if(pSource != NULL) {
1174 rb_str_cat(error_msg, pSource, strlen(pSource));
1175 }
1176 else {
1177 rb_str_cat(error_msg, "<Unknown>", 9);
1178 }
1179 rb_str_cat2(error_msg, "\n ");
1180 if(pDescription != NULL) {
1181 rb_str_cat2(error_msg, pDescription);
1182 }
1183 else {
1184 rb_str_cat2(error_msg, "<No Description>");
1185 }
1186 if(pSource) free(pSource);
1187 if(pDescription) free(pDescription);
1188 ole_freeexceptinfo(pExInfo);
1189 return error_msg;
1190 }
1191
1192 static void
1193 ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...)
1194 {
1195 va_list args;
1196 char buf[BUFSIZ];
1197 VALUE err_msg;
1198 va_init_list(args, fmt);
1199 vsnprintf(buf, BUFSIZ, fmt, args);
1200 va_end(args);
1201
1202 err_msg = ole_hresult2msg(hr);
1203 if(err_msg != Qnil) {
1204 rb_raise(ecs, "%s\n%s", buf, StringValuePtr(err_msg));
1205 }
1206 else {
1207 rb_raise(ecs, "%s", buf);
1208 }
1209 }
1210
1211 void
1212 ole_uninitialize(void)
1213 {
1214 if (!g_ole_initialized) return;
1215 OleUninitialize();
1216 g_ole_initialized_set(FALSE);
1217 }
1218
1219 static void
1220 ole_uninitialize_hook(rb_event_flag_t evflag, VALUE data, VALUE self, ID mid, VALUE klass)
1221 {
1222 ole_uninitialize();
1223 }
1224
1225 static void
1226 ole_initialize(void)
1227 {
1228 HRESULT hr;
1229
1230 if(!g_uninitialize_hooked) {
1231 rb_add_event_hook(ole_uninitialize_hook, RUBY_EVENT_THREAD_END, Qnil);
1232 g_uninitialize_hooked = TRUE;
1233 }
1234
1235 if(g_ole_initialized == FALSE) {
1236 hr = OleInitialize(NULL);
1237 if(FAILED(hr)) {
1238 ole_raise(hr, rb_eRuntimeError, "fail: OLE initialize");
1239 }
1240 g_ole_initialized_set(TRUE);
1241
1242 hr = CoRegisterMessageFilter(&imessage_filter, &previous_filter);
1243 if(FAILED(hr)) {
1244 previous_filter = NULL;
1245 ole_raise(hr, rb_eRuntimeError, "fail: install OLE MessageFilter");
1246 }
1247 }
1248 }
1249
1250 static void
1251 ole_msg_loop() {
1252 MSG msg;
1253 while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
1254 TranslateMessage(&msg);
1255 DispatchMessage(&msg);
1256 }
1257 }
1258
1259 static void
1260 ole_free(struct oledata *pole)
1261 {
1262 OLE_FREE(pole->pDispatch);
1263 free(pole);
1264 }
1265
1266 static void
1267 oletypelib_free(struct oletypelibdata *poletypelib)
1268 {
1269 OLE_FREE(poletypelib->pTypeLib);
1270 free(poletypelib);
1271 }
1272
1273 static void
1274 oletype_free(struct oletypedata *poletype)
1275 {
1276 OLE_FREE(poletype->pTypeInfo);
1277 free(poletype);
1278 }
1279
1280 static void
1281 olemethod_free(struct olemethoddata *polemethod)
1282 {
1283 OLE_FREE(polemethod->pTypeInfo);
1284 OLE_FREE(polemethod->pOwnerTypeInfo);
1285 free(polemethod);
1286 }
1287
1288 static void
1289 olevariable_free(struct olevariabledata *polevar)
1290 {
1291 OLE_FREE(polevar->pTypeInfo);
1292 free(polevar);
1293 }
1294
1295 static void
1296 oleparam_free(struct oleparamdata *pole)
1297 {
1298 OLE_FREE(pole->pTypeInfo);
1299 free(pole);
1300 }
1301
1302
1303 static LPWSTR
1304 ole_vstr2wc(VALUE vstr)
1305 {
1306 rb_encoding *enc;
1307 int cp;
1308 UINT size = 0;
1309 LPWSTR pw;
1310 st_data_t data;
1311 enc = rb_enc_get(vstr);
1312
1313 if (st_lookup(enc2cp_table, (st_data_t)enc, &data)) {
1314 cp = data;
1315 } else {
1316 cp = ole_encoding2cp(enc);
1317 if (code_page_installed(cp) ||
1318 cp == CP_ACP ||
1319 cp == CP_OEMCP ||
1320 cp == CP_MACCP ||
1321 cp == CP_THREAD_ACP ||
1322 cp == CP_SYMBOL ||
1323 cp == CP_UTF7 ||
1324 cp == CP_UTF8 ||
1325 cp == 51932) {
1326 st_insert(enc2cp_table, (st_data_t)enc, (st_data_t)cp);
1327 } else {
1328 rb_raise(eWIN32OLERuntimeError, "not installed Windows codepage(%d) according to `%s'", cp, rb_enc_name(enc));
1329 }
1330 }
1331 if (conv_51932(cp)) {
1332 #ifndef pIMultiLanguage
1333 DWORD dw = 0;
1334 UINT len = RSTRING_LENINT(vstr);
1335 HRESULT hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage,
1336 &dw, cp, RSTRING_PTR(vstr), &len, NULL, &size);
1337 if (FAILED(hr)) {
1338 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cp);
1339 }
1340 pw = SysAllocStringLen(NULL, size);
1341 len = RSTRING_LEN(vstr);
1342 hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage,
1343 &dw, cp, RSTRING_PTR(vstr), &len, pw, &size);
1344 if (FAILED(hr)) {
1345 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cp);
1346 }
1347 #endif
1348 return pw;
1349 }
1350 size = MultiByteToWideChar(cp, 0, RSTRING_PTR(vstr), RSTRING_LEN(vstr), NULL, 0);
1351 pw = SysAllocStringLen(NULL, size);
1352 MultiByteToWideChar(cp, 0, RSTRING_PTR(vstr), RSTRING_LEN(vstr), pw, size);
1353 return pw;
1354 }
1355
1356 static LPWSTR
1357 ole_mb2wc(char *pm, int len)
1358 {
1359 UINT size = 0;
1360 LPWSTR pw;
1361
1362 if (conv_51932(cWIN32OLE_cp)) {
1363 #ifndef pIMultiLanguage
1364 DWORD dw = 0;
1365 UINT n = len;
1366 HRESULT hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage,
1367 &dw, cWIN32OLE_cp, pm, &n, NULL, &size);
1368 if (FAILED(hr)) {
1369 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cWIN32OLE_cp);
1370 }
1371 pw = SysAllocStringLen(NULL, size);
1372 hr = pIMultiLanguage->lpVtbl->ConvertStringToUnicode(pIMultiLanguage,
1373 &dw, cWIN32OLE_cp, pm, &n, pw, &size);
1374 if (FAILED(hr)) {
1375 ole_raise(hr, eWIN32OLERuntimeError, "fail to convert CP%d to Unicode", cWIN32OLE_cp);
1376 }
1377 #endif
1378 return pw;
1379 }
1380 size = MultiByteToWideChar(cWIN32OLE_cp, 0, pm, len, NULL, 0);
1381 pw = SysAllocStringLen(NULL, size - 1);
1382 MultiByteToWideChar(cWIN32OLE_cp, 0, pm, len, pw, size);
1383 return pw;
1384 }
1385
1386 static VALUE
1387 ole_wc2vstr(LPWSTR pw, BOOL isfree)
1388 {
1389 char *p = ole_wc2mb(pw);
1390 VALUE vstr = rb_enc_str_new(p, strlen(p), cWIN32OLE_enc);
1391 if(isfree)
1392 SysFreeString(pw);
1393 free(p);
1394 return vstr;
1395 }
1396
1397 static VALUE
1398 ole_ary_m_entry(VALUE val, long *pid)
1399 {
1400 VALUE obj = Qnil;
1401 int i = 0;
1402 obj = val;
1403 while(TYPE(obj) == T_ARRAY) {
1404 obj = rb_ary_entry(obj, pid[i]);
1405 i++;
1406 }
1407 return obj;
1408 }
1409
1410 static void *
1411 get_ptr_of_variant(VARIANT *pvar)
1412 {
1413 switch(V_VT(pvar)) {
1414 case VT_UI1:
1415 return &V_UI1(pvar);
1416 break;
1417 case VT_I2:
1418 return &V_I2(pvar);
1419 break;
1420 case VT_UI2:
1421 return &V_UI2(pvar);
1422 break;
1423 case VT_I4:
1424 return &V_I4(pvar);
1425 break;
1426 case VT_UI4:
1427 return &V_UI4(pvar);
1428 break;
1429 case VT_R4:
1430 return &V_R4(pvar);
1431 break;
1432 case VT_R8:
1433 return &V_R8(pvar);
1434 break;
1435 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
1436 case VT_I8:
1437 return &V_I8(pvar);
1438 break;
1439 case VT_UI8:
1440 return &V_UI8(pvar);
1441 break;
1442 #endif
1443 case VT_INT:
1444 return &V_INT(pvar);
1445 break;
1446 case VT_UINT:
1447 return &V_UINT(pvar);
1448 break;
1449 case VT_CY:
1450 return &V_CY(pvar);
1451 break;
1452 case VT_DATE:
1453 return &V_DATE(pvar);
1454 break;
1455 case VT_BSTR:
1456 return V_BSTR(pvar);
1457 break;
1458 case VT_DISPATCH:
1459 return V_DISPATCH(pvar);
1460 break;
1461 case VT_ERROR:
1462 return &V_ERROR(pvar);
1463 break;
1464 case VT_BOOL:
1465 return &V_BOOL(pvar);
1466 break;
1467 case VT_UNKNOWN:
1468 return V_UNKNOWN(pvar);
1469 break;
1470 case VT_ARRAY:
1471 return &V_ARRAY(pvar);
1472 break;
1473 default:
1474 return NULL;
1475 break;
1476 }
1477 }
1478
1479 static VALUE
1480 is_all_index_under(long *pid, long *pub, long dim)
1481 {
1482 long i = 0;
1483 for (i = 0; i < dim; i++) {
1484 if (pid[i] > pub[i]) {
1485 return Qfalse;
1486 }
1487 }
1488 return Qtrue;
1489 }
1490
1491 static void
1492 ole_set_safe_array(long n, SAFEARRAY *psa, long *pid, long *pub, VALUE val, long dim, VARTYPE vt)
1493 {
1494 VALUE val1;
1495 HRESULT hr = S_OK;
1496 VARIANT var;
1497 VOID *p = NULL;
1498 long i = n;
1499 while(i >= 0) {
1500 val1 = ole_ary_m_entry(val, pid);
1501 VariantInit(&var);
1502 p = val2variant_ptr(val1, &var, vt);
1503 if (is_all_index_under(pid, pub, dim) == Qtrue) {
1504 if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) ||
1505 (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) {
1506 rb_raise(eWIN32OLERuntimeError, "element of array does not have IDispatch or IUnknown Interface");
1507 }
1508 hr = SafeArrayPutElement(psa, pid, p);
1509 }
1510 if (FAILED(hr)) {
1511 ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayPutElement");
1512 }
1513 pid[i] += 1;
1514 if (pid[i] > pub[i]) {
1515 pid[i] = 0;
1516 i -= 1;
1517 } else {
1518 i = dim - 1;
1519 }
1520 }
1521 }
1522
1523 static long
1524 dimension(VALUE val) {
1525 long dim = 0;
1526 long dim1 = 0;
1527 long len = 0;
1528 long i = 0;
1529 if (TYPE(val) == T_ARRAY) {
1530 len = RARRAY_LEN(val);
1531 for (i = 0; i < len; i++) {
1532 dim1 = dimension(rb_ary_entry(val, i));
1533 if (dim < dim1) {
1534 dim = dim1;
1535 }
1536 }
1537 dim += 1;
1538 }
1539 return dim;
1540 }
1541
1542 static long
1543 ary_len_of_dim(VALUE ary, long dim) {
1544 long ary_len = 0;
1545 long ary_len1 = 0;
1546 long len = 0;
1547 long i = 0;
1548 VALUE val;
1549 if (dim == 0) {
1550 if (TYPE(ary) == T_ARRAY) {
1551 ary_len = RARRAY_LEN(ary);
1552 }
1553 } else {
1554 if (TYPE(ary) == T_ARRAY) {
1555 len = RARRAY_LEN(ary);
1556 for (i = 0; i < len; i++) {
1557 val = rb_ary_entry(ary, i);
1558 ary_len1 = ary_len_of_dim(val, dim-1);
1559 if (ary_len < ary_len1) {
1560 ary_len = ary_len1;
1561 }
1562 }
1563 }
1564 }
1565 return ary_len;
1566 }
1567
1568 static HRESULT
1569 ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt)
1570 {
1571 long dim = 0;
1572 int i = 0;
1573 HRESULT hr = S_OK;
1574
1575 SAFEARRAYBOUND *psab = NULL;
1576 SAFEARRAY *psa = NULL;
1577 long *pub, *pid;
1578
1579 Check_Type(val, T_ARRAY);
1580
1581 dim = dimension(val);
1582
1583 psab = ALLOC_N(SAFEARRAYBOUND, dim);
1584 pub = ALLOC_N(long, dim);
1585 pid = ALLOC_N(long, dim);
1586
1587 if(!psab || !pub || !pid) {
1588 if(pub) free(pub);
1589 if(psab) free(psab);
1590 if(pid) free(pid);
1591 rb_raise(rb_eRuntimeError, "memory allocation error");
1592 }
1593
1594 for (i = 0; i < dim; i++) {
1595 psab[i].cElements = ary_len_of_dim(val, i);
1596 psab[i].lLbound = 0;
1597 pub[i] = psab[i].cElements - 1;
1598 pid[i] = 0;
1599 }
1600 /* Create and fill VARIANT array */
1601 if ((vt & ~VT_BYREF) == VT_ARRAY) {
1602 vt = (vt | VT_VARIANT);
1603 }
1604 psa = SafeArrayCreate((VARTYPE)(vt & VT_TYPEMASK), dim, psab);
1605 if (psa == NULL)
1606 hr = E_OUTOFMEMORY;
1607 else
1608 hr = SafeArrayLock(psa);
1609 if (SUCCEEDED(hr)) {
1610 ole_set_safe_array(dim-1, psa, pid, pub, val, dim, (VARTYPE)(vt & VT_TYPEMASK));
1611 hr = SafeArrayUnlock(psa);
1612 }
1613
1614 if(pub) free(pub);
1615 if(psab) free(psab);
1616 if(pid) free(pid);
1617
1618 if (SUCCEEDED(hr)) {
1619 V_VT(var) = vt;
1620 V_ARRAY(var) = psa;
1621 }
1622 else {
1623 if (psa != NULL)
1624 SafeArrayDestroy(psa);
1625 }
1626 return hr;
1627 }
1628
1629 static void
1630 ole_val2variant(VALUE val, VARIANT *var)
1631 {
1632 struct oledata *pole;
1633 struct olevariantdata *pvar;
1634 if(rb_obj_is_kind_of(val, cWIN32OLE)) {
1635 Data_Get_Struct(val, struct oledata, pole);
1636 OLE_ADDREF(pole->pDispatch);
1637 V_VT(var) = VT_DISPATCH;
1638 V_DISPATCH(var) = pole->pDispatch;
1639 return;
1640 }
1641 if (rb_obj_is_kind_of(val, cWIN32OLE_VARIANT)) {
1642 Data_Get_Struct(val, struct olevariantdata, pvar);
1643 VariantCopy(var, &(pvar->var));
1644 return;
1645 }
1646
1647 if (rb_obj_is_kind_of(val, rb_cTime)) {
1648 V_VT(var) = VT_DATE;
1649 V_DATE(var) = rbtime2vtdate(val);
1650 return;
1651 }
1652 switch (TYPE(val)) {
1653 case T_ARRAY:
1654 ole_val_ary2variant_ary(val, var, VT_VARIANT|VT_ARRAY);
1655 break;
1656 case T_STRING:
1657 V_VT(var) = VT_BSTR;
1658 V_BSTR(var) = ole_vstr2wc(val);
1659 break;
1660 case T_FIXNUM:
1661 V_VT(var) = VT_I4;
1662 V_I4(var) = NUM2INT(val);
1663 break;
1664 case T_BIGNUM:
1665 V_VT(var) = VT_R8;
1666 V_R8(var) = rb_big2dbl(val);
1667 break;
1668 case T_FLOAT:
1669 V_VT(var) = VT_R8;
1670 V_R8(var) = NUM2DBL(val);
1671 break;
1672 case T_TRUE:
1673 V_VT(var) = VT_BOOL;
1674 V_BOOL(var) = VARIANT_TRUE;
1675 break;
1676 case T_FALSE:
1677 V_VT(var) = VT_BOOL;
1678 V_BOOL(var) = VARIANT_FALSE;
1679 break;
1680 case T_NIL:
1681 if (g_nil_to == VT_ERROR) {
1682 V_VT(var) = VT_ERROR;
1683 V_ERROR(var) = DISP_E_PARAMNOTFOUND;
1684 }else {
1685 V_VT(var) = VT_EMPTY;
1686 }
1687 break;
1688 default:
1689 V_VT(var) = VT_DISPATCH;
1690 V_DISPATCH(var) = val2dispatch(val);
1691 break;
1692 }
1693 }
1694
1695 static void
1696 ole_val2variant_ex(VALUE val, VARIANT *var, VARTYPE vt)
1697 {
1698 if (val == Qnil) {
1699 if (vt == VT_VARIANT) {
1700 ole_val2variant2(val, var);
1701 } else {
1702 V_VT(var) = (vt & ~VT_BYREF);
1703 if (V_VT(var) == VT_DISPATCH) {
1704 V_DISPATCH(var) = NULL;
1705 } else if (V_VT(var) == VT_UNKNOWN) {
1706 V_UNKNOWN(var) = NULL;
1707 }
1708 }
1709 return;
1710 }
1711 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
1712 switch(vt & ~VT_BYREF) {
1713 case VT_I8:
1714 V_VT(var) = VT_I8;
1715 V_I8(var) = NUM2I8 (val);
1716 break;
1717 case VT_UI8:
1718 V_VT(var) = VT_UI8;
1719 V_UI8(var) = NUM2UI8(val);
1720 break;
1721 default:
1722 ole_val2variant2(val, var);
1723 break;
1724 }
1725 #else /* (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) */
1726 ole_val2variant2(val, var);
1727 #endif
1728 }
1729
1730 static void
1731 ole_val2ptr_variant(VALUE val, VARIANT *var)
1732 {
1733 switch (TYPE(val)) {
1734 case T_STRING:
1735 if (V_VT(var) == (VT_BSTR | VT_BYREF)) {
1736 *V_BSTRREF(var) = ole_vstr2wc(val);
1737 }
1738 break;
1739 case T_FIXNUM:
1740 switch(V_VT(var)) {
1741 case (VT_UI1 | VT_BYREF) :
1742 *V_UI1REF(var) = NUM2CHR(val);
1743 break;
1744 case (VT_I2 | VT_BYREF) :
1745 *V_I2REF(var) = (short)NUM2INT(val);
1746 break;
1747 case (VT_I4 | VT_BYREF) :
1748 *V_I4REF(var) = NUM2INT(val);
1749 break;
1750 case (VT_R4 | VT_BYREF) :
1751 *V_R4REF(var) = (float)NUM2INT(val);
1752 break;
1753 case (VT_R8 | VT_BYREF) :
1754 *V_R8REF(var) = NUM2INT(val);
1755 break;
1756 default:
1757 break;
1758 }
1759 break;
1760 case T_FLOAT:
1761 switch(V_VT(var)) {
1762 case (VT_I2 | VT_BYREF) :
1763 *V_I2REF(var) = (short)NUM2INT(val);
1764 break;
1765 case (VT_I4 | VT_BYREF) :
1766 *V_I4REF(var) = NUM2INT(val);
1767 break;
1768 case (VT_R4 | VT_BYREF) :
1769 *V_R4REF(var) = (float)NUM2DBL(val);
1770 break;
1771 case (VT_R8 | VT_BYREF) :
1772 *V_R8REF(var) = NUM2DBL(val);
1773 break;
1774 default:
1775 break;
1776 }
1777 break;
1778 case T_BIGNUM:
1779 if (V_VT(var) == (VT_R8 | VT_BYREF)) {
1780 *V_R8REF(var) = rb_big2dbl(val);
1781 }
1782 break;
1783 case T_TRUE:
1784 if (V_VT(var) == (VT_BOOL | VT_BYREF)) {
1785 *V_BOOLREF(var) = VARIANT_TRUE;
1786 }
1787 break;
1788 case T_FALSE:
1789 if (V_VT(var) == (VT_BOOL | VT_BYREF)) {
1790 *V_BOOLREF(var) = VARIANT_FALSE;
1791 }
1792 break;
1793 default:
1794 break;
1795 }
1796 }
1797
1798 static void
1799 ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt)
1800 {
1801 V_VT(var) = vt;
1802 if (vt == (VT_VARIANT|VT_BYREF)) {
1803 V_VARIANTREF(var) = realvar;
1804 } else {
1805 if (V_VT(realvar) != (vt & ~VT_BYREF)) {
1806 rb_raise(eWIN32OLERuntimeError, "variant type mismatch");
1807 }
1808 switch(vt & ~VT_BYREF) {
1809 case VT_I1:
1810 V_I1REF(var) = &V_I1(realvar);
1811 break;
1812 case VT_UI1:
1813 V_UI1REF(var) = &V_UI1(realvar);
1814 break;
1815 case VT_I2:
1816 V_I2REF(var) = &V_I2(realvar);
1817 break;
1818 case VT_UI2:
1819 V_UI2REF(var) = &V_UI2(realvar);
1820 break;
1821 case VT_I4:
1822 V_I4REF(var) = &V_I4(realvar);
1823 break;
1824 case VT_UI4:
1825 V_UI4REF(var) = &V_UI4(realvar);
1826 break;
1827 case VT_R4:
1828 V_R4REF(var) = &V_R4(realvar);
1829 break;
1830 case VT_R8:
1831 V_R8REF(var) = &V_R8(realvar);
1832 break;
1833
1834 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
1835 #ifdef V_I8REF
1836 case VT_I8:
1837 V_I8REF(var) = &V_I8(realvar);
1838 break;
1839 #endif
1840 #ifdef V_UI8REF
1841 case VT_UI8:
1842 V_UI8REF(var) = &V_UI8(realvar);
1843 break;
1844 #endif
1845 #endif
1846 case VT_INT:
1847 V_INTREF(var) = &V_INT(realvar);
1848 break;
1849
1850 case VT_UINT:
1851 V_UINTREF(var) = &V_UINT(realvar);
1852 break;
1853
1854 case VT_CY:
1855 V_CYREF(var) = &V_CY(realvar);
1856 break;
1857 case VT_DATE:
1858 V_DATEREF(var) = &V_DATE(realvar);
1859 break;
1860 case VT_BSTR:
1861 V_BSTRREF(var) = &V_BSTR(realvar);
1862 break;
1863 case VT_DISPATCH:
1864 V_DISPATCHREF(var) = &V_DISPATCH(realvar);
1865 break;
1866 case VT_ERROR:
1867 V_ERRORREF(var) = &V_ERROR(realvar);
1868 break;
1869 case VT_BOOL:
1870 V_BOOLREF(var) = &V_BOOL(realvar);
1871 break;
1872 case VT_UNKNOWN:
1873 V_UNKNOWNREF(var) = &V_UNKNOWN(realvar);
1874 break;
1875 case VT_ARRAY:
1876 V_ARRAYREF(var) = &V_ARRAY(realvar);
1877 break;
1878 default:
1879 rb_raise(eWIN32OLERuntimeError, "unknown type specified(setting BYREF):%d", vt);
1880 break;
1881 }
1882 }
1883 }
1884
1885 static void
1886 ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar)
1887 {
1888 HRESULT hr = S_OK;
1889
1890 if (((vt & ~VT_BYREF) == (VT_ARRAY | VT_UI1)) && TYPE(val) == T_STRING) {
1891 long len = RSTRING_LEN(val);
1892 void *pdest = NULL;
1893 SAFEARRAY *p = NULL;
1894 SAFEARRAY *psa = SafeArrayCreateVector(VT_UI1, 0, len);
1895 if (!psa) {
1896 rb_raise(rb_eRuntimeError, "fail to SafeArrayCreateVector");
1897 }
1898 hr = SafeArrayAccessData(psa, &pdest);
1899 if (SUCCEEDED(hr)) {
1900 memcpy(pdest, RSTRING_PTR(val), len);
1901 SafeArrayUnaccessData(psa);
1902 V_VT(&(pvar->realvar)) = (vt & ~VT_BYREF);
1903 p = V_ARRAY(&(pvar->realvar));
1904 if (p != NULL) {
1905 SafeArrayDestroy(p);
1906 }
1907 V_ARRAY(&(pvar->realvar)) = psa;
1908 if (vt & VT_BYREF) {
1909 V_VT(&(pvar->var)) = vt;
1910 V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
1911 } else {
1912 hr = VariantCopy(&(pvar->var), &(pvar->realvar));
1913 }
1914 } else {
1915 if (psa)
1916 SafeArrayDestroy(psa);
1917 }
1918 } else if (vt & VT_ARRAY) {
1919 if (val == Qnil) {
1920 V_VT(&(pvar->var)) = vt;
1921 if (vt & VT_BYREF) {
1922 V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
1923 }
1924 } else {
1925 hr = ole_val_ary2variant_ary(val, &(pvar->realvar), (VARTYPE)(vt & ~VT_BYREF));
1926 if (SUCCEEDED(hr)) {
1927 if (vt & VT_BYREF) {
1928 V_VT(&(pvar->var)) = vt;
1929 V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
1930 } else {
1931 hr = VariantCopy(&(pvar->var), &(pvar->realvar));
1932 }
1933 }
1934 }
1935 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
1936 } else if ( (vt & ~VT_BYREF) == VT_I8 || (vt & ~VT_BYREF) == VT_UI8) {
1937 ole_val2variant_ex(val, &(pvar->realvar), (vt & ~VT_BYREF));
1938 ole_val2variant_ex(val, &(pvar->var), (vt & ~VT_BYREF));
1939 V_VT(&(pvar->var)) = vt;
1940 if (vt & VT_BYREF) {
1941 ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
1942 }
1943 #endif
1944 } else {
1945 if (val == Qnil) {
1946 V_VT(&(pvar->var)) = vt;
1947 if (vt == (VT_BYREF | VT_VARIANT)) {
1948 ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
1949 } else {
1950 V_VT(&(pvar->realvar)) = vt & ~VT_BYREF;
1951 if (vt & VT_BYREF) {
1952 ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
1953 }
1954 }
1955 } else {
1956 ole_val2variant_ex(val, &(pvar->realvar), (VARTYPE)(vt & ~VT_BYREF));
1957 if (vt == (VT_BYREF | VT_VARIANT)) {
1958 ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
1959 } else if (vt & VT_BYREF) {
1960 if ( (vt & ~VT_BYREF) != V_VT(&(pvar->realvar))) {
1961 hr = VariantChangeTypeEx(&(pvar->realvar), &(pvar->realvar),
1962 cWIN32OLE_lcid, 0, (VARTYPE)(vt & ~VT_BYREF));
1963 }
1964 if (SUCCEEDED(hr)) {
1965 ole_set_byref(&(pvar->realvar), &(pvar->var), vt);
1966 }
1967 } else {
1968 if (vt == V_VT(&(pvar->realvar))) {
1969 hr = VariantCopy(&(pvar->var), &(pvar->realvar));
1970 } else {
1971 hr = VariantChangeTypeEx(&(pvar->var), &(pvar->realvar),
1972 cWIN32OLE_lcid, 0, vt);
1973 }
1974 }
1975 }
1976 }
1977 if (FAILED(hr)) {
1978 ole_raise(hr, eWIN32OLERuntimeError, "failed to change type");
1979 }
1980 }
1981
1982 static void
1983 ole_val2variant2(VALUE val, VARIANT *var)
1984 {
1985 g_nil_to = VT_EMPTY;
1986 ole_val2variant(val, var);
1987 g_nil_to = VT_ERROR;
1988 }
1989
1990 static VALUE
1991 make_inspect(const char *class_name, VALUE detail)
1992 {
1993 VALUE str;
1994 str = rb_str_new2("#<");
1995 rb_str_cat2(str, class_name);
1996 rb_str_cat2(str, ":");
1997 rb_str_concat(str, detail);
1998 rb_str_cat2(str, ">");
1999 return str;
2000 }
2001
2002 static VALUE
2003 default_inspect(VALUE self, const char *class_name)
2004 {
2005 VALUE detail = rb_funcall(self, rb_intern("to_s"), 0);
2006 return make_inspect(class_name, detail);
2007 }
2008
2009 static VALUE
2010 ole_set_member(VALUE self, IDispatch *dispatch)
2011 {
2012 struct oledata *pole;
2013 Data_Get_Struct(self, struct oledata, pole);
2014 if (pole->pDispatch) {
2015 OLE_RELEASE(pole->pDispatch);
2016 pole->pDispatch = NULL;
2017 }
2018 pole->pDispatch = dispatch;
2019 return self;
2020 }
2021
2022
2023 static VALUE
2024 fole_s_allocate(VALUE klass)
2025 {
2026 struct oledata *pole;
2027 VALUE obj;
2028 ole_initialize();
2029 obj = Data_Make_Struct(klass,struct oledata,0,ole_free,pole);
2030 pole->pDispatch = NULL;
2031 return obj;
2032 }
2033
2034 static VALUE
2035 create_win32ole_object(VALUE klass, IDispatch *pDispatch, int argc, VALUE *argv)
2036 {
2037 VALUE obj = fole_s_allocate(klass);
2038 ole_set_member(obj, pDispatch);
2039 return obj;
2040 }
2041
2042 static VALUE
2043 ary_new_dim(VALUE myary, long *pid, long *plb, long dim) {
2044 long i;
2045 VALUE obj = Qnil;
2046 VALUE pobj = Qnil;
2047 long *ids = ALLOC_N(long, dim);
2048 if (!ids) {
2049 rb_raise(rb_eRuntimeError, "memory allocation error");
2050 }
2051 for(i = 0; i < dim; i++) {
2052 ids[i] = pid[i] - plb[i];
2053 }
2054 obj = myary;
2055 pobj = myary;
2056 for(i = 0; i < dim-1; i++) {
2057 obj = rb_ary_entry(pobj, ids[i]);
2058 if (obj == Qnil) {
2059 rb_ary_store(pobj, ids[i], rb_ary_new());
2060 }
2061 obj = rb_ary_entry(pobj, ids[i]);
2062 pobj = obj;
2063 }
2064 if (ids) free(ids);
2065 return obj;
2066 }
2067
2068 static void
2069 ary_store_dim(VALUE myary, long *pid, long *plb, long dim, VALUE val) {
2070 long id = pid[dim - 1] - plb[dim - 1];
2071 VALUE obj = ary_new_dim(myary, pid, plb, dim);
2072 rb_ary_store(obj, id, val);
2073 }
2074
2075 static VALUE
2076 ole_variant2val(VARIANT *pvar)
2077 {
2078 VALUE obj = Qnil;
2079 HRESULT hr;
2080 while ( V_VT(pvar) == (VT_BYREF | VT_VARIANT) )
2081 pvar = V_VARIANTREF(pvar);
2082
2083 if(V_ISARRAY(pvar)) {
2084 SAFEARRAY *psa = V_ISBYREF(pvar) ? *V_ARRAYREF(pvar) : V_ARRAY(pvar);
2085 UINT i = 0;
2086 long *pid, *plb, *pub;
2087 VARIANT variant;
2088 VALUE val;
2089 UINT dim = 0;
2090 if (!psa) {
2091 return obj;
2092 }
2093 dim = SafeArrayGetDim(psa);
2094 VariantInit(&variant);
2095 V_VT(&variant) = (V_VT(pvar) & ~VT_ARRAY) | VT_BYREF;
2096
2097 pid = ALLOC_N(long, dim);
2098 plb = ALLOC_N(long, dim);
2099 pub = ALLOC_N(long, dim);
2100
2101 if(!pid || !plb || !pub) {
2102 if(pid) free(pid);
2103 if(plb) free(plb);
2104 if(pub) free(pub);
2105 rb_raise(rb_eRuntimeError, "memory allocation error");
2106 }
2107
2108 for(i = 0; i < dim; ++i) {
2109 SafeArrayGetLBound(psa, i+1, &plb[i]);
2110 SafeArrayGetLBound(psa, i+1, &pid[i]);
2111 SafeArrayGetUBound(psa, i+1, &pub[i]);
2112 }
2113 hr = SafeArrayLock(psa);
2114 if (SUCCEEDED(hr)) {
2115 obj = rb_ary_new();
2116 i = 0;
2117 while (i < dim) {
2118 ary_new_dim(obj, pid, plb, dim);
2119 hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant));
2120 if (SUCCEEDED(hr)) {
2121 val = ole_variant2val(&variant);
2122 ary_store_dim(obj, pid, plb, dim, val);
2123 }
2124 for (i = 0; i < dim; ++i) {
2125 if (++pid[i] <= pub[i])
2126 break;
2127 pid[i] = plb[i];
2128 }
2129 }
2130 SafeArrayUnlock(psa);
2131 }
2132 if(pid) free(pid);
2133 if(plb) free(plb);
2134 if(pub) free(pub);
2135 return obj;
2136 }
2137 switch(V_VT(pvar) & ~VT_BYREF){
2138 case VT_EMPTY:
2139 break;
2140 case VT_NULL:
2141 break;
2142 case VT_I1:
2143 if(V_ISBYREF(pvar))
2144 obj = INT2NUM((long)*V_I1REF(pvar));
2145 else
2146 obj = INT2NUM((long)V_I1(pvar));
2147 break;
2148
2149 case VT_UI1:
2150 if(V_ISBYREF(pvar))
2151 obj = INT2NUM((long)*V_UI1REF(pvar));
2152 else
2153 obj = INT2NUM((long)V_UI1(pvar));
2154 break;
2155
2156 case VT_I2:
2157 if(V_ISBYREF(pvar))
2158 obj = INT2NUM((long)*V_I2REF(pvar));
2159 else
2160 obj = INT2NUM((long)V_I2(pvar));
2161 break;
2162
2163 case VT_UI2:
2164 if(V_ISBYREF(pvar))
2165 obj = INT2NUM((long)*V_UI2REF(pvar));
2166 else
2167 obj = INT2NUM((long)V_UI2(pvar));
2168 break;
2169
2170 case VT_I4:
2171 if(V_ISBYREF(pvar))
2172 obj = INT2NUM((long)*V_I4REF(pvar));
2173 else
2174 obj = INT2NUM((long)V_I4(pvar));
2175 break;
2176
2177 case VT_UI4:
2178 if(V_ISBYREF(pvar))
2179 obj = INT2NUM((long)*V_UI4REF(pvar));
2180 else
2181 obj = INT2NUM((long)V_UI4(pvar));
2182 break;
2183
2184 case VT_INT:
2185 if(V_ISBYREF(pvar))
2186 obj = INT2NUM((long)*V_INTREF(pvar));
2187 else
2188 obj = INT2NUM((long)V_INT(pvar));
2189 break;
2190
2191 case VT_UINT:
2192 if(V_ISBYREF(pvar))
2193 obj = INT2NUM((long)*V_UINTREF(pvar));
2194 else
2195 obj = INT2NUM((long)V_UINT(pvar));
2196 break;
2197
2198 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
2199 case VT_I8:
2200 if(V_ISBYREF(pvar))
2201 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
2202 #ifdef V_I8REF
2203 obj = I8_2_NUM(*V_I8REF(pvar));
2204 #endif
2205 #else
2206 obj = Qnil;
2207 #endif
2208 else
2209 obj = I8_2_NUM(V_I8(pvar));
2210 break;
2211 case VT_UI8:
2212 if(V_ISBYREF(pvar))
2213 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
2214 #ifdef V_UI8REF
2215 obj = UI8_2_NUM(*V_UI8REF(pvar));
2216 #endif
2217 #else
2218 obj = Qnil;
2219 #endif
2220 else
2221 obj = UI8_2_NUM(V_UI8(pvar));
2222 break;
2223 #endif /* (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__) */
2224
2225 case VT_R4:
2226 if(V_ISBYREF(pvar))
2227 obj = rb_float_new(*V_R4REF(pvar));
2228 else
2229 obj = rb_float_new(V_R4(pvar));
2230 break;
2231
2232 case VT_R8:
2233 if(V_ISBYREF(pvar))
2234 obj = rb_float_new(*V_R8REF(pvar));
2235 else
2236 obj = rb_float_new(V_R8(pvar));
2237 break;
2238
2239 case VT_BSTR:
2240 {
2241 if(V_ISBYREF(pvar))
2242 obj = ole_wc2vstr(*V_BSTRREF(pvar), FALSE);
2243 else
2244 obj = ole_wc2vstr(V_BSTR(pvar), FALSE);
2245 break;
2246 }
2247
2248 case VT_ERROR:
2249 if(V_ISBYREF(pvar))
2250 obj = INT2NUM(*V_ERRORREF(pvar));
2251 else
2252 obj = INT2NUM(V_ERROR(pvar));
2253 break;
2254
2255 case VT_BOOL:
2256 if (V_ISBYREF(pvar))
2257 obj = (*V_BOOLREF(pvar) ? Qtrue : Qfalse);
2258 else
2259 obj = (V_BOOL(pvar) ? Qtrue : Qfalse);
2260 break;
2261
2262 case VT_DISPATCH:
2263 {
2264 IDispatch *pDispatch;
2265
2266 if (V_ISBYREF(pvar))
2267 pDispatch = *V_DISPATCHREF(pvar);
2268 else
2269 pDispatch = V_DISPATCH(pvar);
2270
2271 if (pDispatch != NULL ) {
2272 OLE_ADDREF(pDispatch);
2273 obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
2274 }
2275 break;
2276 }
2277
2278 case VT_UNKNOWN:
2279 {
2280 /* get IDispatch interface from IUnknown interface */
2281 IUnknown *punk;
2282 IDispatch *pDispatch;
2283 void *p;
2284 HRESULT hr;
2285
2286 if (V_ISBYREF(pvar))
2287 punk = *V_UNKNOWNREF(pvar);
2288 else
2289 punk = V_UNKNOWN(pvar);
2290
2291 if(punk != NULL) {
2292 hr = punk->lpVtbl->QueryInterface(punk, &IID_IDispatch, &p);
2293 if(SUCCEEDED(hr)) {
2294 pDispatch = p;
2295 obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
2296 }
2297 }
2298 break;
2299 }
2300
2301 case VT_DATE:
2302 {
2303 DATE date;
2304 if(V_ISBYREF(pvar))
2305 date = *V_DATEREF(pvar);
2306 else
2307 date = V_DATE(pvar);
2308
2309 obj = vtdate2rbtime(date);
2310 break;
2311 }
2312 case VT_CY:
2313 default:
2314 {
2315 HRESULT hr;
2316 VARIANT variant;
2317 VariantInit(&variant);
2318 hr = VariantChangeTypeEx(&variant, pvar,
2319 cWIN32OLE_lcid, 0, VT_BSTR);
2320 if (SUCCEEDED(hr) && V_VT(&variant) == VT_BSTR) {
2321 obj = ole_wc2vstr(V_BSTR(&variant), FALSE);
2322 }
2323 VariantClear(&variant);
2324 break;
2325 }
2326 }
2327 return obj;
2328 }
2329
2330 static LONG
2331 reg_open_key(HKEY hkey, const char *name, HKEY *phkey)
2332 {
2333 return RegOpenKeyEx(hkey, name, 0, KEY_READ, phkey);
2334 }
2335
2336 static LONG
2337 reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey)
2338 {
2339 return reg_open_key(hkey, StringValuePtr(key), phkey);
2340 }
2341
2342 static VALUE
2343 reg_enum_key(HKEY hkey, DWORD i)
2344 {
2345 char buf[BUFSIZ + 1];
2346 DWORD size_buf = sizeof(buf);
2347 FILETIME ft;
2348 LONG err = RegEnumKeyEx(hkey, i, buf, &size_buf,
2349 NULL, NULL, NULL, &ft);
2350 if(err == ERROR_SUCCESS) {
2351 buf[BUFSIZ] = '\0';
2352 return rb_str_new2(buf);
2353 }
2354 return Qnil;
2355 }
2356
2357 static VALUE
2358 reg_get_val(HKEY hkey, const char *subkey)
2359 {
2360 char *pbuf;
2361 DWORD dwtype = 0;
2362 DWORD size = 0;
2363 VALUE val = Qnil;
2364 LONG err = RegQueryValueEx(hkey, subkey, NULL, &dwtype, NULL, &size);
2365
2366 if (err == ERROR_SUCCESS) {
2367 pbuf = ALLOC_N(char, size + 1);
2368 err = RegQueryValueEx(hkey, subkey, NULL, &dwtype, (BYTE *)pbuf, &size);
2369 if (err == ERROR_SUCCESS) {
2370 pbuf[size] = '\0';
2371 if (dwtype == REG_EXPAND_SZ) {
2372 char* pbuf2 = (char *)pbuf;
2373 DWORD len = ExpandEnvironmentStrings(pbuf2, NULL, 0);
2374 pbuf = ALLOC_N(char, len + 1);
2375 ExpandEnvironmentStrings(pbuf2, pbuf, len + 1);
2376 free(pbuf2);
2377 }
2378 val = rb_str_new2((char *)pbuf);
2379 }
2380 free(pbuf);
2381 }
2382 return val;
2383 }
2384
2385 static VALUE
2386 reg_get_val2(HKEY hkey, const char *subkey)
2387 {
2388 HKEY hsubkey;
2389 LONG err;
2390 VALUE val = Qnil;
2391 err = RegOpenKeyEx(hkey, subkey, 0, KEY_READ, &hsubkey);
2392 if (err == ERROR_SUCCESS) {
2393 val = reg_get_val(hsubkey, NULL);
2394 RegCloseKey(hsubkey);
2395 }
2396 if (val == Qnil) {
2397 val = reg_get_val(hkey, subkey);
2398 }
2399 return val;
2400 }
2401
2402 static VALUE
2403 reg_get_typelib_file_path(HKEY hkey)
2404 {
2405 VALUE path = Qnil;
2406 path = reg_get_val2(hkey, "win64");
2407 if (path != Qnil) {
2408 return path;
2409 }
2410 path = reg_get_val2(hkey, "win32");
2411 if (path != Qnil) {
2412 return path;
2413 }
2414 path = reg_get_val2(hkey, "win16");
2415 return path;
2416 }
2417
2418 static VALUE
2419 typelib_file_from_clsid(VALUE ole)
2420 {
2421 HKEY hroot, hclsid;
2422 LONG err;
2423 VALUE typelib;
2424 char path[MAX_PATH + 1];
2425
2426 err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hroot);
2427 if (err != ERROR_SUCCESS) {
2428 return Qnil;
2429 }
2430 err = reg_open_key(hroot, StringValuePtr(ole), &hclsid);
2431 if (err != ERROR_SUCCESS) {
2432 RegCloseKey(hroot);
2433 return Qnil;
2434 }
2435 typelib = reg_get_val2(hclsid, "InprocServer32");
2436 RegCloseKey(hroot);
2437 RegCloseKey(hclsid);
2438 if (typelib != Qnil) {
2439 ExpandEnvironmentStrings(StringValuePtr(typelib), path, sizeof(path));
2440 path[MAX_PATH] = '\0';
2441 typelib = rb_str_new2(path);
2442 }
2443 return typelib;
2444 }
2445
2446 static VALUE
2447 typelib_file_from_typelib(VALUE ole)
2448 {
2449 HKEY htypelib, hclsid, hversion, hlang;
2450 double fver;
2451 DWORD i, j, k;
2452 LONG err;
2453 BOOL found = FALSE;
2454 VALUE typelib;
2455 VALUE file = Qnil;
2456 VALUE clsid;
2457 VALUE ver;
2458 VALUE lang;
2459
2460 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
2461 if(err != ERROR_SUCCESS) {
2462 return Qnil;
2463 }
2464 for(i = 0; !found; i++) {
2465 clsid = reg_enum_key(htypelib, i);
2466 if (clsid == Qnil)
2467 break;
2468 err = reg_open_vkey(htypelib, clsid, &hclsid);
2469 if (err != ERROR_SUCCESS)
2470 continue;
2471 fver = 0;
2472 for(j = 0; !found; j++) {
2473 ver = reg_enum_key(hclsid, j);
2474 if (ver == Qnil)
2475 break;
2476 err = reg_open_vkey(hclsid, ver, &hversion);
2477 if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver)))
2478 continue;
2479 fver = atof(StringValuePtr(ver));
2480 typelib = reg_get_val(hversion, NULL);
2481 if (typelib == Qnil)
2482 continue;
2483 if (rb_str_cmp(typelib, ole) == 0) {
2484 for(k = 0; !found; k++) {
2485 lang = reg_enum_key(hversion, k);
2486 if (lang == Qnil)
2487 break;
2488 err = reg_open_vkey(hversion, lang, &hlang);
2489 if (err == ERROR_SUCCESS) {
2490 if ((file = reg_get_typelib_file_path(hlang)) != Qnil)
2491 found = TRUE;
2492 RegCloseKey(hlang);
2493 }
2494 }
2495 }
2496 RegCloseKey(hversion);
2497 }
2498 RegCloseKey(hclsid);
2499 }
2500 RegCloseKey(htypelib);
2501 return file;
2502 }
2503
2504 static VALUE
2505 typelib_file(VALUE ole)
2506 {
2507 VALUE file = typelib_file_from_clsid(ole);
2508 if (file != Qnil) {
2509 return file;
2510 }
2511 return typelib_file_from_typelib(ole);
2512 }
2513
2514 static void
2515 ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self)
2516 {
2517 unsigned int count;
2518 unsigned int index;
2519 int iVar;
2520 ITypeInfo *pTypeInfo;
2521 TYPEATTR *pTypeAttr;
2522 VARDESC *pVarDesc;
2523 HRESULT hr;
2524 unsigned int len;
2525 BSTR bstr;
2526 char *pName = NULL;
2527 VALUE val;
2528 VALUE constant;
2529 ID id;
2530 constant = rb_hash_new();
2531 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
2532 for (index = 0; index < count; index++) {
2533 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, index, &pTypeInfo);
2534 if (FAILED(hr))
2535 continue;
2536 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
2537 if(FAILED(hr)) {
2538 OLE_RELEASE(pTypeInfo);
2539 continue;
2540 }
2541 for(iVar = 0; iVar < pTypeAttr->cVars; iVar++) {
2542 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, iVar, &pVarDesc);
2543 if(FAILED(hr))
2544 continue;
2545 if(pVarDesc->varkind == VAR_CONST &&
2546 !(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
2547 VARFLAG_FRESTRICTED |
2548 VARFLAG_FNONBROWSABLE))) {
2549 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
2550 1, &len);
2551 if(FAILED(hr) || len == 0 || !bstr)
2552 continue;
2553 pName = ole_wc2mb(bstr);
2554 val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));
2555 *pName = toupper((int)*pName);
2556 id = rb_intern(pName);
2557 if (rb_is_const_id(id)) {
2558 rb_define_const(klass, pName, val);
2559 }
2560 else {
2561 rb_hash_aset(constant, rb_str_new2(pName), val);
2562 }
2563 SysFreeString(bstr);
2564 if(pName) {
2565 free(pName);
2566 pName = NULL;
2567 }
2568 }
2569 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
2570 }
2571 pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
2572 OLE_RELEASE(pTypeInfo);
2573 }
2574 rb_define_const(klass, "CONSTANTS", constant);
2575 }
2576
2577 static HRESULT
2578 clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid)
2579 {
2580 HKEY hlm;
2581 HKEY hpid;
2582 VALUE subkey;
2583 LONG err;
2584 char clsid[100];
2585 OLECHAR *pbuf;
2586 DWORD len;
2587 DWORD dwtype;
2588 HRESULT hr = S_OK;
2589 err = RegConnectRegistry(StringValuePtr(host), HKEY_LOCAL_MACHINE, &hlm);
2590 if (err != ERROR_SUCCESS)
2591 return HRESULT_FROM_WIN32(err);
2592 subkey = rb_str_new2("SOFTWARE\\Classes\\");
2593 rb_str_concat(subkey, com);
2594 rb_str_cat2(subkey, "\\CLSID");
2595 err = RegOpenKeyEx(hlm, StringValuePtr(subkey), 0, KEY_READ, &hpid);
2596 if (err != ERROR_SUCCESS)
2597 hr = HRESULT_FROM_WIN32(err);
2598 else {
2599 len = sizeof(clsid);
2600 err = RegQueryValueEx(hpid, "", NULL, &dwtype, (BYTE *)clsid, &len);
2601 if (err == ERROR_SUCCESS && dwtype == REG_SZ) {
2602 pbuf = ole_mb2wc(clsid, -1);
2603 hr = CLSIDFromString(pbuf, pclsid);
2604 SysFreeString(pbuf);
2605 }
2606 else {
2607 hr = HRESULT_FROM_WIN32(err);
2608 }
2609 RegCloseKey(hpid);
2610 }
2611 RegCloseKey(hlm);
2612 return hr;
2613 }
2614
2615 static VALUE
2616 ole_create_dcom(int argc, VALUE *argv, VALUE self)
2617 {
2618 VALUE ole, host, others;
2619 HRESULT hr;
2620 CLSID clsid;
2621 OLECHAR *pbuf;
2622
2623 COSERVERINFO serverinfo;
2624 MULTI_QI multi_qi;
2625 DWORD clsctx = CLSCTX_REMOTE_SERVER;
2626
2627 if (!gole32)
2628 gole32 = LoadLibrary("OLE32");
2629 if (!gole32)
2630 rb_raise(rb_eRuntimeError, "failed to load OLE32");
2631 if (!gCoCreateInstanceEx)
2632 gCoCreateInstanceEx = (FNCOCREATEINSTANCEEX*)
2633 GetProcAddress(gole32, "CoCreateInstanceEx");
2634 if (!gCoCreateInstanceEx)
2635 rb_raise(rb_eRuntimeError, "CoCreateInstanceEx is not supported in this environment");
2636 rb_scan_args(argc, argv, "2*", &ole, &host, &others);
2637
2638 pbuf = ole_vstr2wc(ole);
2639 hr = CLSIDFromProgID(pbuf, &clsid);
2640 if (FAILED(hr))
2641 hr = clsid_from_remote(host, ole, &clsid);
2642 if (FAILED(hr))
2643 hr = CLSIDFromString(pbuf, &clsid);
2644 SysFreeString(pbuf);
2645 if (FAILED(hr))
2646 ole_raise(hr, eWIN32OLERuntimeError,
2647 "unknown OLE server: `%s'",
2648 StringValuePtr(ole));
2649 memset(&serverinfo, 0, sizeof(COSERVERINFO));
2650 serverinfo.pwszName = ole_vstr2wc(host);
2651 memset(&multi_qi, 0, sizeof(MULTI_QI));
2652 multi_qi.pIID = &IID_IDispatch;
2653 hr = gCoCreateInstanceEx(&clsid, NULL, clsctx, &serverinfo, 1, &multi_qi);
2654 SysFreeString(serverinfo.pwszName);
2655 if (FAILED(hr))
2656 ole_raise(hr, eWIN32OLERuntimeError,
2657 "failed to create DCOM server `%s' in `%s'",
2658 StringValuePtr(ole),
2659 StringValuePtr(host));
2660
2661 ole_set_member(self, (IDispatch*)multi_qi.pItf);
2662 return self;
2663 }
2664
2665 static VALUE
2666 ole_bind_obj(VALUE moniker, int argc, VALUE *argv, VALUE self)
2667 {
2668 IBindCtx *pBindCtx;
2669 IMoniker *pMoniker;
2670 IDispatch *pDispatch;
2671 void *p;
2672 HRESULT hr;
2673 OLECHAR *pbuf;
2674 ULONG eaten = 0;
2675
2676 ole_initialize();
2677
2678 hr = CreateBindCtx(0, &pBindCtx);
2679 if(FAILED(hr)) {
2680 ole_raise(hr, eWIN32OLERuntimeError,
2681 "failed to create bind context");
2682 }
2683
2684 pbuf = ole_vstr2wc(moniker);
2685 hr = MkParseDisplayName(pBindCtx, pbuf, &eaten, &pMoniker);
2686 SysFreeString(pbuf);
2687 if(FAILED(hr)) {
2688 OLE_RELEASE(pBindCtx);
2689 ole_raise(hr, eWIN32OLERuntimeError,
2690 "failed to parse display name of moniker `%s'",
2691 StringValuePtr(moniker));
2692 }
2693 hr = pMoniker->lpVtbl->BindToObject(pMoniker, pBindCtx, NULL,
2694 &IID_IDispatch, &p);
2695 pDispatch = p;
2696 OLE_RELEASE(pMoniker);
2697 OLE_RELEASE(pBindCtx);
2698
2699 if(FAILED(hr)) {
2700 ole_raise(hr, eWIN32OLERuntimeError,
2701 "failed to bind moniker `%s'",
2702 StringValuePtr(moniker));
2703 }
2704 return create_win32ole_object(self, pDispatch, argc, argv);
2705 }
2706
2707 /*
2708 * call-seq:
2709 * WIN32OLE.connect( ole ) --> aWIN32OLE
2710 *
2711 * Returns running OLE Automation object or WIN32OLE object from moniker.
2712 * 1st argument should be OLE program id or class id or moniker.
2713 *
2714 * WIN32OLE.connect('Excel.Application') # => WIN32OLE object which represents running Excel.
2715 */
2716 static VALUE
2717 fole_s_connect(int argc, VALUE *argv, VALUE self)
2718 {
2719 VALUE svr_name;
2720 VALUE others;
2721 HRESULT hr;
2722 CLSID clsid;
2723 OLECHAR *pBuf;
2724 IDispatch *pDispatch;
2725 void *p;
2726 IUnknown *pUnknown;
2727
2728 rb_secure(4);
2729 /* initialize to use OLE */
2730 ole_initialize();
2731
2732 rb_scan_args(argc, argv, "1*", &svr_name, &others);
2733 SafeStringValue(svr_name);
2734 if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
2735 rb_raise(rb_eSecurityError, "Insecure Object Connection - %s",
2736 StringValuePtr(svr_name));
2737 }
2738
2739 /* get CLSID from OLE server name */
2740 pBuf = ole_vstr2wc(svr_name);
2741 hr = CLSIDFromProgID(pBuf, &clsid);
2742 if(FAILED(hr)) {
2743 hr = CLSIDFromString(pBuf, &clsid);
2744 }
2745 SysFreeString(pBuf);
2746 if(FAILED(hr)) {
2747 return ole_bind_obj(svr_name, argc, argv, self);
2748 }
2749
2750 hr = GetActiveObject(&clsid, 0, &pUnknown);
2751 if (FAILED(hr)) {
2752 ole_raise(hr, eWIN32OLERuntimeError,
2753 "OLE server `%s' not running", StringValuePtr(svr_name));
2754 }
2755 hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch, &p);
2756 pDispatch = p;
2757 if(FAILED(hr)) {
2758 OLE_RELEASE(pUnknown);
2759 ole_raise(hr, eWIN32OLERuntimeError,
2760 "failed to create WIN32OLE server `%s'",
2761 StringValuePtr(svr_name));
2762 }
2763
2764 OLE_RELEASE(pUnknown);
2765
2766 return create_win32ole_object(self, pDispatch, argc, argv);
2767 }
2768
2769 /*
2770 * call-seq:
2771 * WIN32OLE.const_load( ole, mod = WIN32OLE)
2772 *
2773 * Defines the constants of OLE Automation server as mod's constants.
2774 * The first argument is WIN32OLE object or type library name.
2775 * If 2nd argument is omitted, the default is WIN32OLE.
2776 * The first letter of Ruby's constant variable name is upper case,
2777 * so constant variable name of WIN32OLE object is capitalized.
2778 * For example, the 'xlTop' constant of Excel is changed to 'XlTop'
2779 * in WIN32OLE.
2780 * If the first letter of constant variabl is not [A-Z], then
2781 * the constant is defined as CONSTANTS hash element.
2782 *
2783 * module EXCEL_CONST
2784 * end
2785 * excel = WIN32OLE.new('Excel.Application')
2786 * WIN32OLE.const_load(excel, EXCEL_CONST)
2787 * puts EXCEL_CONST::XlTop # => -4160
2788 * puts EXCEL_CONST::CONSTANTS['_xlDialogChartSourceData'] # => 541
2789 *
2790 * WIN32OLE.const_load(excel)
2791 * puts WIN32OLE::XlTop # => -4160
2792 *
2793 * module MSO
2794 * end
2795 * WIN32OLE.const_load('Microsoft Office 9.0 Object Library', MSO)
2796 * puts MSO::MsoLineSingle # => 1
2797 */
2798 static VALUE
2799 fole_s_const_load(int argc, VALUE *argv, VALUE self)
2800 {
2801 VALUE ole;
2802 VALUE klass;
2803 struct oledata *pole;
2804 ITypeInfo *pTypeInfo;
2805 ITypeLib *pTypeLib;
2806 unsigned int index;
2807 HRESULT hr;
2808 OLECHAR *pBuf;
2809 VALUE file;
2810 LCID lcid = cWIN32OLE_lcid;
2811
2812 rb_secure(4);
2813 rb_scan_args(argc, argv, "11", &ole, &klass);
2814 if (TYPE(klass) != T_CLASS &&
2815 TYPE(klass) != T_MODULE &&
2816 TYPE(klass) != T_NIL) {
2817 rb_raise(rb_eTypeError, "2nd parameter must be Class or Module");
2818 }
2819 if (rb_obj_is_kind_of(ole, cWIN32OLE)) {
2820 OLEData_Get_Struct(ole, pole);
2821 hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
2822 0, lcid, &pTypeInfo);
2823 if(FAILED(hr)) {
2824 ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
2825 }
2826 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
2827 if(FAILED(hr)) {
2828 OLE_RELEASE(pTypeInfo);
2829 ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib");
2830 }
2831 OLE_RELEASE(pTypeInfo);
2832 if(TYPE(klass) != T_NIL) {
2833 ole_const_load(pTypeLib, klass, self);
2834 }
2835 else {
2836 ole_const_load(pTypeLib, cWIN32OLE, self);
2837 }
2838 OLE_RELEASE(pTypeLib);
2839 }
2840 else if(TYPE(ole) == T_STRING) {
2841 file = typelib_file(ole);
2842 if (file == Qnil) {
2843 file = ole;
2844 }
2845 pBuf = ole_vstr2wc(file);
2846 hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib);
2847 SysFreeString(pBuf);
2848 if (FAILED(hr))
2849 ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
2850 if(TYPE(klass) != T_NIL) {
2851 ole_const_load(pTypeLib, klass, self);
2852 }
2853 else {
2854 ole_const_load(pTypeLib, cWIN32OLE, self);
2855 }
2856 OLE_RELEASE(pTypeLib);
2857 }
2858 else {
2859 rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE instance");
2860 }
2861 return Qnil;
2862 }
2863
2864 static VALUE
2865 ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes)
2866 {
2867
2868 long count;
2869 int i;
2870 HRESULT hr;
2871 BSTR bstr;
2872 ITypeInfo *pTypeInfo;
2873 VALUE type;
2874
2875 rb_secure(4);
2876 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
2877 for (i = 0; i < count; i++) {
2878 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
2879 &bstr, NULL, NULL, NULL);
2880 if (FAILED(hr))
2881 continue;
2882
2883 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
2884 if (FAILED(hr))
2885 continue;
2886
2887 type = foletype_s_allocate(cWIN32OLE_TYPE);
2888 oletype_set_member(type, pTypeInfo, WC2VSTR(bstr));
2889
2890 rb_ary_push(classes, type);
2891 OLE_RELEASE(pTypeInfo);
2892 }
2893 return classes;
2894 }
2895
2896 static ULONG
2897 reference_count(struct oledata * pole)
2898 {
2899 ULONG n = 0;
2900 if(pole->pDispatch) {
2901 OLE_ADDREF(pole->pDispatch);
2902 n = OLE_RELEASE(pole->pDispatch);
2903 }
2904 return n;
2905 }
2906
2907 /*
2908 * call-seq:
2909 * WIN32OLE.ole_reference_count(aWIN32OLE) --> number
2910 *
2911 * Returns reference counter of Dispatch interface of WIN32OLE object.
2912 * You should not use this method because this method
2913 * exists only for debugging WIN32OLE.
2914 */
2915 static VALUE
2916 fole_s_reference_count(VALUE self, VALUE obj)
2917 {
2918 struct oledata * pole;
2919 OLEData_Get_Struct(obj, pole);
2920 return INT2NUM(reference_count(pole));
2921 }
2922
2923 /*
2924 * call-seq:
2925 * WIN32OLE.ole_free(aWIN32OLE) --> number
2926 *
2927 * Invokes Release method of Dispatch interface of WIN32OLE object.
2928 * You should not use this method because this method
2929 * exists only for debugging WIN32OLE.
2930 * The return value is reference counter of OLE object.
2931 */
2932 static VALUE
2933 fole_s_free(VALUE self, VALUE obj)
2934 {
2935 ULONG n = 0;
2936 struct oledata * pole;
2937 OLEData_Get_Struct(obj, pole);
2938 if(pole->pDispatch) {
2939 if (reference_count(pole) > 0) {
2940 n = OLE_RELEASE(pole->pDispatch);
2941 }
2942 }
2943 return INT2NUM(n);
2944 }
2945
2946 static HWND
2947 ole_show_help(VALUE helpfile, VALUE helpcontext)
2948 {
2949 FNHTMLHELP *pfnHtmlHelp;
2950 HWND hwnd = 0;
2951
2952 if(!ghhctrl)
2953 ghhctrl = LoadLibrary("HHCTRL.OCX");
2954 if (!ghhctrl)
2955 return hwnd;
2956 pfnHtmlHelp = (FNHTMLHELP*)GetProcAddress(ghhctrl, "HtmlHelpA");
2957 if (!pfnHtmlHelp)
2958 return hwnd;
2959 hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile),
2960 0x0f, NUM2INT(helpcontext));
2961 if (hwnd == 0)
2962 hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile),
2963 0, NUM2INT(helpcontext));
2964 return hwnd;
2965 }
2966
2967 /*
2968 * call-seq:
2969 * WIN32OLE.ole_show_help(obj [,helpcontext])
2970 *
2971 * Displays helpfile. The 1st argument specifies WIN32OLE_TYPE
2972 * object or WIN32OLE_METHOD object or helpfile.
2973 *
2974 * excel = WIN32OLE.new('Excel.Application')
2975 * typeobj = excel.ole_type
2976 * WIN32OLE.ole_show_help(typeobj)
2977 */
2978 static VALUE
2979 fole_s_show_help(int argc, VALUE *argv, VALUE self)
2980 {
2981 VALUE target;
2982 VALUE helpcontext;
2983 VALUE helpfile;
2984 VALUE name;
2985 HWND hwnd;
2986 rb_scan_args(argc, argv, "11", &target, &helpcontext);
2987 if (rb_obj_is_kind_of(target, cWIN32OLE_TYPE) ||
2988 rb_obj_is_kind_of(target, cWIN32OLE_METHOD)) {
2989 helpfile = rb_funcall(target, rb_intern("helpfile"), 0);
2990 if(strlen(StringValuePtr(helpfile)) == 0) {
2991 name = rb_ivar_get(target, rb_intern("name"));
2992 rb_raise(rb_eRuntimeError, "no helpfile of `%s'",
2993 StringValuePtr(name));
2994 }
2995 helpcontext = rb_funcall(target, rb_intern("helpcontext"), 0);
2996 } else {
2997 helpfile = target;
2998 }
2999 if (TYPE(helpfile) != T_STRING) {
3000 rb_raise(rb_eTypeError, "1st parameter must be (String|WIN32OLE_TYPE|WIN32OLE_METHOD)");
3001 }
3002 hwnd = ole_show_help(helpfile, helpcontext);
3003 if(hwnd == 0) {
3004 rb_raise(rb_eRuntimeError, "failed to open help file `%s'",
3005 StringValuePtr(helpfile));
3006 }
3007 return Qnil;
3008 }
3009
3010 /*
3011 * call-seq:
3012 * WIN32OLE.codepage
3013 *
3014 * Returns current codepage.
3015 * WIN32OLE.codepage # => WIN32OLE::CP_ACP
3016 */
3017 static VALUE
3018 fole_s_get_code_page(VALUE self)
3019 {
3020 return INT2FIX(cWIN32OLE_cp);
3021 }
3022
3023 static BOOL CALLBACK
3024 installed_code_page_proc(LPTSTR str) {
3025 if (strtoul(str, NULL, 10) == g_cp_to_check) {
3026 g_cp_installed = TRUE;
3027 return FALSE;
3028 }
3029 return TRUE;
3030 }
3031
3032 static BOOL
3033 code_page_installed(UINT cp)
3034 {
3035 g_cp_installed = FALSE;
3036 g_cp_to_check = cp;
3037 EnumSystemCodePages(installed_code_page_proc, CP_INSTALLED);
3038 return g_cp_installed;
3039 }
3040
3041 /*
3042 * call-seq:
3043 * WIN32OLE.codepage = CP
3044 *
3045 * Sets current codepage.
3046 * The WIN32OLE.codepage is initialized according to
3047 * Encoding.default_internal.
3048 * If Encoding.default_internal is nil then WIN32OLE.codepage
3049 * is initialized according to Encoding.default_external.
3050 *
3051 * WIN32OLE.codepage = WIN32OLE::CP_UTF8
3052 * WIN32OLE.codepage = 65001
3053 */
3054 static VALUE
3055 fole_s_set_code_page(VALUE self, VALUE vcp)
3056 {
3057 UINT cp = FIX2INT(vcp);
3058 set_ole_codepage(cp);
3059 /*
3060 * Should this method return old codepage?
3061 */
3062 return Qnil;
3063 }
3064
3065 /*
3066 * call-seq:
3067 * WIN32OLE.locale -> locale id.
3068 *
3069 * Returns current locale id (lcid). The default locale is
3070 * LOCALE_SYSTEM_DEFAULT.
3071 *
3072 * lcid = WIN32OLE.locale
3073 */
3074 static VALUE
3075 fole_s_get_locale(VALUE self)
3076 {
3077 return INT2FIX(cWIN32OLE_lcid);
3078 }
3079
3080 static BOOL
3081 CALLBACK installed_lcid_proc(LPTSTR str)
3082 {
3083 if (strcmp(str, g_lcid_to_check) == 0) {
3084 g_lcid_installed = TRUE;
3085 return FALSE;
3086 }
3087 return TRUE;
3088 }
3089
3090 static BOOL
3091 lcid_installed(LCID lcid)
3092 {
3093 g_lcid_installed = FALSE;
3094 snprintf(g_lcid_to_check, sizeof(g_lcid_to_check), "%08lx", lcid);
3095 EnumSystemLocales(installed_lcid_proc, LCID_INSTALLED);
3096 return g_lcid_installed;
3097 }
3098
3099 /*
3100 * call-seq:
3101 * WIN32OLE.locale = lcid
3102 *
3103 * Sets current locale id (lcid).
3104 *
3105 * WIN32OLE.locale = 1033 # set locale English(U.S)
3106 * obj = WIN32OLE_VARIANT.new("$100,000", WIN32OLE::VARIANT::VT_CY)
3107 *
3108 */
3109 static VALUE
3110 fole_s_set_locale(VALUE self, VALUE vlcid)
3111 {
3112 LCID lcid = FIX2INT(vlcid);
3113 if (lcid_installed(lcid)) {
3114 cWIN32OLE_lcid = lcid;
3115 } else {
3116 switch (lcid) {
3117 case LOCALE_SYSTEM_DEFAULT:
3118 case LOCALE_USER_DEFAULT:
3119 cWIN32OLE_lcid = lcid;
3120 break;
3121 default:
3122 rb_raise(eWIN32OLERuntimeError, "not installed locale: %u", (unsigned int)lcid);
3123 }
3124 }
3125 return Qnil;
3126 }
3127
3128 /*
3129 * call-seq:
3130 * WIN32OLE.create_guid
3131 *
3132 * Creates GUID.
3133 * WIN32OLE.create_guid # => {1CB530F1-F6B1-404D-BCE6-1959BF91F4A8}
3134 */
3135 static VALUE
3136 fole_s_create_guid(VALUE self)
3137 {
3138 GUID guid;
3139 HRESULT hr;
3140 OLECHAR bstr[80];
3141 int len = 0;
3142 hr = CoCreateGuid(&guid);
3143 if (FAILED(hr)) {
3144 ole_raise(hr, eWIN32OLERuntimeError, "failed to create GUID");
3145 }
3146 len = StringFromGUID2(&guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
3147 if (len == 0) {
3148 rb_raise(rb_eRuntimeError, "failed to create GUID(buffer over)");
3149 }
3150 return ole_wc2vstr(bstr, FALSE);
3151 }
3152
3153 /*
3154 * WIN32OLE.ole_initialize and WIN32OLE.ole_uninitialize
3155 * are used in win32ole.rb to fix the issue bug #2618 (ruby-core:27634).
3156 * You must not use thease method.
3157 */
3158
3159 /* :nodoc */
3160 static VALUE
3161 fole_s_ole_initialize(VALUE self)
3162 {
3163 ole_initialize();
3164 return Qnil;
3165 }
3166
3167 /* :nodoc */
3168 static VALUE
3169 fole_s_ole_uninitialize(VALUE self)
3170 {
3171 ole_uninitialize();
3172 return Qnil;
3173 }
3174
3175 /*
3176 * Document-class: WIN32OLE
3177 *
3178 * <code>WIN32OLE</code> objects represent OLE Automation object in Ruby.
3179 *
3180 * By using WIN32OLE, you can access OLE server like VBScript.
3181 *
3182 * Here is sample script.
3183 *
3184 * require 'win32ole'
3185 *
3186 * excel = WIN32OLE.new('Excel.Application')
3187 * excel.visible = true
3188 * workbook = excel.Workbooks.Add();
3189 * worksheet = workbook.Worksheets(1);
3190 * worksheet.Range("A1:D1").value = ["North","South","East","West"];
3191 * worksheet.Range("A2:B2").value = [5.2, 10];
3192 * worksheet.Range("C2").value = 8;
3193 * worksheet.Range("D2").value = 20;
3194 *
3195 * range = worksheet.Range("A1:D2");
3196 * range.select
3197 * chart = workbook.Charts.Add;
3198 *
3199 * workbook.saved = true;
3200 *
3201 * excel.ActiveWorkbook.Close(0);
3202 * excel.Quit();
3203 *
3204 * Unfortunately, Win32OLE doesn't support the argument passed by
3205 * reference directly.
3206 * Instead, Win32OLE provides WIN32OLE::ARGV.
3207 * If you want to get the result value of argument passed by reference,
3208 * you can use WIN32OLE::ARGV.
3209 *
3210 * oleobj.method(arg1, arg2, refargv3)
3211 * puts WIN32OLE::ARGV[2] # the value of refargv3 after called oleobj.method
3212 *
3213 */
3214
3215 /*
3216 * call-seq:
3217 * WIN32OLE.new(server, [host]) -> WIN32OLE object
3218 *
3219 * Returns a new WIN32OLE object(OLE Automation object).
3220 * The first argument server specifies OLE Automation server.
3221 * The first argument should be CLSID or PROGID.
3222 * If second argument host specified, then returns OLE Automation
3223 * object on host.
3224 *
3225 * WIN32OLE.new('Excel.Application') # => Excel OLE Automation WIN32OLE object.
3226 * WIN32OLE.new('{00024500-0000-0000-C000-000000000046}') # => Excel OLE Automation WIN32OLE object.
3227 */
3228 static VALUE
3229 fole_initialize(int argc, VALUE *argv, VALUE self)
3230 {
3231 VALUE svr_name;
3232 VALUE host;
3233 VALUE others;
3234 HRESULT hr;
3235 CLSID clsid;
3236 OLECHAR *pBuf;
3237 IDispatch *pDispatch;
3238 void *p;
3239 rb_secure(4);
3240 rb_call_super(0, 0);
3241 rb_scan_args(argc, argv, "11*", &svr_name, &host, &others);
3242
3243 SafeStringValue(svr_name);
3244 if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
3245 rb_raise(rb_eSecurityError, "Insecure Object Creation - %s",
3246 StringValuePtr(svr_name));
3247 }
3248 if (!NIL_P(host)) {
3249 SafeStringValue(host);
3250 if (rb_safe_level() > 0 && OBJ_TAINTED(host)) {
3251 rb_raise(rb_eSecurityError, "Insecure Object Creation - %s",
3252 StringValuePtr(svr_name));
3253 }
3254 return ole_create_dcom(argc, argv, self);
3255 }
3256
3257 /* get CLSID from OLE server name */
3258 pBuf = ole_vstr2wc(svr_name);
3259 hr = CLSIDFromProgID(pBuf, &clsid);
3260 if(FAILED(hr)) {
3261 hr = CLSIDFromString(pBuf, &clsid);
3262 }
3263 SysFreeString(pBuf);
3264 if(FAILED(hr)) {
3265 ole_raise(hr, eWIN32OLERuntimeError,
3266 "unknown OLE server: `%s'",
3267 StringValuePtr(svr_name));
3268 }
3269
3270 /* get IDispatch interface */
3271 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
3272 &IID_IDispatch, &p);
3273 pDispatch = p;
3274 if(FAILED(hr)) {
3275 ole_raise(hr, eWIN32OLERuntimeError,
3276 "failed to create WIN32OLE object from `%s'",
3277 StringValuePtr(svr_name));
3278 }
3279
3280 ole_set_member(self, pDispatch);
3281 return self;
3282 }
3283
3284 static VALUE
3285 hash2named_arg(VALUE pair, struct oleparam* pOp)
3286 {
3287 unsigned int index, i;
3288 VALUE key, value;
3289 index = pOp->dp.cNamedArgs;
3290
3291 /*---------------------------------------------
3292 the data-type of key must be String or Symbol
3293 -----------------------------------------------*/
3294 key = rb_ary_entry(pair, 0);
3295 if(TYPE(key) != T_STRING && TYPE(key) != T_SYMBOL) {
3296 /* clear name of dispatch parameters */
3297 for(i = 1; i < index + 1; i++) {
3298 SysFreeString(pOp->pNamedArgs[i]);
3299 }
3300 /* clear dispatch parameters */
3301 for(i = 0; i < index; i++ ) {
3302 VariantClear(&(pOp->dp.rgvarg[i]));
3303 }
3304 /* raise an exception */
3305 rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
3306 }
3307 if (TYPE(key) == T_SYMBOL) {
3308 key = rb_sym_to_s(key);
3309 }
3310
3311 /* pNamedArgs[0] is <method name>, so "index + 1" */
3312 pOp->pNamedArgs[index + 1] = ole_vstr2wc(key);
3313
3314 value = rb_ary_entry(pair, 1);
3315 VariantInit(&(pOp->dp.rgvarg[index]));
3316 ole_val2variant(value, &(pOp->dp.rgvarg[index]));
3317
3318 pOp->dp.cNamedArgs += 1;
3319 return Qnil;
3320 }
3321
3322 static VALUE
3323 set_argv(VARIANTARG* realargs, unsigned int beg, unsigned int end)
3324 {
3325 VALUE argv = rb_const_get(cWIN32OLE, rb_intern("ARGV"));
3326
3327 Check_Type(argv, T_ARRAY);
3328 rb_ary_clear(argv);
3329 while (end-- > beg) {
3330 rb_ary_push(argv, ole_variant2val(&realargs[end]));
3331 VariantClear(&realargs[end]);
3332 }
3333 return argv;
3334 }
3335
3336 static VALUE
3337 ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket)
3338 {
3339 LCID lcid = cWIN32OLE_lcid;
3340 struct oledata *pole;
3341 HRESULT hr;
3342 VALUE cmd;
3343 VALUE paramS;
3344 VALUE param;
3345 VALUE obj;
3346 VALUE v;
3347
3348 BSTR wcmdname;
3349
3350 DISPID DispID;
3351 DISPID* pDispID;
3352 EXCEPINFO excepinfo;
3353 VARIANT result;
3354 VARIANTARG* realargs = NULL;
3355 unsigned int argErr = 0;
3356 unsigned int i;
3357 unsigned int cNamedArgs;
3358 int n;
3359 struct oleparam op;
3360 struct olevariantdata *pvar;
3361 memset(&excepinfo, 0, sizeof(EXCEPINFO));
3362
3363 VariantInit(&result);
3364
3365 op.dp.rgvarg = NULL;
3366 op.dp.rgdispidNamedArgs = NULL;
3367 op.dp.cNamedArgs = 0;
3368 op.dp.cArgs = 0;
3369
3370 rb_scan_args(argc, argv, "1*", &cmd, &paramS);
3371 if(TYPE(cmd) != T_STRING && TYPE(cmd) != T_SYMBOL && !is_bracket) {
3372 rb_raise(rb_eTypeError, "method is wrong type (expected String or Symbol)");
3373 }
3374 if (TYPE(cmd) == T_SYMBOL) {
3375 cmd = rb_sym_to_s(cmd);
3376 }
3377 OLEData_Get_Struct(self, pole);
3378 if(!pole->pDispatch) {
3379 rb_raise(rb_eRuntimeError, "failed to get dispatch interface");
3380 }
3381 if (is_bracket) {
3382 DispID = DISPID_VALUE;
3383 argc += 1;
3384 rb_ary_unshift(paramS, cmd);
3385 } else {
3386 wcmdname = ole_vstr2wc(cmd);
3387 hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
3388 &wcmdname, 1, lcid, &DispID);
3389 SysFreeString(wcmdname);
3390 if(FAILED(hr)) {
3391 ole_raise(hr, rb_eNoMethodError,
3392 "unknown property or method: `%s'",
3393 StringValuePtr(cmd));
3394 }
3395 }
3396
3397 /* pick up last argument of method */
3398 param = rb_ary_entry(paramS, argc-2);
3399
3400 op.dp.cNamedArgs = 0;
3401
3402 /* if last arg is hash object */
3403 if(TYPE(param) == T_HASH) {
3404 /*------------------------------------------
3405 hash object ==> named dispatch parameters
3406 --------------------------------------------*/
3407 cNamedArgs = NUM2INT(rb_funcall(param, rb_intern("length"), 0));
3408 op.dp.cArgs = cNamedArgs + argc - 2;
3409 op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);
3410 op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs);
3411 rb_block_call(param, rb_intern("each"), 0, 0, hash2named_arg, (VALUE)&op);
3412
3413 pDispID = ALLOCA_N(DISPID, cNamedArgs + 1);
3414 op.pNamedArgs[0] = ole_vstr2wc(cmd);
3415 hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch,
3416 &IID_NULL,
3417 op.pNamedArgs,
3418 op.dp.cNamedArgs + 1,
3419 lcid, pDispID);
3420 for(i = 0; i < op.dp.cNamedArgs + 1; i++) {
3421 SysFreeString(op.pNamedArgs[i]);
3422 op.pNamedArgs[i] = NULL;
3423 }
3424 if(FAILED(hr)) {
3425 /* clear dispatch parameters */
3426 for(i = 0; i < op.dp.cArgs; i++ ) {
3427 VariantClear(&op.dp.rgvarg[i]);
3428 }
3429 ole_raise(hr, eWIN32OLERuntimeError,
3430 "failed to get named argument info: `%s'",
3431 StringValuePtr(cmd));
3432 }
3433 op.dp.rgdispidNamedArgs = &(pDispID[1]);
3434 }
3435 else {
3436 cNamedArgs = 0;
3437 op.dp.cArgs = argc - 1;
3438 op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);
3439 if (op.dp.cArgs > 0) {
3440 op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs);
3441 }
3442 }
3443 /*--------------------------------------
3444 non hash args ==> dispatch parameters
3445 ----------------------------------------*/
3446 if(op.dp.cArgs > cNamedArgs) {
3447 realargs = ALLOCA_N(VARIANTARG, op.dp.cArgs-cNamedArgs+1);
3448 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
3449 n = op.dp.cArgs - i + cNamedArgs - 1;
3450 VariantInit(&realargs[n]);
3451 VariantInit(&op.dp.rgvarg[n]);
3452 param = rb_ary_entry(paramS, i-cNamedArgs);
3453 if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) {
3454 Data_Get_Struct(param, struct olevariantdata, pvar);
3455 VariantCopy(&op.dp.rgvarg[n], &(pvar->var));
3456 } else {
3457 ole_val2variant(param, &realargs[n]);
3458 V_VT(&op.dp.rgvarg[n]) = VT_VARIANT | VT_BYREF;
3459 V_VARIANTREF(&op.dp.rgvarg[n]) = &realargs[n];
3460 }
3461 }
3462 }
3463 /* apparent you need to call propput, you need this */
3464 if (wFlags & DISPATCH_PROPERTYPUT) {
3465 if (op.dp.cArgs == 0)
3466 ole_raise(ResultFromScode(E_INVALIDARG), eWIN32OLERuntimeError, "argument error");
3467
3468 op.dp.cNamedArgs = 1;
3469 op.dp.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 );
3470 op.dp.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
3471 }
3472
3473 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
3474 &IID_NULL, lcid, wFlags, &op.dp,
3475 &result, &excepinfo, &argErr);
3476
3477 if (FAILED(hr)) {
3478 /* retry to call args by value */
3479 if(op.dp.cArgs >= cNamedArgs) {
3480 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
3481 n = op.dp.cArgs - i + cNamedArgs - 1;
3482 param = rb_ary_entry(paramS, i-cNamedArgs);
3483 ole_val2variant(param, &op.dp.rgvarg[n]);
3484 }
3485 if (hr == DISP_E_EXCEPTION) {
3486 ole_freeexceptinfo(&excepinfo);
3487 }
3488 memset(&excepinfo, 0, sizeof(EXCEPINFO));
3489 VariantInit(&result);
3490 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
3491 &IID_NULL, lcid, wFlags,
3492 &op.dp, &result,
3493 &excepinfo, &argErr);
3494
3495 /* mega kludge. if a method in WORD is called and we ask
3496 * for a result when one is not returned then
3497 * hResult == DISP_E_EXCEPTION. this only happens on
3498 * functions whose DISPID > 0x8000 */
3499 if ((hr == DISP_E_EXCEPTION || hr == DISP_E_MEMBERNOTFOUND) && DispID > 0x8000) {
3500 if (hr == DISP_E_EXCEPTION) {
3501 ole_freeexceptinfo(&excepinfo);
3502 }
3503 memset(&excepinfo, 0, sizeof(EXCEPINFO));
3504 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
3505 &IID_NULL, lcid, wFlags,
3506 &op.dp, NULL,
3507 &excepinfo, &argErr);
3508
3509 }
3510 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
3511 n = op.dp.cArgs - i + cNamedArgs - 1;
3512 VariantClear(&op.dp.rgvarg[n]);
3513 }
3514 }
3515
3516 if (FAILED(hr)) {
3517 /* retry after converting nil to VT_EMPTY */
3518 if (op.dp.cArgs > cNamedArgs) {
3519 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
3520 n = op.dp.cArgs - i + cNamedArgs - 1;
3521 param = rb_ary_entry(paramS, i-cNamedArgs);
3522 ole_val2variant2(param, &op.dp.rgvarg[n]);
3523 }
3524 if (hr == DISP_E_EXCEPTION) {
3525 ole_freeexceptinfo(&excepinfo);
3526 }
3527 memset(&excepinfo, 0, sizeof(EXCEPINFO));
3528 VariantInit(&result);
3529 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
3530 &IID_NULL, lcid, wFlags,
3531 &op.dp, &result,
3532 &excepinfo, &argErr);
3533 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
3534 n = op.dp.cArgs - i + cNamedArgs - 1;
3535 VariantClear(&op.dp.rgvarg[n]);
3536 }
3537 }
3538 }
3539
3540 }
3541 /* clear dispatch parameter */
3542 if(op.dp.cArgs > cNamedArgs) {
3543 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
3544 n = op.dp.cArgs - i + cNamedArgs - 1;
3545 param = rb_ary_entry(paramS, i-cNamedArgs);
3546 if (rb_obj_is_kind_of(param, cWIN32OLE_VARIANT)) {
3547 ole_val2variant(param, &realargs[n]);
3548 }
3549 }
3550 set_argv(realargs, cNamedArgs, op.dp.cArgs);
3551 }
3552 else {
3553 for(i = 0; i < op.dp.cArgs; i++) {
3554 VariantClear(&op.dp.rgvarg[i]);
3555 }
3556 }
3557
3558 if (FAILED(hr)) {
3559 v = ole_excepinfo2msg(&excepinfo);
3560 ole_raise(hr, eWIN32OLERuntimeError, "(in OLE method `%s': )%s",
3561 StringValuePtr(cmd),
3562 StringValuePtr(v));
3563 }
3564 obj = ole_variant2val(&result);
3565 VariantClear(&result);
3566 return obj;
3567 }
3568
3569 /*
3570 * call-seq:
3571 * WIN32OLE#invoke(method, [arg1,...]) => return value of method.
3572 *
3573 * Runs OLE method.
3574 * The first argument specifies the method name of OLE Automation object.
3575 * The others specify argument of the <i>method</i>.
3576 * If you can not execute <i>method</i> directly, then use this method instead.
3577 *
3578 * excel = WIN32OLE.new('Excel.Application')
3579 * excel.invoke('Quit') # => same as excel.Quit
3580 *
3581 */
3582 static VALUE
3583 fole_invoke(int argc, VALUE *argv, VALUE self)
3584 {
3585 return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
3586 }
3587
3588 static VALUE
3589 ole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types, USHORT dispkind)
3590 {
3591 HRESULT hr;
3592 struct oledata *pole;
3593 unsigned int argErr = 0;
3594 EXCEPINFO excepinfo;
3595 VARIANT result;
3596 DISPPARAMS dispParams;
3597 VARIANTARG* realargs = NULL;
3598 int i, j;
3599 VALUE obj = Qnil;
3600 VALUE tp, param;
3601 VALUE v;
3602 VARTYPE vt;
3603
3604 Check_Type(args, T_ARRAY);
3605 Check_Type(types, T_ARRAY);
3606
3607 memset(&excepinfo, 0, sizeof(EXCEPINFO));
3608 memset(&dispParams, 0, sizeof(DISPPARAMS));
3609 VariantInit(&result);
3610 OLEData_Get_Struct(self, pole);
3611
3612 dispParams.cArgs = RARRAY_LEN(args);
3613 dispParams.rgvarg = ALLOCA_N(VARIANTARG, dispParams.cArgs);
3614 realargs = ALLOCA_N(VARIANTARG, dispParams.cArgs);
3615 for (i = 0, j = dispParams.cArgs - 1; i < (int)dispParams.cArgs; i++, j--)
3616 {
3617 VariantInit(&realargs[i]);
3618 VariantInit(&dispParams.rgvarg[i]);
3619 tp = rb_ary_entry(types, j);
3620 vt = (VARTYPE)FIX2INT(tp);
3621 V_VT(&dispParams.rgvarg[i]) = vt;
3622 param = rb_ary_entry(args, j);
3623 if (param == Qnil)
3624 {
3625
3626 V_VT(&dispParams.rgvarg[i]) = V_VT(&realargs[i]) = VT_ERROR;
3627 V_ERROR(&dispParams.rgvarg[i]) = V_ERROR(&realargs[i]) = DISP_E_PARAMNOTFOUND;
3628 }
3629 else
3630 {
3631 if (vt & VT_ARRAY)
3632 {
3633 int ent;
3634 LPBYTE pb;
3635 short* ps;
3636 LPLONG pl;
3637 VARIANT* pv;
3638 CY *py;
3639 VARTYPE v;
3640 SAFEARRAYBOUND rgsabound[1];
3641 Check_Type(param, T_ARRAY);
3642 rgsabound[0].lLbound = 0;
3643 rgsabound[0].cElements = RARRAY_LEN(param);
3644 v = vt & ~(VT_ARRAY | VT_BYREF);
3645 V_ARRAY(&realargs[i]) = SafeArrayCreate(v, 1, rgsabound);
3646 V_VT(&realargs[i]) = VT_ARRAY | v;
3647 SafeArrayLock(V_ARRAY(&realargs[i]));
3648 pb = V_ARRAY(&realargs[i])->pvData;
3649 ps = V_ARRAY(&realargs[i])->pvData;
3650 pl = V_ARRAY(&realargs[i])->pvData;
3651 py = V_ARRAY(&realargs[i])->pvData;
3652 pv = V_ARRAY(&realargs[i])->pvData;
3653 for (ent = 0; ent < (int)rgsabound[0].cElements; ent++)
3654 {
3655 VARIANT velem;
3656 VALUE elem = rb_ary_entry(param, ent);
3657 ole_val2variant(elem, &velem);
3658 if (v != VT_VARIANT)
3659 {
3660 VariantChangeTypeEx(&velem, &velem,
3661 cWIN32OLE_lcid, 0, v);
3662 }
3663 switch (v)
3664 {
3665 /* 128 bits */
3666 case VT_VARIANT:
3667 *pv++ = velem;
3668 break;
3669 /* 64 bits */
3670 case VT_R8:
3671 case VT_CY:
3672 case VT_DATE:
3673 *py++ = V_CY(&velem);
3674 break;
3675 /* 16 bits */
3676 case VT_BOOL:
3677 case VT_I2:
3678 case VT_UI2:
3679 *ps++ = V_I2(&velem);
3680 break;
3681 /* 8 bites */
3682 case VT_UI1:
3683 case VT_I1:
3684 *pb++ = V_UI1(&velem);
3685 break;
3686 /* 32 bits */
3687 default:
3688 *pl++ = V_I4(&velem);
3689 break;
3690 }
3691 }
3692 SafeArrayUnlock(V_ARRAY(&realargs[i]));
3693 }
3694 else
3695 {
3696 ole_val2variant(param, &realargs[i]);
3697 if ((vt & (~VT_BYREF)) != VT_VARIANT)
3698 {
3699 hr = VariantChangeTypeEx(&realargs[i], &realargs[i],
3700 cWIN32OLE_lcid, 0,
3701 (VARTYPE)(vt & (~VT_BYREF)));
3702 if (hr != S_OK)
3703 {
3704 rb_raise(rb_eTypeError, "not valid value");
3705 }
3706 }
3707 }
3708 if ((vt & VT_BYREF) || vt == VT_VARIANT)
3709 {
3710 if (vt == VT_VARIANT)
3711 V_VT(&dispParams.rgvarg[i]) = VT_VARIANT | VT_BYREF;
3712 switch (vt & (~VT_BYREF))
3713 {
3714 /* 128 bits */
3715 case VT_VARIANT:
3716 V_VARIANTREF(&dispParams.rgvarg[i]) = &realargs[i];
3717 break;
3718 /* 64 bits */
3719 case VT_R8:
3720 case VT_CY:
3721 case VT_DATE:
3722 V_CYREF(&dispParams.rgvarg[i]) = &V_CY(&realargs[i]);
3723 break;
3724 /* 16 bits */
3725 case VT_BOOL:
3726 case VT_I2:
3727 case VT_UI2:
3728 V_I2REF(&dispParams.rgvarg[i]) = &V_I2(&realargs[i]);
3729 break;
3730 /* 8 bites */
3731 case VT_UI1:
3732 case VT_I1:
3733 V_UI1REF(&dispParams.rgvarg[i]) = &V_UI1(&realargs[i]);
3734 break;
3735 /* 32 bits */
3736 default:
3737 V_I4REF(&dispParams.rgvarg[i]) = &V_I4(&realargs[i]);
3738 break;
3739 }
3740 }
3741 else
3742 {
3743 /* copy 64 bits of data */
3744 V_CY(&dispParams.rgvarg[i]) = V_CY(&realargs[i]);
3745 }
3746 }
3747 }
3748
3749 if (dispkind & DISPATCH_PROPERTYPUT) {
3750 dispParams.cNamedArgs = 1;
3751 dispParams.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 );
3752 dispParams.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
3753 }
3754
3755 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, NUM2INT(dispid),
3756 &IID_NULL, cWIN32OLE_lcid,
3757 dispkind,
3758 &dispParams, &result,
3759 &excepinfo, &argErr);
3760
3761 if (FAILED(hr)) {
3762 v = ole_excepinfo2msg(&excepinfo);
3763 ole_raise(hr, eWIN32OLERuntimeError, "(in OLE method `<dispatch id:%d>': )%s",
3764 NUM2INT(dispid),
3765 StringValuePtr(v));
3766 }
3767
3768 /* clear dispatch parameter */
3769 if(dispParams.cArgs > 0) {
3770 set_argv(realargs, 0, dispParams.cArgs);
3771 }
3772
3773 obj = ole_variant2val(&result);
3774 VariantClear(&result);
3775 return obj;
3776 }
3777
3778 /*
3779 * call-seq:
3780 * WIN32OLE#_invoke(dispid, args, types)
3781 *
3782 * Runs the early binding method.
3783 * The 1st argument specifies dispatch ID,
3784 * the 2nd argument specifies the array of arguments,
3785 * the 3rd argument specifies the array of the type of arguments.
3786 *
3787 * excel = WIN32OLE.new('Excel.Application')
3788 * excel._invoke(302, [], []) # same effect as excel.Quit
3789 */
3790 static VALUE
3791 fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types)
3792 {
3793 return ole_invoke2(self, dispid, args, types, DISPATCH_METHOD);
3794 }
3795
3796 /*
3797 * call-seq:
3798 * WIN32OLE#_getproperty(dispid, args, types)
3799 *
3800 * Runs the early binding method to get property.
3801 * The 1st argument specifies dispatch ID,
3802 * the 2nd argument specifies the array of arguments,
3803 * the 3rd argument specifies the array of the type of arguments.
3804 *
3805 * excel = WIN32OLE.new('Excel.Application')
3806 * puts excel._getproperty(558, [], []) # same effect as puts excel.visible
3807 */
3808 static VALUE
3809 fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
3810 {
3811 return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYGET);
3812 }
3813
3814 /*
3815 * call-seq:
3816 * WIN32OLE#_setproperty(dispid, args, types)
3817 *
3818 * Runs the early binding method to set property.
3819 * The 1st argument specifies dispatch ID,
3820 * the 2nd argument specifies the array of arguments,
3821 * the 3rd argument specifies the array of the type of arguments.
3822 *
3823 * excel = WIN32OLE.new('Excel.Application')
3824 * excel._setproperty(558, [true], [WIN32OLE::VARIANT::VT_BOOL]) # same effect as excel.visible = true
3825 */
3826 static VALUE
3827 fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
3828 {
3829 return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYPUT);
3830 }
3831
3832 /*
3833 * call-seq:
3834 * WIN32OLE[a1, a2, ...]=val
3835 *
3836 * Sets the value to WIN32OLE object specified by a1, a2, ...
3837 *
3838 * dict = WIN32OLE.new('Scripting.Dictionary')
3839 * dict.add('ruby', 'RUBY')
3840 * dict['ruby'] = 'Ruby'
3841 * puts dict['ruby'] # => 'Ruby'
3842 *
3843 * Remark: You can not use this method to set the property value.
3844 *
3845 * excel = WIN32OLE.new('Excel.Application')
3846 * # excel['Visible'] = true # This is error !!!
3847 * excel.Visible = true # You should to use this style to set the property.
3848 *
3849 */
3850 static VALUE
3851 fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self)
3852 {
3853 return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, TRUE);
3854 }
3855
3856 /*
3857 * call-seq:
3858 * WIN32OLE.setproperty('property', [arg1, arg2,...] val)
3859 *
3860 * Sets property of OLE object.
3861 * When you want to set property with argument, you can use this method.
3862 *
3863 * excel = WIN32OLE.new('Excel.Application')
3864 * excel.Visible = true
3865 * book = excel.workbooks.add
3866 * sheet = book.worksheets(1)
3867 * sheet.setproperty('Cells', 1, 2, 10) # => The B1 cell value is 10.
3868 */
3869 static VALUE
3870 fole_setproperty(int argc, VALUE *argv, VALUE self)
3871 {
3872 return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, FALSE);
3873 }
3874
3875 /*
3876 * call-seq:
3877 * WIN32OLE[a1,a2,...]
3878 *
3879 * Returns the value of Collection specified by a1, a2,....
3880 *
3881 * dict = WIN32OLE.new('Scripting.Dictionary')
3882 * dict.add('ruby', 'Ruby')
3883 * puts dict['ruby'] # => 'Ruby' (same as `puts dict.item('ruby')')
3884 *
3885 * Remark: You can not use this method to get the property.
3886 * excel = WIN32OLE.new('Excel.Application')
3887 * # puts excel['Visible'] This is error !!!
3888 * puts excel.Visible # You should to use this style to get the property.
3889 *
3890 */
3891 static VALUE
3892 fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self)
3893 {
3894 return ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET, TRUE);
3895 }
3896
3897 static VALUE
3898 ole_propertyput(VALUE self, VALUE property, VALUE value)
3899 {
3900 struct oledata *pole;
3901 unsigned argErr;
3902 unsigned int index;
3903 HRESULT hr;
3904 EXCEPINFO excepinfo;
3905 DISPID dispID = DISPID_VALUE;
3906 DISPID dispIDParam = DISPID_PROPERTYPUT;
3907 USHORT wFlags = DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF;
3908 DISPPARAMS dispParams;
3909 VARIANTARG propertyValue[2];
3910 OLECHAR* pBuf[1];
3911 VALUE v;
3912 LCID lcid = cWIN32OLE_lcid;
3913 dispParams.rgdispidNamedArgs = &dispIDParam;
3914 dispParams.rgvarg = propertyValue;
3915 dispParams.cNamedArgs = 1;
3916 dispParams.cArgs = 1;
3917
3918 VariantInit(&propertyValue[0]);
3919 VariantInit(&propertyValue[1]);
3920 memset(&excepinfo, 0, sizeof(excepinfo));
3921
3922 OLEData_Get_Struct(self, pole);
3923
3924 /* get ID from property name */
3925 pBuf[0] = ole_vstr2wc(property);
3926 hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch, &IID_NULL,
3927 pBuf, 1, lcid, &dispID);
3928 SysFreeString(pBuf[0]);
3929 pBuf[0] = NULL;
3930
3931 if(FAILED(hr)) {
3932 ole_raise(hr, eWIN32OLERuntimeError,
3933 "unknown property or method: `%s'",
3934 StringValuePtr(property));
3935 }
3936 /* set property value */
3937 ole_val2variant(value, &propertyValue[0]);
3938 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, dispID, &IID_NULL,
3939 lcid, wFlags, &dispParams,
3940 NULL, &excepinfo, &argErr);
3941
3942 for(index = 0; index < dispParams.cArgs; ++index) {
3943 VariantClear(&propertyValue[index]);
3944 }
3945 if (FAILED(hr)) {
3946 v = ole_excepinfo2msg(&excepinfo);
3947 ole_raise(hr, eWIN32OLERuntimeError, "(in setting property `%s': )%s",
3948 StringValuePtr(property),
3949 StringValuePtr(v));
3950 }
3951 return Qnil;
3952 }
3953
3954 /*
3955 * call-seq:
3956 * WIN32OLE#ole_free
3957 *
3958 * invokes Release method of Dispatch interface of WIN32OLE object.
3959 * Usually, you do not need to call this method because Release method
3960 * called automatically when WIN32OLE object garbaged.
3961 *
3962 */
3963 static VALUE
3964 fole_free(VALUE self)
3965 {
3966 struct oledata *pole;
3967 rb_secure(4);
3968 OLEData_Get_Struct(self, pole);
3969 OLE_FREE(pole->pDispatch);
3970 pole->pDispatch = NULL;
3971 return Qnil;
3972 }
3973
3974 static VALUE
3975 ole_each_sub(VALUE pEnumV)
3976 {
3977 VARIANT variant;
3978 VALUE obj = Qnil;
3979 IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
3980 VariantInit(&variant);
3981 while(pEnum->lpVtbl->Next(pEnum, 1, &variant, NULL) == S_OK) {
3982 obj = ole_variant2val(&variant);
3983 VariantClear(&variant);
3984 VariantInit(&variant);
3985 rb_yield(obj);
3986 }
3987 return Qnil;
3988 }
3989
3990 static VALUE
3991 ole_ienum_free(VALUE pEnumV)
3992 {
3993 IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
3994 OLE_RELEASE(pEnum);
3995 return Qnil;
3996 }
3997
3998 /*
3999 * call-seq:
4000 * WIN32OLE#each {|i|...}
4001 *
4002 * Iterates over each item of OLE collection which has IEnumVARIANT interface.
4003 *
4004 * excel = WIN32OLE.new('Excel.Application')
4005 * book = excel.workbooks.add
4006 * sheets = book.worksheets(1)
4007 * cells = sheets.cells("A1:A5")
4008 * cells.each do |cell|
4009 * cell.value = 10
4010 * end
4011 */
4012 static VALUE
4013 fole_each(VALUE self)
4014 {
4015 LCID lcid = cWIN32OLE_lcid;
4016
4017 struct oledata *pole;
4018
4019 unsigned int argErr;
4020 EXCEPINFO excepinfo;
4021 DISPPARAMS dispParams;
4022 VARIANT result;
4023 HRESULT hr;
4024 IEnumVARIANT *pEnum = NULL;
4025 void *p;
4026
4027 RETURN_ENUMERATOR(self, 0, 0);
4028
4029 VariantInit(&result);
4030 dispParams.rgvarg = NULL;
4031 dispParams.rgdispidNamedArgs = NULL;
4032 dispParams.cNamedArgs = 0;
4033 dispParams.cArgs = 0;
4034 memset(&excepinfo, 0, sizeof(excepinfo));
4035
4036 OLEData_Get_Struct(self, pole);
4037 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DISPID_NEWENUM,
4038 &IID_NULL, lcid,
4039 DISPATCH_METHOD | DISPATCH_PROPERTYGET,
4040 &dispParams, &result,
4041 &excepinfo, &argErr);
4042
4043 if (FAILED(hr)) {
4044 VariantClear(&result);
4045 ole_raise(hr, eWIN32OLERuntimeError, "failed to get IEnum Interface");
4046 }
4047
4048 if (V_VT(&result) == VT_UNKNOWN) {
4049 hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result),
4050 &IID_IEnumVARIANT,
4051 &p);
4052 pEnum = p;
4053 } else if (V_VT(&result) == VT_DISPATCH) {
4054 hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result),
4055 &IID_IEnumVARIANT,
4056 &p);
4057 pEnum = p;
4058 }
4059 if (FAILED(hr) || !pEnum) {
4060 VariantClear(&result);
4061 ole_raise(hr, rb_eRuntimeError, "failed to get IEnum Interface");
4062 }
4063
4064 VariantClear(&result);
4065 rb_ensure(ole_each_sub, (VALUE)pEnum, ole_ienum_free, (VALUE)pEnum);
4066 return Qnil;
4067 }
4068
4069 /*
4070 * call-seq:
4071 * WIN32OLE#method_missing(id [,arg1, arg2, ...])
4072 *
4073 * Calls WIN32OLE#invoke method.
4074 */
4075 static VALUE
4076 fole_missing(int argc, VALUE *argv, VALUE self)
4077 {
4078 ID id;
4079 const char* mname;
4080 int n;
4081 id = rb_to_id(argv[0]);
4082 mname = rb_id2name(id);
4083 if(!mname) {
4084 rb_raise(rb_eRuntimeError, "fail: unknown method or property");
4085 }
4086 n = strlen(mname);
4087 if(mname[n-1] == '=') {
4088 argv[0] = rb_enc_str_new(mname, n-1, cWIN32OLE_enc);
4089
4090 return ole_propertyput(self, argv[0], argv[1]);
4091 }
4092 else {
4093 argv[0] = rb_enc_str_new(mname, n, cWIN32OLE_enc);
4094 return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
4095 }
4096 }
4097
4098 static VALUE
4099 ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name)
4100 {
4101 HRESULT hr;
4102 TYPEATTR *pTypeAttr;
4103 BSTR bstr;
4104 FUNCDESC *pFuncDesc;
4105 WORD i;
4106 VALUE fname;
4107 VALUE method = Qnil;
4108 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
4109 if (FAILED(hr)) {
4110 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
4111 }
4112 for(i = 0; i < pTypeAttr->cFuncs && method == Qnil; i++) {
4113 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
4114 if (FAILED(hr))
4115 continue;
4116
4117 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
4118 &bstr, NULL, NULL, NULL);
4119 if (FAILED(hr)) {
4120 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4121 continue;
4122 }
4123 fname = WC2VSTR(bstr);
4124 if (strcasecmp(StringValuePtr(name), StringValuePtr(fname)) == 0) {
4125 olemethod_set_member(self, pTypeInfo, pOwnerTypeInfo, i, fname);
4126 method = self;
4127 }
4128 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4129 pFuncDesc=NULL;
4130 }
4131 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
4132 return method;
4133 }
4134
4135 static VALUE
4136 olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
4137 {
4138 HRESULT hr;
4139 TYPEATTR *pTypeAttr;
4140 WORD i;
4141 HREFTYPE href;
4142 ITypeInfo *pRefTypeInfo;
4143 VALUE method = Qnil;
4144 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
4145 if (FAILED(hr)) {
4146 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
4147 }
4148 method = ole_method_sub(self, 0, pTypeInfo, name);
4149 if (method != Qnil) {
4150 return method;
4151 }
4152 for(i=0; i < pTypeAttr->cImplTypes && method == Qnil; i++){
4153 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
4154 if(FAILED(hr))
4155 continue;
4156 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
4157 if (FAILED(hr))
4158 continue;
4159 method = ole_method_sub(self, pTypeInfo, pRefTypeInfo, name);
4160 OLE_RELEASE(pRefTypeInfo);
4161 }
4162 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
4163 return method;
4164 }
4165
4166 static VALUE
4167 ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask)
4168 {
4169 HRESULT hr;
4170 TYPEATTR *pTypeAttr;
4171 BSTR bstr;
4172 FUNCDESC *pFuncDesc;
4173 VALUE method;
4174 WORD i;
4175 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
4176 if (FAILED(hr)) {
4177 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
4178 }
4179 for(i = 0; i < pTypeAttr->cFuncs; i++) {
4180 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
4181 if (FAILED(hr))
4182 continue;
4183
4184 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
4185 &bstr, NULL, NULL, NULL);
4186 if (FAILED(hr)) {
4187 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4188 continue;
4189 }
4190 if(pFuncDesc->invkind & mask) {
4191 method = folemethod_s_allocate(cWIN32OLE_METHOD);
4192 olemethod_set_member(method, pTypeInfo, pOwnerTypeInfo,
4193 i, WC2VSTR(bstr));
4194 rb_ary_push(methods, method);
4195 }
4196 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4197 pFuncDesc=NULL;
4198 }
4199 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
4200
4201 return methods;
4202 }
4203
4204 static VALUE
4205 ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask)
4206 {
4207 HRESULT hr;
4208 TYPEATTR *pTypeAttr;
4209 WORD i;
4210 HREFTYPE href;
4211 ITypeInfo *pRefTypeInfo;
4212 VALUE methods = rb_ary_new();
4213 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
4214 if (FAILED(hr)) {
4215 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
4216 }
4217
4218 ole_methods_sub(0, pTypeInfo, methods, mask);
4219 for(i=0; i < pTypeAttr->cImplTypes; i++){
4220 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
4221 if(FAILED(hr))
4222 continue;
4223 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
4224 if (FAILED(hr))
4225 continue;
4226 ole_methods_sub(pTypeInfo, pRefTypeInfo, methods, mask);
4227 OLE_RELEASE(pRefTypeInfo);
4228 }
4229 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
4230 return methods;
4231 }
4232
4233 static HRESULT
4234 typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti)
4235 {
4236 ITypeInfo *pTypeInfo;
4237 ITypeLib *pTypeLib;
4238 BSTR bstr;
4239 VALUE type;
4240 UINT i;
4241 UINT count;
4242 LCID lcid = cWIN32OLE_lcid;
4243 HRESULT hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
4244 0, lcid, &pTypeInfo);
4245 if(FAILED(hr)) {
4246 ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
4247 }
4248 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo,
4249 -1,
4250 &bstr,
4251 NULL, NULL, NULL);
4252 type = WC2VSTR(bstr);
4253 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
4254 OLE_RELEASE(pTypeInfo);
4255 if (FAILED(hr)) {
4256 ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib");
4257 }
4258 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
4259 for (i = 0; i < count; i++) {
4260 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
4261 &bstr, NULL, NULL, NULL);
4262 if (SUCCEEDED(hr) && rb_str_cmp(WC2VSTR(bstr), type) == 0) {
4263 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
4264 if (SUCCEEDED(hr)) {
4265 *ppti = pTypeInfo;
4266 break;
4267 }
4268 }
4269 }
4270 OLE_RELEASE(pTypeLib);
4271 return hr;
4272 }
4273
4274 static VALUE
4275 ole_methods(VALUE self, int mask)
4276 {
4277 ITypeInfo *pTypeInfo;
4278 HRESULT hr;
4279 VALUE methods;
4280 struct oledata *pole;
4281
4282 OLEData_Get_Struct(self, pole);
4283 methods = rb_ary_new();
4284
4285 hr = typeinfo_from_ole(pole, &pTypeInfo);
4286 if(FAILED(hr))
4287 return methods;
4288 rb_ary_concat(methods, ole_methods_from_typeinfo(pTypeInfo, mask));
4289 OLE_RELEASE(pTypeInfo);
4290 return methods;
4291 }
4292
4293 /*
4294 * call-seq:
4295 * WIN32OLE#ole_methods
4296 *
4297 * Returns the array of WIN32OLE_METHOD object.
4298 * The element is OLE method of WIN32OLE object.
4299 *
4300 * excel = WIN32OLE.new('Excel.Application')
4301 * methods = excel.ole_methods
4302 *
4303 */
4304 static VALUE
4305 fole_methods(VALUE self)
4306 {
4307 return ole_methods( self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
4308 }
4309
4310 /*
4311 * call-seq:
4312 * WIN32OLE#ole_get_methods
4313 *
4314 * Returns the array of WIN32OLE_METHOD object .
4315 * The element of the array is property (gettable) of WIN32OLE object.
4316 *
4317 * excel = WIN32OLE.new('Excel.Application')
4318 * properties = excel.ole_get_methods
4319 */
4320 static VALUE
4321 fole_get_methods(VALUE self)
4322 {
4323 return ole_methods( self, INVOKE_PROPERTYGET);
4324 }
4325
4326 /*
4327 * call-seq:
4328 * WIN32OLE#ole_put_methods
4329 *
4330 * Returns the array of WIN32OLE_METHOD object .
4331 * The element of the array is property (settable) of WIN32OLE object.
4332 *
4333 * excel = WIN32OLE.new('Excel.Application')
4334 * properties = excel.ole_put_methods
4335 */
4336 static VALUE
4337 fole_put_methods(VALUE self)
4338 {
4339 return ole_methods( self, INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF);
4340 }
4341
4342 /*
4343 * call-seq:
4344 * WIN32OLE#ole_func_methods
4345 *
4346 * Returns the array of WIN32OLE_METHOD object .
4347 * The element of the array is property (settable) of WIN32OLE object.
4348 *
4349 * excel = WIN32OLE.new('Excel.Application')
4350 * properties = excel.ole_func_methods
4351 *
4352 */
4353 static VALUE
4354 fole_func_methods(VALUE self)
4355 {
4356 return ole_methods( self, INVOKE_FUNC);
4357 }
4358
4359 static VALUE
4360 ole_type_from_itypeinfo(ITypeInfo *pTypeInfo)
4361 {
4362 ITypeLib *pTypeLib;
4363 VALUE type = Qnil;
4364 HRESULT hr;
4365 unsigned int index;
4366 BSTR bstr;
4367
4368 hr = pTypeInfo->lpVtbl->GetContainingTypeLib( pTypeInfo, &pTypeLib, &index );
4369 if(FAILED(hr)) {
4370 return Qnil;
4371 }
4372 hr = pTypeLib->lpVtbl->GetDocumentation( pTypeLib, index,
4373 &bstr, NULL, NULL, NULL);
4374 OLE_RELEASE(pTypeLib);
4375 if (FAILED(hr)) {
4376 return Qnil;
4377 }
4378 type = foletype_s_allocate(cWIN32OLE_TYPE);
4379 oletype_set_member(type, pTypeInfo, WC2VSTR(bstr));
4380 return type;
4381 }
4382
4383 /*
4384 * call-seq:
4385 * WIN32OLE#ole_type
4386 *
4387 * Returns WIN32OLE_TYPE object.
4388 *
4389 * excel = WIN32OLE.new('Excel.Application')
4390 * tobj = excel.ole_type
4391 */
4392 static VALUE
4393 fole_type(VALUE self)
4394 {
4395 ITypeInfo *pTypeInfo;
4396 HRESULT hr;
4397 struct oledata *pole;
4398 LCID lcid = cWIN32OLE_lcid;
4399 VALUE type = Qnil;
4400
4401 OLEData_Get_Struct(self, pole);
4402
4403 hr = pole->pDispatch->lpVtbl->GetTypeInfo( pole->pDispatch, 0, lcid, &pTypeInfo );
4404 if(FAILED(hr)) {
4405 ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
4406 }
4407 type = ole_type_from_itypeinfo(pTypeInfo);
4408 OLE_RELEASE(pTypeInfo);
4409 if (type == Qnil) {
4410 rb_raise(rb_eRuntimeError, "failed to create WIN32OLE_TYPE obj from ITypeInfo");
4411 }
4412 return type;
4413 }
4414
4415 static VALUE
4416 ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo)
4417 {
4418 HRESULT hr;
4419 ITypeLib *pTypeLib;
4420 unsigned int index;
4421 VALUE retval = Qnil;
4422
4423 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
4424 if(FAILED(hr)) {
4425 return Qnil;
4426 }
4427 retval = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("allocate"), 0);
4428 oletypelib_set_member(retval, pTypeLib);
4429 return retval;
4430 }
4431
4432 /*
4433 * call-seq:
4434 * WIN32OLE#ole_typelib -> The WIN32OLE_TYPELIB object
4435 *
4436 * Returns the WIN32OLE_TYPELIB object. The object represents the
4437 * type library which contains the WIN32OLE object.
4438 *
4439 * excel = WIN32OLE.new('Excel.Application')
4440 * tlib = excel.ole_typelib
4441 * puts tlib.name # -> 'Microsoft Excel 9.0 Object Library'
4442 */
4443 static VALUE
4444 fole_typelib(VALUE self)
4445 {
4446 struct oledata *pole;
4447 HRESULT hr;
4448 ITypeInfo *pTypeInfo;
4449 LCID lcid = cWIN32OLE_lcid;
4450 VALUE vtlib = Qnil;
4451
4452 OLEData_Get_Struct(self, pole);
4453 hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
4454 0, lcid, &pTypeInfo);
4455 if(FAILED(hr)) {
4456 ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
4457 }
4458 vtlib = ole_typelib_from_itypeinfo(pTypeInfo);
4459 OLE_RELEASE(pTypeInfo);
4460 if (vtlib == Qnil) {
4461 rb_raise(rb_eRuntimeError, "failed to get type library info.");
4462 }
4463 return vtlib;
4464 }
4465
4466 /*
4467 * call-seq:
4468 * WIN32OLE#ole_query_interface(iid) -> WIN32OLE object
4469 *
4470 * Returns WIN32OLE object for a specific dispatch or dual
4471 * interface specified by iid.
4472 *
4473 * ie = WIN32OLE.new('InternetExplorer.Application')
4474 * ie_web_app = ie.ole_query_interface('{0002DF05-0000-0000-C000-000000000046}') # => WIN32OLE object for dispinterface IWebBrowserApp
4475 */
4476 static VALUE
4477 fole_query_interface(VALUE self, VALUE str_iid)
4478 {
4479 HRESULT hr;
4480 OLECHAR *pBuf;
4481 IID iid;
4482 struct oledata *pole;
4483 IDispatch *pDispatch;
4484 void *p;
4485
4486 pBuf = ole_vstr2wc(str_iid);
4487 hr = CLSIDFromString(pBuf, &iid);
4488 SysFreeString(pBuf);
4489 if(FAILED(hr)) {
4490 ole_raise(hr, eWIN32OLERuntimeError,
4491 "invalid iid: `%s'",
4492 StringValuePtr(str_iid));
4493 }
4494
4495 OLEData_Get_Struct(self, pole);
4496 if(!pole->pDispatch) {
4497 rb_raise(rb_eRuntimeError, "failed to get dispatch interface");
4498 }
4499
4500 hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &iid,
4501 &p);
4502 if(FAILED(hr)) {
4503 ole_raise(hr, eWIN32OLERuntimeError,
4504 "failed to get interface `%s'",
4505 StringValuePtr(str_iid));
4506 }
4507
4508 pDispatch = p;
4509 return create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
4510 }
4511
4512 /*
4513 * call-seq:
4514 * WIN32OLE#ole_respond_to?(method) -> true or false
4515 *
4516 * Returns true when OLE object has OLE method, otherwise returns false.
4517 *
4518 * ie = WIN32OLE.new('InternetExplorer.Application')
4519 * ie.ole_respond_to?("gohome") => true
4520 */
4521 static VALUE
4522 fole_respond_to(VALUE self, VALUE method)
4523 {
4524 struct oledata *pole;
4525 BSTR wcmdname;
4526 DISPID DispID;
4527 HRESULT hr;
4528 rb_secure(4);
4529 if(TYPE(method) != T_STRING && TYPE(method) != T_SYMBOL) {
4530 rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
4531 }
4532 if (TYPE(method) == T_SYMBOL) {
4533 method = rb_sym_to_s(method);
4534 }
4535 OLEData_Get_Struct(self, pole);
4536 wcmdname = ole_vstr2wc(method);
4537 hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
4538 &wcmdname, 1, cWIN32OLE_lcid, &DispID);
4539 SysFreeString(wcmdname);
4540 return SUCCEEDED(hr) ? Qtrue : Qfalse;
4541 }
4542
4543 static HRESULT
4544 ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile)
4545 {
4546 HRESULT hr;
4547 ITypeLib *pTypeLib;
4548 UINT i;
4549
4550 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
4551 if (FAILED(hr)) {
4552 return hr;
4553 }
4554
4555 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
4556 name, helpstr,
4557 helpcontext, helpfile);
4558 if (FAILED(hr)) {
4559 OLE_RELEASE(pTypeLib);
4560 return hr;
4561 }
4562 OLE_RELEASE(pTypeLib);
4563 return hr;
4564 }
4565
4566 static VALUE
4567 ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
4568 {
4569 HRESULT hr;
4570 BSTR bstr;
4571 ITypeInfo *pRefTypeInfo;
4572 VALUE type = Qnil;
4573
4574 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
4575 V_UNION1(pTypeDesc, hreftype),
4576 &pRefTypeInfo);
4577 if(FAILED(hr))
4578 return Qnil;
4579 hr = ole_docinfo_from_type(pRefTypeInfo, &bstr, NULL, NULL, NULL);
4580 if(FAILED(hr)) {
4581 OLE_RELEASE(pRefTypeInfo);
4582 return Qnil;
4583 }
4584 OLE_RELEASE(pRefTypeInfo);
4585 type = WC2VSTR(bstr);
4586 if(typedetails != Qnil)
4587 rb_ary_push(typedetails, type);
4588 return type;
4589 }
4590
4591 static VALUE
4592 ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
4593 {
4594 TYPEDESC *p = pTypeDesc;
4595 VALUE type = rb_str_new2("");
4596
4597 if (p->vt == VT_PTR || p->vt == VT_SAFEARRAY) {
4598 p = V_UNION1(p, lptdesc);
4599 type = ole_typedesc2val(pTypeInfo, p, typedetails);
4600 }
4601 return type;
4602 }
4603
4604 static VALUE
4605 ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
4606 {
4607 VALUE str;
4608 VALUE typestr = Qnil;
4609 switch(pTypeDesc->vt) {
4610 case VT_I2:
4611 typestr = rb_str_new2("I2");
4612 break;
4613 case VT_I4:
4614 typestr = rb_str_new2("I4");
4615 break;
4616 case VT_R4:
4617 typestr = rb_str_new2("R4");
4618 break;
4619 case VT_R8:
4620 typestr = rb_str_new2("R8");
4621 break;
4622 case VT_CY:
4623 typestr = rb_str_new2("CY");
4624 break;
4625 case VT_DATE:
4626 typestr = rb_str_new2("DATE");
4627 break;
4628 case VT_BSTR:
4629 typestr = rb_str_new2("BSTR");
4630 break;
4631 case VT_BOOL:
4632 typestr = rb_str_new2("BOOL");
4633 break;
4634 case VT_VARIANT:
4635 typestr = rb_str_new2("VARIANT");
4636 break;
4637 case VT_DECIMAL:
4638 typestr = rb_str_new2("DECIMAL");
4639 break;
4640 case VT_I1:
4641 typestr = rb_str_new2("I1");
4642 break;
4643 case VT_UI1:
4644 typestr = rb_str_new2("UI1");
4645 break;
4646 case VT_UI2:
4647 typestr = rb_str_new2("UI2");
4648 break;
4649 case VT_UI4:
4650 typestr = rb_str_new2("UI4");
4651 break;
4652 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
4653 case VT_I8:
4654 typestr = rb_str_new2("I8");
4655 break;
4656 case VT_UI8:
4657 typestr = rb_str_new2("UI8");
4658 break;
4659 #endif
4660 case VT_INT:
4661 typestr = rb_str_new2("INT");
4662 break;
4663 case VT_UINT:
4664 typestr = rb_str_new2("UINT");
4665 break;
4666 case VT_VOID:
4667 typestr = rb_str_new2("VOID");
4668 break;
4669 case VT_HRESULT:
4670 typestr = rb_str_new2("HRESULT");
4671 break;
4672 case VT_PTR:
4673 typestr = rb_str_new2("PTR");
4674 if(typedetails != Qnil)
4675 rb_ary_push(typedetails, typestr);
4676 return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
4677 case VT_SAFEARRAY:
4678 typestr = rb_str_new2("SAFEARRAY");
4679 if(typedetails != Qnil)
4680 rb_ary_push(typedetails, typestr);
4681 return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
4682 case VT_CARRAY:
4683 typestr = rb_str_new2("CARRAY");
4684 break;
4685 case VT_USERDEFINED:
4686 typestr = rb_str_new2("USERDEFINED");
4687 if (typedetails != Qnil)
4688 rb_ary_push(typedetails, typestr);
4689 str = ole_usertype2val(pTypeInfo, pTypeDesc, typedetails);
4690 if (str != Qnil) {
4691 return str;
4692 }
4693 return typestr;
4694 case VT_UNKNOWN:
4695 typestr = rb_str_new2("UNKNOWN");
4696 break;
4697 case VT_DISPATCH:
4698 typestr = rb_str_new2("DISPATCH");
4699 break;
4700 case VT_ERROR:
4701 typestr = rb_str_new2("ERROR");
4702 break;
4703 case VT_LPWSTR:
4704 typestr = rb_str_new2("LPWSTR");
4705 break;
4706 case VT_LPSTR:
4707 typestr = rb_str_new2("LPSTR");
4708 break;
4709 default:
4710 typestr = rb_str_new2("Unknown Type ");
4711 rb_str_concat(typestr, rb_fix2str(INT2FIX(pTypeDesc->vt), 10));
4712 break;
4713 }
4714 if (typedetails != Qnil)
4715 rb_ary_push(typedetails, typestr);
4716 return typestr;
4717 }
4718
4719 /*
4720 * call-seq:
4721 * WIN32OLE#ole_method_help(method)
4722 *
4723 * Returns WIN32OLE_METHOD object corresponding with method
4724 * specified by 1st argument.
4725 *
4726 * excel = WIN32OLE.new('Excel.Application')
4727 * method = excel.ole_method_help('Quit')
4728 *
4729 */
4730 static VALUE
4731 fole_method_help(VALUE self, VALUE cmdname)
4732 {
4733 ITypeInfo *pTypeInfo;
4734 HRESULT hr;
4735 struct oledata *pole;
4736 VALUE method, obj;
4737
4738 SafeStringValue(cmdname);
4739 OLEData_Get_Struct(self, pole);
4740 hr = typeinfo_from_ole(pole, &pTypeInfo);
4741 if(FAILED(hr))
4742 ole_raise(hr, rb_eRuntimeError, "failed to get ITypeInfo");
4743 method = folemethod_s_allocate(cWIN32OLE_METHOD);
4744 obj = olemethod_from_typeinfo(method, pTypeInfo, cmdname);
4745 OLE_RELEASE(pTypeInfo);
4746 if (obj == Qnil)
4747 rb_raise(eWIN32OLERuntimeError, "not found %s",
4748 StringValuePtr(cmdname));
4749 return obj;
4750 }
4751
4752 /*
4753 * call-seq:
4754 * WIN32OLE#ole_activex_initialize() -> Qnil
4755 *
4756 * Initialize WIN32OLE object(ActiveX Control) by calling
4757 * IPersistMemory::InitNew.
4758 *
4759 * Before calling OLE method, some kind of the ActiveX controls
4760 * created with MFC should be initialized by calling
4761 * IPersistXXX::InitNew.
4762 *
4763 * If and only if you received the exception "HRESULT error code:
4764 * 0x8000ffff catastrophic failure", try this method before
4765 * invoking any ole_method.
4766 *
4767 * obj = WIN32OLE.new("ProgID_or_GUID_of_ActiveX_Control")
4768 * obj.ole_activex_initialize
4769 * obj.method(...)
4770 *
4771 */
4772 static VALUE
4773 fole_activex_initialize(VALUE self)
4774 {
4775 struct oledata *pole;
4776 IPersistMemory *pPersistMemory;
4777 void *p;
4778
4779 HRESULT hr = S_OK;
4780
4781 OLEData_Get_Struct(self, pole);
4782
4783 hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &IID_IPersistMemory, &p);
4784 pPersistMemory = p;
4785 if (SUCCEEDED(hr)) {
4786 hr = pPersistMemory->lpVtbl->InitNew(pPersistMemory);
4787 OLE_RELEASE(pPersistMemory);
4788 if (SUCCEEDED(hr)) {
4789 return Qnil;
4790 }
4791 }
4792
4793 if (FAILED(hr)) {
4794 ole_raise(hr, eWIN32OLERuntimeError, "fail to initialize ActiveX control");
4795 }
4796
4797 return Qnil;
4798 }
4799
4800 /*
4801 * call-seq:
4802 * WIN32OLE_TYPE.ole_classes(typelib)
4803 *
4804 * Returns array of WIN32OLE_TYPE objects defined by the <i>typelib</i> type library.
4805 * This method will be OBSOLETE. Use WIN32OLE_TYPELIB.new(typelib).ole_classes instead.
4806 */
4807 static VALUE
4808 foletype_s_ole_classes(VALUE self, VALUE typelib)
4809 {
4810 VALUE obj;
4811
4812 /*
4813 rb_warn("%s is obsolete; use %s instead.",
4814 "WIN32OLE_TYPE.ole_classes",
4815 "WIN32OLE_TYPELIB.new(typelib).ole_types");
4816 */
4817 obj = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("new"), 1, typelib);
4818 return rb_funcall(obj, rb_intern("ole_types"), 0);
4819 }
4820
4821 /*
4822 * call-seq:
4823 * WIN32OLE_TYPE.typelibs
4824 *
4825 * Returns array of type libraries.
4826 * This method will be OBSOLETE. Use WIN32OLE_TYPELIB.typelibs.collect{|t| t.name} instead.
4827 *
4828 */
4829 static VALUE
4830 foletype_s_typelibs(VALUE self)
4831 {
4832 /*
4833 rb_warn("%s is obsolete. use %s instead.",
4834 "WIN32OLE_TYPE.typelibs",
4835 "WIN32OLE_TYPELIB.typelibs.collect{t|t.name}");
4836 */
4837 return rb_eval_string("WIN32OLE_TYPELIB.typelibs.collect{|t|t.name}");
4838 }
4839
4840 /*
4841 * call-seq:
4842 * WIN32OLE_TYPE.progids
4843 *
4844 * Returns array of ProgID.
4845 */
4846 static VALUE
4847 foletype_s_progids(VALUE self)
4848 {
4849 HKEY hclsids, hclsid;
4850 DWORD i;
4851 LONG err;
4852 VALUE clsid;
4853 VALUE v = rb_str_new2("");
4854 VALUE progids = rb_ary_new();
4855
4856 err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hclsids);
4857 if(err != ERROR_SUCCESS) {
4858 return progids;
4859 }
4860 for(i = 0; ; i++) {
4861 clsid = reg_enum_key(hclsids, i);
4862 if (clsid == Qnil)
4863 break;
4864 err = reg_open_vkey(hclsids, clsid, &hclsid);
4865 if (err != ERROR_SUCCESS)
4866 continue;
4867 if ((v = reg_get_val2(hclsid, "ProgID")) != Qnil)
4868 rb_ary_push(progids, v);
4869 if ((v = reg_get_val2(hclsid, "VersionIndependentProgID")) != Qnil)
4870 rb_ary_push(progids, v);
4871 RegCloseKey(hclsid);
4872 }
4873 RegCloseKey(hclsids);
4874 return progids;
4875 }
4876
4877 static VALUE
4878 foletype_s_allocate(VALUE klass)
4879 {
4880 struct oletypedata *poletype;
4881 VALUE obj;
4882 ole_initialize();
4883 obj = Data_Make_Struct(klass,struct oletypedata,0,oletype_free,poletype);
4884 poletype->pTypeInfo = NULL;
4885 return obj;
4886 }
4887
4888 static VALUE
4889 oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
4890 {
4891 struct oletypedata *ptype;
4892 Data_Get_Struct(self, struct oletypedata, ptype);
4893 rb_ivar_set(self, rb_intern("name"), name);
4894 ptype->pTypeInfo = pTypeInfo;
4895 if(pTypeInfo) OLE_ADDREF(pTypeInfo);
4896 return self;
4897 }
4898
4899 static VALUE
4900 oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass)
4901 {
4902
4903 long count;
4904 int i;
4905 HRESULT hr;
4906 BSTR bstr;
4907 VALUE typelib;
4908 ITypeInfo *pTypeInfo;
4909
4910 VALUE found = Qfalse;
4911
4912 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
4913 for (i = 0; i < count && found == Qfalse; i++) {
4914 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
4915 if (FAILED(hr))
4916 continue;
4917 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
4918 &bstr, NULL, NULL, NULL);
4919 if (FAILED(hr))
4920 continue;
4921 typelib = WC2VSTR(bstr);
4922 if (rb_str_cmp(oleclass, typelib) == 0) {
4923 oletype_set_member(self, pTypeInfo, typelib);
4924 found = Qtrue;
4925 }
4926 OLE_RELEASE(pTypeInfo);
4927 }
4928 return found;
4929 }
4930
4931 /*
4932 * Document-class: WIN32OLE_TYPELIB
4933 *
4934 * <code>WIN32OLE_TYPELIB</code> objects represent OLE tyblib information.
4935 */
4936
4937 static VALUE
4938 oletypelib_set_member(VALUE self, ITypeLib *pTypeLib)
4939 {
4940 struct oletypelibdata *ptlib;
4941 Data_Get_Struct(self, struct oletypelibdata, ptlib);
4942 ptlib->pTypeLib = pTypeLib;
4943 return self;
4944 }
4945
4946 static ITypeLib *
4947 oletypelib_get_typelib(VALUE self)
4948 {
4949 struct oletypelibdata *ptlib;
4950 Data_Get_Struct(self, struct oletypelibdata, ptlib);
4951 return ptlib->pTypeLib;
4952 }
4953
4954 static void
4955 oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr)
4956 {
4957 HRESULT hr;
4958 hr = pTypeLib->lpVtbl->GetLibAttr(pTypeLib, ppTLibAttr);
4959 if (FAILED(hr)) {
4960 ole_raise(hr, eWIN32OLERuntimeError,
4961 "failed to get library attribute(TLIBATTR) from ITypeLib");
4962 }
4963 }
4964
4965 /*
4966 * call-seq:
4967 *
4968 * WIN32OLE_TYPELIB.typelibs
4969 *
4970 * Returns the array of WIN32OLE_TYPELIB object.
4971 *
4972 * tlibs = WIN32OLE_TYPELIB.typelibs
4973 *
4974 */
4975 static VALUE
4976 foletypelib_s_typelibs(VALUE self)
4977 {
4978 HKEY htypelib, hguid;
4979 DWORD i, j;
4980 LONG err;
4981 VALUE guid;
4982 VALUE version;
4983 VALUE name = Qnil;
4984 VALUE typelibs = rb_ary_new();
4985 VALUE typelib = Qnil;
4986 HRESULT hr;
4987 ITypeLib *pTypeLib;
4988
4989 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
4990 if(err != ERROR_SUCCESS) {
4991 return typelibs;
4992 }
4993 for(i = 0; ; i++) {
4994 guid = reg_enum_key(htypelib, i);
4995 if (guid == Qnil)
4996 break;
4997 err = reg_open_vkey(htypelib, guid, &hguid);
4998 if (err != ERROR_SUCCESS)
4999 continue;
5000 for(j = 0; ; j++) {
5001 version = reg_enum_key(hguid, j);
5002 if (version == Qnil)
5003 break;
5004 if ( (name = reg_get_val2(hguid, StringValuePtr(version))) != Qnil ) {
5005 hr = oletypelib_from_guid(guid, version, &pTypeLib);
5006 if (SUCCEEDED(hr)) {
5007 typelib = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("allocate"), 0);
5008 oletypelib_set_member(typelib, pTypeLib);
5009 rb_ary_push(typelibs, typelib);
5010 }
5011 }
5012 }
5013 RegCloseKey(hguid);
5014 }
5015 RegCloseKey(htypelib);
5016 return typelibs;
5017 }
5018
5019 static VALUE
5020 make_version_str(VALUE major, VALUE minor)
5021 {
5022 VALUE version_str = Qnil;
5023 VALUE minor_str = Qnil;
5024 if (major == Qnil) {
5025 return Qnil;
5026 }
5027 version_str = rb_String(major);
5028 if (minor != Qnil) {
5029 minor_str = rb_String(minor);
5030 rb_str_cat2(version_str, ".");
5031 rb_str_append(version_str, minor_str);
5032 }
5033 return version_str;
5034 }
5035
5036 static VALUE
5037 oletypelib_search_registry2(VALUE self, VALUE args)
5038 {
5039 HKEY htypelib, hguid, hversion;
5040 double fver;
5041 DWORD j;
5042 LONG err;
5043 VALUE found = Qfalse;
5044 VALUE tlib;
5045 VALUE ver;
5046 VALUE version_str;
5047 VALUE version = Qnil;
5048 VALUE typelib = Qnil;
5049 HRESULT hr;
5050 ITypeLib *pTypeLib;
5051
5052 VALUE guid = rb_ary_entry(args, 0);
5053 version_str = make_version_str(rb_ary_entry(args, 1), rb_ary_entry(args, 2));
5054
5055 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
5056 if(err != ERROR_SUCCESS) {
5057 return Qfalse;
5058 }
5059 err = reg_open_vkey(htypelib, guid, &hguid);
5060 if (err != ERROR_SUCCESS) {
5061 RegCloseKey(htypelib);
5062 return Qfalse;
5063 }
5064 if (version_str != Qnil) {
5065 err = reg_open_vkey(hguid, version_str, &hversion);
5066 if (err == ERROR_SUCCESS) {
5067 tlib = reg_get_val(hversion, NULL);
5068 if (tlib != Qnil) {
5069 typelib = tlib;
5070 version = version_str;
5071 }
5072 }
5073 RegCloseKey(hversion);
5074 } else {
5075 fver = 0.0;
5076 for(j = 0; ;j++) {
5077 ver = reg_enum_key(hguid, j);
5078 if (ver == Qnil)
5079 break;
5080 err = reg_open_vkey(hguid, ver, &hversion);
5081 if (err != ERROR_SUCCESS)
5082 continue;
5083 tlib = reg_get_val(hversion, NULL);
5084 if (tlib == Qnil) {
5085 RegCloseKey(hversion);
5086 continue;
5087 }
5088 if (fver < atof(StringValuePtr(ver))) {
5089 fver = atof(StringValuePtr(ver));
5090 version = ver;
5091 typelib = tlib;
5092 }
5093 RegCloseKey(hversion);
5094 }
5095 }
5096 RegCloseKey(hguid);
5097 RegCloseKey(htypelib);
5098 if (typelib != Qnil) {
5099 hr = oletypelib_from_guid(guid, version, &pTypeLib);
5100 if (SUCCEEDED(hr)) {
5101 found = Qtrue;
5102 oletypelib_set_member(self, pTypeLib);
5103 }
5104 }
5105 return found;
5106 }
5107
5108 static VALUE
5109 oletypelib_search_registry(VALUE self, VALUE typelib)
5110 {
5111 HKEY htypelib, hguid, hversion;
5112 DWORD i, j;
5113 LONG err;
5114 VALUE found = Qfalse;
5115 VALUE tlib;
5116 VALUE guid;
5117 VALUE ver;
5118 HRESULT hr;
5119 ITypeLib *pTypeLib;
5120
5121 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
5122 if(err != ERROR_SUCCESS) {
5123 return Qfalse;
5124 }
5125 for(i = 0; !found; i++) {
5126 guid = reg_enum_key(htypelib, i);
5127 if (guid == Qnil)
5128 break;
5129 err = reg_open_vkey(htypelib, guid, &hguid);
5130 if (err != ERROR_SUCCESS)
5131 continue;
5132 for(j = 0; found == Qfalse; j++) {
5133 ver = reg_enum_key(hguid, j);
5134 if (ver == Qnil)
5135 break;
5136 err = reg_open_vkey(hguid, ver, &hversion);
5137 if (err != ERROR_SUCCESS)
5138 continue;
5139 tlib = reg_get_val(hversion, NULL);
5140 if (tlib == Qnil) {
5141 RegCloseKey(hversion);
5142 continue;
5143 }
5144 if (rb_str_cmp(typelib, tlib) == 0) {
5145 hr = oletypelib_from_guid(guid, ver, &pTypeLib);
5146 if (SUCCEEDED(hr)) {
5147 oletypelib_set_member(self, pTypeLib);
5148 found = Qtrue;
5149 }
5150 }
5151 RegCloseKey(hversion);
5152 }
5153 RegCloseKey(hguid);
5154 }
5155 RegCloseKey(htypelib);
5156 return found;
5157 }
5158
5159 static VALUE
5160 foletypelib_s_allocate(VALUE klass)
5161 {
5162 struct oletypelibdata *poletypelib;
5163 VALUE obj;
5164 ole_initialize();
5165 obj = Data_Make_Struct(klass, struct oletypelibdata, 0, oletypelib_free, poletypelib);
5166 poletypelib->pTypeLib = NULL;
5167 return obj;
5168 }
5169
5170 /*
5171 * call-seq:
5172 * WIN32OLE_TYPELIB.new(typelib [, version1, version2]) -> WIN32OLE_TYPELIB object
5173 *
5174 * Returns a new WIN32OLE_TYPELIB object.
5175 *
5176 * The first argument <i>typelib</i> specifies OLE type library name or GUID or
5177 * OLE library file.
5178 * The second argument is major version or version of the type library.
5179 * The third argument is minor version.
5180 * The second argument and third argument are optional.
5181 * If the first argument is type library name, then the second and third argument
5182 * are ignored.
5183 *
5184 * tlib1 = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5185 * tlib2 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}')
5186 * tlib3 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1.3)
5187 * tlib4 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1, 3)
5188 * tlib5 = WIN32OLE_TYPELIB.new("C:\\WINNT\\SYSTEM32\\SHELL32.DLL")
5189 * puts tlib1.name # -> 'Microsoft Excel 9.0 Object Library'
5190 * puts tlib2.name # -> 'Microsoft Excel 9.0 Object Library'
5191 * puts tlib3.name # -> 'Microsoft Excel 9.0 Object Library'
5192 * puts tlib4.name # -> 'Microsoft Excel 9.0 Object Library'
5193 * puts tlib5.name # -> 'Microsoft Shell Controls And Automation'
5194 *
5195 */
5196 static VALUE
5197 foletypelib_initialize(VALUE self, VALUE args)
5198 {
5199 VALUE found = Qfalse;
5200 VALUE typelib = Qnil;
5201 int len = 0;
5202 OLECHAR * pbuf;
5203 ITypeLib *pTypeLib;
5204 HRESULT hr = S_OK;
5205
5206 len = RARRAY_LEN(args);
5207 if (len < 1 || len > 3) {
5208 rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", len);
5209 }
5210
5211 typelib = rb_ary_entry(args, 0);
5212
5213 SafeStringValue(typelib);
5214
5215 found = oletypelib_search_registry(self, typelib);
5216 if (found == Qfalse) {
5217 found = oletypelib_search_registry2(self, args);
5218 }
5219 if (found == Qfalse) {
5220 pbuf = ole_vstr2wc(typelib);
5221 hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
5222 SysFreeString(pbuf);
5223 if (SUCCEEDED(hr)) {
5224 found = Qtrue;
5225 oletypelib_set_member(self, pTypeLib);
5226 }
5227 }
5228
5229 if (found == Qfalse) {
5230 rb_raise(eWIN32OLERuntimeError, "not found type library `%s`",
5231 StringValuePtr(typelib));
5232 }
5233 return self;
5234 }
5235
5236 /*
5237 * call-seq:
5238 * WIN32OLE_TYPELIB#guid -> The guid string.
5239 *
5240 * Returns guid string which specifies type library.
5241 *
5242 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5243 * guid = tlib.guid # -> '{00020813-0000-0000-C000-000000000046}'
5244 */
5245 static VALUE
5246 foletypelib_guid(VALUE self)
5247 {
5248 ITypeLib *pTypeLib;
5249 OLECHAR bstr[80];
5250 VALUE guid = Qnil;
5251 int len;
5252 TLIBATTR *pTLibAttr;
5253
5254 pTypeLib = oletypelib_get_typelib(self);
5255 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
5256 len = StringFromGUID2(&pTLibAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
5257 if (len > 3) {
5258 guid = ole_wc2vstr(bstr, FALSE);
5259 }
5260 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
5261 return guid;
5262 }
5263
5264 /*
5265 * call-seq:
5266 * WIN32OLE_TYPELIB#name -> The type library name
5267 *
5268 * Returns the type library name.
5269 *
5270 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5271 * name = tlib.name # -> 'Microsoft Excel 9.0 Object Library'
5272 */
5273 static VALUE
5274 foletypelib_name(VALUE self)
5275 {
5276 ITypeLib *pTypeLib;
5277 HRESULT hr;
5278 BSTR bstr;
5279 VALUE name;
5280 pTypeLib = oletypelib_get_typelib(self);
5281 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
5282 NULL, &bstr, NULL, NULL);
5283
5284 if (FAILED(hr)) {
5285 ole_raise(hr, eWIN32OLERuntimeError, "failed to get name from ITypeLib");
5286 }
5287 name = WC2VSTR(bstr);
5288 return rb_enc_str_new(StringValuePtr(name), strlen(StringValuePtr(name)), cWIN32OLE_enc);
5289 }
5290
5291 /*
5292 * call-seq:
5293 * WIN32OLE_TYPELIB#version -> The type library version.
5294 *
5295 * Returns the type library version.
5296 *
5297 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5298 * puts tlib.version #-> 1.3
5299 */
5300 static VALUE
5301 foletypelib_version(VALUE self)
5302 {
5303 TLIBATTR *pTLibAttr;
5304 VALUE major;
5305 VALUE minor;
5306 ITypeLib *pTypeLib;
5307
5308 pTypeLib = oletypelib_get_typelib(self);
5309 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
5310 major = INT2NUM(pTLibAttr->wMajorVerNum);
5311 minor = INT2NUM(pTLibAttr->wMinorVerNum);
5312 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
5313 return rb_Float(make_version_str(major, minor));
5314 }
5315
5316 /*
5317 * call-seq:
5318 * WIN32OLE_TYPELIB#major_version -> The type library major version.
5319 *
5320 * Returns the type library major version.
5321 *
5322 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5323 * puts tlib.major_version # -> 1
5324 */
5325 static VALUE
5326 foletypelib_major_version(VALUE self)
5327 {
5328 TLIBATTR *pTLibAttr;
5329 VALUE major;
5330 ITypeLib *pTypeLib;
5331 pTypeLib = oletypelib_get_typelib(self);
5332 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
5333
5334 major = INT2NUM(pTLibAttr->wMajorVerNum);
5335 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
5336 return major;
5337 }
5338
5339 /*
5340 * call-seq:
5341 * WIN32OLE_TYPELIB#minor_version -> The type library minor version.
5342 *
5343 * Returns the type library minor version.
5344 *
5345 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5346 * puts tlib.minor_version # -> 3
5347 */
5348 static VALUE
5349 foletypelib_minor_version(VALUE self)
5350 {
5351 TLIBATTR *pTLibAttr;
5352 VALUE minor;
5353 ITypeLib *pTypeLib;
5354 pTypeLib = oletypelib_get_typelib(self);
5355 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
5356 minor = INT2NUM(pTLibAttr->wMinorVerNum);
5357 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
5358 return minor;
5359 }
5360
5361 static VALUE
5362 oletypelib_path(VALUE guid, VALUE version)
5363 {
5364 int k;
5365 LONG err;
5366 HKEY hkey;
5367 HKEY hlang;
5368 VALUE lang;
5369 VALUE path = Qnil;
5370
5371 VALUE key = rb_str_new2("TypeLib\\");
5372 rb_str_concat(key, guid);
5373 rb_str_cat2(key, "\\");
5374 rb_str_concat(key, version);
5375
5376 err = reg_open_vkey(HKEY_CLASSES_ROOT, key, &hkey);
5377 if (err != ERROR_SUCCESS) {
5378 return Qnil;
5379 }
5380 for(k = 0; path == Qnil; k++) {
5381 lang = reg_enum_key(hkey, k);
5382 if (lang == Qnil)
5383 break;
5384 err = reg_open_vkey(hkey, lang, &hlang);
5385 if (err == ERROR_SUCCESS) {
5386 path = reg_get_typelib_file_path(hlang);
5387 RegCloseKey(hlang);
5388 }
5389 }
5390 RegCloseKey(hkey);
5391 return path;
5392 }
5393
5394 static HRESULT
5395 oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib)
5396 {
5397 VALUE path;
5398 OLECHAR *pBuf;
5399 HRESULT hr;
5400 path = oletypelib_path(guid, version);
5401 if (path == Qnil) {
5402 return E_UNEXPECTED;
5403 }
5404 pBuf = ole_vstr2wc(path);
5405 hr = LoadTypeLibEx(pBuf, REGKIND_NONE, ppTypeLib);
5406 SysFreeString(pBuf);
5407 return hr;
5408 }
5409
5410 /*
5411 * call-seq:
5412 * WIN32OLE_TYPELIB#path -> The type library file path.
5413 *
5414 * Returns the type library file path.
5415 *
5416 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5417 * puts tlib.path #-> 'C:\...\EXCEL9.OLB'
5418 */
5419 static VALUE
5420 foletypelib_path(VALUE self)
5421 {
5422 TLIBATTR *pTLibAttr;
5423 HRESULT hr = S_OK;
5424 BSTR bstr;
5425 LCID lcid = cWIN32OLE_lcid;
5426 VALUE path;
5427 ITypeLib *pTypeLib;
5428
5429 pTypeLib = oletypelib_get_typelib(self);
5430 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
5431 hr = QueryPathOfRegTypeLib(&pTLibAttr->guid,
5432 pTLibAttr->wMajorVerNum,
5433 pTLibAttr->wMinorVerNum,
5434 lcid,
5435 &bstr);
5436 if (FAILED(hr)) {
5437 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
5438 ole_raise(hr, eWIN32OLERuntimeError, "failed to QueryPathOfRegTypeTypeLib");
5439 }
5440
5441 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
5442 path = WC2VSTR(bstr);
5443 return rb_enc_str_new(StringValuePtr(path), strlen(StringValuePtr(path)), cWIN32OLE_enc);
5444 }
5445
5446 /*
5447 * call-seq:
5448 * WIN32OLE_TYPELIB#visible?
5449 *
5450 * Returns true if the type library information is not hidden.
5451 * If wLibFlags of TLIBATTR is 0 or LIBFLAG_FRESTRICTED or LIBFLAG_FHIDDEN,
5452 * the method returns false, otherwise, returns true.
5453 * If the method fails to access the TLIBATTR information, then
5454 * WIN32OLERuntimeError is raised.
5455 *
5456 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5457 * tlib.visible? # => true
5458 */
5459 static VALUE
5460 foletypelib_visible(VALUE self)
5461 {
5462 ITypeLib *pTypeLib = NULL;
5463 VALUE visible = Qtrue;
5464 TLIBATTR *pTLibAttr;
5465
5466 pTypeLib = oletypelib_get_typelib(self);
5467 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
5468
5469 if ((pTLibAttr->wLibFlags == 0) ||
5470 (pTLibAttr->wLibFlags & LIBFLAG_FRESTRICTED) ||
5471 (pTLibAttr->wLibFlags & LIBFLAG_FHIDDEN)) {
5472 visible = Qfalse;
5473 }
5474 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
5475 return visible;
5476 }
5477
5478 /*
5479 * call-seq:
5480 * WIN32OLE_TYPELIB#library_name
5481 *
5482 * Returns library name.
5483 * If the method fails to access library name, WIN32OLERuntimeError is raised.
5484 *
5485 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5486 * tlib.library_name # => Excel
5487 */
5488 static VALUE
5489 foletypelib_library_name(VALUE self)
5490 {
5491 HRESULT hr;
5492 ITypeLib *pTypeLib = NULL;
5493 VALUE libname = Qnil;
5494 BSTR bstr;
5495
5496 pTypeLib = oletypelib_get_typelib(self);
5497 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
5498 &bstr, NULL, NULL, NULL);
5499 if (FAILED(hr)) {
5500 ole_raise(hr, eWIN32OLERuntimeError, "failed to get library name");
5501 }
5502 libname = WC2VSTR(bstr);
5503 return libname;
5504 }
5505
5506
5507 /*
5508 * call-seq:
5509 * WIN32OLE_TYPELIB#ole_types -> The array of WIN32OLE_TYPE object included the type library.
5510 *
5511 * Returns the type library file path.
5512 *
5513 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5514 * classes = tlib.ole_types.collect{|k| k.name} # -> ['AddIn', 'AddIns' ...]
5515 */
5516 static VALUE
5517 foletypelib_ole_types(VALUE self)
5518 {
5519 ITypeLib *pTypeLib = NULL;
5520 VALUE classes = rb_ary_new();
5521 pTypeLib = oletypelib_get_typelib(self);
5522 ole_types_from_typelib(pTypeLib, classes);
5523 return classes;
5524 }
5525
5526 /*
5527 * call-seq:
5528 * WIN32OLE_TYPELIB#inspect -> String
5529 *
5530 * Returns the type library name with class name.
5531 *
5532 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
5533 * tlib.inspect # => "<#WIN32OLE_TYPELIB:Microsoft Excel 9.0 Object Library>"
5534 */
5535 static VALUE
5536 foletypelib_inspect(VALUE self)
5537 {
5538 return default_inspect(self, "WIN32OLE_TYPELIB");
5539 }
5540
5541 /*
5542 * Document-class: WIN32OLE_TYPE
5543 *
5544 * <code>WIN32OLE_TYPE</code> objects represent OLE type libarary information.
5545 */
5546
5547 /*
5548 * call-seq:
5549 * WIN32OLE_TYPE.new(typelib, ole_class) -> WIN32OLE_TYPE object
5550 *
5551 * Returns a new WIN32OLE_TYPE object.
5552 * The first argument <i>typelib</i> specifies OLE type library name.
5553 * The second argument specifies OLE class name.
5554 *
5555 * WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
5556 * # => WIN32OLE_TYPE object of Application class of Excel.
5557 */
5558 static VALUE
5559 foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass)
5560 {
5561 VALUE file;
5562 OLECHAR * pbuf;
5563 ITypeLib *pTypeLib;
5564 HRESULT hr;
5565
5566 SafeStringValue(oleclass);
5567 SafeStringValue(typelib);
5568 file = typelib_file(typelib);
5569 if (file == Qnil) {
5570 file = typelib;
5571 }
5572 pbuf = ole_vstr2wc(file);
5573 hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
5574 if (FAILED(hr))
5575 ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
5576 SysFreeString(pbuf);
5577 if (oleclass_from_typelib(self, pTypeLib, oleclass) == Qfalse) {
5578 OLE_RELEASE(pTypeLib);
5579 rb_raise(eWIN32OLERuntimeError, "not found `%s` in `%s`",
5580 StringValuePtr(oleclass), StringValuePtr(typelib));
5581 }
5582 OLE_RELEASE(pTypeLib);
5583 return self;
5584 }
5585
5586 /*
5587 * call-seq:
5588 * WIN32OLE_TYPE#name #=> OLE type name
5589 *
5590 * Returns OLE type name.
5591 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
5592 * puts tobj.name # => Application
5593 */
5594 static VALUE
5595 foletype_name(VALUE self)
5596 {
5597 return rb_ivar_get(self, rb_intern("name"));
5598 }
5599
5600 static VALUE
5601 ole_ole_type(ITypeInfo *pTypeInfo)
5602 {
5603 HRESULT hr;
5604 TYPEATTR *pTypeAttr;
5605 VALUE type = Qnil;
5606 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
5607 if(FAILED(hr)){
5608 return type;
5609 }
5610 switch(pTypeAttr->typekind) {
5611 case TKIND_ENUM:
5612 type = rb_str_new2("Enum");
5613 break;
5614 case TKIND_RECORD:
5615 type = rb_str_new2("Record");
5616 break;
5617 case TKIND_MODULE:
5618 type = rb_str_new2("Module");
5619 break;
5620 case TKIND_INTERFACE:
5621 type = rb_str_new2("Interface");
5622 break;
5623 case TKIND_DISPATCH:
5624 type = rb_str_new2("Dispatch");
5625 break;
5626 case TKIND_COCLASS:
5627 type = rb_str_new2("Class");
5628 break;
5629 case TKIND_ALIAS:
5630 type = rb_str_new2("Alias");
5631 break;
5632 case TKIND_UNION:
5633 type = rb_str_new2("Union");
5634 break;
5635 case TKIND_MAX:
5636 type = rb_str_new2("Max");
5637 break;
5638 default:
5639 type = Qnil;
5640 break;
5641 }
5642 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
5643 return type;
5644 }
5645
5646 /*
5647 * call-seq:
5648 * WIN32OLE_TYPE#ole_type #=> OLE type string.
5649 *
5650 * returns type of OLE class.
5651 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
5652 * puts tobj.ole_type # => Class
5653 */
5654 static VALUE
5655 foletype_ole_type(VALUE self)
5656 {
5657 struct oletypedata *ptype;
5658 Data_Get_Struct(self, struct oletypedata, ptype);
5659 return ole_ole_type(ptype->pTypeInfo);
5660 }
5661
5662 static VALUE
5663 ole_type_guid(ITypeInfo *pTypeInfo)
5664 {
5665 HRESULT hr;
5666 TYPEATTR *pTypeAttr;
5667 int len;
5668 OLECHAR bstr[80];
5669 VALUE guid = Qnil;
5670 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
5671 if (FAILED(hr))
5672 return guid;
5673 len = StringFromGUID2(&pTypeAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
5674 if (len > 3) {
5675 guid = ole_wc2vstr(bstr, FALSE);
5676 }
5677 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
5678 return guid;
5679 }
5680
5681 /*
5682 * call-seq:
5683 * WIN32OLE_TYPE#guid #=> GUID
5684 *
5685 * Returns GUID.
5686 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
5687 * puts tobj.guid # => {00024500-0000-0000-C000-000000000046}
5688 */
5689 static VALUE
5690 foletype_guid(VALUE self)
5691 {
5692 struct oletypedata *ptype;
5693 Data_Get_Struct(self, struct oletypedata, ptype);
5694 return ole_type_guid(ptype->pTypeInfo);
5695 }
5696
5697 static VALUE
5698 ole_type_progid(ITypeInfo *pTypeInfo)
5699 {
5700 HRESULT hr;
5701 TYPEATTR *pTypeAttr;
5702 OLECHAR *pbuf;
5703 VALUE progid = Qnil;
5704 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
5705 if (FAILED(hr))
5706 return progid;
5707 hr = ProgIDFromCLSID(&pTypeAttr->guid, &pbuf);
5708 if (SUCCEEDED(hr)) {
5709 progid = ole_wc2vstr(pbuf, FALSE);
5710 CoTaskMemFree(pbuf);
5711 }
5712 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
5713 return progid;
5714 }
5715
5716 /*
5717 * call-seq:
5718 * WIN32OLE_TYPE#progid #=> ProgID
5719 *
5720 * Returns ProgID if it exists. If not found, then returns nil.
5721 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
5722 * puts tobj.progid # => Excel.Application.9
5723 */
5724 static VALUE
5725 foletype_progid(VALUE self)
5726 {
5727 struct oletypedata *ptype;
5728 Data_Get_Struct(self, struct oletypedata, ptype);
5729 return ole_type_progid(ptype->pTypeInfo);
5730 }
5731
5732
5733 static VALUE
5734 ole_type_visible(ITypeInfo *pTypeInfo)
5735 {
5736 HRESULT hr;
5737 TYPEATTR *pTypeAttr;
5738 VALUE visible;
5739 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
5740 if (FAILED(hr))
5741 return Qtrue;
5742 if (pTypeAttr->wTypeFlags & (TYPEFLAG_FHIDDEN | TYPEFLAG_FRESTRICTED)) {
5743 visible = Qfalse;
5744 } else {
5745 visible = Qtrue;
5746 }
5747 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
5748 return visible;
5749 }
5750
5751 /*
5752 * call-seq:
5753 * WIN32OLE_TYPE#visible #=> true or false
5754 *
5755 * Returns true if the OLE class is public.
5756 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Application')
5757 * puts tobj.visible # => true
5758 */
5759 static VALUE
5760 foletype_visible(VALUE self)
5761 {
5762 struct oletypedata *ptype;
5763 Data_Get_Struct(self, struct oletypedata, ptype);
5764 return ole_type_visible(ptype->pTypeInfo);
5765 }
5766
5767 static VALUE
5768 ole_type_major_version(ITypeInfo *pTypeInfo)
5769 {
5770 VALUE ver;
5771 TYPEATTR *pTypeAttr;
5772 HRESULT hr;
5773 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
5774 if (FAILED(hr))
5775 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
5776 ver = INT2FIX(pTypeAttr->wMajorVerNum);
5777 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
5778 return ver;
5779 }
5780
5781 /*
5782 * call-seq:
5783 * WIN32OLE_TYPE#major_version
5784 *
5785 * Returns major version.
5786 * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')
5787 * puts tobj.major_version # => 8
5788 */
5789 static VALUE
5790 foletype_major_version(VALUE self)
5791 {
5792 struct oletypedata *ptype;
5793 Data_Get_Struct(self, struct oletypedata, ptype);
5794 return ole_type_major_version(ptype->pTypeInfo);
5795 }
5796
5797 static VALUE
5798 ole_type_minor_version(ITypeInfo *pTypeInfo)
5799 {
5800 VALUE ver;
5801 TYPEATTR *pTypeAttr;
5802 HRESULT hr;
5803 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
5804 if (FAILED(hr))
5805 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
5806 ver = INT2FIX(pTypeAttr->wMinorVerNum);
5807 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
5808 return ver;
5809 }
5810
5811 /*
5812 * call-seq:
5813 * WIN32OLE_TYPE#minor_version #=> OLE minor version
5814 *
5815 * Returns minor version.
5816 * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')
5817 * puts tobj.minor_version # => 2
5818 */
5819 static VALUE
5820 foletype_minor_version(VALUE self)
5821 {
5822 struct oletypedata *ptype;
5823 Data_Get_Struct(self, struct oletypedata, ptype);
5824 return ole_type_minor_version(ptype->pTypeInfo);
5825 }
5826
5827 static VALUE
5828 ole_type_typekind(ITypeInfo *pTypeInfo)
5829 {
5830 VALUE typekind;
5831 TYPEATTR *pTypeAttr;
5832 HRESULT hr;
5833 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
5834 if (FAILED(hr))
5835 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
5836 typekind = INT2FIX(pTypeAttr->typekind);
5837 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
5838 return typekind;
5839 }
5840
5841 /*
5842 * call-seq:
5843 * WIN32OLE_TYPE#typekind #=> number of type.
5844 *
5845 * Returns number which represents type.
5846 * tobj = WIN32OLE_TYPE.new('Microsoft Word 10.0 Object Library', 'Documents')
5847 * puts tobj.typekind # => 4
5848 *
5849 */
5850 static VALUE
5851 foletype_typekind(VALUE self)
5852 {
5853 struct oletypedata *ptype;
5854 Data_Get_Struct(self, struct oletypedata, ptype);
5855 return ole_type_typekind(ptype->pTypeInfo);
5856 }
5857
5858 static VALUE
5859 ole_type_helpstring(ITypeInfo *pTypeInfo)
5860 {
5861 HRESULT hr;
5862 BSTR bhelpstr;
5863 hr = ole_docinfo_from_type(pTypeInfo, NULL, &bhelpstr, NULL, NULL);
5864 if(FAILED(hr)) {
5865 return Qnil;
5866 }
5867 return WC2VSTR(bhelpstr);
5868 }
5869
5870 /*
5871 * call-seq:
5872 * WIN32OLE_TYPE#helpstring #=> help string.
5873 *
5874 * Returns help string.
5875 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser')
5876 * puts tobj.helpstring # => Web Browser interface
5877 */
5878 static VALUE
5879 foletype_helpstring(VALUE self)
5880 {
5881 struct oletypedata *ptype;
5882 Data_Get_Struct(self, struct oletypedata, ptype);
5883 return ole_type_helpstring(ptype->pTypeInfo);
5884 }
5885
5886 static VALUE
5887 ole_type_src_type(ITypeInfo *pTypeInfo)
5888 {
5889 HRESULT hr;
5890 TYPEATTR *pTypeAttr;
5891 VALUE alias = Qnil;
5892 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
5893 if (FAILED(hr))
5894 return alias;
5895 if(pTypeAttr->typekind != TKIND_ALIAS) {
5896 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
5897 return alias;
5898 }
5899 alias = ole_typedesc2val(pTypeInfo, &(pTypeAttr->tdescAlias), Qnil);
5900 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
5901 return alias;
5902 }
5903
5904 /*
5905 * call-seq:
5906 * WIN32OLE_TYPE#src_type #=> OLE source class
5907 *
5908 * Returns source class when the OLE class is 'Alias'.
5909 * tobj = WIN32OLE_TYPE.new('Microsoft Office 9.0 Object Library', 'MsoRGBType')
5910 * puts tobj.src_type # => I4
5911 *
5912 */
5913 static VALUE
5914 foletype_src_type(VALUE self)
5915 {
5916 struct oletypedata *ptype;
5917 Data_Get_Struct(self, struct oletypedata, ptype);
5918 return ole_type_src_type(ptype->pTypeInfo);
5919 }
5920
5921 static VALUE
5922 ole_type_helpfile(ITypeInfo *pTypeInfo)
5923 {
5924 HRESULT hr;
5925 BSTR bhelpfile;
5926 hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL, NULL, &bhelpfile);
5927 if(FAILED(hr)) {
5928 return Qnil;
5929 }
5930 return WC2VSTR(bhelpfile);
5931 }
5932
5933 /*
5934 * call-seq:
5935 * WIN32OLE_TYPE#helpfile
5936 *
5937 * Returns helpfile path. If helpfile is not found, then returns nil.
5938 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
5939 * puts tobj.helpfile # => C:\...\VBAXL9.CHM
5940 *
5941 */
5942 static VALUE
5943 foletype_helpfile(VALUE self)
5944 {
5945 struct oletypedata *ptype;
5946 Data_Get_Struct(self, struct oletypedata, ptype);
5947 return ole_type_helpfile(ptype->pTypeInfo);
5948 }
5949
5950 static VALUE
5951 ole_type_helpcontext(ITypeInfo *pTypeInfo)
5952 {
5953 HRESULT hr;
5954 DWORD helpcontext;
5955 hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL,
5956 &helpcontext, NULL);
5957 if(FAILED(hr))
5958 return Qnil;
5959 return INT2FIX(helpcontext);
5960 }
5961
5962 /*
5963 * call-seq:
5964 * WIN32OLE_TYPE#helpcontext
5965 *
5966 * Returns helpcontext. If helpcontext is not found, then returns nil.
5967 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
5968 * puts tobj.helpfile # => 131185
5969 */
5970 static VALUE
5971 foletype_helpcontext(VALUE self)
5972 {
5973 struct oletypedata *ptype;
5974 Data_Get_Struct(self, struct oletypedata, ptype);
5975 return ole_type_helpcontext(ptype->pTypeInfo);
5976 }
5977
5978 /*
5979 * call-seq:
5980 * WIN32OLE_TYPE#ole_typelib
5981 *
5982 * Returns the WIN32OLE_TYPELIB object which is including the WIN32OLE_TYPE
5983 * object. If it is not found, then returns nil.
5984 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
5985 * puts tobj.ole_typelib # => 'Microsoft Excel 9.0 Object Library'
5986 */
5987 static VALUE
5988 foletype_ole_typelib(VALUE self)
5989 {
5990 struct oletypedata *ptype;
5991 Data_Get_Struct(self, struct oletypedata, ptype);
5992 return ole_typelib_from_itypeinfo(ptype->pTypeInfo);
5993 }
5994
5995 static VALUE
5996 ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags)
5997 {
5998 HRESULT hr;
5999 ITypeInfo *pRefTypeInfo;
6000 HREFTYPE href;
6001 WORD i;
6002 VALUE type;
6003 TYPEATTR *pTypeAttr;
6004 int flags;
6005
6006 VALUE types = rb_ary_new();
6007 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
6008 if (FAILED(hr)) {
6009 return types;
6010 }
6011 for (i = 0; i < pTypeAttr->cImplTypes; i++) {
6012 hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
6013 if (FAILED(hr))
6014 continue;
6015
6016 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
6017 if (FAILED(hr))
6018 continue;
6019 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
6020 if (FAILED(hr))
6021 continue;
6022
6023 if ((flags & implflags) == implflags) {
6024 type = ole_type_from_itypeinfo(pRefTypeInfo);
6025 if (type != Qnil) {
6026 rb_ary_push(types, type);
6027 }
6028 }
6029
6030 OLE_RELEASE(pRefTypeInfo);
6031 }
6032 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
6033 return types;
6034 }
6035
6036 /*
6037 * call-seq:
6038 * WIN32OLE_TYPE#implemented_ole_types
6039 *
6040 * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE
6041 * object.
6042 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
6043 * p tobj.implemented_ole_types # => [_Worksheet, DocEvents]
6044 */
6045 static VALUE
6046 foletype_impl_ole_types(VALUE self)
6047 {
6048 struct oletypedata *ptype;
6049 Data_Get_Struct(self, struct oletypedata, ptype);
6050 return ole_type_impl_ole_types(ptype->pTypeInfo, 0);
6051 }
6052
6053 /*
6054 * call-seq:
6055 * WIN32OLE_TYPE#source_ole_types
6056 *
6057 * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE
6058 * object and having IMPLTYPEFLAG_FSOURCE.
6059 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer")
6060 * p tobj.source_ole_types
6061 * # => [#<WIN32OLE_TYPE:DWebBrowserEvents2>, #<WIN32OLE_TYPE:DWebBrowserEvents>]
6062 */
6063 static VALUE
6064 foletype_source_ole_types(VALUE self)
6065 {
6066 struct oletypedata *ptype;
6067 Data_Get_Struct(self, struct oletypedata, ptype);
6068 return ole_type_impl_ole_types(ptype->pTypeInfo, IMPLTYPEFLAG_FSOURCE);
6069 }
6070
6071 /*
6072 * call-seq:
6073 * WIN32OLE_TYPE#default_event_sources
6074 *
6075 * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE
6076 * object and having IMPLTYPEFLAG_FSOURCE and IMPLTYPEFLAG_FDEFAULT.
6077 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer")
6078 * p tobj.default_event_sources # => [#<WIN32OLE_TYPE:DWebBrowserEvents2>]
6079 */
6080 static VALUE
6081 foletype_default_event_sources(VALUE self)
6082 {
6083 struct oletypedata *ptype;
6084 Data_Get_Struct(self, struct oletypedata, ptype);
6085 return ole_type_impl_ole_types(ptype->pTypeInfo, IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT);
6086 }
6087
6088 /*
6089 * call-seq:
6090 * WIN32OLE_TYPE#default_ole_types
6091 *
6092 * Returns the array of WIN32OLE_TYPE object which is implemented by the WIN32OLE_TYPE
6093 * object and having IMPLTYPEFLAG_FDEFAULT.
6094 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', "InternetExplorer")
6095 * p tobj.default_ole_types
6096 * # => [#<WIN32OLE_TYPE:IWebBrowser2>, #<WIN32OLE_TYPE:DWebBrowserEvents2>]
6097 */
6098 static VALUE
6099 foletype_default_ole_types(VALUE self)
6100 {
6101 struct oletypedata *ptype;
6102 Data_Get_Struct(self, struct oletypedata, ptype);
6103 return ole_type_impl_ole_types(ptype->pTypeInfo, IMPLTYPEFLAG_FDEFAULT);
6104 }
6105
6106 /*
6107 * call-seq:
6108 * WIN32OLE_TYPE#inspect -> String
6109 *
6110 * Returns the type name with class name.
6111 *
6112 * ie = WIN32OLE.new('InternetExplorer.Application')
6113 * ie.ole_type.inspect => #<WIN32OLE_TYPE:IWebBrowser2>
6114 */
6115 static VALUE
6116 foletype_inspect(VALUE self)
6117 {
6118 return default_inspect(self, "WIN32OLE_TYPE");
6119 }
6120
6121 static VALUE
6122 ole_variables(ITypeInfo *pTypeInfo)
6123 {
6124 HRESULT hr;
6125 TYPEATTR *pTypeAttr;
6126 WORD i;
6127 UINT len;
6128 BSTR bstr;
6129 VARDESC *pVarDesc;
6130 struct olevariabledata *pvar;
6131 VALUE var;
6132 VALUE variables = rb_ary_new();
6133 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
6134 if (FAILED(hr)) {
6135 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetTypeAttr");
6136 }
6137
6138 for(i = 0; i < pTypeAttr->cVars; i++) {
6139 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, i, &pVarDesc);
6140 if(FAILED(hr))
6141 continue;
6142 len = 0;
6143 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
6144 1, &len);
6145 if(FAILED(hr) || len == 0 || !bstr)
6146 continue;
6147
6148 var = Data_Make_Struct(cWIN32OLE_VARIABLE, struct olevariabledata,
6149 0,olevariable_free,pvar);
6150 pvar->pTypeInfo = pTypeInfo;
6151 OLE_ADDREF(pTypeInfo);
6152 pvar->index = i;
6153 rb_ivar_set(var, rb_intern("name"), WC2VSTR(bstr));
6154 rb_ary_push(variables, var);
6155
6156 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
6157 pVarDesc = NULL;
6158 }
6159 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
6160 return variables;
6161 }
6162
6163 /*
6164 * call-seq:
6165 * WIN32OLE_TYPE#variables
6166 *
6167 * Returns array of WIN32OLE_VARIABLE objects which represent variables
6168 * defined in OLE class.
6169 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6170 * vars = tobj.variables
6171 * vars.each do |v|
6172 * puts "#{v.name} = #{v.value}"
6173 * end
6174 *
6175 * The result of above sample script is follows:
6176 * xlChart = -4109
6177 * xlDialogSheet = -4116
6178 * xlExcel4IntlMacroSheet = 4
6179 * xlExcel4MacroSheet = 3
6180 * xlWorksheet = -4167
6181 *
6182 */
6183 static VALUE
6184 foletype_variables(VALUE self)
6185 {
6186 struct oletypedata *ptype;
6187 Data_Get_Struct(self, struct oletypedata, ptype);
6188 return ole_variables(ptype->pTypeInfo);
6189 }
6190
6191 /*
6192 * call-seq:
6193 * WIN32OLE_TYPE#ole_methods # the array of WIN32OLE_METHOD objects.
6194 *
6195 * Returns array of WIN32OLE_METHOD objects which represent OLE method defined in
6196 * OLE type library.
6197 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Worksheet')
6198 * methods = tobj.ole_methods.collect{|m|
6199 * m.name
6200 * }
6201 * # => ['Activate', 'Copy', 'Delete',....]
6202 */
6203 static VALUE
6204 foletype_methods(VALUE self)
6205 {
6206 struct oletypedata *ptype;
6207 Data_Get_Struct(self, struct oletypedata, ptype);
6208 return ole_methods_from_typeinfo(ptype->pTypeInfo, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
6209 }
6210
6211 /*
6212 * Document-class: WIN32OLE_VARIABLE
6213 *
6214 * <code>WIN32OLE_VARIABLE</code> objects represent OLE variable information.
6215 */
6216
6217 /*
6218 * call-seq:
6219 * WIN32OLE_VARIABLE#name
6220 *
6221 * Returns the name of variable.
6222 *
6223 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6224 * variables = tobj.variables
6225 * variables.each do |variable|
6226 * puts "#{variable.name}"
6227 * end
6228 *
6229 * The result of above script is following:
6230 * xlChart
6231 * xlDialogSheet
6232 * xlExcel4IntlMacroSheet
6233 * xlExcel4MacroSheet
6234 * xlWorksheet
6235 *
6236 */
6237 static VALUE
6238 folevariable_name(VALUE self)
6239 {
6240 return rb_ivar_get(self, rb_intern("name"));
6241 }
6242
6243 static VALUE
6244 ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index)
6245 {
6246 VARDESC *pVarDesc;
6247 HRESULT hr;
6248 VALUE type;
6249 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
6250 if (FAILED(hr))
6251 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc");
6252 type = ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), Qnil);
6253 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
6254 return type;
6255 }
6256
6257 /*
6258 * call-seq:
6259 * WIN32OLE_VARIABLE#ole_type
6260 *
6261 * Returns OLE type string.
6262 *
6263 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6264 * variables = tobj.variables
6265 * variables.each do |variable|
6266 * puts "#{variable.ole_type} #{variable.name}"
6267 * end
6268 *
6269 * The result of above script is following:
6270 * INT xlChart
6271 * INT xlDialogSheet
6272 * INT xlExcel4IntlMacroSheet
6273 * INT xlExcel4MacroSheet
6274 * INT xlWorksheet
6275 *
6276 */
6277 static VALUE
6278 folevariable_ole_type(VALUE self)
6279 {
6280 struct olevariabledata *pvar;
6281 Data_Get_Struct(self, struct olevariabledata, pvar);
6282 return ole_variable_ole_type(pvar->pTypeInfo, pvar->index);
6283 }
6284
6285 static VALUE
6286 ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index)
6287 {
6288 VARDESC *pVarDesc;
6289 HRESULT hr;
6290 VALUE type = rb_ary_new();
6291 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
6292 if (FAILED(hr))
6293 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetVarDesc");
6294 ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), type);
6295 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
6296 return type;
6297 }
6298
6299 /*
6300 * call-seq:
6301 * WIN32OLE_VARIABLE#ole_type_detail
6302 *
6303 * Returns detail information of type. The information is array of type.
6304 *
6305 * tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library', 'D3DCLIPSTATUS')
6306 * variable = tobj.variables.find {|variable| variable.name == 'lFlags'}
6307 * tdetail = variable.ole_type_detail
6308 * p tdetail # => ["USERDEFINED", "CONST_D3DCLIPSTATUSFLAGS"]
6309 *
6310 */
6311 static VALUE
6312 folevariable_ole_type_detail(VALUE self)
6313 {
6314 struct olevariabledata *pvar;
6315 Data_Get_Struct(self, struct olevariabledata, pvar);
6316 return ole_variable_ole_type_detail(pvar->pTypeInfo, pvar->index);
6317 }
6318
6319 static VALUE
6320 ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index)
6321 {
6322 VARDESC *pVarDesc;
6323 HRESULT hr;
6324 VALUE val = Qnil;
6325 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
6326 if (FAILED(hr))
6327 return Qnil;
6328 if(pVarDesc->varkind == VAR_CONST)
6329 val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));
6330 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
6331 return val;
6332 }
6333
6334 /*
6335 * call-seq:
6336 * WIN32OLE_VARIABLE#value
6337 *
6338 * Returns value if value is exists. If the value does not exist,
6339 * this method returns nil.
6340 *
6341 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6342 * variables = tobj.variables
6343 * variables.each do |variable|
6344 * puts "#{variable.name} #{variable.value}"
6345 * end
6346 *
6347 * The result of above script is following:
6348 * xlChart = -4109
6349 * xlDialogSheet = -4116
6350 * xlExcel4IntlMacroSheet = 4
6351 * xlExcel4MacroSheet = 3
6352 * xlWorksheet = -4167
6353 *
6354 */
6355 static VALUE
6356 folevariable_value(VALUE self)
6357 {
6358 struct olevariabledata *pvar;
6359 Data_Get_Struct(self, struct olevariabledata, pvar);
6360 return ole_variable_value(pvar->pTypeInfo, pvar->index);
6361 }
6362
6363 static VALUE
6364 ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index)
6365 {
6366 VARDESC *pVarDesc;
6367 HRESULT hr;
6368 VALUE visible = Qfalse;
6369 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
6370 if (FAILED(hr))
6371 return visible;
6372 if (!(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
6373 VARFLAG_FRESTRICTED |
6374 VARFLAG_FNONBROWSABLE))) {
6375 visible = Qtrue;
6376 }
6377 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
6378 return visible;
6379 }
6380
6381 /*
6382 * call-seq:
6383 * WIN32OLE_VARIABLE#visible?
6384 *
6385 * Returns true if the variable is public.
6386 *
6387 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6388 * variables = tobj.variables
6389 * variables.each do |variable|
6390 * puts "#{variable.name} #{variable.visible?}"
6391 * end
6392 *
6393 * The result of above script is following:
6394 * xlChart true
6395 * xlDialogSheet true
6396 * xlExcel4IntlMacroSheet true
6397 * xlExcel4MacroSheet true
6398 * xlWorksheet true
6399 *
6400 */
6401 static VALUE
6402 folevariable_visible(VALUE self)
6403 {
6404 struct olevariabledata *pvar;
6405 Data_Get_Struct(self, struct olevariabledata, pvar);
6406 return ole_variable_visible(pvar->pTypeInfo, pvar->index);
6407 }
6408
6409 static VALUE
6410 ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index)
6411 {
6412 VARDESC *pVarDesc;
6413 HRESULT hr;
6414 VALUE kind = rb_str_new2("UNKNOWN");
6415 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
6416 if (FAILED(hr))
6417 return kind;
6418 switch(pVarDesc->varkind) {
6419 case VAR_PERINSTANCE:
6420 kind = rb_str_new2("PERINSTANCE");
6421 break;
6422 case VAR_STATIC:
6423 kind = rb_str_new2("STATIC");
6424 break;
6425 case VAR_CONST:
6426 kind = rb_str_new2("CONSTANT");
6427 break;
6428 case VAR_DISPATCH:
6429 kind = rb_str_new2("DISPATCH");
6430 break;
6431 default:
6432 break;
6433 }
6434 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
6435 return kind;
6436 }
6437
6438 /*
6439 * call-seq:
6440 * WIN32OLE_VARIABLE#variable_kind
6441 *
6442 * Returns variable kind string.
6443 *
6444 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6445 * variables = tobj.variables
6446 * variables.each do |variable|
6447 * puts "#{variable.name} #{variable.variable_kind}"
6448 * end
6449 *
6450 * The result of above script is following:
6451 * xlChart CONSTANT
6452 * xlDialogSheet CONSTANT
6453 * xlExcel4IntlMacroSheet CONSTANT
6454 * xlExcel4MacroSheet CONSTANT
6455 * xlWorksheet CONSTANT
6456 */
6457 static VALUE
6458 folevariable_variable_kind(VALUE self)
6459 {
6460 struct olevariabledata *pvar;
6461 Data_Get_Struct(self, struct olevariabledata, pvar);
6462 return ole_variable_kind(pvar->pTypeInfo, pvar->index);
6463 }
6464
6465 static VALUE
6466 ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index)
6467 {
6468 VARDESC *pVarDesc;
6469 HRESULT hr;
6470 VALUE kind = Qnil;
6471 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
6472 if (FAILED(hr))
6473 return kind;
6474 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
6475 kind = INT2FIX(pVarDesc->varkind);
6476 return kind;
6477 }
6478
6479 /*
6480 * call-seq:
6481 * WIN32OLE_VARIABLE#varkind
6482 *
6483 * Returns the number which represents variable kind.
6484 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'XlSheetType')
6485 * variables = tobj.variables
6486 * variables.each do |variable|
6487 * puts "#{variable.name} #{variable.varkind}"
6488 * end
6489 *
6490 * The result of above script is following:
6491 * xlChart 2
6492 * xlDialogSheet 2
6493 * xlExcel4IntlMacroSheet 2
6494 * xlExcel4MacroSheet 2
6495 * xlWorksheet 2
6496 */
6497 static VALUE
6498 folevariable_varkind(VALUE self)
6499 {
6500 struct olevariabledata *pvar;
6501 Data_Get_Struct(self, struct olevariabledata, pvar);
6502 return ole_variable_varkind(pvar->pTypeInfo, pvar->index);
6503 }
6504
6505 /*
6506 * call-seq:
6507 * WIN32OLE_VARIABLE#inspect -> String
6508 *
6509 * Returns the OLE variable name and the value with class name.
6510 *
6511 */
6512 static VALUE
6513 folevariable_inspect(VALUE self)
6514 {
6515 VALUE detail = rb_funcall(self, rb_intern("to_s"), 0);
6516 rb_str_cat2(detail, "=");
6517 rb_str_concat(detail, rb_funcall(rb_funcall(self, rb_intern("value"), 0), rb_intern("inspect"), 0));
6518 return make_inspect("WIN32OLE_VARIABLE", detail);
6519 }
6520
6521 /*
6522 * Document-class: WIN32OLE_METHOD
6523 *
6524 * <code>WIN32OLE_METHOD</code> objects represent OLE method information.
6525 */
6526
6527 static VALUE
6528 olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name)
6529 {
6530 struct olemethoddata *pmethod;
6531 Data_Get_Struct(self, struct olemethoddata, pmethod);
6532 pmethod->pTypeInfo = pTypeInfo;
6533 OLE_ADDREF(pTypeInfo);
6534 pmethod->pOwnerTypeInfo = pOwnerTypeInfo;
6535 if(pOwnerTypeInfo) OLE_ADDREF(pOwnerTypeInfo);
6536 pmethod->index = index;
6537 rb_ivar_set(self, rb_intern("name"), name);
6538 return self;
6539 }
6540
6541 static VALUE
6542 folemethod_s_allocate(VALUE klass)
6543 {
6544 struct olemethoddata *pmethod;
6545 VALUE obj;
6546 obj = Data_Make_Struct(klass,
6547 struct olemethoddata,
6548 0, olemethod_free, pmethod);
6549 pmethod->pTypeInfo = NULL;
6550 pmethod->pOwnerTypeInfo = NULL;
6551 pmethod->index = 0;
6552 return obj;
6553 }
6554
6555 /*
6556 * call-seq:
6557 * WIN32OLE_METHOD.new(ole_type, method) -> WIN32OLE_METHOD object
6558 *
6559 * Returns a new WIN32OLE_METHOD object which represents the information
6560 * about OLE method.
6561 * The first argument <i>ole_type</i> specifies WIN32OLE_TYPE object.
6562 * The second argument <i>method</i> specifies OLE method name defined OLE class
6563 * which represents WIN32OLE_TYPE object.
6564 *
6565 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
6566 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
6567 */
6568 static VALUE
6569 folemethod_initialize(VALUE self, VALUE oletype, VALUE method)
6570 {
6571 struct oletypedata *ptype;
6572 VALUE obj = Qnil;
6573 if (rb_obj_is_kind_of(oletype, cWIN32OLE_TYPE)) {
6574 SafeStringValue(method);
6575 Data_Get_Struct(oletype, struct oletypedata, ptype);
6576 obj = olemethod_from_typeinfo(self, ptype->pTypeInfo, method);
6577 if (obj == Qnil) {
6578 rb_raise(eWIN32OLERuntimeError, "not found %s",
6579 StringValuePtr(method));
6580 }
6581 }
6582 else {
6583 rb_raise(rb_eTypeError, "1st argument should be WIN32OLE_TYPE object");
6584 }
6585 return obj;
6586 }
6587
6588 /*
6589 * call-seq
6590 * WIN32OLE_METHOD#name
6591 *
6592 * Returns the name of the method.
6593 *
6594 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
6595 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
6596 * puts method.name # => SaveAs
6597 *
6598 */
6599 static VALUE
6600 folemethod_name(VALUE self)
6601 {
6602 return rb_ivar_get(self, rb_intern("name"));
6603 }
6604
6605 static VALUE
6606 ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index)
6607 {
6608 FUNCDESC *pFuncDesc;
6609 HRESULT hr;
6610 VALUE type;
6611
6612 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
6613 if (FAILED(hr))
6614 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
6615
6616 type = ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), Qnil);
6617 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
6618 return type;
6619 }
6620
6621 /*
6622 * call-seq:
6623 * WIN32OLE_METHOD#return_type
6624 *
6625 * Returns string of return value type of method.
6626 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6627 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6628 * puts method.return_type # => Workbook
6629 *
6630 */
6631 static VALUE
6632 folemethod_return_type(VALUE self)
6633 {
6634 struct olemethoddata *pmethod;
6635 Data_Get_Struct(self, struct olemethoddata, pmethod);
6636 return ole_method_return_type(pmethod->pTypeInfo, pmethod->index);
6637 }
6638
6639 static VALUE
6640 ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index)
6641 {
6642 FUNCDESC *pFuncDesc;
6643 HRESULT hr;
6644 VALUE vvt;
6645
6646 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
6647 if (FAILED(hr))
6648 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
6649
6650 vvt = INT2FIX(pFuncDesc->elemdescFunc.tdesc.vt);
6651 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
6652 return vvt;
6653 }
6654
6655 /*
6656 * call-seq:
6657 * WIN32OLE_METHOD#return_vtype
6658 *
6659 * Returns number of return value type of method.
6660 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6661 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6662 * puts method.return_vtype # => 26
6663 *
6664 */
6665 static VALUE
6666 folemethod_return_vtype(VALUE self)
6667 {
6668 struct olemethoddata *pmethod;
6669 Data_Get_Struct(self, struct olemethoddata, pmethod);
6670 return ole_method_return_vtype(pmethod->pTypeInfo, pmethod->index);
6671 }
6672
6673 static VALUE
6674 ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index)
6675 {
6676 FUNCDESC *pFuncDesc;
6677 HRESULT hr;
6678 VALUE type = rb_ary_new();
6679
6680 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
6681 if (FAILED(hr))
6682 return type;
6683
6684 ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), type);
6685 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
6686 return type;
6687 }
6688
6689 /*
6690 * call-seq:
6691 * WIN32OLE_METHOD#return_type_detail
6692 *
6693 * Returns detail information of return value type of method.
6694 * The information is array.
6695 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6696 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6697 * p method.return_type_detail # => ["PTR", "USERDEFINED", "Workbook"]
6698 */
6699 static VALUE
6700 folemethod_return_type_detail(VALUE self)
6701 {
6702 struct olemethoddata *pmethod;
6703 Data_Get_Struct(self, struct olemethoddata, pmethod);
6704 return ole_method_return_type_detail(pmethod->pTypeInfo, pmethod->index);
6705 }
6706
6707 static VALUE
6708 ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index)
6709 {
6710 FUNCDESC *pFuncDesc;
6711 HRESULT hr;
6712 VALUE invkind;
6713 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
6714 if(FAILED(hr))
6715 ole_raise(hr, eWIN32OLERuntimeError, "failed to GetFuncDesc");
6716 invkind = INT2FIX(pFuncDesc->invkind);
6717 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
6718 return invkind;
6719 }
6720
6721 static VALUE
6722 ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index)
6723 {
6724 VALUE type = rb_str_new2("UNKNOWN");
6725 VALUE invkind = ole_method_invkind(pTypeInfo, method_index);
6726 if((FIX2INT(invkind) & INVOKE_PROPERTYGET) &&
6727 (FIX2INT(invkind) & INVOKE_PROPERTYPUT) ) {
6728 type = rb_str_new2("PROPERTY");
6729 } else if(FIX2INT(invkind) & INVOKE_PROPERTYGET) {
6730 type = rb_str_new2("PROPERTYGET");
6731 } else if(FIX2INT(invkind) & INVOKE_PROPERTYPUT) {
6732 type = rb_str_new2("PROPERTYPUT");
6733 } else if(FIX2INT(invkind) & INVOKE_PROPERTYPUTREF) {
6734 type = rb_str_new2("PROPERTYPUTREF");
6735 } else if(FIX2INT(invkind) & INVOKE_FUNC) {
6736 type = rb_str_new2("FUNC");
6737 }
6738 return type;
6739 }
6740
6741 /*
6742 * call-seq:
6743 * WIN32OLE_MTHOD#invkind
6744 *
6745 * Returns the method invoke kind.
6746 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6747 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6748 * puts method.invkind # => 1
6749 *
6750 */
6751 static VALUE
6752 folemethod_invkind(VALUE self)
6753 {
6754 struct olemethoddata *pmethod;
6755 Data_Get_Struct(self, struct olemethoddata, pmethod);
6756 return ole_method_invkind(pmethod->pTypeInfo, pmethod->index);
6757 }
6758
6759 /*
6760 * call-seq:
6761 * WIN32OLE_METHOD#invoke_kind
6762 *
6763 * Returns the method kind string. The string is "UNKNOWN" or "PROPERTY"
6764 * or "PROPERTY" or "PROPERTYGET" or "PROPERTYPUT" or "PROPERTYPPUTREF"
6765 * or "FUNC".
6766 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6767 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6768 * puts method.invoke_kind # => "FUNC"
6769 */
6770 static VALUE
6771 folemethod_invoke_kind(VALUE self)
6772 {
6773 struct olemethoddata *pmethod;
6774 Data_Get_Struct(self, struct olemethoddata, pmethod);
6775 return ole_method_invoke_kind(pmethod->pTypeInfo, pmethod->index);
6776 }
6777
6778 static VALUE
6779 ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index)
6780 {
6781 FUNCDESC *pFuncDesc;
6782 HRESULT hr;
6783 VALUE visible;
6784 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
6785 if(FAILED(hr))
6786 return Qfalse;
6787 if (pFuncDesc->wFuncFlags & (FUNCFLAG_FRESTRICTED |
6788 FUNCFLAG_FHIDDEN |
6789 FUNCFLAG_FNONBROWSABLE)) {
6790 visible = Qfalse;
6791 } else {
6792 visible = Qtrue;
6793 }
6794 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
6795 return visible;
6796 }
6797
6798 /*
6799 * call-seq:
6800 * WIN32OLE_METHOD#visible?
6801 *
6802 * Returns true if the method is public.
6803 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6804 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6805 * puts method.visible? # => true
6806 */
6807 static VALUE
6808 folemethod_visible(VALUE self)
6809 {
6810 struct olemethoddata *pmethod;
6811 Data_Get_Struct(self, struct olemethoddata, pmethod);
6812 return ole_method_visible(pmethod->pTypeInfo, pmethod->index);
6813 }
6814
6815 static VALUE
6816 ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name)
6817 {
6818 TYPEATTR *pTypeAttr;
6819 HRESULT hr;
6820 WORD i;
6821 int flags;
6822 HREFTYPE href;
6823 ITypeInfo *pRefTypeInfo;
6824 FUNCDESC *pFuncDesc;
6825 BSTR bstr;
6826 VALUE name;
6827 VALUE event = Qfalse;
6828
6829 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
6830 if (FAILED(hr))
6831 return event;
6832 if(pTypeAttr->typekind != TKIND_COCLASS) {
6833 pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
6834 return event;
6835 }
6836 for (i = 0; i < pTypeAttr->cImplTypes; i++) {
6837 hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
6838 if (FAILED(hr))
6839 continue;
6840
6841 if (flags & IMPLTYPEFLAG_FSOURCE) {
6842 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
6843 i, &href);
6844 if (FAILED(hr))
6845 continue;
6846 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
6847 href, &pRefTypeInfo);
6848 if (FAILED(hr))
6849 continue;
6850 hr = pRefTypeInfo->lpVtbl->GetFuncDesc(pRefTypeInfo, method_index,
6851 &pFuncDesc);
6852 if (FAILED(hr)) {
6853 OLE_RELEASE(pRefTypeInfo);
6854 continue;
6855 }
6856
6857 hr = pRefTypeInfo->lpVtbl->GetDocumentation(pRefTypeInfo,
6858 pFuncDesc->memid,
6859 &bstr, NULL, NULL, NULL);
6860 if (FAILED(hr)) {
6861 pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);
6862 OLE_RELEASE(pRefTypeInfo);
6863 continue;
6864 }
6865
6866 name = WC2VSTR(bstr);
6867 pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);
6868 OLE_RELEASE(pRefTypeInfo);
6869 if (rb_str_cmp(method_name, name) == 0) {
6870 event = Qtrue;
6871 break;
6872 }
6873 }
6874 }
6875 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
6876 return event;
6877 }
6878
6879 /*
6880 * call-seq:
6881 * WIN32OLE_METHOD#event?
6882 *
6883 * Returns true if the method is event.
6884 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
6885 * method = WIN32OLE_METHOD.new(tobj, 'SheetActivate')
6886 * puts method.event? # => true
6887 *
6888 */
6889 static VALUE
6890 folemethod_event(VALUE self)
6891 {
6892 struct olemethoddata *pmethod;
6893 Data_Get_Struct(self, struct olemethoddata, pmethod);
6894 if (!pmethod->pOwnerTypeInfo)
6895 return Qfalse;
6896 return ole_method_event(pmethod->pOwnerTypeInfo,
6897 pmethod->index,
6898 rb_ivar_get(self, rb_intern("name")));
6899 }
6900
6901 /*
6902 * call-seq:
6903 * WIN32OLE_METHOD#event_interface
6904 *
6905 * Returns event interface name if the method is event.
6906 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
6907 * method = WIN32OLE_METHOD.new(tobj, 'SheetActivate')
6908 * puts method.event_interface # => WorkbookEvents
6909 */
6910 static VALUE
6911 folemethod_event_interface(VALUE self)
6912 {
6913 BSTR name;
6914 struct olemethoddata *pmethod;
6915 HRESULT hr;
6916 Data_Get_Struct(self, struct olemethoddata, pmethod);
6917 if(folemethod_event(self) == Qtrue) {
6918 hr = ole_docinfo_from_type(pmethod->pTypeInfo, &name, NULL, NULL, NULL);
6919 if(SUCCEEDED(hr))
6920 return WC2VSTR(name);
6921 }
6922 return Qnil;
6923 }
6924
6925 static VALUE
6926 ole_method_docinfo_from_type(
6927 ITypeInfo *pTypeInfo,
6928 UINT method_index,
6929 BSTR *name,
6930 BSTR *helpstr,
6931 DWORD *helpcontext,
6932 BSTR *helpfile
6933 )
6934 {
6935 FUNCDESC *pFuncDesc;
6936 HRESULT hr;
6937 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
6938 if (FAILED(hr))
6939 return hr;
6940 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
6941 name, helpstr,
6942 helpcontext, helpfile);
6943 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
6944 return hr;
6945 }
6946
6947 static VALUE
6948 ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index)
6949 {
6950 HRESULT hr;
6951 BSTR bhelpstring;
6952 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, &bhelpstring,
6953 NULL, NULL);
6954 if (FAILED(hr))
6955 return Qnil;
6956 return WC2VSTR(bhelpstring);
6957 }
6958
6959 /*
6960 * call-seq:
6961 * WIN32OLE_METHOD#helpstring
6962 *
6963 * Returns help string of OLE method. If the help string is not found,
6964 * then the method returns nil.
6965 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'IWebBrowser')
6966 * method = WIN32OLE_METHOD.new(tobj, 'Navigate')
6967 * puts method.helpstring # => Navigates to a URL or file.
6968 *
6969 */
6970 static VALUE
6971 folemethod_helpstring(VALUE self)
6972 {
6973 struct olemethoddata *pmethod;
6974 Data_Get_Struct(self, struct olemethoddata, pmethod);
6975 return ole_method_helpstring(pmethod->pTypeInfo, pmethod->index);
6976 }
6977
6978 static VALUE
6979 ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index)
6980 {
6981 HRESULT hr;
6982 BSTR bhelpfile;
6983 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,
6984 NULL, &bhelpfile);
6985 if (FAILED(hr))
6986 return Qnil;
6987 return WC2VSTR(bhelpfile);
6988 }
6989
6990 /*
6991 * call-seq:
6992 * WIN32OLE_METHOD#helpfile
6993 *
6994 * Returns help file. If help file is not found, then
6995 * the method returns nil.
6996 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
6997 * method = WIN32OLE_METHOD.new(tobj, 'Add')
6998 * puts method.helpfile # => C:\...\VBAXL9.CHM
6999 */
7000 static VALUE
7001 folemethod_helpfile(VALUE self)
7002 {
7003 struct olemethoddata *pmethod;
7004 Data_Get_Struct(self, struct olemethoddata, pmethod);
7005
7006 return ole_method_helpfile(pmethod->pTypeInfo, pmethod->index);
7007 }
7008
7009 static VALUE
7010 ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index)
7011 {
7012 HRESULT hr;
7013 DWORD helpcontext = 0;
7014 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,
7015 &helpcontext, NULL);
7016 if (FAILED(hr))
7017 return Qnil;
7018 return INT2FIX(helpcontext);
7019 }
7020
7021 /*
7022 * call-seq:
7023 * WIN32OLE_METHOD#helpcontext
7024 *
7025 * Returns help context.
7026 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
7027 * method = WIN32OLE_METHOD.new(tobj, 'Add')
7028 * puts method.helpcontext # => 65717
7029 */
7030 static VALUE
7031 folemethod_helpcontext(VALUE self)
7032 {
7033 struct olemethoddata *pmethod;
7034 Data_Get_Struct(self, struct olemethoddata, pmethod);
7035 return ole_method_helpcontext(pmethod->pTypeInfo, pmethod->index);
7036 }
7037
7038 static VALUE
7039 ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index)
7040 {
7041 FUNCDESC *pFuncDesc;
7042 HRESULT hr;
7043 VALUE dispid = Qnil;
7044 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
7045 if (FAILED(hr))
7046 return dispid;
7047 dispid = INT2NUM(pFuncDesc->memid);
7048 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7049 return dispid;
7050 }
7051
7052 /*
7053 * call-seq:
7054 * WIN32OLE_METHOD#dispid
7055 *
7056 * Returns dispatch ID.
7057 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
7058 * method = WIN32OLE_METHOD.new(tobj, 'Add')
7059 * puts method.dispid # => 181
7060 */
7061 static VALUE
7062 folemethod_dispid(VALUE self)
7063 {
7064 struct olemethoddata *pmethod;
7065 Data_Get_Struct(self, struct olemethoddata, pmethod);
7066 return ole_method_dispid(pmethod->pTypeInfo, pmethod->index);
7067 }
7068
7069 static VALUE
7070 ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index)
7071 {
7072 FUNCDESC *pFuncDesc;
7073 HRESULT hr;
7074 VALUE offset_vtbl = Qnil;
7075 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
7076 if (FAILED(hr))
7077 return offset_vtbl;
7078 offset_vtbl = INT2FIX(pFuncDesc->oVft);
7079 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7080 return offset_vtbl;
7081 }
7082
7083 /*
7084 * call-seq:
7085 * WIN32OLE_METHOD#offset_vtbl
7086 *
7087 * Returns the offset ov VTBL.
7088 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbooks')
7089 * method = WIN32OLE_METHOD.new(tobj, 'Add')
7090 * puts method.offset_vtbl # => 40
7091 */
7092 static VALUE
7093 folemethod_offset_vtbl(VALUE self)
7094 {
7095 struct olemethoddata *pmethod;
7096 Data_Get_Struct(self, struct olemethoddata, pmethod);
7097 return ole_method_offset_vtbl(pmethod->pTypeInfo, pmethod->index);
7098 }
7099
7100 static VALUE
7101 ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index)
7102 {
7103 FUNCDESC *pFuncDesc;
7104 HRESULT hr;
7105 VALUE size_params = Qnil;
7106 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
7107 if (FAILED(hr))
7108 return size_params;
7109 size_params = INT2FIX(pFuncDesc->cParams);
7110 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7111 return size_params;
7112 }
7113
7114 /*
7115 * call-seq:
7116 * WIN32OLE_METHOD#size_params
7117 *
7118 * Returns the size of arguments of the method.
7119 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7120 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7121 * puts method.size_params # => 11
7122 *
7123 */
7124 static VALUE
7125 folemethod_size_params(VALUE self)
7126 {
7127 struct olemethoddata *pmethod;
7128 Data_Get_Struct(self, struct olemethoddata, pmethod);
7129 return ole_method_size_params(pmethod->pTypeInfo, pmethod->index);
7130 }
7131
7132 static VALUE
7133 ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index)
7134 {
7135 FUNCDESC *pFuncDesc;
7136 HRESULT hr;
7137 VALUE size_opt_params = Qnil;
7138 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
7139 if (FAILED(hr))
7140 return size_opt_params;
7141 size_opt_params = INT2FIX(pFuncDesc->cParamsOpt);
7142 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7143 return size_opt_params;
7144 }
7145
7146 /*
7147 * call-seq:
7148 * WIN32OLE_METHOD#size_opt_params
7149 *
7150 * Returns the size of optional parameters.
7151 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7152 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7153 * puts method.size_opt_params # => 4
7154 */
7155 static VALUE
7156 folemethod_size_opt_params(VALUE self)
7157 {
7158 struct olemethoddata *pmethod;
7159 Data_Get_Struct(self, struct olemethoddata, pmethod);
7160 return ole_method_size_opt_params(pmethod->pTypeInfo, pmethod->index);
7161 }
7162
7163 static VALUE
7164 ole_method_params(ITypeInfo *pTypeInfo, UINT method_index)
7165 {
7166 FUNCDESC *pFuncDesc;
7167 HRESULT hr;
7168 BSTR *bstrs;
7169 UINT len, i;
7170 struct oleparamdata *pparam;
7171 VALUE param;
7172 VALUE params = rb_ary_new();
7173 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
7174 if (FAILED(hr))
7175 return params;
7176
7177 len = 0;
7178 bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1);
7179 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid,
7180 bstrs, pFuncDesc->cParams + 1,
7181 &len);
7182 if (FAILED(hr)) {
7183 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7184 return params;
7185 }
7186 SysFreeString(bstrs[0]);
7187 if (pFuncDesc->cParams > 0) {
7188 for(i = 1; i < len; i++) {
7189 param = Data_Make_Struct(cWIN32OLE_PARAM, struct oleparamdata, 0,
7190 oleparam_free, pparam);
7191 pparam->pTypeInfo = pTypeInfo;
7192 OLE_ADDREF(pTypeInfo);
7193 pparam->method_index = method_index;
7194 pparam->index = i - 1;
7195 rb_ivar_set(param, rb_intern("name"), WC2VSTR(bstrs[i]));
7196 rb_ary_push(params, param);
7197 }
7198 }
7199 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7200 return params;
7201 }
7202
7203
7204 /*
7205 * call-seq:
7206 * WIN32OLE_METHOD#params
7207 *
7208 * returns array of WIN32OLE_PARAM object corresponding with method parameters.
7209 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7210 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7211 * p method.params # => [Filename, FileFormat, Password, WriteResPassword,
7212 * ReadOnlyRecommended, CreateBackup, AccessMode,
7213 * ConflictResolution, AddToMru, TextCodepage,
7214 * TextVisualLayout]
7215 */
7216 static VALUE
7217 folemethod_params(VALUE self)
7218 {
7219 struct olemethoddata *pmethod;
7220 Data_Get_Struct(self, struct olemethoddata, pmethod);
7221 return ole_method_params(pmethod->pTypeInfo, pmethod->index);
7222 }
7223
7224 /*
7225 * call-seq:
7226 * WIN32OLE_METHOD#inspect -> String
7227 *
7228 * Returns the method name with class name.
7229 *
7230 */
7231 static VALUE
7232 folemethod_inspect(VALUE self)
7233 {
7234 return default_inspect(self, "WIN32OLE_METHOD");
7235 }
7236
7237 /*
7238 * Document-class: WIN32OLE_PARAM
7239 *
7240 * <code>WIN32OLE_PARAM</code> objects represent param information of
7241 * the OLE method.
7242 */
7243 static VALUE foleparam_s_allocate(VALUE klass)
7244 {
7245 struct oleparamdata *pparam;
7246 VALUE obj;
7247 obj = Data_Make_Struct(klass,
7248 struct oleparamdata,
7249 0, oleparam_free, pparam);
7250 pparam->pTypeInfo = NULL;
7251 pparam->method_index = 0;
7252 pparam->index = 0;
7253 return obj;
7254 }
7255
7256 static VALUE
7257 oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index)
7258 {
7259 FUNCDESC *pFuncDesc;
7260 HRESULT hr;
7261 BSTR *bstrs;
7262 UINT len;
7263 struct oleparamdata *pparam;
7264 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
7265 if (FAILED(hr))
7266 ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetFuncDesc");
7267
7268 len = 0;
7269 bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1);
7270 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid,
7271 bstrs, pFuncDesc->cParams + 1,
7272 &len);
7273 if (FAILED(hr)) {
7274 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7275 ole_raise(hr, rb_eRuntimeError, "fail to ITypeInfo::GetNames");
7276 }
7277 SysFreeString(bstrs[0]);
7278 if (param_index < 1 || len <= (UINT)param_index)
7279 {
7280 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7281 rb_raise(rb_eIndexError, "index of param must be in 1..%d", len);
7282 }
7283
7284 Data_Get_Struct(self, struct oleparamdata, pparam);
7285 pparam->pTypeInfo = pTypeInfo;
7286 OLE_ADDREF(pTypeInfo);
7287 pparam->method_index = method_index;
7288 pparam->index = param_index - 1;
7289 rb_ivar_set(self, rb_intern("name"), WC2VSTR(bstrs[param_index]));
7290
7291 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7292 return self;
7293 }
7294
7295 static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n)
7296 {
7297 struct olemethoddata *pmethod;
7298 Data_Get_Struct(olemethod, struct olemethoddata, pmethod);
7299 return oleparam_ole_param_from_index(self, pmethod->pTypeInfo, pmethod->index, n);
7300 }
7301
7302 static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n)
7303 {
7304 int idx;
7305 if (!rb_obj_is_kind_of(olemethod, cWIN32OLE_METHOD)) {
7306 rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE_METHOD object");
7307 }
7308 idx = FIX2INT(n);
7309 return oleparam_ole_param(self, olemethod, idx);
7310 }
7311
7312 /*
7313 * call-seq:
7314 * WIN32OLE_PARAM#name
7315 *
7316 * Returns name.
7317 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7318 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7319 * param1 = method.params[0]
7320 * puts param1.name # => Filename
7321 */
7322 static VALUE
7323 foleparam_name(VALUE self)
7324 {
7325 return rb_ivar_get(self, rb_intern("name"));
7326 }
7327
7328 static VALUE
7329 ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
7330 {
7331 FUNCDESC *pFuncDesc;
7332 HRESULT hr;
7333 VALUE type = rb_str_new2("unknown type");
7334 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
7335 if (FAILED(hr))
7336 return type;
7337 type = ole_typedesc2val(pTypeInfo,
7338 &(pFuncDesc->lprgelemdescParam[index].tdesc), Qnil);
7339 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7340 return type;
7341 }
7342
7343 /*
7344 * call-seq:
7345 * WIN32OLE_PARAM#ole_type
7346 *
7347 * Returns OLE type of WIN32OLE_PARAM object(parameter of OLE method).
7348 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7349 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7350 * param1 = method.params[0]
7351 * puts param1.ole_type # => VARIANT
7352 */
7353 static VALUE
7354 foleparam_ole_type(VALUE self)
7355 {
7356 struct oleparamdata *pparam;
7357 Data_Get_Struct(self, struct oleparamdata, pparam);
7358 return ole_param_ole_type(pparam->pTypeInfo, pparam->method_index,
7359 pparam->index);
7360 }
7361
7362 static VALUE
7363 ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
7364 {
7365 FUNCDESC *pFuncDesc;
7366 HRESULT hr;
7367 VALUE typedetail = rb_ary_new();
7368 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
7369 if (FAILED(hr))
7370 return typedetail;
7371 ole_typedesc2val(pTypeInfo,
7372 &(pFuncDesc->lprgelemdescParam[index].tdesc), typedetail);
7373 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7374 return typedetail;
7375 }
7376
7377 /*
7378 * call-seq:
7379 * WIN32OLE_PARAM#ole_type_detail
7380 *
7381 * Returns detail information of type of argument.
7382 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'IWorksheetFunction')
7383 * method = WIN32OLE_METHOD.new(tobj, 'SumIf')
7384 * param1 = method.params[0]
7385 * p param1.ole_type_detail # => ["PTR", "USERDEFINED", "Range"]
7386 */
7387 static VALUE
7388 foleparam_ole_type_detail(VALUE self)
7389 {
7390 struct oleparamdata *pparam;
7391 Data_Get_Struct(self, struct oleparamdata, pparam);
7392 return ole_param_ole_type_detail(pparam->pTypeInfo, pparam->method_index,
7393 pparam->index);
7394 }
7395
7396 static VALUE
7397 ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask)
7398 {
7399 FUNCDESC *pFuncDesc;
7400 HRESULT hr;
7401 VALUE ret = Qfalse;
7402 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
7403 if(FAILED(hr))
7404 return ret;
7405 if (V_UNION1((&(pFuncDesc->lprgelemdescParam[index])), paramdesc).wParamFlags &mask)
7406 ret = Qtrue;
7407 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7408 return ret;
7409 }
7410
7411 /*
7412 * call-seq:
7413 * WIN32OLE_PARAM#input?
7414 *
7415 * Returns true if the parameter is input.
7416 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7417 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7418 * param1 = method.params[0]
7419 * puts param1.input? # => true
7420 */
7421 static VALUE foleparam_input(VALUE self)
7422 {
7423 struct oleparamdata *pparam;
7424 Data_Get_Struct(self, struct oleparamdata, pparam);
7425 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
7426 pparam->index, PARAMFLAG_FIN);
7427 }
7428
7429 /*
7430 * call-seq:
7431 * WIN32OLE#output?
7432 *
7433 * Returns true if argument is output.
7434 * tobj = WIN32OLE_TYPE.new('Microsoft Internet Controls', 'DWebBrowserEvents')
7435 * method = WIN32OLE_METHOD.new(tobj, 'NewWindow')
7436 * method.params.each do |param|
7437 * puts "#{param.name} #{param.output?}"
7438 * end
7439 *
7440 * The result of above script is following:
7441 * URL false
7442 * Flags false
7443 * TargetFrameName false
7444 * PostData false
7445 * Headers false
7446 * Processed true
7447 */
7448 static VALUE foleparam_output(VALUE self)
7449 {
7450 struct oleparamdata *pparam;
7451 Data_Get_Struct(self, struct oleparamdata, pparam);
7452 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
7453 pparam->index, PARAMFLAG_FOUT);
7454 }
7455
7456 /*
7457 * call-seq:
7458 * WIN32OLE_PARAM#optional?
7459 *
7460 * Returns true if argument is optional.
7461 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7462 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7463 * param1 = method.params[0]
7464 * puts "#{param1.name} #{param1.optional?}" # => Filename true
7465 */
7466 static VALUE foleparam_optional(VALUE self)
7467 {
7468 struct oleparamdata *pparam;
7469 Data_Get_Struct(self, struct oleparamdata, pparam);
7470 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
7471 pparam->index, PARAMFLAG_FOPT);
7472 }
7473
7474 /*
7475 * call-seq:
7476 * WIN32OLE_PARAM#retval?
7477 *
7478 * Returns true if argument is return value.
7479 * tobj = WIN32OLE_TYPE.new('DirectX 7 for Visual Basic Type Library',
7480 * 'DirectPlayLobbyConnection')
7481 * method = WIN32OLE_METHOD.new(tobj, 'GetPlayerShortName')
7482 * param = method.params[0]
7483 * puts "#{param.name} #{param.retval?}" # => name true
7484 */
7485 static VALUE foleparam_retval(VALUE self)
7486 {
7487 struct oleparamdata *pparam;
7488 Data_Get_Struct(self, struct oleparamdata, pparam);
7489 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
7490 pparam->index, PARAMFLAG_FRETVAL);
7491 }
7492
7493 static VALUE
7494 ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
7495 {
7496 FUNCDESC *pFuncDesc;
7497 ELEMDESC *pElemDesc;
7498 PARAMDESCEX * pParamDescEx;
7499 HRESULT hr;
7500 USHORT wParamFlags;
7501 USHORT mask = PARAMFLAG_FOPT|PARAMFLAG_FHASDEFAULT;
7502 VALUE defval = Qnil;
7503 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
7504 if (FAILED(hr))
7505 return defval;
7506 pElemDesc = &pFuncDesc->lprgelemdescParam[index];
7507 wParamFlags = V_UNION1(pElemDesc, paramdesc).wParamFlags;
7508 if ((wParamFlags & mask) == mask) {
7509 pParamDescEx = V_UNION1(pElemDesc, paramdesc).pparamdescex;
7510 defval = ole_variant2val(&pParamDescEx->varDefaultValue);
7511 }
7512 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
7513 return defval;
7514 }
7515
7516 /*
7517 * call-seq:
7518 * WIN32OLE_PARAM#default
7519 *
7520 * Returns default value. If the default value does not exist,
7521 * this method returns nil.
7522 * tobj = WIN32OLE_TYPE.new('Microsoft Excel 9.0 Object Library', 'Workbook')
7523 * method = WIN32OLE_METHOD.new(tobj, 'SaveAs')
7524 * method.params.each do |param|
7525 * if param.default
7526 * puts "#{param.name} (= #{param.default})"
7527 * else
7528 * puts "#{param}"
7529 * end
7530 * end
7531 *
7532 * The above script result is following:
7533 * Filename
7534 * FileFormat
7535 * Password
7536 * WriteResPassword
7537 * ReadOnlyRecommended
7538 * CreateBackup
7539 * AccessMode (= 1)
7540 * ConflictResolution
7541 * AddToMru
7542 * TextCodepage
7543 * TextVisualLayout
7544 */
7545 static VALUE foleparam_default(VALUE self)
7546 {
7547 struct oleparamdata *pparam;
7548 Data_Get_Struct(self, struct oleparamdata, pparam);
7549 return ole_param_default(pparam->pTypeInfo, pparam->method_index,
7550 pparam->index);
7551 }
7552
7553 /*
7554 * call-seq:
7555 * WIN32OLE_PARAM#inspect -> String
7556 *
7557 * Returns the parameter name with class name. If the parameter has default value,
7558 * then returns name=value string with class name.
7559 *
7560 */
7561 static VALUE
7562 foleparam_inspect(VALUE self)
7563 {
7564 VALUE detail = foleparam_name(self);
7565 VALUE defval = foleparam_default(self);
7566 if (defval != Qnil) {
7567 rb_str_cat2(detail, "=");
7568 rb_str_concat(detail, rb_funcall(defval, rb_intern("inspect"), 0));
7569 }
7570 return make_inspect("WIN32OLE_PARAM", detail);
7571 }
7572
7573 /*
7574 * Document-class: WIN32OLE_EVENT
7575 *
7576 * <code>WIN32OLE_EVENT</code> objects controls OLE event.
7577 */
7578
7579 static IEventSinkVtbl vtEventSink;
7580 static BOOL g_IsEventSinkVtblInitialized = FALSE;
7581
7582 void EVENTSINK_Destructor(PIEVENTSINKOBJ);
7583
7584 STDMETHODIMP
7585 EVENTSINK_QueryInterface(
7586 PEVENTSINK pEV,
7587 REFIID iid,
7588 LPVOID* ppv
7589 ) {
7590 if (IsEqualIID(iid, &IID_IUnknown) ||
7591 IsEqualIID(iid, &IID_IDispatch) ||
7592 IsEqualIID(iid, &((PIEVENTSINKOBJ)pEV)->m_iid)) {
7593 *ppv = pEV;
7594 }
7595 else {
7596 *ppv = NULL;
7597 return E_NOINTERFACE;
7598 }
7599 ((LPUNKNOWN)*ppv)->lpVtbl->AddRef((LPUNKNOWN)*ppv);
7600 return NOERROR;
7601 }
7602
7603 STDMETHODIMP_(ULONG)
7604 EVENTSINK_AddRef(
7605 PEVENTSINK pEV
7606 ){
7607 PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV;
7608 return ++pEVObj->m_cRef;
7609 }
7610
7611 STDMETHODIMP_(ULONG) EVENTSINK_Release(
7612 PEVENTSINK pEV
7613 ) {
7614 PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV;
7615 --pEVObj->m_cRef;
7616 if(pEVObj->m_cRef != 0)
7617 return pEVObj->m_cRef;
7618 EVENTSINK_Destructor(pEVObj);
7619 return 0;
7620 }
7621
7622 STDMETHODIMP EVENTSINK_GetTypeInfoCount(
7623 PEVENTSINK pEV,
7624 UINT *pct
7625 ) {
7626 *pct = 0;
7627 return NOERROR;
7628 }
7629
7630 STDMETHODIMP EVENTSINK_GetTypeInfo(
7631 PEVENTSINK pEV,
7632 UINT info,
7633 LCID lcid,
7634 ITypeInfo **pInfo
7635 ) {
7636 *pInfo = NULL;
7637 return DISP_E_BADINDEX;
7638 }
7639
7640 STDMETHODIMP EVENTSINK_GetIDsOfNames(
7641 PEVENTSINK pEventSink,
7642 REFIID riid,
7643 OLECHAR **szNames,
7644 UINT cNames,
7645 LCID lcid,
7646 DISPID *pDispID
7647 ) {
7648 ITypeInfo *pTypeInfo;
7649 PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink;
7650 pTypeInfo = pEV->pTypeInfo;
7651 if (pTypeInfo) {
7652 return pTypeInfo->lpVtbl->GetIDsOfNames(pTypeInfo, szNames, cNames, pDispID);
7653 }
7654 return DISP_E_UNKNOWNNAME;
7655 }
7656
7657 static long
7658 ole_search_event_at(VALUE ary, VALUE ev)
7659 {
7660 VALUE event;
7661 VALUE event_name;
7662 long i, len;
7663 long ret = -1;
7664 len = RARRAY_LEN(ary);
7665 for(i = 0; i < len; i++) {
7666 event = rb_ary_entry(ary, i);
7667 event_name = rb_ary_entry(event, 1);
7668 if(NIL_P(event_name) && NIL_P(ev)) {
7669 ret = i;
7670 break;
7671 }
7672 else if (TYPE(ev) == T_STRING &&
7673 TYPE(event_name) == T_STRING &&
7674 rb_str_cmp(ev, event_name) == 0) {
7675 ret = i;
7676 break;
7677 }
7678 }
7679 return ret;
7680 }
7681
7682 static VALUE
7683 ole_search_event(VALUE ary, VALUE ev, BOOL *is_default)
7684 {
7685 VALUE event;
7686 VALUE def_event;
7687 VALUE event_name;
7688 int i, len;
7689 *is_default = FALSE;
7690 def_event = Qnil;
7691 len = RARRAY_LEN(ary);
7692 for(i = 0; i < len; i++) {
7693 event = rb_ary_entry(ary, i);
7694 event_name = rb_ary_entry(event, 1);
7695 if(NIL_P(event_name)) {
7696 *is_default = TRUE;
7697 def_event = event;
7698 }
7699 else if (rb_str_cmp(ev, event_name) == 0) {
7700 *is_default = FALSE;
7701 return event;
7702 }
7703 }
7704 return def_event;
7705 }
7706 static VALUE
7707 ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler)
7708 {
7709 VALUE mid;
7710
7711 *is_default_handler = FALSE;
7712 mid = rb_to_id(rb_sprintf("on%s", StringValuePtr(ev)));
7713 if (rb_respond_to(handler, mid)) {
7714 return mid;
7715 }
7716 mid = rb_intern("method_missing");
7717 if (rb_respond_to(handler, mid)) {
7718 *is_default_handler = TRUE;
7719 return mid;
7720 }
7721 return Qnil;
7722 }
7723
7724 static void
7725 ole_delete_event(VALUE ary, VALUE ev)
7726 {
7727 long at = -1;
7728 at = ole_search_event_at(ary, ev);
7729 if (at >= 0) {
7730 rb_ary_delete_at(ary, at);
7731 }
7732 }
7733
7734 static void
7735 hash2ptr_dispparams(VALUE hash, ITypeInfo *pTypeInfo, DISPID dispid, DISPPARAMS *pdispparams)
7736 {
7737 BSTR *bstrs;
7738 HRESULT hr;
7739 UINT len, i;
7740 VARIANT *pvar;
7741 VALUE val;
7742 VALUE key;
7743 len = 0;
7744 bstrs = ALLOCA_N(BSTR, pdispparams->cArgs + 1);
7745 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid,
7746 bstrs, pdispparams->cArgs + 1,
7747 &len);
7748 if (FAILED(hr))
7749 return;
7750
7751 for (i = 0; i < len - 1; i++) {
7752 key = WC2VSTR(bstrs[i + 1]);
7753 val = rb_hash_aref(hash, INT2FIX(i));
7754 if (val == Qnil)
7755 val = rb_hash_aref(hash, key);
7756 if (val == Qnil)
7757 val = rb_hash_aref(hash, rb_str_intern(key));
7758 pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
7759 ole_val2ptr_variant(val, pvar);
7760 }
7761 }
7762
7763 static VALUE
7764 hash2result(VALUE hash)
7765 {
7766 VALUE ret = Qnil;
7767 ret = rb_hash_aref(hash, rb_str_new2("return"));
7768 if (ret == Qnil)
7769 ret = rb_hash_aref(hash, rb_str_intern(rb_str_new2("return")));
7770 return ret;
7771 }
7772
7773 static void
7774 ary2ptr_dispparams(VALUE ary, DISPPARAMS *pdispparams)
7775 {
7776 int i;
7777 VALUE v;
7778 VARIANT *pvar;
7779 for(i = 0; i < RARRAY_LEN(ary) && (unsigned int) i < pdispparams->cArgs; i++) {
7780 v = rb_ary_entry(ary, i);
7781 pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
7782 ole_val2ptr_variant(v, pvar);
7783 }
7784 }
7785
7786 static VALUE
7787 exec_callback(VALUE arg)
7788 {
7789 VALUE *parg = (VALUE *)arg;
7790 VALUE handler = parg[0];
7791 VALUE mid = parg[1];
7792 VALUE args = parg[2];
7793 return rb_apply(handler, mid, args);
7794 }
7795
7796 static VALUE
7797 rescue_callback(VALUE arg)
7798 {
7799
7800 VALUE error;
7801 VALUE e = rb_errinfo();
7802 VALUE bt = rb_funcall(e, rb_intern("backtrace"), 0);
7803 VALUE msg = rb_funcall(e, rb_intern("message"), 0);
7804 bt = rb_ary_entry(bt, 0);
7805 error = rb_sprintf("%s: %s (%s)\n", StringValuePtr(bt), StringValuePtr(msg), rb_obj_classname(e));
7806 rb_write_error(StringValuePtr(error));
7807 rb_backtrace();
7808 ruby_finalize();
7809 exit(-1);
7810
7811 return Qnil;
7812 }
7813
7814 STDMETHODIMP EVENTSINK_Invoke(
7815 PEVENTSINK pEventSink,
7816 DISPID dispid,
7817 REFIID riid,
7818 LCID lcid,
7819 WORD wFlags,
7820 DISPPARAMS *pdispparams,
7821 VARIANT *pvarResult,
7822 EXCEPINFO *pexcepinfo,
7823 UINT *puArgErr
7824 ) {
7825
7826 HRESULT hr;
7827 BSTR bstr;
7828 unsigned int count;
7829 unsigned int i;
7830 ITypeInfo *pTypeInfo;
7831 VARIANT *pvar;
7832 VALUE ary, obj, event, args, outargv, ev, result;
7833 VALUE handler = Qnil;
7834 VALUE arg[3];
7835 VALUE mid;
7836 VALUE is_outarg = Qfalse;
7837 BOOL is_default_handler = FALSE;
7838 int state;
7839
7840 PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink;
7841 pTypeInfo = pEV->pTypeInfo;
7842 obj = evs_entry(pEV->m_event_id);
7843 if (!rb_obj_is_kind_of(obj, cWIN32OLE_EVENT)) {
7844 return NOERROR;
7845 }
7846
7847 ary = rb_ivar_get(obj, id_events);
7848 if (NIL_P(ary) || TYPE(ary) != T_ARRAY) {
7849 return NOERROR;
7850 }
7851 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid,
7852 &bstr, 1, &count);
7853 if (FAILED(hr)) {
7854 return NOERROR;
7855 }
7856 ev = WC2VSTR(bstr);
7857 event = ole_search_event(ary, ev, &is_default_handler);
7858 if (TYPE(event) == T_ARRAY) {
7859 handler = rb_ary_entry(event, 0);
7860 mid = rb_intern("call");
7861 is_outarg = rb_ary_entry(event, 3);
7862 } else {
7863 handler = rb_ivar_get(obj, rb_intern("handler"));
7864 if (handler == Qnil) {
7865 return NOERROR;
7866 }
7867 mid = ole_search_handler_method(handler, ev, &is_default_handler);
7868 }
7869 if (handler == Qnil || mid == Qnil) {
7870 return NOERROR;
7871 }
7872
7873 args = rb_ary_new();
7874 if (is_default_handler) {
7875 rb_ary_push(args, ev);
7876 }
7877
7878 /* make argument of event handler */
7879 for (i = 0; i < pdispparams->cArgs; ++i) {
7880 pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
7881 rb_ary_push(args, ole_variant2val(pvar));
7882 }
7883 outargv = Qnil;
7884 if (is_outarg == Qtrue) {
7885 outargv = rb_ary_new();
7886 rb_ary_push(args, outargv);
7887 }
7888
7889 /*
7890 * if exception raised in event callback,
7891 * then you receive cfp consistency error.
7892 * to avoid this error we use begin rescue end.
7893 * and the exception raised then error message print
7894 * and exit ruby process by Win32OLE itself.
7895 */
7896 arg[0] = handler;
7897 arg[1] = mid;
7898 arg[2] = args;
7899 result = rb_protect(exec_callback, (VALUE)arg, &state);
7900 if (state != 0) {
7901 rescue_callback(Qnil);
7902 }
7903 if(TYPE(result) == T_HASH) {
7904 hash2ptr_dispparams(result, pTypeInfo, dispid, pdispparams);
7905 result = hash2result(result);
7906 }else if (is_outarg == Qtrue && TYPE(outargv) == T_ARRAY) {
7907 ary2ptr_dispparams(outargv, pdispparams);
7908 }
7909
7910 if (pvarResult) {
7911 VariantInit(pvarResult);
7912 ole_val2variant(result, pvarResult);
7913 }
7914
7915 return NOERROR;
7916 }
7917
7918 PIEVENTSINKOBJ
7919 EVENTSINK_Constructor() {
7920 PIEVENTSINKOBJ pEv;
7921 if (!g_IsEventSinkVtblInitialized) {
7922 vtEventSink.QueryInterface=EVENTSINK_QueryInterface;
7923 vtEventSink.AddRef = EVENTSINK_AddRef;
7924 vtEventSink.Release = EVENTSINK_Release;
7925 vtEventSink.Invoke = EVENTSINK_Invoke;
7926 vtEventSink.GetIDsOfNames = EVENTSINK_GetIDsOfNames;
7927 vtEventSink.GetTypeInfoCount = EVENTSINK_GetTypeInfoCount;
7928 vtEventSink.GetTypeInfo = EVENTSINK_GetTypeInfo;
7929
7930 g_IsEventSinkVtblInitialized = TRUE;
7931 }
7932 pEv = ALLOC_N(IEVENTSINKOBJ, 1);
7933 if(pEv == NULL) return NULL;
7934 pEv->lpVtbl = &vtEventSink;
7935 pEv->m_cRef = 0;
7936 pEv->m_event_id = 0;
7937 pEv->pTypeInfo = NULL;
7938 return pEv;
7939 }
7940
7941 void EVENTSINK_Destructor(
7942 PIEVENTSINKOBJ pEVObj
7943 ) {
7944 if(pEVObj != NULL) {
7945 OLE_RELEASE(pEVObj->pTypeInfo);
7946 free(pEVObj);
7947 pEVObj = NULL;
7948 }
7949 }
7950
7951 static HRESULT
7952 find_iid(VALUE ole, char *pitf, IID *piid, ITypeInfo **ppTypeInfo)
7953 {
7954 HRESULT hr;
7955 IDispatch *pDispatch;
7956 ITypeInfo *pTypeInfo;
7957 ITypeLib *pTypeLib;
7958 TYPEATTR *pTypeAttr;
7959 HREFTYPE RefType;
7960 ITypeInfo *pImplTypeInfo;
7961 TYPEATTR *pImplTypeAttr;
7962
7963 struct oledata *pole;
7964 unsigned int index;
7965 unsigned int count;
7966 int type;
7967 BSTR bstr;
7968 char *pstr;
7969
7970 BOOL is_found = FALSE;
7971 LCID lcid = cWIN32OLE_lcid;
7972
7973 OLEData_Get_Struct(ole, pole);
7974
7975 pDispatch = pole->pDispatch;
7976
7977 hr = pDispatch->lpVtbl->GetTypeInfo(pDispatch, 0, lcid, &pTypeInfo);
7978 if (FAILED(hr))
7979 return hr;
7980
7981 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo,
7982 &pTypeLib,
7983 &index);
7984 OLE_RELEASE(pTypeInfo);
7985 if (FAILED(hr))
7986 return hr;
7987
7988 if (!pitf) {
7989 hr = pTypeLib->lpVtbl->GetTypeInfoOfGuid(pTypeLib,
7990 piid,
7991 ppTypeInfo);
7992 OLE_RELEASE(pTypeLib);
7993 return hr;
7994 }
7995 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
7996 for (index = 0; index < count; index++) {
7997 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib,
7998 index,
7999 &pTypeInfo);
8000 if (FAILED(hr))
8001 break;
8002 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
8003
8004 if(FAILED(hr)) {
8005 OLE_RELEASE(pTypeInfo);
8006 break;
8007 }
8008 if(pTypeAttr->typekind == TKIND_COCLASS) {
8009 for (type = 0; type < pTypeAttr->cImplTypes; type++) {
8010 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
8011 type,
8012 &RefType);
8013 if (FAILED(hr))
8014 break;
8015 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
8016 RefType,
8017 &pImplTypeInfo);
8018 if (FAILED(hr))
8019 break;
8020
8021 hr = pImplTypeInfo->lpVtbl->GetDocumentation(pImplTypeInfo,
8022 -1,
8023 &bstr,
8024 NULL, NULL, NULL);
8025 if (FAILED(hr)) {
8026 OLE_RELEASE(pImplTypeInfo);
8027 break;
8028 }
8029 pstr = ole_wc2mb(bstr);
8030 if (strcmp(pitf, pstr) == 0) {
8031 hr = pImplTypeInfo->lpVtbl->GetTypeAttr(pImplTypeInfo,
8032 &pImplTypeAttr);
8033 if (SUCCEEDED(hr)) {
8034 is_found = TRUE;
8035 *piid = pImplTypeAttr->guid;
8036 if (ppTypeInfo) {
8037 *ppTypeInfo = pImplTypeInfo;
8038 (*ppTypeInfo)->lpVtbl->AddRef((*ppTypeInfo));
8039 }
8040 pImplTypeInfo->lpVtbl->ReleaseTypeAttr(pImplTypeInfo,
8041 pImplTypeAttr);
8042 }
8043 }
8044 free(pstr);
8045 OLE_RELEASE(pImplTypeInfo);
8046 if (is_found || FAILED(hr))
8047 break;
8048 }
8049 }
8050
8051 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
8052 OLE_RELEASE(pTypeInfo);
8053 if (is_found || FAILED(hr))
8054 break;
8055 }
8056 OLE_RELEASE(pTypeLib);
8057 if(!is_found)
8058 return E_NOINTERFACE;
8059 return hr;
8060 }
8061
8062 static HRESULT
8063 find_coclass(
8064 ITypeInfo *pTypeInfo,
8065 TYPEATTR *pTypeAttr,
8066 ITypeInfo **pCOTypeInfo,
8067 TYPEATTR **pCOTypeAttr)
8068 {
8069 HRESULT hr = E_NOINTERFACE;
8070 ITypeLib *pTypeLib;
8071 int count;
8072 BOOL found = FALSE;
8073 ITypeInfo *pTypeInfo2;
8074 TYPEATTR *pTypeAttr2;
8075 int flags;
8076 int i,j;
8077 HREFTYPE href;
8078 ITypeInfo *pRefTypeInfo;
8079 TYPEATTR *pRefTypeAttr;
8080
8081 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, NULL);
8082 if (FAILED(hr)) {
8083 return hr;
8084 }
8085 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
8086 for (i = 0; i < count && !found; i++) {
8087 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo2);
8088 if (FAILED(hr))
8089 continue;
8090 hr = OLE_GET_TYPEATTR(pTypeInfo2, &pTypeAttr2);
8091 if (FAILED(hr)) {
8092 OLE_RELEASE(pTypeInfo2);
8093 continue;
8094 }
8095 if (pTypeAttr2->typekind != TKIND_COCLASS) {
8096 OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
8097 OLE_RELEASE(pTypeInfo2);
8098 continue;
8099 }
8100 for (j = 0; j < pTypeAttr2->cImplTypes && !found; j++) {
8101 hr = pTypeInfo2->lpVtbl->GetImplTypeFlags(pTypeInfo2, j, &flags);
8102 if (FAILED(hr))
8103 continue;
8104 if (!(flags & IMPLTYPEFLAG_FDEFAULT))
8105 continue;
8106 hr = pTypeInfo2->lpVtbl->GetRefTypeOfImplType(pTypeInfo2, j, &href);
8107 if (FAILED(hr))
8108 continue;
8109 hr = pTypeInfo2->lpVtbl->GetRefTypeInfo(pTypeInfo2, href, &pRefTypeInfo);
8110 if (FAILED(hr))
8111 continue;
8112 hr = OLE_GET_TYPEATTR(pRefTypeInfo, &pRefTypeAttr);
8113 if (FAILED(hr)) {
8114 OLE_RELEASE(pRefTypeInfo);
8115 continue;
8116 }
8117 if (IsEqualGUID(&(pTypeAttr->guid), &(pRefTypeAttr->guid))) {
8118 found = TRUE;
8119 }
8120 }
8121 if (!found) {
8122 OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
8123 OLE_RELEASE(pTypeInfo2);
8124 }
8125 }
8126 OLE_RELEASE(pTypeLib);
8127 if (found) {
8128 *pCOTypeInfo = pTypeInfo2;
8129 *pCOTypeAttr = pTypeAttr2;
8130 hr = S_OK;
8131 } else {
8132 hr = E_NOINTERFACE;
8133 }
8134 return hr;
8135 }
8136
8137 static HRESULT
8138 find_default_source_from_typeinfo(
8139 ITypeInfo *pTypeInfo,
8140 TYPEATTR *pTypeAttr,
8141 ITypeInfo **ppTypeInfo)
8142 {
8143 int i = 0;
8144 HRESULT hr = E_NOINTERFACE;
8145 int flags;
8146 HREFTYPE hRefType;
8147 /* Enumerate all implemented types of the COCLASS */
8148 for (i = 0; i < pTypeAttr->cImplTypes; i++) {
8149 hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
8150 if (FAILED(hr))
8151 continue;
8152
8153 /*
8154 looking for the [default] [source]
8155 we just hope that it is a dispinterface :-)
8156 */
8157 if ((flags & IMPLTYPEFLAG_FDEFAULT) &&
8158 (flags & IMPLTYPEFLAG_FSOURCE)) {
8159
8160 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
8161 i, &hRefType);
8162 if (FAILED(hr))
8163 continue;
8164 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
8165 hRefType, ppTypeInfo);
8166 if (SUCCEEDED(hr))
8167 break;
8168 }
8169 }
8170 return hr;
8171 }
8172
8173 static HRESULT
8174 find_default_source(VALUE ole, IID *piid, ITypeInfo **ppTypeInfo)
8175 {
8176 HRESULT hr;
8177 IProvideClassInfo2 *pProvideClassInfo2;
8178 IProvideClassInfo *pProvideClassInfo;
8179 void *p;
8180
8181 IDispatch *pDispatch;
8182 ITypeInfo *pTypeInfo;
8183 ITypeInfo *pTypeInfo2 = NULL;
8184 TYPEATTR *pTypeAttr;
8185 TYPEATTR *pTypeAttr2 = NULL;
8186
8187 struct oledata *pole;
8188
8189 OLEData_Get_Struct(ole, pole);
8190 pDispatch = pole->pDispatch;
8191 hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
8192 &IID_IProvideClassInfo2,
8193 &p);
8194 if (SUCCEEDED(hr)) {
8195 pProvideClassInfo2 = p;
8196 hr = pProvideClassInfo2->lpVtbl->GetGUID(pProvideClassInfo2,
8197 GUIDKIND_DEFAULT_SOURCE_DISP_IID,
8198 piid);
8199 OLE_RELEASE(pProvideClassInfo2);
8200 if (SUCCEEDED(hr)) {
8201 hr = find_iid(ole, NULL, piid, ppTypeInfo);
8202 }
8203 }
8204 if (SUCCEEDED(hr)) {
8205 return hr;
8206 }
8207 hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
8208 &IID_IProvideClassInfo,
8209 &p);
8210 if (SUCCEEDED(hr)) {
8211 pProvideClassInfo = p;
8212 hr = pProvideClassInfo->lpVtbl->GetClassInfo(pProvideClassInfo,
8213 &pTypeInfo);
8214 OLE_RELEASE(pProvideClassInfo);
8215 }
8216 if (FAILED(hr)) {
8217 hr = pDispatch->lpVtbl->GetTypeInfo(pDispatch, 0, cWIN32OLE_lcid, &pTypeInfo );
8218 }
8219 if (FAILED(hr))
8220 return hr;
8221 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
8222 if (FAILED(hr)) {
8223 OLE_RELEASE(pTypeInfo);
8224 return hr;
8225 }
8226
8227 *ppTypeInfo = 0;
8228 hr = find_default_source_from_typeinfo(pTypeInfo, pTypeAttr, ppTypeInfo);
8229 if (!*ppTypeInfo) {
8230 hr = find_coclass(pTypeInfo, pTypeAttr, &pTypeInfo2, &pTypeAttr2);
8231 if (SUCCEEDED(hr)) {
8232 hr = find_default_source_from_typeinfo(pTypeInfo2, pTypeAttr2, ppTypeInfo);
8233 OLE_RELEASE_TYPEATTR(pTypeInfo2, pTypeAttr2);
8234 OLE_RELEASE(pTypeInfo2);
8235 }
8236 }
8237 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
8238 OLE_RELEASE(pTypeInfo);
8239 /* Now that would be a bad surprise, if we didn't find it, wouldn't it? */
8240 if (!*ppTypeInfo) {
8241 if (SUCCEEDED(hr))
8242 hr = E_UNEXPECTED;
8243 return hr;
8244 }
8245
8246 /* Determine IID of default source interface */
8247 hr = (*ppTypeInfo)->lpVtbl->GetTypeAttr(*ppTypeInfo, &pTypeAttr);
8248 if (SUCCEEDED(hr)) {
8249 *piid = pTypeAttr->guid;
8250 (*ppTypeInfo)->lpVtbl->ReleaseTypeAttr(*ppTypeInfo, pTypeAttr);
8251 }
8252 else
8253 OLE_RELEASE(*ppTypeInfo);
8254
8255 return hr;
8256
8257 }
8258
8259 static void
8260 ole_event_free(struct oleeventdata *poleev)
8261 {
8262 if (poleev->pConnectionPoint) {
8263 poleev->pConnectionPoint->lpVtbl->Unadvise(poleev->pConnectionPoint, poleev->dwCookie);
8264 OLE_RELEASE(poleev->pConnectionPoint);
8265 poleev->pConnectionPoint = NULL;
8266 }
8267 free(poleev);
8268 }
8269
8270 static VALUE
8271 fev_s_allocate(VALUE klass)
8272 {
8273 VALUE obj;
8274 struct oleeventdata *poleev;
8275 obj = Data_Make_Struct(klass,struct oleeventdata,0,ole_event_free,poleev);
8276 poleev->dwCookie = 0;
8277 poleev->pConnectionPoint = NULL;
8278 poleev->event_id = 0;
8279 return obj;
8280 }
8281
8282 static VALUE
8283 ev_advise(int argc, VALUE *argv, VALUE self)
8284 {
8285
8286 VALUE ole, itf;
8287 struct oledata *pole;
8288 char *pitf;
8289 HRESULT hr;
8290 IID iid;
8291 ITypeInfo *pTypeInfo = 0;
8292 IDispatch *pDispatch;
8293 IConnectionPointContainer *pContainer;
8294 IConnectionPoint *pConnectionPoint;
8295 IEVENTSINKOBJ *pIEV;
8296 DWORD dwCookie;
8297 struct oleeventdata *poleev;
8298 void *p;
8299
8300 rb_secure(4);
8301 rb_scan_args(argc, argv, "11", &ole, &itf);
8302
8303 if (!rb_obj_is_kind_of(ole, cWIN32OLE)) {
8304 rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE object");
8305 }
8306
8307 if(TYPE(itf) != T_NIL) {
8308 if (rb_safe_level() > 0 && OBJ_TAINTED(itf)) {
8309 rb_raise(rb_eSecurityError, "Insecure Event Creation - %s",
8310 StringValuePtr(itf));
8311 }
8312 SafeStringValue(itf);
8313 pitf = StringValuePtr(itf);
8314 hr = find_iid(ole, pitf, &iid, &pTypeInfo);
8315 }
8316 else {
8317 hr = find_default_source(ole, &iid, &pTypeInfo);
8318 }
8319 if (FAILED(hr)) {
8320 ole_raise(hr, rb_eRuntimeError, "interface not found");
8321 }
8322
8323 OLEData_Get_Struct(ole, pole);
8324 pDispatch = pole->pDispatch;
8325 hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
8326 &IID_IConnectionPointContainer,
8327 &p);
8328 if (FAILED(hr)) {
8329 OLE_RELEASE(pTypeInfo);
8330 ole_raise(hr, rb_eRuntimeError,
8331 "failed to query IConnectionPointContainer");
8332 }
8333 pContainer = p;
8334
8335 hr = pContainer->lpVtbl->FindConnectionPoint(pContainer,
8336 &iid,
8337 &pConnectionPoint);
8338 OLE_RELEASE(pContainer);
8339 if (FAILED(hr)) {
8340 OLE_RELEASE(pTypeInfo);
8341 ole_raise(hr, rb_eRuntimeError, "failed to query IConnectionPoint");
8342 }
8343 pIEV = EVENTSINK_Constructor();
8344 pIEV->m_iid = iid;
8345 hr = pConnectionPoint->lpVtbl->Advise(pConnectionPoint,
8346 (IUnknown*)pIEV,
8347 &dwCookie);
8348 if (FAILED(hr)) {
8349 ole_raise(hr, rb_eRuntimeError, "Advise Error");
8350 }
8351
8352 Data_Get_Struct(self, struct oleeventdata, poleev);
8353 pIEV->m_event_id
8354 = NUM2INT(evs_length());
8355 pIEV->pTypeInfo = pTypeInfo;
8356 poleev->dwCookie = dwCookie;
8357 poleev->pConnectionPoint = pConnectionPoint;
8358 poleev->event_id = pIEV->m_event_id;
8359
8360 return self;
8361 }
8362
8363 /*
8364 * call-seq:
8365 * WIN32OLE_EVENT.new(ole, event) #=> WIN32OLE_EVENT object.
8366 *
8367 * Returns OLE event object.
8368 * The first argument specifies WIN32OLE object.
8369 * The second argument specifies OLE event name.
8370 * ie = WIN32OLE.new('InternetExplorer.Application')
8371 * ev = WIN32OLE_EVENT.new(ie, 'DWebBrowserEvents')
8372 */
8373 static VALUE
8374 fev_initialize(int argc, VALUE *argv, VALUE self)
8375 {
8376 ev_advise(argc, argv, self);
8377 evs_push(self);
8378 rb_ivar_set(self, id_events, rb_ary_new());
8379 fev_set_handler(self, Qnil);
8380 return self;
8381 }
8382
8383 /*
8384 * call-seq:
8385 * WIN32OLE_EVENT.message_loop
8386 *
8387 * Translates and dispatches Windows message.
8388 */
8389 static VALUE
8390 fev_s_msg_loop(VALUE klass)
8391 {
8392 ole_msg_loop();
8393 return Qnil;
8394 }
8395
8396
8397 static void
8398 add_event_call_back(VALUE obj, VALUE event, VALUE data)
8399 {
8400 VALUE events = rb_ivar_get(obj, id_events);
8401 if (NIL_P(events) || TYPE(events) != T_ARRAY) {
8402 events = rb_ary_new();
8403 rb_ivar_set(obj, id_events, events);
8404 }
8405 ole_delete_event(events, event);
8406 rb_ary_push(events, data);
8407 }
8408
8409 static VALUE
8410 ev_on_event(int argc, VALUE *argv, VALUE self, VALUE is_ary_arg)
8411 {
8412 struct oleeventdata *poleev;
8413 VALUE event, args, data;
8414 Data_Get_Struct(self, struct oleeventdata, poleev);
8415 if (poleev->pConnectionPoint == NULL) {
8416 rb_raise(eWIN32OLERuntimeError, "IConnectionPoint not found. You must call advise at first.");
8417 }
8418 rb_scan_args(argc, argv, "01*", &event, &args);
8419 if(!NIL_P(event)) {
8420 if(TYPE(event) != T_STRING && TYPE(event) != T_SYMBOL) {
8421 rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
8422 }
8423 if (TYPE(event) == T_SYMBOL) {
8424 event = rb_sym_to_s(event);
8425 }
8426 }
8427 data = rb_ary_new3(4, rb_block_proc(), event, args, is_ary_arg);
8428 add_event_call_back(self, event, data);
8429 return Qnil;
8430 }
8431
8432 /*
8433 * call-seq:
8434 * WIN32OLE_EVENT#on_event([event]){...}
8435 *
8436 * Defines the callback event.
8437 * If argument is omitted, this method defines the callback of all events.
8438 * If you want to modify reference argument in callback, return hash in
8439 * callback. If you want to return value to OLE server as result of callback
8440 * use `return' or :return.
8441 *
8442 * ie = WIN32OLE.new('InternetExplorer.Application')
8443 * ev = WIN32OLE_EVENT.new(ie)
8444 * ev.on_event("NavigateComplete") {|url| puts url}
8445 * ev.on_event() {|ev, *args| puts "#{ev} fired"}
8446 *
8447 * ev.on_event("BeforeNavigate2") {|*args|
8448 * ...
8449 * # set true to BeforeNavigate reference argument `Cancel'.
8450 * # Cancel is 7-th argument of BeforeNavigate,
8451 * # so you can use 6 as key of hash instead of 'Cancel'.
8452 * # The argument is counted from 0.
8453 * # The hash key of 0 means first argument.)
8454 * {:Cancel => true} # or {'Cancel' => true} or {6 => true}
8455 * }
8456 *
8457 * ev.on_event(...) {|*args|
8458 * {:return => 1, :xxx => yyy}
8459 * }
8460 */
8461 static VALUE
8462 fev_on_event(int argc, VALUE *argv, VALUE self)
8463 {
8464 return ev_on_event(argc, argv, self, Qfalse);
8465 }
8466
8467 /*
8468 * call-seq:
8469 * WIN32OLE_EVENT#on_event_with_outargs([event]){...}
8470 *
8471 * Defines the callback of event.
8472 * If you want modify argument in callback,
8473 * you could use this method instead of WIN32OLE_EVENT#on_event.
8474 *
8475 * ie = WIN32OLE.new('InternetExplorer.Application')
8476 * ev = WIN32OLE_EVENT.new(ie)
8477 * ev.on_event_with_outargs('BeforeNavigate2') {|*args|
8478 * args.last[6] = true
8479 * }
8480 */
8481 static VALUE
8482 fev_on_event_with_outargs(int argc, VALUE *argv, VALUE self)
8483 {
8484 return ev_on_event(argc, argv, self, Qtrue);
8485 }
8486
8487 /*
8488 * call-seq:
8489 * WIN32OLE_EVENT#off_event([event])
8490 *
8491 * removes the callback of event.
8492 *
8493 * ie = WIN32OLE.new('InternetExplorer.Application')
8494 * ev = WIN32OLE_EVENT.new(ie)
8495 * ev.on_event('BeforeNavigate2') {|*args|
8496 * args.last[6] = true
8497 * }
8498 * ...
8499 * ev.off_event('BeforeNavigate2')
8500 * ...
8501 */
8502 static VALUE
8503 fev_off_event(int argc, VALUE *argv, VALUE self)
8504 {
8505 VALUE event = Qnil;
8506 VALUE events;
8507
8508 rb_secure(4);
8509 rb_scan_args(argc, argv, "01", &event);
8510 if(!NIL_P(event)) {
8511 if(TYPE(event) != T_STRING && TYPE(event) != T_SYMBOL) {
8512 rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
8513 }
8514 if (TYPE(event) == T_SYMBOL) {
8515 event = rb_sym_to_s(event);
8516 }
8517 }
8518 events = rb_ivar_get(self, id_events);
8519 if (NIL_P(events)) {
8520 return Qnil;
8521 }
8522 ole_delete_event(events, event);
8523 return Qnil;
8524 }
8525
8526 /*
8527 * call-seq:
8528 * WIN32OLE_EVENT#unadvise -> nil
8529 *
8530 * disconnects OLE server. If this method called, then the WIN32OLE_EVENT object
8531 * does not receive the OLE server event any more.
8532 * This method is trial implementation.
8533 *
8534 * ie = WIN32OLE.new('InternetExplorer.Application')
8535 * ev = WIN32OLE_EVENT.new(ie)
8536 * ev.on_event() {...}
8537 * ...
8538 * ev.unadvise
8539 *
8540 */
8541 static VALUE
8542 fev_unadvise(VALUE self)
8543 {
8544 struct oleeventdata *poleev;
8545 Data_Get_Struct(self, struct oleeventdata, poleev);
8546 if (poleev->pConnectionPoint) {
8547 ole_msg_loop();
8548 evs_delete(poleev->event_id);
8549 poleev->pConnectionPoint->lpVtbl->Unadvise(poleev->pConnectionPoint, poleev->dwCookie);
8550 OLE_RELEASE(poleev->pConnectionPoint);
8551 poleev->pConnectionPoint = NULL;
8552 }
8553 return Qnil;
8554 }
8555
8556 static VALUE
8557 evs_push(VALUE ev)
8558 {
8559 return rb_ary_push(ary_ole_event, ev);
8560 }
8561
8562 static VALUE
8563 evs_delete(long i)
8564 {
8565 rb_ary_store(ary_ole_event, i, Qnil);
8566 return Qnil;
8567 }
8568
8569 static VALUE
8570 evs_entry(long i)
8571 {
8572 return rb_ary_entry(ary_ole_event, i);
8573 }
8574
8575 static VALUE
8576 evs_length(void)
8577 {
8578 return rb_funcall(ary_ole_event, rb_intern("length"), 0);
8579 }
8580
8581 /*
8582 * call-seq:
8583 * WIN32OLE_EVENT#handler=
8584 *
8585 * sets event handler object. If handler object has onXXX
8586 * method according to XXX event, then onXXX method is called
8587 * when XXX event occurs.
8588 *
8589 * If handler object has method_missing and there is no
8590 * method according to the event, then method_missing
8591 * called and 1-st argument is event name.
8592 *
8593 * If handler object has onXXX method and there is block
8594 * defined by WIN32OLE_EVENT#on_event('XXX'){},
8595 * then block is executed but handler object method is not called
8596 * when XXX event occurs.
8597 *
8598 * class Handler
8599 * def onStatusTextChange(text)
8600 * puts "StatusTextChanged"
8601 * end
8602 * def onPropertyChange(prop)
8603 * puts "PropertyChanged"
8604 * end
8605 * def method_missing(ev, *arg)
8606 * puts "other event #{ev}"
8607 * end
8608 * end
8609 *
8610 * handler = Handler.new
8611 * ie = WIN32OLE.new('InternetExplorer.Application')
8612 * ev = WIN32OLE_EVENT.new(ie)
8613 * ev.on_event("StatusTextChange") {|*args|
8614 * puts "this block executed."
8615 * puts "handler.onStatusTextChange method is not called."
8616 * }
8617 * ev.handler = handler
8618 *
8619 */
8620 static VALUE
8621 fev_set_handler(VALUE self, VALUE val)
8622 {
8623 return rb_ivar_set(self, rb_intern("handler"), val);
8624 }
8625
8626 /*
8627 * call-seq:
8628 * WIN32OLE_EVENT#handler
8629 *
8630 * returns handler object.
8631 *
8632 */
8633 static VALUE
8634 fev_get_handler(VALUE self)
8635 {
8636 return rb_ivar_get(self, rb_intern("handler"));
8637 }
8638
8639 static void
8640 olevariant_free(struct olevariantdata *pvar)
8641 {
8642 VariantClear(&(pvar->realvar));
8643 VariantClear(&(pvar->var));
8644 free(pvar);
8645 }
8646
8647 static VALUE
8648 folevariant_s_allocate(VALUE klass)
8649 {
8650 struct olevariantdata *pvar;
8651 VALUE obj;
8652 ole_initialize();
8653 obj = Data_Make_Struct(klass,struct olevariantdata,0,olevariant_free,pvar);
8654 VariantInit(&(pvar->var));
8655 VariantInit(&(pvar->realvar));
8656 return obj;
8657 }
8658
8659 /*
8660 * call-seq:
8661 * WIN32OLE_VARIANT.array(ary, vt)
8662 *
8663 * Returns Ruby object wrapping OLE variant whose variant type is VT_ARRAY.
8664 * The first argument should be Array object which specifies dimensions
8665 * and each size of dimensions of OLE array.
8666 * The second argument specifies variant type of the element of OLE array.
8667 *
8668 * The following create 2 dimensions OLE array. The first dimensions size
8669 * is 3, and the second is 4.
8670 *
8671 * ole_ary = WIN32OLE_VARIANT.array([3,4], VT_I4)
8672 * ruby_ary = ole_ary.value # => [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
8673 *
8674 */
8675 static VALUE
8676 folevariant_s_array(VALUE klass, VALUE elems, VALUE vvt)
8677 {
8678 VALUE obj = Qnil;
8679 VARTYPE vt;
8680 struct olevariantdata *pvar;
8681 SAFEARRAYBOUND *psab = NULL;
8682 SAFEARRAY *psa = NULL;
8683 UINT dim = 0;
8684 UINT i = 0;
8685
8686 ole_initialize();
8687
8688 vt = NUM2UINT(vvt);
8689 vt = (vt | VT_ARRAY);
8690 Check_Type(elems, T_ARRAY);
8691 obj = folevariant_s_allocate(klass);
8692
8693 Data_Get_Struct(obj, struct olevariantdata, pvar);
8694 dim = RARRAY_LEN(elems);
8695
8696 psab = ALLOC_N(SAFEARRAYBOUND, dim);
8697
8698 if(!psab) {
8699 rb_raise(rb_eRuntimeError, "memory allocation error");
8700 }
8701
8702 for (i = 0; i < dim; i++) {
8703 psab[i].cElements = FIX2INT(rb_ary_entry(elems, i));
8704 psab[i].lLbound = 0;
8705 }
8706
8707 psa = SafeArrayCreate((VARTYPE)(vt & VT_TYPEMASK), dim, psab);
8708 if (psa == NULL) {
8709 if (psab) free(psab);
8710 rb_raise(rb_eRuntimeError, "memory allocation error(SafeArrayCreate)");
8711 }
8712
8713 V_VT(&(pvar->var)) = vt;
8714 if (vt & VT_BYREF) {
8715 V_VT(&(pvar->realvar)) = (vt & ~VT_BYREF);
8716 V_ARRAY(&(pvar->realvar)) = psa;
8717 V_ARRAYREF(&(pvar->var)) = &(V_ARRAY(&(pvar->realvar)));
8718 } else {
8719 V_ARRAY(&(pvar->var)) = psa;
8720 }
8721 if (psab) free(psab);
8722 return obj;
8723 }
8724
8725 /*
8726 * call-seq:
8727 * WIN32OLE_VARIANT.new(val, vartype) #=> WIN32OLE_VARIANT object.
8728 *
8729 * Returns Ruby object wrapping OLE variant.
8730 * The first argument specifies Ruby object to convert OLE variant variable.
8731 * The second argument specifies VARIANT type.
8732 * In some situation, you need the WIN32OLE_VARIANT object to pass OLE method
8733 *
8734 * shell = WIN32OLE.new("Shell.Application")
8735 * folder = shell.NameSpace("C:\\Windows")
8736 * item = folder.ParseName("tmp.txt")
8737 * # You can't use Ruby String object to call FolderItem.InvokeVerb.
8738 * # Instead, you have to use WIN32OLE_VARIANT object to call the method.
8739 * shortcut = WIN32OLE_VARIANT.new("Create Shortcut(\&S)")
8740 * item.invokeVerb(shortcut)
8741 *
8742 */
8743 static VALUE
8744 folevariant_initialize(VALUE self, VALUE args)
8745 {
8746 int len = 0;
8747 VARIANT var;
8748 VALUE val;
8749 VALUE vvt;
8750 VARTYPE vt;
8751 struct olevariantdata *pvar;
8752
8753 len = RARRAY_LEN(args);
8754 if (len < 1 || len > 3) {
8755 rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..3)", len);
8756 }
8757 VariantInit(&var);
8758 val = rb_ary_entry(args, 0);
8759
8760 if(!rb_obj_is_kind_of(val, cWIN32OLE) &&
8761 !rb_obj_is_kind_of(val, cWIN32OLE_VARIANT) &&
8762 !rb_obj_is_kind_of(val, rb_cTime)) {
8763 switch (TYPE(val)) {
8764 case T_ARRAY:
8765 case T_STRING:
8766 case T_FIXNUM:
8767 case T_BIGNUM:
8768 case T_FLOAT:
8769 case T_TRUE:
8770 case T_FALSE:
8771 case T_NIL:
8772 break;
8773 default:
8774 rb_raise(rb_eTypeError, "can not convert WIN32OLE_VARIANT from type %s",
8775 rb_obj_classname(val));
8776 }
8777 }
8778
8779 Data_Get_Struct(self, struct olevariantdata, pvar);
8780 if (len == 1) {
8781 ole_val2variant(val, &(pvar->var));
8782 } else {
8783 vvt = rb_ary_entry(args, 1);
8784 vt = NUM2INT(vvt);
8785 ole_val2olevariantdata(val, vt, pvar);
8786 }
8787 vt = V_VT(&pvar->var);
8788 return self;
8789 }
8790
8791 static SAFEARRAY *
8792 get_locked_safe_array(VALUE val)
8793 {
8794 struct olevariantdata *pvar;
8795 SAFEARRAY *psa = NULL;
8796 HRESULT hr;
8797 Data_Get_Struct(val, struct olevariantdata, pvar);
8798 if (!(V_VT(&(pvar->var)) & VT_ARRAY)) {
8799 rb_raise(rb_eTypeError, "variant type is not VT_ARRAY.");
8800 }
8801 psa = V_ISBYREF(&(pvar->var)) ? *V_ARRAYREF(&(pvar->var)) : V_ARRAY(&(pvar->var));
8802 if (psa == NULL) {
8803 return psa;
8804 }
8805 hr = SafeArrayLock(psa);
8806 if (FAILED(hr)) {
8807 ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayLock");
8808 }
8809 return psa;
8810 }
8811
8812 static long *
8813 ary2safe_array_index(int ary_size, VALUE *ary, SAFEARRAY *psa)
8814 {
8815 long dim;
8816 long *pid;
8817 long i;
8818 dim = SafeArrayGetDim(psa);
8819 if (dim != ary_size) {
8820 rb_raise(rb_eArgError, "unmatch number of indices");
8821 }
8822 pid = ALLOC_N(long, dim);
8823 if (pid == NULL) {
8824 rb_raise(rb_eRuntimeError, "failed to allocate memory for indices");
8825 }
8826 for (i = 0; i < dim; i++) {
8827 pid[i] = NUM2INT(ary[i]);
8828 }
8829 return pid;
8830 }
8831
8832 static void
8833 unlock_safe_array(SAFEARRAY *psa)
8834 {
8835 HRESULT hr;
8836 hr = SafeArrayUnlock(psa);
8837 if (FAILED(hr)) {
8838 ole_raise(hr, rb_eRuntimeError, "failed to SafeArrayUnlock");
8839 }
8840 }
8841
8842 /*
8843 * call-seq:
8844 * WIN32OLE_VARIANT[i,j,...] #=> element of OLE array.
8845 *
8846 * Returns the element of WIN32OLE_VARIANT object(OLE array).
8847 * This method is available only when the variant type of
8848 * WIN32OLE_VARIANT object is VT_ARRAY.
8849 *
8850 * REMARK:
8851 * The all indicies should be 0 or natural number and
8852 * lower than or equal to max indicies.
8853 * (This point is different with Ruby Array indicies.)
8854 *
8855 * obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]])
8856 * p obj[0,0] # => 1
8857 * p obj[1,0] # => 4
8858 * p obj[2,0] # => WIN32OLERuntimeError
8859 * p obj[0, -1] # => WIN32OLERuntimeError
8860 *
8861 */
8862 static VALUE
8863 folevariant_ary_aref(int argc, VALUE *argv, VALUE self)
8864 {
8865 struct olevariantdata *pvar;
8866 SAFEARRAY *psa;
8867 VALUE val = Qnil;
8868 VARIANT variant;
8869 long *pid;
8870 HRESULT hr;
8871
8872 Data_Get_Struct(self, struct olevariantdata, pvar);
8873 if (!V_ISARRAY(&(pvar->var))) {
8874 rb_raise(eWIN32OLERuntimeError,
8875 "`[]' is not available for this variant type object");
8876 }
8877 psa = get_locked_safe_array(self);
8878 if (psa == NULL) {
8879 return val;
8880 }
8881
8882 pid = ary2safe_array_index(argc, argv, psa);
8883
8884 VariantInit(&variant);
8885 V_VT(&variant) = (V_VT(&(pvar->var)) & ~VT_ARRAY) | VT_BYREF;
8886 hr = SafeArrayPtrOfIndex(psa, pid, &V_BYREF(&variant));
8887 if (FAILED(hr)) {
8888 ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPtrOfIndex");
8889 }
8890 val = ole_variant2val(&variant);
8891
8892 unlock_safe_array(psa);
8893 if (pid) free(pid);
8894 return val;
8895 }
8896
8897 static VOID *
8898 val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt)
8899 {
8900 VOID *p = NULL;
8901 HRESULT hr = S_OK;
8902 ole_val2variant_ex(val, var, vt);
8903 if ((vt & ~VT_BYREF) == VT_VARIANT) {
8904 p = var;
8905 } else {
8906 if ( (vt & ~VT_BYREF) != V_VT(var)) {
8907 hr = VariantChangeTypeEx(var, var,
8908 cWIN32OLE_lcid, 0, (VARTYPE)(vt & ~VT_BYREF));
8909 if (FAILED(hr)) {
8910 ole_raise(hr, rb_eRuntimeError, "failed to change type");
8911 }
8912 }
8913 p = get_ptr_of_variant(var);
8914 }
8915 if (p == NULL) {
8916 rb_raise(rb_eRuntimeError, "failed to get pointer of variant");
8917 }
8918 return p;
8919 }
8920
8921 /*
8922 * call-seq:
8923 * WIN32OLE_VARIANT[i,j,...] = val #=> set the element of OLE array
8924 *
8925 * Set the element of WIN32OLE_VARIANT object(OLE array) to val.
8926 * This method is available only when the variant type of
8927 * WIN32OLE_VARIANT object is VT_ARRAY.
8928 *
8929 * REMARK:
8930 * The all indicies should be 0 or natural number and
8931 * lower than or equal to max indicies.
8932 * (This point is different with Ruby Array indicies.)
8933 *
8934 * obj = WIN32OLE_VARIANT.new([[1,2,3],[4,5,6]])
8935 * obj[0,0] = 7
8936 * obj[1,0] = 8
8937 * p obj.value # => [[7,2,3], [8,5,6]]
8938 * obj[2,0] = 9 # => WIN32OLERuntimeError
8939 * obj[0, -1] = 9 # => WIN32OLERuntimeError
8940 *
8941 */
8942 static VALUE
8943 folevariant_ary_aset(int argc, VALUE *argv, VALUE self)
8944 {
8945 struct olevariantdata *pvar;
8946 SAFEARRAY *psa;
8947 VARIANT var;
8948 VARTYPE vt;
8949 long *pid;
8950 HRESULT hr;
8951 VOID *p = NULL;
8952
8953 Data_Get_Struct(self, struct olevariantdata, pvar);
8954 if (!V_ISARRAY(&(pvar->var))) {
8955 rb_raise(eWIN32OLERuntimeError,
8956 "`[]' is not available for this variant type object");
8957 }
8958 psa = get_locked_safe_array(self);
8959 if (psa == NULL) {
8960 rb_raise(rb_eRuntimeError, "failed to get SafeArray pointer");
8961 }
8962
8963 pid = ary2safe_array_index(argc-1, argv, psa);
8964
8965 VariantInit(&var);
8966 vt = (V_VT(&(pvar->var)) & ~VT_ARRAY);
8967 p = val2variant_ptr(argv[argc-1], &var, vt);
8968 if ((V_VT(&var) == VT_DISPATCH && V_DISPATCH(&var) == NULL) ||
8969 (V_VT(&var) == VT_UNKNOWN && V_UNKNOWN(&var) == NULL)) {
8970 rb_raise(eWIN32OLERuntimeError, "argument does not have IDispatch or IUnknown Interface");
8971 }
8972 hr = SafeArrayPutElement(psa, pid, p);
8973 if (FAILED(hr)) {
8974 ole_raise(hr, eWIN32OLERuntimeError, "failed to SafeArrayPutElement");
8975 }
8976
8977 unlock_safe_array(psa);
8978 if (pid) free(pid);
8979 return argv[argc-1];
8980 }
8981
8982 /*
8983 * call-seq:
8984 * WIN32OLE_VARIANT.value #=> Ruby object.
8985 *
8986 * Returns Ruby object value from OLE variant.
8987 * obj = WIN32OLE_VARIANT.new(1, WIN32OLE::VARIANT::VT_BSTR)
8988 * obj.value # => "1" (not Fixnum object, but String object "1")
8989 *
8990 */
8991 static VALUE
8992 folevariant_value(VALUE self)
8993 {
8994 struct olevariantdata *pvar;
8995 VALUE val = Qnil;
8996 VARTYPE vt;
8997 int dim;
8998 SAFEARRAY *psa;
8999 Data_Get_Struct(self, struct olevariantdata, pvar);
9000
9001 val = ole_variant2val(&(pvar->var));
9002 vt = V_VT(&(pvar->var));
9003
9004 if ((vt & ~VT_BYREF) == (VT_UI1|VT_ARRAY)) {
9005 if (vt & VT_BYREF) {
9006 psa = *V_ARRAYREF(&(pvar->var));
9007 } else {
9008 psa = V_ARRAY(&(pvar->var));
9009 }
9010 if (!psa) {
9011 return val;
9012 }
9013 dim = SafeArrayGetDim(psa);
9014 if (dim == 1) {
9015 val = rb_funcall(val, rb_intern("pack"), 1, rb_str_new2("C*"));
9016 }
9017 }
9018 return val;
9019 }
9020
9021 /*
9022 * call-seq:
9023 * WIN32OLE_VARIANT.vartype #=> OLE variant type.
9024 *
9025 * Returns OLE variant type.
9026 * obj = WIN32OLE_VARIANT.new("string")
9027 * obj.vartype # => WIN32OLE::VARIANT::VT_BSTR
9028 *
9029 */
9030 static VALUE
9031 folevariant_vartype(VALUE self)
9032 {
9033 struct olevariantdata *pvar;
9034 Data_Get_Struct(self, struct olevariantdata, pvar);
9035 return INT2FIX(V_VT(&pvar->var));
9036 }
9037
9038 /*
9039 * call-seq:
9040 * WIN32OLE_VARIANT.value = val #=> set WIN32OLE_VARIANT value to val.
9041 *
9042 * Sets variant value to val. If the val type does not match variant value
9043 * type(vartype), then val is changed to match variant value type(vartype)
9044 * before setting val.
9045 * Thie method is not available when vartype is VT_ARRAY(except VT_UI1|VT_ARRAY).
9046 * If the vartype is VT_UI1|VT_ARRAY, the val should be String object.
9047 *
9048 * obj = WIN32OLE_VARIANT.new(1) # obj.vartype is WIN32OLE::VARIANT::VT_I4
9049 * obj.value = 3.2 # 3.2 is changed to 3 when setting value.
9050 * p obj.value # => 3
9051 */
9052 static VALUE
9053 folevariant_set_value(VALUE self, VALUE val)
9054 {
9055 struct olevariantdata *pvar;
9056 VARTYPE vt;
9057 Data_Get_Struct(self, struct olevariantdata, pvar);
9058 vt = V_VT(&(pvar->var));
9059 if (V_ISARRAY(&(pvar->var)) && ((vt & ~VT_BYREF) != (VT_UI1|VT_ARRAY) || TYPE(val) != T_STRING)) {
9060 rb_raise(eWIN32OLERuntimeError,
9061 "`value=' is not available for this variant type object");
9062 }
9063 ole_val2olevariantdata(val, vt, pvar);
9064 return Qnil;
9065 }
9066
9067 static void
9068 init_enc2cp(void)
9069 {
9070 enc2cp_table = st_init_numtable();
9071 }
9072
9073 static void
9074 free_enc2cp(void)
9075 {
9076 st_free_table(enc2cp_table);
9077 }
9078
9079 void
9080 Init_win32ole(void)
9081 {
9082 g_ole_initialized_init();
9083 ary_ole_event = rb_ary_new();
9084 rb_gc_register_mark_object(ary_ole_event);
9085 id_events = rb_intern("events");
9086
9087 com_vtbl.QueryInterface = QueryInterface;
9088 com_vtbl.AddRef = AddRef;
9089 com_vtbl.Release = Release;
9090 com_vtbl.GetTypeInfoCount = GetTypeInfoCount;
9091 com_vtbl.GetTypeInfo = GetTypeInfo;
9092 com_vtbl.GetIDsOfNames = GetIDsOfNames;
9093 com_vtbl.Invoke = Invoke;
9094
9095 message_filter.QueryInterface = mf_QueryInterface;
9096 message_filter.AddRef = mf_AddRef;
9097 message_filter.Release = mf_Release;
9098 message_filter.HandleInComingCall = mf_HandleInComingCall;
9099 message_filter.RetryRejectedCall = mf_RetryRejectedCall;
9100 message_filter.MessagePending = mf_MessagePending;
9101
9102 com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable());
9103 rb_gc_register_mark_object(com_hash);
9104
9105 cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject);
9106
9107 rb_define_alloc_func(cWIN32OLE, fole_s_allocate);
9108
9109 rb_define_method(cWIN32OLE, "initialize", fole_initialize, -1);
9110
9111 rb_define_singleton_method(cWIN32OLE, "connect", fole_s_connect, -1);
9112 rb_define_singleton_method(cWIN32OLE, "const_load", fole_s_const_load, -1);
9113
9114 rb_define_singleton_method(cWIN32OLE, "ole_free", fole_s_free, 1);
9115 rb_define_singleton_method(cWIN32OLE, "ole_reference_count", fole_s_reference_count, 1);
9116 rb_define_singleton_method(cWIN32OLE, "ole_show_help", fole_s_show_help, -1);
9117 rb_define_singleton_method(cWIN32OLE, "codepage", fole_s_get_code_page, 0);
9118 rb_define_singleton_method(cWIN32OLE, "codepage=", fole_s_set_code_page, 1);
9119 rb_define_singleton_method(cWIN32OLE, "locale", fole_s_get_locale, 0);
9120 rb_define_singleton_method(cWIN32OLE, "locale=", fole_s_set_locale, 1);
9121 rb_define_singleton_method(cWIN32OLE, "create_guid", fole_s_create_guid, 0);
9122 rb_define_singleton_method(cWIN32OLE, "ole_initialize", fole_s_ole_initialize, 0);
9123 rb_define_singleton_method(cWIN32OLE, "ole_uninitialize", fole_s_ole_uninitialize, 0);
9124
9125 rb_define_method(cWIN32OLE, "invoke", fole_invoke, -1);
9126 rb_define_method(cWIN32OLE, "[]", fole_getproperty_with_bracket, -1);
9127 rb_define_method(cWIN32OLE, "_invoke", fole_invoke2, 3);
9128 rb_define_method(cWIN32OLE, "_getproperty", fole_getproperty2, 3);
9129 rb_define_method(cWIN32OLE, "_setproperty", fole_setproperty2, 3);
9130
9131 /* support propput method that takes an argument */
9132 rb_define_method(cWIN32OLE, "[]=", fole_setproperty_with_bracket, -1);
9133
9134 rb_define_method(cWIN32OLE, "ole_free", fole_free, 0);
9135
9136 rb_define_method(cWIN32OLE, "each", fole_each, 0);
9137 rb_define_method(cWIN32OLE, "method_missing", fole_missing, -1);
9138
9139 /* support setproperty method much like Perl ;-) */
9140 rb_define_method(cWIN32OLE, "setproperty", fole_setproperty, -1);
9141
9142 rb_define_method(cWIN32OLE, "ole_methods", fole_methods, 0);
9143 rb_define_method(cWIN32OLE, "ole_get_methods", fole_get_methods, 0);
9144 rb_define_method(cWIN32OLE, "ole_put_methods", fole_put_methods, 0);
9145 rb_define_method(cWIN32OLE, "ole_func_methods", fole_func_methods, 0);
9146
9147 rb_define_method(cWIN32OLE, "ole_method", fole_method_help, 1);
9148 rb_define_alias(cWIN32OLE, "ole_method_help", "ole_method");
9149 rb_define_method(cWIN32OLE, "ole_activex_initialize", fole_activex_initialize, 0);
9150 rb_define_method(cWIN32OLE, "ole_type", fole_type, 0);
9151 rb_define_alias(cWIN32OLE, "ole_obj_help", "ole_type");
9152 rb_define_method(cWIN32OLE, "ole_typelib", fole_typelib, 0);
9153 rb_define_method(cWIN32OLE, "ole_query_interface", fole_query_interface, 1);
9154 rb_define_method(cWIN32OLE, "ole_respond_to?", fole_respond_to, 1);
9155
9156 rb_define_const(cWIN32OLE, "VERSION", rb_str_new2(WIN32OLE_VERSION));
9157 rb_define_const(cWIN32OLE, "ARGV", rb_ary_new());
9158
9159 rb_define_const(cWIN32OLE, "CP_ACP", INT2FIX(CP_ACP));
9160 rb_define_const(cWIN32OLE, "CP_OEMCP", INT2FIX(CP_OEMCP));
9161 rb_define_const(cWIN32OLE, "CP_MACCP", INT2FIX(CP_MACCP));
9162 rb_define_const(cWIN32OLE, "CP_THREAD_ACP", INT2FIX(CP_THREAD_ACP));
9163 rb_define_const(cWIN32OLE, "CP_SYMBOL", INT2FIX(CP_SYMBOL));
9164 rb_define_const(cWIN32OLE, "CP_UTF7", INT2FIX(CP_UTF7));
9165 rb_define_const(cWIN32OLE, "CP_UTF8", INT2FIX(CP_UTF8));
9166
9167 rb_define_const(cWIN32OLE, "LOCALE_SYSTEM_DEFAULT", INT2FIX(LOCALE_SYSTEM_DEFAULT));
9168 rb_define_const(cWIN32OLE, "LOCALE_USER_DEFAULT", INT2FIX(LOCALE_USER_DEFAULT));
9169
9170 mWIN32OLE_VARIANT = rb_define_module_under(cWIN32OLE, "VARIANT");
9171 rb_define_const(mWIN32OLE_VARIANT, "VT_EMPTY", INT2FIX(VT_EMPTY));
9172 rb_define_const(mWIN32OLE_VARIANT, "VT_NULL", INT2FIX(VT_NULL));
9173 rb_define_const(mWIN32OLE_VARIANT, "VT_I2", INT2FIX(VT_I2));
9174 rb_define_const(mWIN32OLE_VARIANT, "VT_I4", INT2FIX(VT_I4));
9175 rb_define_const(mWIN32OLE_VARIANT, "VT_R4", INT2FIX(VT_R4));
9176 rb_define_const(mWIN32OLE_VARIANT, "VT_R8", INT2FIX(VT_R8));
9177 rb_define_const(mWIN32OLE_VARIANT, "VT_CY", INT2FIX(VT_CY));
9178 rb_define_const(mWIN32OLE_VARIANT, "VT_DATE", INT2FIX(VT_DATE));
9179 rb_define_const(mWIN32OLE_VARIANT, "VT_BSTR", INT2FIX(VT_BSTR));
9180 rb_define_const(mWIN32OLE_VARIANT, "VT_USERDEFINED", INT2FIX(VT_USERDEFINED));
9181 rb_define_const(mWIN32OLE_VARIANT, "VT_PTR", INT2FIX(VT_PTR));
9182 rb_define_const(mWIN32OLE_VARIANT, "VT_DISPATCH", INT2FIX(VT_DISPATCH));
9183 rb_define_const(mWIN32OLE_VARIANT, "VT_ERROR", INT2FIX(VT_ERROR));
9184 rb_define_const(mWIN32OLE_VARIANT, "VT_BOOL", INT2FIX(VT_BOOL));
9185 rb_define_const(mWIN32OLE_VARIANT, "VT_VARIANT", INT2FIX(VT_VARIANT));
9186 rb_define_const(mWIN32OLE_VARIANT, "VT_UNKNOWN", INT2FIX(VT_UNKNOWN));
9187 rb_define_const(mWIN32OLE_VARIANT, "VT_I1", INT2FIX(VT_I1));
9188 rb_define_const(mWIN32OLE_VARIANT, "VT_UI1", INT2FIX(VT_UI1));
9189 rb_define_const(mWIN32OLE_VARIANT, "VT_UI2", INT2FIX(VT_UI2));
9190 rb_define_const(mWIN32OLE_VARIANT, "VT_UI4", INT2FIX(VT_UI4));
9191 #if (_MSC_VER >= 1300) || defined(__CYGWIN__) || defined(__MINGW32__)
9192 rb_define_const(mWIN32OLE_VARIANT, "VT_I8", INT2FIX(VT_I8));
9193 rb_define_const(mWIN32OLE_VARIANT, "VT_UI8", INT2FIX(VT_UI8));
9194 #endif
9195 rb_define_const(mWIN32OLE_VARIANT, "VT_INT", INT2FIX(VT_INT));
9196 rb_define_const(mWIN32OLE_VARIANT, "VT_UINT", INT2FIX(VT_UINT));
9197 rb_define_const(mWIN32OLE_VARIANT, "VT_ARRAY", INT2FIX(VT_ARRAY));
9198 rb_define_const(mWIN32OLE_VARIANT, "VT_BYREF", INT2FIX(VT_BYREF));
9199
9200 cWIN32OLE_TYPELIB = rb_define_class("WIN32OLE_TYPELIB", rb_cObject);
9201 rb_define_singleton_method(cWIN32OLE_TYPELIB, "typelibs", foletypelib_s_typelibs, 0);
9202 rb_define_alloc_func(cWIN32OLE_TYPELIB, foletypelib_s_allocate);
9203 rb_define_method(cWIN32OLE_TYPELIB, "initialize", foletypelib_initialize, -2);
9204 rb_define_method(cWIN32OLE_TYPELIB, "guid", foletypelib_guid, 0);
9205 rb_define_method(cWIN32OLE_TYPELIB, "name", foletypelib_name, 0);
9206 rb_define_method(cWIN32OLE_TYPELIB, "version", foletypelib_version, 0);
9207 rb_define_method(cWIN32OLE_TYPELIB, "major_version", foletypelib_major_version, 0);
9208 rb_define_method(cWIN32OLE_TYPELIB, "minor_version", foletypelib_minor_version, 0);
9209 rb_define_method(cWIN32OLE_TYPELIB, "path", foletypelib_path, 0);
9210 rb_define_method(cWIN32OLE_TYPELIB, "ole_types", foletypelib_ole_types, 0);
9211 rb_define_alias(cWIN32OLE_TYPELIB, "ole_classes", "ole_types");
9212 rb_define_method(cWIN32OLE_TYPELIB, "visible?", foletypelib_visible, 0);
9213 rb_define_method(cWIN32OLE_TYPELIB, "library_name", foletypelib_library_name, 0);
9214 rb_define_alias(cWIN32OLE_TYPELIB, "to_s", "name");
9215 rb_define_method(cWIN32OLE_TYPELIB, "inspect", foletypelib_inspect, 0);
9216
9217 cWIN32OLE_TYPE = rb_define_class("WIN32OLE_TYPE", rb_cObject);
9218 rb_define_singleton_method(cWIN32OLE_TYPE, "ole_classes", foletype_s_ole_classes, 1);
9219 rb_define_singleton_method(cWIN32OLE_TYPE, "typelibs", foletype_s_typelibs, 0);
9220 rb_define_singleton_method(cWIN32OLE_TYPE, "progids", foletype_s_progids, 0);
9221 rb_define_alloc_func(cWIN32OLE_TYPE, foletype_s_allocate);
9222 rb_define_method(cWIN32OLE_TYPE, "initialize", foletype_initialize, 2);
9223 rb_define_method(cWIN32OLE_TYPE, "name", foletype_name, 0);
9224 rb_define_method(cWIN32OLE_TYPE, "ole_type", foletype_ole_type, 0);
9225 rb_define_method(cWIN32OLE_TYPE, "guid", foletype_guid, 0);
9226 rb_define_method(cWIN32OLE_TYPE, "progid", foletype_progid, 0);
9227 rb_define_method(cWIN32OLE_TYPE, "visible?", foletype_visible, 0);
9228 rb_define_alias(cWIN32OLE_TYPE, "to_s", "name");
9229 rb_define_method(cWIN32OLE_TYPE, "major_version", foletype_major_version, 0);
9230 rb_define_method(cWIN32OLE_TYPE, "minor_version", foletype_minor_version, 0);
9231 rb_define_method(cWIN32OLE_TYPE, "typekind", foletype_typekind, 0);
9232 rb_define_method(cWIN32OLE_TYPE, "helpstring", foletype_helpstring, 0);
9233 rb_define_method(cWIN32OLE_TYPE, "src_type", foletype_src_type, 0);
9234 rb_define_method(cWIN32OLE_TYPE, "helpfile", foletype_helpfile, 0);
9235 rb_define_method(cWIN32OLE_TYPE, "helpcontext", foletype_helpcontext, 0);
9236 rb_define_method(cWIN32OLE_TYPE, "variables", foletype_variables, 0);
9237 rb_define_method(cWIN32OLE_TYPE, "ole_methods", foletype_methods, 0);
9238 rb_define_method(cWIN32OLE_TYPE, "ole_typelib", foletype_ole_typelib, 0);
9239 rb_define_method(cWIN32OLE_TYPE, "implemented_ole_types", foletype_impl_ole_types, 0);
9240 rb_define_method(cWIN32OLE_TYPE, "source_ole_types", foletype_source_ole_types, 0);
9241 rb_define_method(cWIN32OLE_TYPE, "default_event_sources", foletype_default_event_sources, 0);
9242 rb_define_method(cWIN32OLE_TYPE, "default_ole_types", foletype_default_ole_types, 0);
9243 rb_define_method(cWIN32OLE_TYPE, "inspect", foletype_inspect, 0);
9244
9245 cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject);
9246 rb_define_method(cWIN32OLE_VARIABLE, "name", folevariable_name, 0);
9247 rb_define_method(cWIN32OLE_VARIABLE, "ole_type", folevariable_ole_type, 0);
9248 rb_define_method(cWIN32OLE_VARIABLE, "ole_type_detail", folevariable_ole_type_detail, 0);
9249 rb_define_method(cWIN32OLE_VARIABLE, "value", folevariable_value, 0);
9250 rb_define_method(cWIN32OLE_VARIABLE, "visible?", folevariable_visible, 0);
9251 rb_define_method(cWIN32OLE_VARIABLE, "variable_kind", folevariable_variable_kind, 0);
9252 rb_define_method(cWIN32OLE_VARIABLE, "varkind", folevariable_varkind, 0);
9253 rb_define_method(cWIN32OLE_VARIABLE, "inspect", folevariable_inspect, 0);
9254 rb_define_alias(cWIN32OLE_VARIABLE, "to_s", "name");
9255
9256 cWIN32OLE_METHOD = rb_define_class("WIN32OLE_METHOD", rb_cObject);
9257 rb_define_alloc_func(cWIN32OLE_METHOD, folemethod_s_allocate);
9258 rb_define_method(cWIN32OLE_METHOD, "initialize", folemethod_initialize, 2);
9259 rb_define_method(cWIN32OLE_METHOD, "name", folemethod_name, 0);
9260 rb_define_method(cWIN32OLE_METHOD, "return_type", folemethod_return_type, 0);
9261 rb_define_method(cWIN32OLE_METHOD, "return_vtype", folemethod_return_vtype, 0);
9262 rb_define_method(cWIN32OLE_METHOD, "return_type_detail", folemethod_return_type_detail, 0);
9263 rb_define_method(cWIN32OLE_METHOD, "invoke_kind", folemethod_invoke_kind, 0);
9264 rb_define_method(cWIN32OLE_METHOD, "invkind", folemethod_invkind, 0);
9265 rb_define_method(cWIN32OLE_METHOD, "visible?", folemethod_visible, 0);
9266 rb_define_method(cWIN32OLE_METHOD, "event?", folemethod_event, 0);
9267 rb_define_method(cWIN32OLE_METHOD, "event_interface", folemethod_event_interface, 0);
9268 rb_define_method(cWIN32OLE_METHOD, "helpstring", folemethod_helpstring, 0);
9269 rb_define_method(cWIN32OLE_METHOD, "helpfile", folemethod_helpfile, 0);
9270 rb_define_method(cWIN32OLE_METHOD, "helpcontext", folemethod_helpcontext, 0);
9271 rb_define_method(cWIN32OLE_METHOD, "dispid", folemethod_dispid, 0);
9272 rb_define_method(cWIN32OLE_METHOD, "offset_vtbl", folemethod_offset_vtbl, 0);
9273 rb_define_method(cWIN32OLE_METHOD, "size_params", folemethod_size_params, 0);
9274 rb_define_method(cWIN32OLE_METHOD, "size_opt_params", folemethod_size_opt_params, 0);
9275 rb_define_method(cWIN32OLE_METHOD, "params", folemethod_params, 0);
9276 rb_define_alias(cWIN32OLE_METHOD, "to_s", "name");
9277 rb_define_method(cWIN32OLE_METHOD, "inspect", folemethod_inspect, 0);
9278
9279 cWIN32OLE_PARAM = rb_define_class("WIN32OLE_PARAM", rb_cObject);
9280 rb_define_alloc_func(cWIN32OLE_PARAM, foleparam_s_allocate);
9281 rb_define_method(cWIN32OLE_PARAM, "initialize", foleparam_initialize, 2);
9282 rb_define_method(cWIN32OLE_PARAM, "name", foleparam_name, 0);
9283 rb_define_method(cWIN32OLE_PARAM, "ole_type", foleparam_ole_type, 0);
9284 rb_define_method(cWIN32OLE_PARAM, "ole_type_detail", foleparam_ole_type_detail, 0);
9285 rb_define_method(cWIN32OLE_PARAM, "input?", foleparam_input, 0);
9286 rb_define_method(cWIN32OLE_PARAM, "output?", foleparam_output, 0);
9287 rb_define_method(cWIN32OLE_PARAM, "optional?", foleparam_optional, 0);
9288 rb_define_method(cWIN32OLE_PARAM, "retval?", foleparam_retval, 0);
9289 rb_define_method(cWIN32OLE_PARAM, "default", foleparam_default, 0);
9290 rb_define_alias(cWIN32OLE_PARAM, "to_s", "name");
9291 rb_define_method(cWIN32OLE_PARAM, "inspect", foleparam_inspect, 0);
9292
9293 cWIN32OLE_EVENT = rb_define_class("WIN32OLE_EVENT", rb_cObject);
9294 rb_define_singleton_method(cWIN32OLE_EVENT, "message_loop", fev_s_msg_loop, 0);
9295 rb_define_alloc_func(cWIN32OLE_EVENT, fev_s_allocate);
9296 rb_define_method(cWIN32OLE_EVENT, "initialize", fev_initialize, -1);
9297 rb_define_method(cWIN32OLE_EVENT, "on_event", fev_on_event, -1);
9298 rb_define_method(cWIN32OLE_EVENT, "on_event_with_outargs", fev_on_event_with_outargs, -1);
9299 rb_define_method(cWIN32OLE_EVENT, "off_event", fev_off_event, -1);
9300 rb_define_method(cWIN32OLE_EVENT, "unadvise", fev_unadvise, 0);
9301 rb_define_method(cWIN32OLE_EVENT, "handler=", fev_set_handler, 1);
9302 rb_define_method(cWIN32OLE_EVENT, "handler", fev_get_handler, 0);
9303
9304 cWIN32OLE_VARIANT = rb_define_class("WIN32OLE_VARIANT", rb_cObject);
9305 rb_define_alloc_func(cWIN32OLE_VARIANT, folevariant_s_allocate);
9306 rb_define_singleton_method(cWIN32OLE_VARIANT, "array", folevariant_s_array, 2);
9307 rb_define_method(cWIN32OLE_VARIANT, "initialize", folevariant_initialize, -2);
9308 rb_define_method(cWIN32OLE_VARIANT, "value", folevariant_value, 0);
9309 rb_define_method(cWIN32OLE_VARIANT, "value=", folevariant_set_value, 1);
9310 rb_define_method(cWIN32OLE_VARIANT, "vartype", folevariant_vartype, 0);
9311 rb_define_method(cWIN32OLE_VARIANT, "[]", folevariant_ary_aref, -1);
9312 rb_define_method(cWIN32OLE_VARIANT, "[]=", folevariant_ary_aset, -1);
9313 rb_define_const(cWIN32OLE_VARIANT, "Empty", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_EMPTY)));
9314 rb_define_const(cWIN32OLE_VARIANT, "Null", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_NULL)));
9315 rb_define_const(cWIN32OLE_VARIANT, "Nothing", rb_funcall(cWIN32OLE_VARIANT, rb_intern("new"), 2, Qnil, INT2FIX(VT_DISPATCH)));
9316
9317 eWIN32OLERuntimeError = rb_define_class("WIN32OLERuntimeError", rb_eRuntimeError);
9318
9319 init_enc2cp();
9320 atexit((void (*)(void))free_enc2cp);
9321 ole_init_cp();
9322 }
data
VALUE data
Definition: tcltklib.c:3368
olevariant_free
static void olevariant_free(struct olevariantdata *pvar)
Definition: win32ole.c:8640
fole_invoke2
static VALUE fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types)
Definition: win32ole.c:3791
foletype_helpfile
static VALUE foletype_helpfile(VALUE self)
Definition: win32ole.c:5943
typeinfo_from_ole
static HRESULT typeinfo_from_ole(struct oledata *pole, ITypeInfo **ppti)
Definition: win32ole.c:4234
fole_s_set_locale
static VALUE fole_s_set_locale(VALUE self, VALUE vlcid)
Definition: win32ole.c:3110
lpInterfaceInfo
static DWORD HTASK DWORD LPINTERFACEINFO lpInterfaceInfo
Definition: win32ole.c:633
method_name
static VALUE method_name(VALUE obj)
Definition: proc.c:1156
foletype_minor_version
static VALUE foletype_minor_version(VALUE self)
Definition: win32ole.c:5820
lcid_installed
static BOOL lcid_installed(LCID lcid)
Definition: win32ole.c:3091
load_conv_function51932
#define load_conv_function51932()
Definition: win32ole.c:955
ALLOC
#define ALLOC(type)
foletype_visible
static VALUE foletype_visible(VALUE self)
Definition: win32ole.c:5760
com_vtbl
static IDispatchVtbl com_vtbl
Definition: win32ole.c:234
_Win32OLEIDispatch::dispatch
IDispatch dispatch
Definition: win32ole.c:697
rb_ary_unshift
VALUE rb_ary_unshift(VALUE ary, VALUE item)
Definition: array.c:1084
RUBY_EVENT_THREAD_END
#define RUBY_EVENT_THREAD_END
foletypelib_ole_types
static VALUE foletypelib_ole_types(VALUE self)
Definition: win32ole.c:5517
n
ssize_t n
Definition: bigdecimal.c:5655
fev_on_event_with_outargs
static VALUE fev_on_event_with_outargs(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:8482
cWIN32OLE_PROPERTY
VALUE cWIN32OLE_PROPERTY
Definition: win32ole.c:213
folemethod_return_type_detail
static VALUE folemethod_return_type_detail(VALUE self)
Definition: win32ole.c:6700
ole_variable_ole_type
static VALUE ole_variable_ole_type(ITypeInfo *pTypeInfo, UINT var_index)
Definition: win32ole.c:6244
FIXNUM_FLAG
#define FIXNUM_FLAG
ary
volatile VALUE ary
Definition: tcltklib.c:9713
cWIN32OLE_PARAM
VALUE cWIN32OLE_PARAM
Definition: win32ole.c:208
EVENTSINK_Invoke
STDMETHODIMP EVENTSINK_Invoke(PEVENTSINK pEventSink, DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult, EXCEPINFO *pexcepinfo, UINT *puArgErr)
Definition: win32ole.c:7814
foletype_impl_ole_types
static VALUE foletype_impl_ole_types(VALUE self)
Definition: win32ole.c:6046
ev_on_event
static VALUE ev_on_event(int argc, VALUE *argv, VALUE self, VALUE is_ary_arg)
Definition: win32ole.c:8410
ole_methods_sub
static VALUE ole_methods_sub(ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE methods, int mask)
Definition: win32ole.c:4167
int
VP_EXPORT int
Definition: bigdecimal.c:5050
myCPINFOEX::CodePage
UINT CodePage
Definition: win32ole.c:1008
find_default_source
static HRESULT find_default_source(VALUE ole, IID *piid, ITypeInfo **ppTypeInfo)
Definition: win32ole.c:8174
rb_ary_entry
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1101
ole_method_return_type_detail
static VALUE ole_method_return_type_detail(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:6674
ole_invoke2
static VALUE ole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types, USHORT dispkind)
Definition: win32ole.c:3589
foletype_guid
static VALUE foletype_guid(VALUE self)
Definition: win32ole.c:5690
oleparamdata::method_index
UINT method_index
Definition: win32ole.c:279
ole_usertype2val
static VALUE ole_usertype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
Definition: win32ole.c:4567
FALSE
#define FALSE
Definition: nkf.h:174
folemethod_dispid
static VALUE folemethod_dispid(VALUE self)
Definition: win32ole.c:7062
ole_show_help
static HWND ole_show_help(VALUE helpfile, VALUE helpcontext)
Definition: win32ole.c:2947
foletype_s_allocate
static VALUE foletype_s_allocate(VALUE klass)
Definition: win32ole.c:4878
g_lcid_to_check
static char g_lcid_to_check[8+1]
Definition: win32ole.c:239
strlen
size_t strlen(const char *)
fev_unadvise
static VALUE fev_unadvise(VALUE self)
Definition: win32ole.c:8542
folemethod_size_opt_params
static VALUE folemethod_size_opt_params(VALUE self)
Definition: win32ole.c:7156
foleparam_input
static VALUE foleparam_input(VALUE self)
Definition: win32ole.c:7421
st_table
Definition: ripper.y:77
evs_entry
static VALUE evs_entry(long i)
Definition: win32ole.c:8570
rb_obj_classname
const char * rb_obj_classname(VALUE)
Definition: variable.c:396
fole_setproperty_with_bracket
static VALUE fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:3851
p
Win32OLEIDispatch * p
Definition: win32ole.c:786
clsid_from_remote
static HRESULT clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid)
Definition: win32ole.c:2578
minor
int minor
Definition: tcltklib.c:110
fole_s_ole_uninitialize
static VALUE fole_s_ole_uninitialize(VALUE self)
Definition: win32ole.c:3169
ruby_finalize
void ruby_finalize(void)
Runs the VM finalization processes.
Definition: eval.c:138
count
int count
Definition: encoding.c:51
threadIDCaller
static DWORD HTASK threadIDCaller
Definition: win32ole.c:628
pair
volatile VALUE pair
Definition: tkutil.c:554
st_lookup
int st_lookup(st_table *, st_data_t, st_data_t *)
foletypelib_minor_version
static VALUE foletypelib_minor_version(VALUE self)
Definition: win32ole.c:5349
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1497
EVENTSINK_Constructor
PIEVENTSINKOBJ EVENTSINK_Constructor()
Definition: win32ole.c:7919
EVENTSINK_AddRef
EVENTSINK_AddRef(PEVENTSINK pEV)
Definition: win32ole.c:7604
ev_advise
static VALUE ev_advise(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:8283
fole_setproperty2
static VALUE fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
Definition: win32ole.c:3827
folemethod_event_interface
static VALUE folemethod_event_interface(VALUE self)
Definition: win32ole.c:6911
ole_search_event_at
static long ole_search_event_at(VALUE ary, VALUE ev)
Definition: win32ole.c:7658
ruby.h
rb_sym_to_s
VALUE rb_sym_to_s(VALUE)
Definition: string.c:7906
EVENTSINK_QueryInterface
STDMETHODIMP EVENTSINK_QueryInterface(PEVENTSINK pEV, REFIID iid, LPVOID *ppv)
Definition: win32ole.c:7585
ole_val2olevariantdata
static void ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar)
Definition: win32ole.c:1886
oletype_set_member
static VALUE oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
Definition: win32ole.c:4889
foletype_default_event_sources
static VALUE foletype_default_event_sources(VALUE self)
Definition: win32ole.c:6081
st_init_numtable
st_table * st_init_numtable(void)
Definition: st.c:272
ole_search_event
static VALUE ole_search_event(VALUE ary, VALUE ev, BOOL *is_default)
Definition: win32ole.c:7683
Data_Make_Struct
#define Data_Make_Struct(klass, type, mark, free, sval)
ole_methods
static VALUE ole_methods(VALUE self, int mask)
Definition: win32ole.c:4275
ole_method_params
static VALUE ole_method_params(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:7164
EVENTSINK_GetIDsOfNames
STDMETHODIMP EVENTSINK_GetIDsOfNames(PEVENTSINK pEventSink, REFIID riid, OLECHAR **szNames, UINT cNames, LCID lcid, DISPID *pDispID)
Definition: win32ole.c:7640
hash2ptr_dispparams
static void hash2ptr_dispparams(VALUE hash, ITypeInfo *pTypeInfo, DISPID dispid, DISPPARAMS *pdispparams)
Definition: win32ole.c:7735
rb_ary_delete_at
VALUE rb_ary_delete_at(VALUE ary, long pos)
Definition: array.c:2813
rgszNames
static REFIID LPOLESTR __RPC_FAR * rgszNames
Definition: win32ole.c:305
reg_get_typelib_file_path
static VALUE reg_get_typelib_file_path(HKEY hkey)
Definition: win32ole.c:2403
evs_delete
static VALUE evs_delete(long i)
Definition: win32ole.c:8563
rb_secure
void rb_secure(int)
Definition: safe.c:79
ole_param_ole_type_detail
static VALUE ole_param_ole_type_detail(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
Definition: win32ole.c:7363
foleparam_output
static VALUE foleparam_output(VALUE self)
Definition: win32ole.c:7448
g_ole_initialized_key
static volatile DWORD g_ole_initialized_key
Definition: win32ole.c:222
rb_const_get
VALUE rb_const_get(VALUE, ID)
Definition: variable.c:1876
fole_func_methods
static VALUE fole_func_methods(VALUE self)
Definition: win32ole.c:4354
UI8_2_NUM
#define UI8_2_NUM
Definition: win32ole.c:139
rb_str_cmp
int rb_str_cmp(VALUE, VALUE)
Definition: string.c:2308
olevariantdata::realvar
VARIANT realvar
Definition: win32ole.c:295
cWIN32OLE_lcid
static LCID cWIN32OLE_lcid
Definition: win32ole.c:236
g_ole_initialized_set
#define g_ole_initialized_set(val)
Definition: win32ole.c:225
i
ssize_t i
Definition: bigdecimal.c:5655
dwTickCount
static DWORD HTASK DWORD dwTickCount
Definition: win32ole.c:628
ole_type_helpfile
static VALUE ole_type_helpfile(ITypeInfo *pTypeInfo)
Definition: win32ole.c:5922
ary_new_dim
static VALUE ary_new_dim(VALUE myary, long *pid, long *plb, long dim)
Definition: win32ole.c:2043
rb_cTime
RUBY_EXTERN VALUE rb_cTime
Definition: ripper.y:1460
fev_on_event
static VALUE fev_on_event(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:8462
folevariable_varkind
static VALUE folevariable_varkind(VALUE self)
Definition: win32ole.c:6498
info
Tcl_CmdInfo * info
Definition: tcltklib.c:1463
rb_enc_name
#define rb_enc_name(enc)
olemethoddata::pTypeInfo
ITypeInfo * pTypeInfo
Definition: win32ole.c:268
target
VALUE target
Definition: tcltklib.c:5532
cWIN32OLE
VALUE cWIN32OLE
Definition: win32ole.c:203
oleeventdata::event_id
long event_id
Definition: win32ole.c:286
foletype_inspect
static VALUE foletype_inspect(VALUE self)
Definition: win32ole.c:6116
reg_enum_key
static VALUE reg_enum_key(HKEY hkey, DWORD i)
Definition: win32ole.c:2343
cNames
static REFIID LPOLESTR __RPC_FAR UINT cNames
Definition: win32ole.c:305
strcasecmp
#define strcasecmp
Definition: win32.h:200
ret
int ret
Definition: tcltklib.c:280
ole_method_invoke_kind
static VALUE ole_method_invoke_kind(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:6722
FNENUMSYSEMCODEPAGES
BOOL( FNENUMSYSEMCODEPAGES)(CODEPAGE_ENUMPROC, DWORD)
Definition: win32ole.c:153
typelib_file_from_typelib
static VALUE typelib_file_from_typelib(VALUE ole)
Definition: win32ole.c:2447
foletype_s_progids
static VALUE foletype_s_progids(VALUE self)
Definition: win32ole.c:4847
vtEventSink
static IEventSinkVtbl vtEventSink
Definition: win32ole.c:7579
foletype_helpcontext
static VALUE foletype_helpcontext(VALUE self)
Definition: win32ole.c:5971
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:511
dwCallType
static DWORD dwCallType
Definition: win32ole.c:628
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
fole_free
static VALUE fole_free(VALUE self)
Definition: win32ole.c:3964
OBJ_TAINTED
#define OBJ_TAINTED(x)
cWIN32OLE_enc
static rb_encoding * cWIN32OLE_enc
Definition: win32ole.c:237
cWIN32OLE_cp
static UINT cWIN32OLE_cp
Definition: win32ole.c:235
rb_default_internal_encoding
rb_encoding * rb_default_internal_encoding(void)
Definition: encoding.c:1373
enc
VALUE enc
Definition: tcltklib.c:10311
NUM2I8
#define NUM2I8
Definition: win32ole.c:140
installed_lcid_proc
static BOOL CALLBACK installed_lcid_proc(LPTSTR str)
Definition: win32ole.c:3081
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
ole_typelib_from_itypeinfo
static VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo)
Definition: win32ole.c:4416
make_inspect
static VALUE make_inspect(const char *class_name, VALUE detail)
Definition: win32ole.c:1991
init_enc2cp
static void init_enc2cp(void)
Definition: win32ole.c:9068
ole_variant2val
static VALUE ole_variant2val(VARIANT *pvar)
Definition: win32ole.c:2076
fole_type
static VALUE fole_type(VALUE self)
Definition: win32ole.c:4393
tagIEVENTSINKOBJ::lpVtbl
IEventSinkVtbl * lpVtbl
Definition: win32ole.c:196
path
gz path
Definition: zlib.c:2279
ole_const_load
static void ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self)
Definition: win32ole.c:2515
folevariant_initialize
static VALUE folevariant_initialize(VALUE self, VALUE args)
Definition: win32ole.c:8744
val2dispatch
static IDispatch * val2dispatch(VALUE val)
Definition: win32ole.c:804
TYPE
#define TYPE(x)
ole_mb2wc
static LPWSTR ole_mb2wc(char *pm, int len)
Definition: win32ole.c:1357
ole_param_flag_mask
static VALUE ole_param_flag_mask(ITypeInfo *pTypeInfo, UINT method_index, UINT index, USHORT mask)
Definition: win32ole.c:7397
olevariable_free
static void olevariable_free(struct olevariabledata *polevar)
Definition: win32ole.c:1289
IEVENTSINKOBJ
struct tagIEVENTSINKOBJ IEVENTSINKOBJ
ole_method_offset_vtbl
static VALUE ole_method_offset_vtbl(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:7070
RSTRING_PTR
#define RSTRING_PTR(str)
Win32OLEIDispatch
struct _Win32OLEIDispatch Win32OLEIDispatch
NIL_P
NIL_P(eventloop_thread)
Definition: tcltklib.c:4068
T_ARRAY
#define T_ARRAY
rb_enc_str_new
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
Definition: string.c:439
var
VALUE var
Definition: tcltklib.c:5517
rb_protect
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
Definition: eval.c:771
rb_funcall
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:774
tp
register C_block * tp
Definition: crypt.c:311
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1780
folemethod_helpfile
static VALUE folemethod_helpfile(VALUE self)
Definition: win32ole.c:7001
foleparam_inspect
static VALUE foleparam_inspect(VALUE self)
Definition: win32ole.c:7562
EVENTSINK_Destructor
void EVENTSINK_Destructor(PIEVENTSINKOBJ)
Definition: win32ole.c:7941
MEMCMP
#define MEMCMP(p1, p2, type, n)
T_HASH
#define T_HASH
Qtrue
return Qtrue
Definition: tcltklib.c:9610
V_UINTREF
#define V_UINTREF(X)
Definition: win32ole.c:97
ole_method_dispid
static VALUE ole_method_dispid(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:7039
RETURN_ENUMERATOR
#define RETURN_ENUMERATOR(obj, argc, argv)
rb_ary_clear
VALUE rb_ary_clear(VALUE ary)
Definition: array.c:3220
rb_backtrace
void rb_backtrace(void)
Definition: vm_backtrace.c:766
fole_methods
static VALUE fole_methods(VALUE self)
Definition: win32ole.c:4305
OLEData_Get_Struct
#define OLEData_Get_Struct(obj, pole)
Definition: win32ole.c:125
ole_method_visible
static VALUE ole_method_visible(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:6779
wFlags
static DISPID REFIID LCID WORD wFlags
Definition: win32ole.c:306
ole_val2variant_ex
static void ole_val2variant_ex(VALUE val, VARIANT *var, VARTYPE vt)
Definition: win32ole.c:1696
is_all_index_under
static VALUE is_all_index_under(long *pid, long *pub, long dim)
Definition: win32ole.c:1480
SafeStringValue
#define SafeStringValue(v)
foletype_major_version
static VALUE foletype_major_version(VALUE self)
Definition: win32ole.c:5790
index
int index
Definition: tcltklib.c:4478
rb_ary_new3
VALUE rb_ary_new3(long n,...)
Definition: array.c:432
oletypelib_get_typelib
static ITypeLib * oletypelib_get_typelib(VALUE self)
Definition: win32ole.c:4947
rb_eSecurityError
VALUE rb_eSecurityError
Definition: error.c:520
olevariantdata
Definition: win32ole.c:294
T_NIL
#define T_NIL
oletypelibdata
Definition: win32ole.c:258
enc_name
VALUE enc_name
Definition: tcltklib.c:8445
myCPINFOEX::CodePageName
char CodePageName[MAX_PATH]
Definition: win32ole.c:1009
alias
const char * alias
Definition: nkf.c:1151
ghhctrl
static HINSTANCE ghhctrl
Definition: win32ole.c:230
fole_s_reference_count
static VALUE fole_s_reference_count(VALUE self, VALUE obj)
Definition: win32ole.c:2916
rb_big2dbl
double rb_big2dbl(VALUE x)
Definition: bignum.c:1429
eWIN32OLERuntimeError
VALUE eWIN32OLERuntimeError
Definition: win32ole.c:211
rb_str_new2
#define rb_str_new2
OLE_GET_TYPEATTR
#define OLE_GET_TYPEATTR(X, Y)
Definition: win32ole.c:113
oleeventdata::pConnectionPoint
IConnectionPoint * pConnectionPoint
Definition: win32ole.c:285
fole_method_help
static VALUE fole_method_help(VALUE self, VALUE cmdname)
Definition: win32ole.c:4731
folemethod_inspect
static VALUE folemethod_inspect(VALUE self)
Definition: win32ole.c:7232
ole_set_member
static VALUE ole_set_member(VALUE self, IDispatch *dispatch)
Definition: win32ole.c:2010
state
int state
Definition: tcltklib.c:1462
ole_method_event
static VALUE ole_method_event(ITypeInfo *pTypeInfo, UINT method_index, VALUE method_name)
Definition: win32ole.c:6816
dwData
IUnknown COSERVERINFO MULTI_QI *typedef LPCSTR UINT DWORD dwData
Definition: win32ole.c:151
olevariabledata::pTypeInfo
ITypeInfo * pTypeInfo
Definition: win32ole.c:273
folemethod_return_type
static VALUE folemethod_return_type(VALUE self)
Definition: win32ole.c:6632
threadIDCallee
static HTASK threadIDCallee
Definition: win32ole.c:662
foletype_s_typelibs
static VALUE foletype_s_typelibs(VALUE self)
Definition: win32ole.c:4830
T_FLOAT
#define T_FLOAT
tbl
VALUE tbl
Definition: tkutil.c:1280
args
VALUE VALUE args
Definition: tcltklib.c:2561
get_ptr_of_variant
static void * get_ptr_of_variant(VARIANT *pvar)
Definition: win32ole.c:1411
myCPINFOEX::LeadByte
BYTE LeadByte[12]
Definition: win32ole.c:1006
rb_str_append
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2121
oleclass_from_typelib
static VALUE oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass)
Definition: win32ole.c:4900
oleparamdata
Definition: win32ole.c:277
ary_store_dim
static void ary_store_dim(VALUE myary, long *pid, long *plb, long dim, VALUE val)
Definition: win32ole.c:2069
fole_s_get_code_page
static VALUE fole_s_get_code_page(VALUE self)
Definition: win32ole.c:3018
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1116
rb_str_concat
VALUE rb_str_concat(VALUE, VALUE)
Definition: string.c:2162
olemethod_free
static void olemethod_free(struct olemethoddata *polemethod)
Definition: win32ole.c:1281
ole_delete_event
static void ole_delete_event(VALUE ary, VALUE ev)
Definition: win32ole.c:7725
myCPINFOEX::MaxCharSize
UINT MaxCharSize
Definition: win32ole.c:1004
ole_val2ptr_variant
static void ole_val2ptr_variant(VALUE val, VARIANT *var)
Definition: win32ole.c:1731
_Win32OLEIDispatch
Definition: win32ole.c:695
cWIN32OLE_TYPE
VALUE cWIN32OLE_TYPE
Definition: win32ole.c:205
ole_ary_m_entry
static VALUE ole_ary_m_entry(VALUE val, long *pid)
Definition: win32ole.c:1398
ole_type_visible
static VALUE ole_type_visible(ITypeInfo *pTypeInfo)
Definition: win32ole.c:5734
ole_type_impl_ole_types
static VALUE ole_type_impl_ole_types(ITypeInfo *pTypeInfo, int implflags)
Definition: win32ole.c:5996
rb_event_flag_t
unsigned long rb_event_flag_t
Definition: ripper.y:1603
find_default_source_from_typeinfo
static HRESULT find_default_source_from_typeinfo(ITypeInfo *pTypeInfo, TYPEATTR *pTypeAttr, ITypeInfo **ppTypeInfo)
Definition: win32ole.c:8138
fmt
const char * fmt
Definition: tcltklib.c:841
set_argv
static VALUE set_argv(VARIANTARG *realargs, unsigned int beg, unsigned int end)
Definition: win32ole.c:3323
folevariant_ary_aref
static VALUE folevariant_ary_aref(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:8863
WC2VSTR
#define WC2VSTR(x)
Definition: win32ole.c:144
ole_ole_type
static VALUE ole_ole_type(ITypeInfo *pTypeInfo)
Definition: win32ole.c:5601
foleparam_ole_type_detail
static VALUE foleparam_ole_type_detail(VALUE self)
Definition: win32ole.c:7388
oleparam_free
static void oleparam_free(struct oleparamdata *pole)
Definition: win32ole.c:1296
ole_method_helpfile
static VALUE ole_method_helpfile(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:6979
tagIEVENTSINKOBJ::m_cRef
DWORD m_cRef
Definition: win32ole.c:197
NORETURN
#define NORETURN(x)
Definition: ruby.h:31
folemethod_invkind
static VALUE folemethod_invkind(VALUE self)
Definition: win32ole.c:6752
ole_val2variant
static void ole_val2variant(VALUE val, VARIANT *var)
Definition: win32ole.c:1630
foletypelib_guid
static VALUE foletypelib_guid(VALUE self)
Definition: win32ole.c:5246
uCommand
IUnknown COSERVERINFO MULTI_QI *typedef LPCSTR UINT uCommand
Definition: win32ole.c:151
g_uninitialize_hooked
static BOOL g_uninitialize_hooked
Definition: win32ole.c:227
foletype_ole_type
static VALUE foletype_ole_type(VALUE self)
Definition: win32ole.c:5655
g_cp_to_check
static UINT g_cp_to_check
Definition: win32ole.c:238
st_data_t
unsigned long st_data_t
Definition: ripper.y:35
g_ole_initialized_init
#define g_ole_initialized_init()
Definition: win32ole.c:224
st_delete
int st_delete(st_table *, st_data_t *, st_data_t *)
rb_is_const_id
int rb_is_const_id(ID id)
Definition: ripper.c:17046
folevariable_ole_type_detail
static VALUE folevariable_ole_type_detail(VALUE self)
Definition: win32ole.c:6312
foletype_default_ole_types
static VALUE foletype_default_ole_types(VALUE self)
Definition: win32ole.c:6099
PIEVENTSINKOBJ
struct tagIEVENTSINKOBJ * PIEVENTSINKOBJ
EVENTSINK_GetTypeInfoCount
STDMETHODIMP EVENTSINK_GetTypeInfoCount(PEVENTSINK pEV, UINT *pct)
Definition: win32ole.c:7622
ole_docinfo_from_type
static HRESULT ole_docinfo_from_type(ITypeInfo *pTypeInfo, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile)
Definition: win32ole.c:4544
PEVENTSINK
struct IEventSink * PEVENTSINK
folevariable_value
static VALUE folevariable_value(VALUE self)
Definition: win32ole.c:6356
rb_float_new
static VALUE rb_float_new(double d)
Definition: ripper.y:790
oleparam::pNamedArgs
OLECHAR ** pNamedArgs
Definition: win32ole.c:291
hash
VALUE hash
Definition: tkutil.c:267
folemethod_invoke_kind
static VALUE folemethod_invoke_kind(VALUE self)
Definition: win32ole.c:6771
ole_search_handler_method
static VALUE ole_search_handler_method(VALUE handler, VALUE ev, BOOL *is_default_handler)
Definition: win32ole.c:7707
ole_typedesc2val
static VALUE ole_typedesc2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
Definition: win32ole.c:4605
fev_initialize
static VALUE fev_initialize(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:8374
oleparam_ole_param
static VALUE oleparam_ole_param(VALUE self, VALUE olemethod, int n)
Definition: win32ole.c:7295
ole_val2variant2
static void ole_val2variant2(VALUE val, VARIANT *var)
Definition: win32ole.c:1983
create_win32ole_object
static VALUE create_win32ole_object(VALUE klass, IDispatch *pDispatch, int argc, VALUE *argv)
Definition: win32ole.c:2035
oleparamdata::pTypeInfo
ITypeInfo * pTypeInfo
Definition: win32ole.c:278
pExcepInfo
static DISPID REFIID LCID WORD DISPPARAMS __RPC_FAR VARIANT __RPC_FAR EXCEPINFO __RPC_FAR * pExcepInfo
Definition: win32ole.c:306
rb_default_external_encoding
rb_encoding * rb_default_external_encoding(void)
Definition: encoding.c:1288
ole_types_from_typelib
static VALUE ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes)
Definition: win32ole.c:2865
memset
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
unlock_safe_array
static void unlock_safe_array(SAFEARRAY *psa)
Definition: win32ole.c:8833
rb_block_proc
VALUE rb_block_proc(void)
Definition: proc.c:479
ole_wc2vstr
static VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree)
Definition: win32ole.c:1387
OLE_FREE
#define OLE_FREE(x)
Definition: win32ole.c:116
Data_Wrap_Struct
return Data_Wrap_Struct(CLASS_OF(interp), 0, ip_free, slave)
folemethod_event
static VALUE folemethod_event(VALUE self)
Definition: win32ole.c:6890
ole_hresult2msg
static VALUE ole_hresult2msg(HRESULT hr)
Definition: win32ole.c:1103
foleparam_default
static VALUE foleparam_default(VALUE self)
Definition: win32ole.c:7545
ole_variable_varkind
static VALUE ole_variable_varkind(ITypeInfo *pTypeInfo, UINT var_index)
Definition: win32ole.c:6466
com_hash
static VALUE com_hash
Definition: win32ole.c:233
ole_method_return_vtype
static VALUE ole_method_return_vtype(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:6640
ole_variable_kind
static VALUE ole_variable_kind(ITypeInfo *pTypeInfo, UINT var_index)
Definition: win32ole.c:6410
ole_encoding2cp
static UINT ole_encoding2cp(rb_encoding *enc)
Definition: win32ole.c:863
tagIEVENTSINKOBJ::pTypeInfo
ITypeInfo * pTypeInfo
Definition: win32ole.c:200
olemethoddata::pOwnerTypeInfo
ITypeInfo * pOwnerTypeInfo
Definition: win32ole.c:267
olemethod_set_member
static VALUE olemethod_set_member(VALUE self, ITypeInfo *pTypeInfo, ITypeInfo *pOwnerTypeInfo, int index, VALUE name)
Definition: win32ole.c:6528
Qfalse
return Qfalse
Definition: tcltklib.c:6779
rb_Float
VALUE rb_Float(VALUE)
Definition: object.c:2647
ole_variable_visible
static VALUE ole_variable_visible(ITypeInfo *pTypeInfo, UINT var_index)
Definition: win32ole.c:6364
ole_initialize
static void ole_initialize(void)
Definition: win32ole.c:1226
mWIN32OLE_VARIANT
VALUE mWIN32OLE_VARIANT
Definition: win32ole.c:212
_Win32OLEIDispatch::refcount
ULONG refcount
Definition: win32ole.c:698
g_lcid_installed
static BOOL g_lcid_installed
Definition: win32ole.c:229
RARRAY_LEN
#define RARRAY_LEN(a)
IEventSinkVtbl::QueryInterface
STDMETHOD() QueryInterface(PEVENTSINK, REFIID, LPVOID *)
NUM2DBL
#define NUM2DBL(x)
Qnil
#define Qnil
Definition: tcltklib.c:1896
StringValuePtr
#define StringValuePtr(v)
elem
volatile VALUE elem
Definition: tcltklib.c:9713
ole_variable_value
static VALUE ole_variable_value(ITypeInfo *pTypeInfo, UINT var_index)
Definition: win32ole.c:6320
val
#define val
Definition: tcltklib.c:1949
foletype_src_type
static VALUE foletype_src_type(VALUE self)
Definition: win32ole.c:5914
ole_vstr2wc
static LPWSTR ole_vstr2wc(VALUE vstr)
Definition: win32ole.c:1304
rbtime2vtdate
static double rbtime2vtdate(VALUE tmobj)
Definition: win32ole.c:825
ole_type_helpcontext
static VALUE ole_type_helpcontext(ITypeInfo *pTypeInfo)
Definition: win32ole.c:5951
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:510
DWORD
IUnknown DWORD
Definition: win32ole.c:149
ole_uninitialize_hook
static void ole_uninitialize_hook(rb_event_flag_t evflag, VALUE data, VALUE self, ID mid, VALUE klass)
Definition: win32ole.c:1220
ole_ptrtype2val
static VALUE ole_ptrtype2val(ITypeInfo *pTypeInfo, TYPEDESC *pTypeDesc, VALUE typedetails)
Definition: win32ole.c:4592
foletype_s_ole_classes
static VALUE foletype_s_ole_classes(VALUE self, VALUE typelib)
Definition: win32ole.c:4808
ole_set_byref
static void ole_set_byref(VARIANT *realvar, VARIANT *var, VARTYPE vt)
Definition: win32ole.c:1799
vsnprintf
vsnprintf(buf, BUFSIZ, fmt, args)
_Win32OLEIDispatch::obj
VALUE obj
Definition: win32ole.c:699
str
static VALUE char * str
Definition: tcltklib.c:3547
typelib_file
static VALUE typelib_file(VALUE ole)
Definition: win32ole.c:2505
g_ole_initialized
#define g_ole_initialized
Definition: win32ole.c:223
oletypelib_search_registry
static VALUE oletypelib_search_registry(VALUE self, VALUE typelib)
Definition: win32ole.c:5109
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:424
Check_Type
#define Check_Type(v, t)
StringValueCStr
#define StringValueCStr(v)
folemethod_helpcontext
static VALUE folemethod_helpcontext(VALUE self)
Definition: win32ole.c:7031
flags
int flags
Definition: tcltklib.c:3023
ID
unsigned long ID
Definition: ripper.y:105
va_end
va_end(args)
IEventSink
Definition: win32ole.c:154
oletypelib_get_libattr
static void oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr)
Definition: win32ole.c:4955
rb_define_const
void rb_define_const(VALUE, const char *, VALUE)
Definition: variable.c:2202
pctinfo
static UINT __RPC_FAR * pctinfo
Definition: win32ole.c:303
ole_type_from_itypeinfo
static VALUE ole_type_from_itypeinfo(ITypeInfo *pTypeInfo)
Definition: win32ole.c:4360
oledata
Definition: win32ole.c:254
rb_str_cat2
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:1982
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:499
cWIN32OLE_EVENT
VALUE cWIN32OLE_EVENT
Definition: win32ole.c:209
imessage_filter
static IMessageFilter imessage_filter
Definition: win32ole.c:243
rb_eNoMethodError
VALUE rb_eNoMethodError
Definition: error.c:519
obj
static VALUE VALUE obj
Definition: tcltklib.c:3158
RSTRING_LEN
#define RSTRING_LEN(str)
FIX2INT
#define FIX2INT(x)
INT2FIX
#define INT2FIX(i)
idx
int idx
Definition: tcltklib.c:9716
rb_ary_store
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:719
message_filter
static IMessageFilterVtbl message_filter
Definition: win32ole.c:242
reg_get_val
static VALUE reg_get_val(HKEY hkey, const char *subkey)
Definition: win32ole.c:2358
tagIEVENTSINKOBJ
Definition: win32ole.c:195
T_STRING
#define T_STRING
olevariantdata::var
VARIANT var
Definition: win32ole.c:296
fole_s_allocate
static VALUE fole_s_allocate(VALUE klass)
Definition: win32ole.c:2024
fole_getproperty2
static VALUE fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
Definition: win32ole.c:3809
oletypelib_free
static void oletypelib_free(struct oletypelibdata *poletypelib)
Definition: win32ole.c:1267
ole_method_invkind
static VALUE ole_method_invkind(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:6708
fole_invoke
static VALUE fole_invoke(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:3583
get_locked_safe_array
static SAFEARRAY * get_locked_safe_array(VALUE val)
Definition: win32ole.c:8792
ole_type_progid
static VALUE ole_type_progid(ITypeInfo *pTypeInfo)
Definition: win32ole.c:5698
code_page_installed
static BOOL code_page_installed(UINT cp)
Definition: win32ole.c:3033
foletypelib_path
static VALUE foletypelib_path(VALUE self)
Definition: win32ole.c:5420
param
pure parser lex param
Definition: ripper.y:686
method
volatile ID method
Definition: tcltklib.c:3599
fole_typelib
static VALUE fole_typelib(VALUE self)
Definition: win32ole.c:4444
rb_call_super
VALUE rb_call_super(int, const VALUE *)
Definition: vm_eval.c:273
ole_set_safe_array
static void ole_set_safe_array(long n, SAFEARRAY *psa, long *pid, long *pub, VALUE val, long dim, VARTYPE vt)
Definition: win32ole.c:1492
foletype_name
static VALUE foletype_name(VALUE self)
Definition: win32ole.c:5595
folevariant_set_value
static VALUE folevariant_set_value(VALUE self, VALUE val)
Definition: win32ole.c:9053
ole_wc2mb
static char * ole_wc2mb(LPWSTR pw)
Definition: win32ole.c:1067
foletypelib_name
static VALUE foletypelib_name(VALUE self)
Definition: win32ole.c:5274
foletypelib_visible
static VALUE foletypelib_visible(VALUE self)
Definition: win32ole.c:5460
folemethod_initialize
static VALUE folemethod_initialize(VALUE self, VALUE oletype, VALUE method)
Definition: win32ole.c:6569
hash2named_arg
static VALUE hash2named_arg(VALUE pair, struct oleparam *pOp)
Definition: win32ole.c:3285
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
folevariable_inspect
static VALUE folevariable_inspect(VALUE self)
Definition: win32ole.c:6513
ole_methods_from_typeinfo
static VALUE ole_methods_from_typeinfo(ITypeInfo *pTypeInfo, int mask)
Definition: win32ole.c:4205
iTInfo
static UINT iTInfo
Definition: win32ole.c:304
err
int err
Definition: win32.c:87
I8_2_NUM
#define I8_2_NUM
Definition: win32ole.c:138
ole_type_guid
static VALUE ole_type_guid(ITypeInfo *pTypeInfo)
Definition: win32ole.c:5663
ALLOCA_N
#define ALLOCA_N(type, n)
rb_eIndexError
VALUE rb_eIndexError
Definition: error.c:513
fole_activex_initialize
static VALUE fole_activex_initialize(VALUE self)
Definition: win32ole.c:4773
key
static int VALUE key
Definition: tkutil.c:265
oleparamdata::index
UINT index
Definition: win32ole.c:280
encoding.h
rgDispId
static REFIID LPOLESTR __RPC_FAR UINT LCID DISPID __RPC_FAR * rgDispId
Definition: win32ole.c:305
tagIEVENTSINKOBJ::m_event_id
int m_event_id
Definition: win32ole.c:199
V_INTREF
#define V_INTREF(X)
Definition: win32ole.c:89
add_event_call_back
static void add_event_call_back(VALUE obj, VALUE event, VALUE data)
Definition: win32ole.c:8398
olevariabledata::index
UINT index
Definition: win32ole.c:274
STDMETHODIMP_
STDMETHODIMP_(ULONG)
Definition: win32ole.c:7611
folevariant_ary_aset
static VALUE folevariant_ary_aset(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:8943
folemethod_name
static VALUE folemethod_name(VALUE self)
Definition: win32ole.c:6600
ole_raise
static void ole_raise(HRESULT hr, VALUE ecs, const char *fmt,...)
Definition: win32ole.c:1193
rb_eval_string
VALUE rb_eval_string(const char *)
Evaluates the given string in an isolated binding.
Definition: vm_eval.c:1387
set_ole_codepage
static void set_ole_codepage(UINT cp)
Definition: win32ole.c:961
dimension
static long dimension(VALUE val)
Definition: win32ole.c:1524
folevariable_variable_kind
static VALUE folevariable_variable_kind(VALUE self)
Definition: win32ole.c:6458
ole_cp2encoding
static rb_encoding * ole_cp2encoding(UINT cp)
Definition: win32ole.c:1013
fole_put_methods
static VALUE fole_put_methods(VALUE self)
Definition: win32ole.c:4337
fole_s_set_code_page
static VALUE fole_s_set_code_page(VALUE self, VALUE vcp)
Definition: win32ole.c:3055
argv
VALUE * argv
Definition: tcltklib.c:1971
rb_hash_aset
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
fev_set_handler
static VALUE fev_set_handler(VALUE self, VALUE val)
Definition: win32ole.c:8621
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1539
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:934
ole_create_dcom
static VALUE ole_create_dcom(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:2616
memcpy
memcpy(buf+1, str, len)
myCPINFOEX::DefaultChar
BYTE DefaultChar[2]
Definition: win32ole.c:1005
ary_len_of_dim
static long ary_len_of_dim(VALUE ary, long dim)
Definition: win32ole.c:1543
id
const int id
Definition: nkf.c:209
folevariant_value
static VALUE folevariant_value(VALUE self)
Definition: win32ole.c:8992
fev_s_msg_loop
static VALUE fev_s_msg_loop(VALUE klass)
Definition: win32ole.c:8390
folevariant_s_allocate
static VALUE folevariant_s_allocate(VALUE klass)
Definition: win32ole.c:8648
foletypelib_major_version
static VALUE foletypelib_major_version(VALUE self)
Definition: win32ole.c:5326
TRUE
#define TRUE
Definition: nkf.h:175
result
q result
Definition: tcltklib.c:7070
foletype_helpstring
static VALUE foletype_helpstring(VALUE self)
Definition: win32ole.c:5879
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1270
evs_length
static VALUE evs_length(void)
Definition: win32ole.c:8576
value
volatile VALUE value
Definition: tcltklib.c:9442
enc2cp_table
static st_table * enc2cp_table
Definition: win32ole.c:241
foleparam_retval
static VALUE foleparam_retval(VALUE self)
Definition: win32ole.c:7485
ole_val_ary2variant_ary
static HRESULT ole_val_ary2variant_ary(VALUE val, VARIANT *var, VARTYPE vt)
Definition: win32ole.c:1569
foletype_progid
static VALUE foletype_progid(VALUE self)
Definition: win32ole.c:5725
reg_get_val2
static VALUE reg_get_val2(HKEY hkey, const char *subkey)
Definition: win32ole.c:2386
rb_gc_register_mark_object
void rb_gc_register_mark_object(VALUE)
Definition: gc.c:2980
ole_type_major_version
static VALUE ole_type_major_version(ITypeInfo *pTypeInfo)
Definition: win32ole.c:5768
rb_String
VALUE rb_String(VALUE)
Definition: object.c:2738
oletypelibdata::pTypeLib
ITypeLib * pTypeLib
Definition: win32ole.c:259
OLE_RELEASE_TYPEATTR
#define OLE_RELEASE_TYPEATTR(X, Y)
Definition: win32ole.c:114
ole_propertyput
static VALUE ole_propertyput(VALUE self, VALUE property, VALUE value)
Definition: win32ole.c:3898
fole_get_methods
static VALUE fole_get_methods(VALUE self)
Definition: win32ole.c:4321
rb_scan_args
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1570
typelib_file_from_clsid
static VALUE typelib_file_from_clsid(VALUE ole)
Definition: win32ole.c:2419
NUM2UINT
#define NUM2UINT(x)
rb_block_call
VALUE rb_block_call(VALUE, ID, int, VALUE *, VALUE(*)(ANYARGS), VALUE)
Definition: vm_eval.c:1131
retval
VALUE retval
Definition: tcltklib.c:7830
foleparam_initialize
static VALUE foleparam_initialize(VALUE self, VALUE olemethod, VALUE n)
Definition: win32ole.c:7302
oletypelib_search_registry2
static VALUE oletypelib_search_registry2(VALUE self, VALUE args)
Definition: win32ole.c:5037
ole_invoke
static VALUE ole_invoke(int argc, VALUE *argv, VALUE self, USHORT wFlags, BOOL is_bracket)
Definition: win32ole.c:3337
gole32
static HINSTANCE gole32
Definition: win32ole.c:231
ole_method_size_params
static VALUE ole_method_size_params(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:7101
cWIN32OLE_TYPELIB
VALUE cWIN32OLE_TYPELIB
Definition: win32ole.c:204
type
int type
Definition: tcltklib.c:111
rb_define_dummy_encoding
int rb_define_dummy_encoding(const char *name)
Definition: encoding.c:400
T_FIXNUM
#define T_FIXNUM
dwPendingType
static HTASK DWORD DWORD dwPendingType
Definition: win32ole.c:682
ole_method_size_opt_params
static VALUE ole_method_size_opt_params(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:7133
failed_load_conv51932
static void failed_load_conv51932(void)
Definition: win32ole.c:929
ole_method_sub
static VALUE ole_method_sub(VALUE self, ITypeInfo *pOwnerTypeInfo, ITypeInfo *pTypeInfo, VALUE name)
Definition: win32ole.c:4099
argc
int argc
Definition: tcltklib.c:1970
lcid
static UINT LCID lcid
Definition: win32ole.c:304
IEventSink::lpVtbl
struct IEventSinkVtbl * lpVtbl
Definition: win32ole.c:155
vtdate2rbtime
static VALUE vtdate2rbtime(double date)
Definition: win32ole.c:842
free_enc2cp
static void free_enc2cp(void)
Definition: win32ole.c:9074
folemethod_size_params
static VALUE folemethod_size_params(VALUE self)
Definition: win32ole.c:7125
ole_uninitialize
void ole_uninitialize(void)
Definition: win32ole.c:1212
ENC_MACHING_CP
#define ENC_MACHING_CP(enc, encname, cp)
Definition: win32ole.c:861
g_nil_to
static VARTYPE g_nil_to
Definition: win32ole.c:240
fev_get_handler
static VALUE fev_get_handler(VALUE self)
Definition: win32ole.c:8634
foletypelib_s_allocate
static VALUE foletypelib_s_allocate(VALUE klass)
Definition: win32ole.c:5160
oletypelib_set_member
static VALUE oletypelib_set_member(VALUE self, ITypeLib *pTypeLib)
Definition: win32ole.c:4938
dwRejectType
static HTASK DWORD DWORD dwRejectType
Definition: win32ole.c:666
conv_51932
#define conv_51932(cp)
Definition: win32ole.c:958
fole_s_get_locale
static VALUE fole_s_get_locale(VALUE self)
Definition: win32ole.c:3075
ole_param_default
static VALUE ole_param_default(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
Definition: win32ole.c:7494
folemethod_return_vtype
static VALUE folemethod_return_vtype(VALUE self)
Definition: win32ole.c:6666
myCPINFOEX::UnicodeDefaultChar
WCHAR UnicodeDefaultChar
Definition: win32ole.c:1007
ole_variable_ole_type_detail
static VALUE ole_variable_ole_type_detail(ITypeInfo *pTypeInfo, UINT var_index)
Definition: win32ole.c:6286
fole_setproperty
static VALUE fole_setproperty(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:3870
rb_ensure
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:804
cmd
const char * cmd
Definition: tcltklib.c:278
foleparam_name
static VALUE foleparam_name(VALUE self)
Definition: win32ole.c:7323
ole_method_helpcontext
static VALUE ole_method_helpcontext(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:7010
ole_type_helpstring
static VALUE ole_type_helpstring(ITypeInfo *pTypeInfo)
Definition: win32ole.c:5859
ole_variables
static VALUE ole_variables(ITypeInfo *pTypeInfo)
Definition: win32ole.c:6122
OLE_ADDREF
#define OLE_ADDREF(X)
Definition: win32ole.c:111
ole_method_docinfo_from_type
static VALUE ole_method_docinfo_from_type(ITypeInfo *pTypeInfo, UINT method_index, BSTR *name, BSTR *helpstr, DWORD *helpcontext, BSTR *helpfile)
Definition: win32ole.c:6926
foletypelib_s_typelibs
static VALUE foletypelib_s_typelibs(VALUE self)
Definition: win32ole.c:4976
fev_s_allocate
static VALUE fev_s_allocate(VALUE klass)
Definition: win32ole.c:8271
g_IsEventSinkVtblInitialized
static BOOL g_IsEventSinkVtblInitialized
Definition: win32ole.c:7580
free
#define free(x)
Definition: dln.c:50
oleparam_ole_param_from_index
static VALUE oleparam_ole_param_from_index(VALUE self, ITypeInfo *pTypeInfo, UINT method_index, int param_index)
Definition: win32ole.c:7257
foletypelib_initialize
static VALUE foletypelib_initialize(VALUE self, VALUE args)
Definition: win32ole.c:5197
fole_getproperty_with_bracket
static VALUE fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:3892
msg
volatile VALUE msg
Definition: tcltklib.c:3100
foletypelib_library_name
static VALUE foletypelib_library_name(VALUE self)
Definition: win32ole.c:5489
T_BIGNUM
#define T_BIGNUM
oletype_free
static void oletype_free(struct oletypedata *poletype)
Definition: win32ole.c:1274
ole_each_sub
static VALUE ole_each_sub(VALUE pEnumV)
Definition: win32ole.c:3975
rb_define_module_under
VALUE rb_define_module_under(VALUE outer, const char *name)
Definition: class.c:637
folemethod_offset_vtbl
static VALUE folemethod_offset_vtbl(VALUE self)
Definition: win32ole.c:7093
T_TRUE
#define T_TRUE
end
gz end
Definition: zlib.c:2272
rb_to_id
ID rb_to_id(VALUE)
Definition: string.c:8154
folemethod_s_allocate
static VALUE folemethod_s_allocate(VALUE klass)
Definition: win32ole.c:6542
V_UNION1
#define V_UNION1(X, Y)
Definition: win32ole.c:62
oletypedata::pTypeInfo
ITypeInfo * pTypeInfo
Definition: win32ole.c:263
oleparam::dp
DISPPARAMS dp
Definition: win32ole.c:290
va_init_list
#define va_init_list(a, b)
Definition: tcltklib.c:61
rb_ivar_set
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1128
V_INT
#define V_INT(X)
Definition: win32ole.c:85
find_coclass
static HRESULT find_coclass(ITypeInfo *pTypeInfo, TYPEATTR *pTypeAttr, ITypeInfo **pTypeInfo2, TYPEATTR **pTypeAttr2)
Definition: win32ole.c:8063
olemethoddata
Definition: win32ole.c:266
arg
arg
Definition: ripper.y:1315
foletype_initialize
static VALUE foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass)
Definition: win32ole.c:5559
T_SYMBOL
#define T_SYMBOL
fole_each
static VALUE fole_each(VALUE self)
Definition: win32ole.c:4013
rb_str_cat
VALUE rb_str_cat(VALUE, const char *, long)
Definition: string.c:1963
ary_ole_event
static VALUE ary_ole_event
Definition: win32ole.c:215
rb_enc_get
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:772
oleeventdata
Definition: win32ole.c:283
size
int size
Definition: encoding.c:52
oletypedata
Definition: win32ole.c:262
oleeventdata::dwCookie
DWORD dwCookie
Definition: win32ole.c:284
ppvObject
static REFIID void __RPC_FAR *__RPC_FAR * ppvObject
Definition: win32ole.c:300
pIMultiLanguage
#define pIMultiLanguage
Definition: win32ole.c:251
folemethod_params
static VALUE folemethod_params(VALUE self)
Definition: win32ole.c:7217
fole_respond_to
static VALUE fole_respond_to(VALUE self, VALUE method)
Definition: win32ole.c:4522
rb_obj_is_kind_of
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Definition: object.c:582
HWND
IUnknown COSERVERINFO MULTI_QI *typedef HWND(WINAPI FNHTMLHELP)(HWND hwndCaller
Definition: win32ole.c:151
T_CLASS
#define T_CLASS
fole_s_free
static VALUE fole_s_free(VALUE self, VALUE obj)
Definition: win32ole.c:2933
oledata::pDispatch
IDispatch * pDispatch
Definition: win32ole.c:255
t
int t
Definition: ripper.c:14699
OLE_RELEASE
#define OLE_RELEASE(X)
Definition: win32ole.c:109
pDispParams
static DISPID REFIID LCID WORD DISPPARAMS __RPC_FAR * pDispParams
Definition: win32ole.c:306
HRESULT
typedef HRESULT(STDAPICALLTYPE FNCOCREATEINSTANCEEX)(REFCLSID
DATA_PTR
DATA_PTR(self)
gCoCreateInstanceEx
static FNCOCREATEINSTANCEEX * gCoCreateInstanceEx
Definition: win32ole.c:232
IEventSinkVtbl
Definition: win32ole.c:160
folevariant_s_array
static VALUE folevariant_s_array(VALUE klass, VALUE dims, VALUE vvt)
Definition: win32ole.c:8676
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ripper.y:1426
ALLOC_N
#define ALLOC_N(type, n)
EVENTSINK_GetTypeInfo
STDMETHODIMP EVENTSINK_GetTypeInfo(PEVENTSINK pEV, UINT info, LCID lcid, ITypeInfo **pInfo)
Definition: win32ole.c:7630
ary2ptr_dispparams
static void ary2ptr_dispparams(VALUE ary, DISPPARAMS *pdispparams)
Definition: win32ole.c:7774
ev
static const unsigned char ev[]
Definition: nkf.c:607
exec_callback
static VALUE exec_callback(VALUE arg)
Definition: win32ole.c:7787
klass
klass
Definition: tcltklib.c:3504
INT2NUM
#define INT2NUM(x)
find_iid
static HRESULT find_iid(VALUE ole, char *pitf, IID *piid, ITypeInfo **ppTypeInfo)
Definition: win32ole.c:7952
folevariable_name
static VALUE folevariable_name(VALUE self)
Definition: win32ole.c:6238
ole_bind_obj
static VALUE ole_bind_obj(VALUE moniker, int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:2666
Data_Get_Struct
#define Data_Get_Struct(obj, type, sval)
foletypelib_inspect
static VALUE foletypelib_inspect(VALUE self)
Definition: win32ole.c:5536
fole_query_interface
static VALUE fole_query_interface(VALUE self, VALUE str_iid)
Definition: win32ole.c:4477
rb_respond_to
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:1564
reference_count
static ULONG reference_count(struct oledata *pole)
Definition: win32ole.c:2897
ole_event_free
static void ole_event_free(struct oleeventdata *poleev)
Definition: win32ole.c:8260
foletype_ole_typelib
static VALUE foletype_ole_typelib(VALUE self)
Definition: win32ole.c:5988
hash2result
static VALUE hash2result(VALUE hash)
Definition: win32ole.c:7764
ole_method_helpstring
static VALUE ole_method_helpstring(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:6948
rescue_callback
static VALUE rescue_callback(VALUE arg)
Definition: win32ole.c:7797
folemethod_helpstring
static VALUE folemethod_helpstring(VALUE self)
Definition: win32ole.c:6971
st_insert
int st_insert(st_table *, st_data_t, st_data_t)
rb_apply
VALUE rb_apply(VALUE, ID, VALUE)
Calls a method.
Definition: vm_eval.c:745
ole_method_return_type
static VALUE ole_method_return_type(ITypeInfo *pTypeInfo, UINT method_index)
Definition: win32ole.c:6606
st.h
rb_ary_concat
VALUE rb_ary_concat(VALUE x, VALUE y)
Definition: array.c:3382
cWIN32OLE_METHOD
VALUE cWIN32OLE_METHOD
Definition: win32ole.c:207
olemethoddata::index
UINT index
Definition: win32ole.c:269
ole_type_src_type
static VALUE ole_type_src_type(ITypeInfo *pTypeInfo)
Definition: win32ole.c:5887
WIN32OLE_VERSION
#define WIN32OLE_VERSION
Definition: win32ole.c:146
RSTRING_LENINT
#define RSTRING_LENINT(str)
ole_ienum_free
static VALUE ole_ienum_free(VALUE pEnumV)
Definition: win32ole.c:3991
rb_safe_level
#define rb_safe_level()
Definition: tcltklib.c:94
rb_write_error
void rb_write_error(const char *)
Definition: io.c:7064
T_MODULE
#define T_MODULE
foletypelib_version
static VALUE foletypelib_version(VALUE self)
Definition: win32ole.c:5301
ole_freeexceptinfo
static void ole_freeexceptinfo(EXCEPINFO *pExInfo)
Definition: win32ole.c:1143
oleparam
Definition: win32ole.c:289
NUM2INT
#define NUM2INT(x)
id_events
static ID id_events
Definition: win32ole.c:216
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:234
rb_id2name
const char * rb_id2name(ID id)
Definition: ripper.c:17005
rb_errinfo
#define rb_errinfo()
Definition: tcltklib.c:89
rb_str_intern
VALUE rb_str_intern(VALUE)
Definition: string.c:7211
g_cp_installed
static BOOL g_cp_installed
Definition: win32ole.c:228
puArgErr
static DISPID REFIID LCID WORD DISPPARAMS __RPC_FAR VARIANT __RPC_FAR EXCEPINFO __RPC_FAR UINT __RPC_FAR * puArgErr
Definition: win32ole.c:306
folevariable_visible
static VALUE folevariable_visible(VALUE self)
Definition: win32ole.c:6402
pszFile
IUnknown COSERVERINFO MULTI_QI *typedef LPCSTR pszFile
Definition: win32ole.c:151
make_version_str
static VALUE make_version_str(VALUE major, VALUE minor)
Definition: win32ole.c:5020
V_I1REF
#define V_I1REF(X)
Definition: win32ole.c:77
ppTInfo
static UINT LCID ITypeInfo __RPC_FAR *__RPC_FAR * ppTInfo
Definition: win32ole.c:304
cWIN32OLE_VARIANT
VALUE cWIN32OLE_VARIANT
Definition: win32ole.c:210
ole_type_minor_version
static VALUE ole_type_minor_version(ITypeInfo *pTypeInfo)
Definition: win32ole.c:5798
fole_initialize
static VALUE fole_initialize(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:3229
oletypelib_from_guid
static HRESULT oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib)
Definition: win32ole.c:5395
e
BDIGIT e
Definition: bigdecimal.c:5085
rb_mark_hash
void rb_mark_hash(struct st_table *)
Definition: gc.c:2411
cWIN32OLE_VARIABLE
VALUE cWIN32OLE_VARIABLE
Definition: win32ole.c:206
foletype_typekind
static VALUE foletype_typekind(VALUE self)
Definition: win32ole.c:5851
V_UINT
#define V_UINT(X)
Definition: win32ole.c:93
rb_hash_aref
VALUE rb_hash_aref(VALUE, VALUE)
Definition: hash.c:560
rb_funcall2
VALUE rb_funcall2(VALUE, ID, int, const VALUE *)
Calls a method.
Definition: vm_eval.c:805
NUM2CHR
#define NUM2CHR(x)
VALUE
unsigned long VALUE
Definition: ripper.y:104
rb_fix2str
VALUE rb_fix2str(VALUE, int)
Definition: numeric.c:2546
rb_enc_find_index
int rb_enc_find_index(const char *name)
Definition: encoding.c:635
ole_free
static void ole_free(struct oledata *pole)
Definition: win32ole.c:1260
folevariant_vartype
static VALUE folevariant_vartype(VALUE self)
Definition: win32ole.c:9031
fole_s_create_guid
static VALUE fole_s_create_guid(VALUE self)
Definition: win32ole.c:3136
foletype_variables
static VALUE foletype_variables(VALUE self)
Definition: win32ole.c:6184
version
static void version(void)
Definition: nkf.c:898
ole_param_ole_type
static VALUE ole_param_ole_type(ITypeInfo *pTypeInfo, UINT method_index, UINT index)
Definition: win32ole.c:7329
major
int major
Definition: tcltklib.c:109
ole_init_cp
static UINT ole_init_cp(void)
Definition: win32ole.c:990
snprintf
#define snprintf
foleparam_optional
static VALUE foleparam_optional(VALUE self)
Definition: win32ole.c:7466
ary2safe_array_index
static long * ary2safe_array_index(int ary_size, VALUE *ary, SAFEARRAY *psa)
Definition: win32ole.c:8813
folemethod_visible
static VALUE folemethod_visible(VALUE self)
Definition: win32ole.c:6808
S_OK
return S_OK
Definition: win32ole.c:769
dispIdMember
static DISPID dispIdMember
Definition: win32ole.c:306
previous_filter
static IMessageFilter * previous_filter
Definition: win32ole.c:244
rb_intern
#define rb_intern(str)
olevariabledata
Definition: win32ole.c:272
v
BDIGIT v
Definition: bigdecimal.c:5656
val2variant_ptr
static VOID * val2variant_ptr(VALUE val, VARIANT *var, VARTYPE vt)
Definition: win32ole.c:8898
oletypelib_path
static VALUE oletypelib_path(VALUE guid, VALUE version)
Definition: win32ole.c:5362
rb_cData
RUBY_EXTERN VALUE rb_cData
Definition: ripper.y:1433
rb_add_event_hook
void rb_add_event_hook(rb_event_hook_func_t func, rb_event_flag_t events, VALUE data)
Definition: vm_trace.c:135
ole_msg_loop
static void ole_msg_loop(void)
Definition: win32ole.c:1251
NULL
#define NULL
Definition: _sdbm.c:103
name
const char * name
Definition: nkf.c:208
foleparam_s_allocate
static VALUE foleparam_s_allocate(VALUE klass)
Definition: win32ole.c:7243
fole_s_show_help
static VALUE fole_s_show_help(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:2979
ole_type_typekind
static VALUE ole_type_typekind(ITypeInfo *pTypeInfo)
Definition: win32ole.c:5828
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1344
ULONG
static ULONG(STDMETHODCALLTYPE AddRef)(IDispatch __RPC_FAR *This)
Definition: win32ole.c:614
olemethod_from_typeinfo
static VALUE olemethod_from_typeinfo(VALUE self, ITypeInfo *pTypeInfo, VALUE name)
Definition: win32ole.c:4136
installed_code_page_proc
static BOOL CALLBACK installed_code_page_proc(LPTSTR str)
Definition: win32ole.c:3024
ole_excepinfo2msg
static VALUE ole_excepinfo2msg(EXCEPINFO *pExInfo)
Definition: win32ole.c:1151
default_inspect
static VALUE default_inspect(VALUE self, const char *class_name)
Definition: win32ole.c:2003
fev_off_event
static VALUE fev_off_event(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:8503
riid
static REFIID riid
Definition: win32ole.c:300
folevariable_ole_type
static VALUE folevariable_ole_type(VALUE self)
Definition: win32ole.c:6278
rb_eArgError
VALUE rb_eArgError
Definition: error.c:512
rb_during_gc
int rb_during_gc(void)
Definition: gc.c:3117
foleparam_ole_type
static VALUE foleparam_ole_type(VALUE self)
Definition: win32ole.c:7354
foletype_source_ole_types
static VALUE foletype_source_ole_types(VALUE self)
Definition: win32ole.c:6064
st_free_table
void st_free_table(st_table *)
Definition: st.c:334
V_UI2REF
#define V_UI2REF(X)
Definition: win32ole.c:81
st
Tcl_Interp *int * st
Definition: stubs.c:510
T_FALSE
#define T_FALSE
tagIEVENTSINKOBJ::m_iid
IID m_iid
Definition: win32ole.c:198
fole_s_ole_initialize
static VALUE fole_s_ole_initialize(VALUE self)
Definition: win32ole.c:3161
myCPINFOEX
Definition: win32ole.c:1003
fole_missing
static VALUE fole_missing(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:4076
pVarResult
static DISPID REFIID LCID WORD DISPPARAMS __RPC_FAR VARIANT __RPC_FAR * pVarResult
Definition: win32ole.c:306
cp
STATIC void unsigned char * cp
Definition: crypt.c:307
reg_open_vkey
static LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey)
Definition: win32ole.c:2337
parg
VALUE * parg
Definition: win32ole.c:787
rb_enc_from_index
rb_encoding * rb_enc_from_index(int index)
Definition: encoding.c:548
OnigEncodingTypeST
Definition: ripper.y:161
NUM2UI8
#define NUM2UI8
Definition: win32ole.c:141
fole_s_const_load
static VALUE fole_s_const_load(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:2799
Init_win32ole
void Init_win32ole(void)
Definition: win32ole.c:9080
reg_open_key
static LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey)
Definition: win32ole.c:2331
len
size_t len
Definition: tcltklib.c:3568
foletype_methods
static VALUE foletype_methods(VALUE self)
Definition: win32ole.c:6204
evs_push
static VALUE evs_push(VALUE ev)
Definition: win32ole.c:8557
fole_s_connect
static VALUE fole_s_connect(int argc, VALUE *argv, VALUE self)
Definition: win32ole.c:2717