Ruby 2.1.5p273(2014-11-13revision48405)

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