DEFINITIONS
This source file includes following functions.
- time2d
- d2time
- civil2jd
- jd2civil
- double2time
- time_object2date
- date2time_str
- ole_wc2mb
- ole_hresult2msg
- ole_excepinfo2msg
- ole_raise
- ole_uninitialize
- ole_initialize
- ole_msg_loop
- ole_free
- oletype_free
- olemethod_free
- olevariable_free
- oleparam_free
- ole_mb2wc
- ole_wc2vstr
- ole_ary_m_entry
- ole_set_safe_array
- ole_val2variant
- ole_set_member
- fole_s_allocate
- create_win32ole_object
- ole_variant2val
- reg_open_key
- reg_open_vkey
- reg_enum_key
- reg_get_val
- typelib_file_from_clsid
- typelib_file_from_typelib
- typelib_file
- ole_const_load
- clsid_from_remote
- ole_create_dcom
- ole_bind_obj
- fole_s_connect
- fole_s_const_load
- ole_classes_from_typelib
- reference_count
- fole_s_reference_count
- fole_s_free
- ole_show_help
- fole_s_show_help
- fole_initialize
- hash2named_arg
- ole_invoke
- fole_invoke
- ole_invoke2
- fole_invoke2
- fole_getproperty2
- fole_setproperty2
- fole_setproperty
- fole_getproperty
- ole_propertyput
- fole_free
- ole_each_sub
- ole_ienum_free
- fole_each
- fole_missing
- ole_method_sub
- olemethod_from_typeinfo
- ole_methods_sub
- ole_methods_from_typeinfo
- typeinfo_from_ole
- ole_methods
- fole_methods
- fole_get_methods
- fole_put_methods
- fole_func_methods
- fole_obj_help
- ole_docinfo_from_type
- ole_usertype2val
- ole_ptrtype2val
- ole_typedesc2val
- fole_method_help
- foletype_s_ole_classes
- foletype_s_typelibs
- foletype_s_progids
- foletype_s_allocate
- oletype_set_member
- oleclass_from_typelib
- foletype_initialize
- foletype_name
- ole_ole_type
- foletype_ole_type
- ole_type_guid
- foletype_guid
- ole_type_progid
- foletype_progid
- ole_type_visible
- foletype_visible
- ole_type_major_version
- foletype_major_version
- ole_type_minor_version
- foletype_minor_version
- ole_type_typekind
- foletype_typekind
- ole_type_helpstring
- foletype_helpstring
- ole_type_src_type
- foletype_src_type
- ole_type_helpfile
- foletype_helpfile
- ole_type_helpcontext
- foletype_helpcontext
- ole_variables
- foletype_variables
- foletype_methods
- folevariable_name
- ole_variable_ole_type
- folevariable_ole_type
- ole_variable_ole_type_detail
- folevariable_ole_type_detail
- ole_variable_value
- folevariable_value
- ole_variable_visible
- folevariable_visible
- ole_variable_kind
- folevariable_variable_kind
- ole_variable_varkind
- folevariable_varkind
- olemethod_set_member
- folemethod_s_allocate
- folemethod_initialize
- folemethod_name
- ole_method_return_type
- folemethod_return_type
- ole_method_return_vtype
- folemethod_return_vtype
- ole_method_return_type_detail
- folemethod_return_type_detail
- ole_method_invkind
- ole_method_invoke_kind
- folemethod_invkind
- folemethod_invoke_kind
- ole_method_visible
- folemethod_visible
- ole_method_event
- folemethod_event
- folemethod_event_interface
- ole_method_docinfo_from_type
- ole_method_helpstring
- folemethod_helpstring
- ole_method_helpfile
- folemethod_helpfile
- ole_method_helpcontext
- folemethod_helpcontext
- ole_method_dispid
- folemethod_dispid
- ole_method_offset_vtbl
- folemethod_offset_vtbl
- ole_method_size_params
- folemethod_size_params
- ole_method_size_opt_params
- folemethod_size_opt_params
- ole_method_params
- folemethod_params
- foleparam_name
- ole_param_ole_type
- foleparam_ole_type
- ole_param_ole_type_detail
- foleparam_ole_type_detail
- ole_param_flag_mask
- foleparam_input
- foleparam_output
- foleparam_optional
- foleparam_retval
- ole_param_default
- foleparam_default
- EVENTSINK_QueryInterface
- STDMETHODIMP_
- STDMETHODIMP_
- EVENTSINK_GetTypeInfoCount
- EVENTSINK_GetTypeInfo
- EVENTSINK_GetIDsOfNames
- ole_search_event
- val2ptr_variant
- ary2ptr_dispparams
- EVENTSINK_Invoke
- EVENTSINK_Constructor
- EVENTSINK_Destructor
- find_iid
- find_default_source
- ole_event_free
- fev_s_allocate
- fev_initialize
- fev_s_msg_loop
- add_event_call_back
- ev_on_event
- fev_on_event
- fev_on_event_with_outargs
- Init_win32ole
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include "ruby.h"
20 #include "st.h"
21 #include <windows.h>
22 #include <ocidl.h>
23 #include <ole2.h>
24 #ifdef HAVE_STDARG_PROTOTYPES
25 #include <stdarg.h>
26 #define va_init_list(a,b) va_start(a,b)
27 #else
28 #include <varargs.h>
29 #define va_init_list(a,b) va_start(a)
30 #endif
31
32 #define DOUT fprintf(stderr,"[%d]\n",__LINE__)
33 #define DOUTS(x) fprintf(stderr,"[%d]:" #x "=%s\n",__LINE__,x)
34 #define DOUTMSG(x) fprintf(stderr, "[%d]:" #x "\n",__LINE__)
35 #define DOUTI(x) fprintf(stderr, "[%ld]:" #x "=%d\n",__LINE__,x)
36 #define DOUTD(x) fprintf(stderr, "[%d]:" #x "=%f\n",__LINE__,x)
37
38 #if defined NONAMELESSUNION && __GNUC__
39 #define V_UNION1(X, Y) ((X)->u.Y)
40 #else
41 #define V_UNION1(X, Y) ((X)->Y)
42 #endif
43
44 #if defined NONAMELESSUNION && __GNUC__
45 #undef V_UNION
46 #define V_UNION(X,Y) ((X)->n1.n2.n3.Y)
47
48 #undef V_VT
49 #define V_VT(X) ((X)->n1.n2.vt)
50
51 #undef V_BOOL
52 #define V_BOOL(X) V_UNION(X,boolVal)
53 #endif
54
55 #define OLE_RELEASE(X) (X) ? ((X)->lpVtbl->Release(X)) : 0
56
57 #define OLE_ADDREF(X) (X) ? ((X)->lpVtbl->AddRef(X)) : 0
58
59 #define OLE_GET_TYPEATTR(X, Y) ((X)->lpVtbl->GetTypeAttr((X), (Y)))
60 #define OLE_RELEASE_TYPEATTR(X, Y) ((X)->lpVtbl->ReleaseTypeAttr((X), (Y)))
61
62 #define OLE_FREE(x) {\
63 if(gOLEInitialized == Qtrue) {\
64 if(x) {\
65 OLE_RELEASE(x);\
66 (x) = 0;\
67 }\
68 }\
69 ole_msg_loop();\
70 CoFreeUnusedLibraries();\
71 }
72
73 #define OLEData_Get_Struct(obj, pole) {\
74 Data_Get_Struct(obj, struct oledata, pole);\
75 if(!pole->pDispatch) {\
76 rb_raise(rb_eRuntimeError, "Fail to get Dispatch Interface");\
77 }\
78 }
79
80 #define WC2VSTR(x) ole_wc2vstr((x), TRUE)
81
82 #define WIN32OLE_VERSION "0.5.2"
83
84 typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX)
85 (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*);
86
87 typedef HWND (WINAPI FNHTMLHELP)(HWND hwndCaller, LPCSTR pszFile,
88 UINT uCommand, DWORD dwData);
89 typedef struct {
90 struct IEventSinkVtbl * lpVtbl;
91 } IEventSink, *PEVENTSINK;
92
93 typedef struct IEventSinkVtbl IEventSinkVtbl;
94
95 struct IEventSinkVtbl {
96 STDMETHOD(QueryInterface)(
97 PEVENTSINK,
98 REFIID,
99 LPVOID *);
100 STDMETHOD_(ULONG, AddRef)(PEVENTSINK);
101 STDMETHOD_(ULONG, Release)(PEVENTSINK);
102
103 STDMETHOD(GetTypeInfoCount)(
104 PEVENTSINK,
105 UINT *);
106 STDMETHOD(GetTypeInfo)(
107 PEVENTSINK,
108 UINT,
109 LCID,
110 ITypeInfo **);
111 STDMETHOD(GetIDsOfNames)(
112 PEVENTSINK,
113 REFIID,
114 OLECHAR **,
115 UINT,
116 LCID,
117 DISPID *);
118 STDMETHOD(Invoke)(
119 PEVENTSINK,
120 DISPID,
121 REFIID,
122 LCID,
123 WORD,
124 DISPPARAMS *,
125 VARIANT *,
126 EXCEPINFO *,
127 UINT *);
128 };
129
130 typedef struct tagIEVENTSINKOBJ {
131 IEventSinkVtbl *lpVtbl;
132 DWORD m_cRef;
133 IID m_iid;
134 int m_event_id;
135 DWORD m_dwCookie;
136 IConnectionPoint *pConnectionPoint;
137 ITypeInfo *pTypeInfo;
138 }IEVENTSINKOBJ, *PIEVENTSINKOBJ;
139
140 VALUE cWIN32OLE;
141 VALUE cWIN32OLE_TYPE;
142 VALUE cWIN32OLE_VARIABLE;
143 VALUE cWIN32OLE_METHOD;
144 VALUE cWIN32OLE_PARAM;
145 VALUE cWIN32OLE_EVENT;
146 VALUE eWIN32OLE_RUNTIME_ERROR;
147 VALUE mWIN32OLE_VARIANT;
148
149 static VALUE ary_ole_event;
150 static ID id_events;
151 static BOOL gOLEInitialized = Qfalse;
152 static HINSTANCE ghhctrl = NULL;
153 static HINSTANCE gole32 = NULL;
154 static FNCOCREATEINSTANCEEX *gCoCreateInstanceEx = NULL;
155
156 struct oledata {
157 IDispatch *pDispatch;
158 };
159
160 struct oletypedata {
161 ITypeInfo *pTypeInfo;
162 };
163
164 struct olemethoddata {
165 ITypeInfo *pOwnerTypeInfo;
166 ITypeInfo *pTypeInfo;
167 UINT index;
168 };
169
170 struct olevariabledata {
171 ITypeInfo *pTypeInfo;
172 UINT index;
173 };
174
175 struct oleparamdata {
176 ITypeInfo *pTypeInfo;
177 UINT method_index;
178 UINT index;
179 };
180
181 struct oleeventdata {
182 IEVENTSINKOBJ *pEvent;
183 };
184
185 struct oleparam {
186 DISPPARAMS dp;
187 OLECHAR** pNamedArgs;
188 };
189
190 static VALUE folemethod_s_allocate _((VALUE));
191 static VALUE olemethod_set_member _((VALUE, ITypeInfo *, ITypeInfo *, int, VALUE));
192 static VALUE foletype_s_allocate _((VALUE));
193 static VALUE oletype_set_member _((VALUE, ITypeInfo *, VALUE));
194 static VALUE olemethod_from_typeinfo _((VALUE, ITypeInfo *, VALUE));
195 static HRESULT ole_docinfo_from_type _((ITypeInfo *, BSTR *, BSTR *, DWORD *, BSTR *));
196
197 static void
198 time2d(hh, mm, ss, pv)
199 int hh, mm, ss;
200 double *pv;
201 {
202 *pv = (hh * 60.0 * 60.0 + mm * 60.0 + ss) / 86400.0;
203 }
204
205 static void
206 d2time(v, hh, mm, ss)
207 double v;
208 int *hh, *mm, *ss;
209 {
210 double d_hh, d_mm, d_ss;
211 int i_hh, i_mm, i_ss;
212
213 double d = v * 86400.0;
214
215 d_hh = d / 3600.0;
216 i_hh = (int)d_hh;
217
218 d = d - i_hh * 3600.0;
219
220 d_mm = d / 60.0;
221 i_mm = (int)d_mm;
222
223 d = d - i_mm * 60.0;
224
225 d_ss = d * 10.0 + 5;
226
227 i_ss = (int)d_ss / 10;
228
229 if(i_ss == 60) {
230 i_mm += 1;
231 i_ss = 0;
232 }
233
234 if (i_mm == 60) {
235 i_hh += 1;
236 i_mm = 0;
237 }
238 if (i_hh == 24) {
239 i_hh = 0;
240 }
241
242 *hh = i_hh;
243 *mm = i_mm;
244 *ss = i_ss;
245 }
246
247 static void
248 civil2jd(y, m, d, jd)
249 int y, m, d;
250 long *jd;
251 {
252 long a, b;
253 if (m <= 2) {
254 y -= 1;
255 m += 12;
256 }
257 a = (long)(y / 100.0);
258 b = 2 - a + (long)(a / 4.0);
259 *jd = (long)(365.25 * (double)(y + 4716))
260 + (long)(30.6001 * (m + 1))
261 + d + b - 1524;
262 }
263
264 static void
265 jd2civil(day, yy, mm, dd)
266 long day;
267 int *yy, *mm, *dd;
268 {
269 long x, a, b, c, d, e;
270 x = (long)(((double)day - 1867216.25) / 36524.25);
271 a = day + 1 + x - (long)(x / 4.0);
272 b = a + 1524;
273 c = (long)(((double)b -122.1) /365.25);
274 d = (long)(365.25 * c);
275 e = (long)((double)(b - d) / 30.6001);
276 *dd = b - d - (long)(30.6001 * e);
277 if (e <= 13) {
278 *mm = e - 1;
279 *yy = c - 4716;
280 }
281 else {
282 *mm = e - 13;
283 *yy = c - 4715;
284 }
285 }
286
287 static void
288 double2time(v, y, m, d, hh, mm, ss)
289 double v;
290 int *y, *m, *d, *hh, *mm, *ss;
291 {
292 long day;
293 double t;
294
295 day = (long)v;
296 t = v - day;
297 jd2civil(2415019 + day, y, m, d);
298
299 d2time(t, hh, mm, ss);
300 }
301
302 static double
303 time_object2date(tmobj)
304 VALUE tmobj;
305 {
306 long y, m, d, hh, mm, ss;
307 long day;
308 double t;
309 y = FIX2INT(rb_funcall(tmobj, rb_intern("year"), 0));
310 m = FIX2INT(rb_funcall(tmobj, rb_intern("month"), 0));
311 d = FIX2INT(rb_funcall(tmobj, rb_intern("mday"), 0));
312 hh = FIX2INT(rb_funcall(tmobj, rb_intern("hour"), 0));
313 mm = FIX2INT(rb_funcall(tmobj, rb_intern("min"), 0));
314 ss = FIX2INT(rb_funcall(tmobj, rb_intern("sec"), 0));
315 civil2jd(y, m, d, &day);
316 time2d(hh, mm, ss, &t);
317 return t + day - 2415019;
318 }
319
320 static VALUE
321 date2time_str(date)
322 double date;
323 {
324 int y, m, d, hh, mm, ss;
325 char szTime[20];
326 double2time(date, &y, &m, &d, &hh, &mm, &ss);
327 sprintf(szTime,
328 "%4.4d/%02.2d/%02.2d %02.2d:%02.2d:%02.2d",
329 y, m, d, hh, mm, ss);
330 return rb_str_new2(szTime);
331 }
332
333 static void ole_val2variant();
334
335 static char *
336 ole_wc2mb(pw)
337 LPWSTR pw;
338 {
339 int size;
340 LPSTR pm;
341 size = WideCharToMultiByte(CP_ACP, 0, pw, -1, NULL, 0, NULL, NULL);
342 if (size) {
343 pm = ALLOC_N(char, size);
344 WideCharToMultiByte(CP_ACP, 0, pw, -1, pm, size, NULL, NULL);
345 }
346 else {
347 pm = ALLOC_N(char, 1);
348 *pm = '\0';
349 }
350 return pm;
351 }
352
353 static VALUE
354 ole_hresult2msg(hr)
355 HRESULT hr;
356 {
357 VALUE msg = Qnil;
358 char *p_msg;
359 DWORD dwCount;
360
361 char strhr[100];
362 sprintf(strhr, " HRESULT error code:0x%08x\n ", hr);
363 msg = rb_str_new2(strhr);
364
365 dwCount = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
366 FORMAT_MESSAGE_FROM_SYSTEM |
367 FORMAT_MESSAGE_IGNORE_INSERTS,
368 NULL, hr, LOCALE_SYSTEM_DEFAULT,
369 (LPTSTR)&p_msg, 0, NULL);
370 if (dwCount > 0) {
371
372 while (dwCount > 0 &&
373 (p_msg[dwCount-1] < ' ' || p_msg[dwCount-1] == '.')) {
374 p_msg[--dwCount] = '\0';
375 }
376 if (p_msg[0] != '\0') {
377 rb_str_cat2(msg, p_msg);
378 }
379 }
380 return msg;
381 }
382
383 static VALUE
384 ole_excepinfo2msg(pExInfo)
385 EXCEPINFO *pExInfo;
386 {
387 char error_code[40];
388 char *pSource = NULL;
389 char *pDescription = NULL;
390 VALUE error_msg;
391 if(pExInfo->pfnDeferredFillIn != NULL) {
392 (*pExInfo->pfnDeferredFillIn)(pExInfo);
393 }
394 if (pExInfo->bstrSource != NULL) {
395 pSource = ole_wc2mb(pExInfo->bstrSource);
396 }
397 if (pExInfo->bstrDescription != NULL) {
398 pDescription = ole_wc2mb(pExInfo->bstrDescription);
399 }
400 if(pExInfo->wCode == 0) {
401 sprintf(error_code, "\n OLE error code:%lX in ", pExInfo->scode);
402 }
403 else{
404 sprintf(error_code, "\n OLE error code:%u in ", pExInfo->wCode);
405 }
406 error_msg = rb_str_new2(error_code);
407 if(pSource != NULL) {
408 rb_str_cat(error_msg, pSource, strlen(pSource));
409 }
410 else {
411 rb_str_cat(error_msg, "<Unknown>", 9);
412 }
413 rb_str_cat2(error_msg, "\n ");
414 if(pDescription != NULL) {
415 rb_str_cat2(error_msg, pDescription);
416 }
417 else {
418 rb_str_cat2(error_msg, "<No Description>");
419 }
420 if(pSource) free(pSource);
421 if(pDescription) free(pDescription);
422 SysFreeString(pExInfo->bstrDescription);
423 SysFreeString(pExInfo->bstrSource);
424 SysFreeString(pExInfo->bstrHelpFile);
425 return error_msg;
426 }
427
428 static void
429 #ifdef HAVE_STDARG_PROTOTYPES
430 ole_raise(HRESULT hr, VALUE ecs, const char *fmt, ...)
431 #else
432 ole_raise(hr, exc, fmt, va_alist)
433 HRESULT hr;
434 VALUE exc;
435 const char *fmt;
436 va_dcl
437 #endif
438 {
439 va_list args;
440 char buf[BUFSIZ];
441 VALUE err_msg;
442 va_init_list(args, fmt);
443 vsnprintf(buf, BUFSIZ, fmt, args);
444 va_end(args);
445
446 err_msg = ole_hresult2msg(hr);
447 if(err_msg != Qnil) {
448 rb_raise(ecs, "%s\n%s", buf, StringValuePtr(err_msg));
449 }
450 else {
451 rb_raise(ecs, "%s", buf);
452 }
453 }
454
455 void
456 ole_uninitialize()
457 {
458 OleUninitialize();
459 gOLEInitialized = Qfalse;
460 }
461
462 static void
463 ole_initialize()
464 {
465 HRESULT hr;
466 int rc;
467
468 if(gOLEInitialized == Qfalse) {
469 hr = OleInitialize(NULL);
470 if(FAILED(hr)) {
471 ole_raise(hr, rb_eRuntimeError, "Fail : OLE initialize");
472 }
473 gOLEInitialized = Qtrue;
474 rc = atexit((void (*)(void))ole_uninitialize);
475 }
476 }
477
478 static void
479 ole_msg_loop() {
480 MSG msg;
481 while(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
482 TranslateMessage(&msg);
483 DispatchMessage(&msg);
484 }
485 }
486
487 static void
488 ole_free(pole)
489 struct oledata *pole;
490 {
491 OLE_FREE(pole->pDispatch);
492 }
493
494 static void
495 oletype_free(poletype)
496 struct oletypedata *poletype;
497 {
498 OLE_FREE(poletype->pTypeInfo);
499 }
500
501 static void
502 olemethod_free(polemethod)
503 struct olemethoddata *polemethod;
504 {
505 OLE_FREE(polemethod->pTypeInfo);
506 OLE_FREE(polemethod->pOwnerTypeInfo);
507 }
508
509 static void
510 olevariable_free(polevar)
511 struct olevariabledata *polevar;
512 {
513 OLE_FREE(polevar->pTypeInfo);
514 }
515
516 static void
517 oleparam_free(pole)
518 struct oleparamdata *pole;
519 {
520 OLE_FREE(pole->pTypeInfo);
521 }
522
523 static LPWSTR
524 ole_mb2wc(pm, len)
525 char *pm;
526 int len;
527 {
528 int size;
529 LPWSTR pw;
530 size = MultiByteToWideChar(CP_ACP, 0, pm, len, NULL, 0);
531 pw = SysAllocStringLen(NULL, size - 1);
532 MultiByteToWideChar(CP_ACP, 0, pm, len, pw, size);
533 return pw;
534 }
535
536 static VALUE
537 ole_wc2vstr(pw, isfree)
538 LPWSTR pw;
539 BOOL isfree;
540 {
541 char *p = ole_wc2mb(pw);
542 VALUE vstr = rb_str_new2(p);
543 if(isfree)
544 SysFreeString(pw);
545 free(p);
546 return vstr;
547 }
548
549 static VALUE
550 ole_ary_m_entry(val, pid)
551 VALUE val;
552 long *pid;
553 {
554 VALUE obj = Qnil;
555 int i = 0;
556 obj = val;
557 while(TYPE(obj) == T_ARRAY) {
558 obj = rb_ary_entry(obj, pid[i]);
559 i++;
560 }
561 return obj;
562 }
563
564 static void
565 ole_set_safe_array(n, psa, pid, pub, val, dim)
566 long n;
567 SAFEARRAY *psa;
568 long *pid;
569 long *pub;
570 VALUE val;
571 long dim;
572 {
573 VALUE val1;
574 VARIANT var;
575 VariantInit(&var);
576 if(n < 0) return;
577 if(n == dim) {
578 val1 = ole_ary_m_entry(val, pid);
579 ole_val2variant(val1, &var);
580 SafeArrayPutElement(psa, pid, &var);
581 }
582 pid[n] += 1;
583 if (pid[n] < pub[n]) {
584 ole_set_safe_array(dim, psa, pid, pub, val, dim);
585 }
586 else {
587 pid[n] = 0;
588 ole_set_safe_array(n-1, psa, pid, pub, val, dim);
589 }
590 }
591
592 static void
593 ole_val2variant(val, var)
594 VALUE val;
595 VARIANT *var;
596 {
597 struct oledata *pole;
598 if(rb_obj_is_kind_of(val, cWIN32OLE)) {
599 Data_Get_Struct(val, struct oledata, pole);
600 OLE_ADDREF(pole->pDispatch);
601 V_VT(var) = VT_DISPATCH;
602 V_DISPATCH(var) = pole->pDispatch;
603 return;
604 }
605 if (rb_obj_is_kind_of(val, rb_cTime)) {
606 V_VT(var) = VT_DATE;
607 V_DATE(var) = time_object2date(val);
608 return;
609 }
610 switch (TYPE(val)) {
611 case T_ARRAY:
612 {
613 VALUE val1;
614 long dim = 0;
615 int i = 0;
616
617 HRESULT hr;
618 SAFEARRAYBOUND *psab;
619 SAFEARRAY *psa;
620 long *pub, *pid;
621
622 val1 = val;
623 while(TYPE(val1) == T_ARRAY) {
624 val1 = rb_ary_entry(val1, 0);
625 dim += 1;
626 }
627 psab = ALLOC_N(SAFEARRAYBOUND, dim);
628 pub = ALLOC_N(long, dim);
629 pid = ALLOC_N(long, dim);
630
631 if(!psab || !pub || !pid) {
632 if(pub) free(pub);
633 if(psab) free(psab);
634 if(pid) free(pid);
635 rb_raise(rb_eRuntimeError, "memory allocate error");
636 }
637 val1 = val;
638 i = 0;
639 while(TYPE(val1) == T_ARRAY) {
640 psab[i].cElements = RARRAY(val1)->len;
641 psab[i].lLbound = 0;
642 pub[i] = psab[i].cElements;
643 pid[i] = 0;
644 i ++;
645 val1 = rb_ary_entry(val1, 0);
646 }
647
648 psa = SafeArrayCreate(VT_VARIANT, dim, psab);
649 if (psa == NULL)
650 hr = E_OUTOFMEMORY;
651 else
652 hr = SafeArrayLock(psa);
653 if (SUCCEEDED(hr)) {
654 ole_set_safe_array(dim-1, psa, pid, pub, val, dim-1);
655 hr = SafeArrayUnlock(psa);
656 }
657 if(pub) free(pub);
658 if(psab) free(psab);
659 if(pid) free(pid);
660
661 if (SUCCEEDED(hr)) {
662 V_VT(var) = VT_VARIANT | VT_ARRAY;
663 V_ARRAY(var) = psa;
664 }
665 else if (psa != NULL)
666 SafeArrayDestroy(psa);
667 break;
668 }
669 case T_STRING:
670 V_VT(var) = VT_BSTR;
671 V_BSTR(var) = ole_mb2wc(StringValuePtr(val), -1);
672 break;
673 case T_FIXNUM:
674 V_VT(var) = VT_I4;
675 V_I4(var) = NUM2INT(val);
676 break;
677 case T_BIGNUM:
678 V_VT(var) = VT_R8;
679 V_R8(var) = rb_big2dbl(val);
680 break;
681 case T_FLOAT:
682 V_VT(var) = VT_R8;
683 V_R8(var) = NUM2DBL(val);
684 break;
685 case T_TRUE:
686 V_VT(var) = VT_BOOL;
687 V_BOOL(var) = VARIANT_TRUE;
688 break;
689 case T_FALSE:
690 V_VT(var) = VT_BOOL;
691 V_BOOL(var) = VARIANT_FALSE;
692 break;
693 case T_NIL:
694 V_VT(var) = VT_ERROR;
695 V_ERROR(var) = DISP_E_PARAMNOTFOUND;
696 break;
697 default:
698 rb_raise(rb_eTypeError, "not valid value");
699 break;
700 }
701 }
702
703 static VALUE
704 ole_set_member(self, dispatch)
705 VALUE self;
706 IDispatch * dispatch;
707 {
708 struct oledata *pole;
709 Data_Get_Struct(self, struct oledata, pole);
710 if (pole->pDispatch) {
711 OLE_RELEASE(pole->pDispatch);
712 pole->pDispatch = NULL;
713 }
714 pole->pDispatch = dispatch;
715 return self;
716 }
717
718 static VALUE
719 fole_s_allocate(klass)
720 VALUE klass;
721 {
722 struct oledata *pole;
723 VALUE obj;
724 ole_initialize();
725 obj = Data_Make_Struct(klass,struct oledata,0,ole_free,pole);
726 pole->pDispatch = NULL;
727 return obj;
728 }
729
730 static VALUE
731 create_win32ole_object(klass, pDispatch, argc, argv)
732 VALUE klass;
733 IDispatch *pDispatch;
734 int argc;
735 VALUE *argv;
736 {
737 VALUE obj = fole_s_allocate(klass);
738 ole_set_member(obj, pDispatch);
739 return obj;
740 }
741
742 static VALUE
743 ole_variant2val(pvar)
744 VARIANT *pvar;
745 {
746 VALUE obj = Qnil;
747 HRESULT hr;
748 while ( V_VT(pvar) == (VT_BYREF | VT_VARIANT) )
749 pvar = V_VARIANTREF(pvar);
750
751 if(V_ISARRAY(pvar)) {
752 SAFEARRAY *psa = V_ISBYREF(pvar) ? *V_ARRAYREF(pvar) : V_ARRAY(pvar);
753 long i;
754 long *pID, *pLB, *pUB;
755 VARIANT variant;
756 VALUE val;
757 VALUE val2;
758
759 int dim = SafeArrayGetDim(psa);
760 VariantInit(&variant);
761 V_VT(&variant) = (V_VT(pvar) & ~VT_ARRAY) | VT_BYREF;
762
763 pID = ALLOC_N(long, dim);
764 pLB = ALLOC_N(long, dim);
765 pUB = ALLOC_N(long, dim);
766
767 if(!pID || !pLB || !pUB) {
768 if(pID) free(pID);
769 if(pLB) free(pLB);
770 if(pUB) free(pUB);
771 rb_raise(rb_eRuntimeError, "memory allocate error");
772 }
773
774 obj = Qnil;
775
776 for(i = 0; i < dim; ++i) {
777 SafeArrayGetLBound(psa, i+1, &pLB[i]);
778 SafeArrayGetLBound(psa, i+1, &pID[i]);
779 SafeArrayGetUBound(psa, i+1, &pUB[i]);
780 }
781
782 hr = SafeArrayLock(psa);
783 if (SUCCEEDED(hr)) {
784 val2 = rb_ary_new();
785 while (i >= 0) {
786 hr = SafeArrayPtrOfIndex(psa, pID, &V_BYREF(&variant));
787 if (FAILED(hr))
788 break;
789
790 val = ole_variant2val(&variant);
791 rb_ary_push(val2, val);
792 for (i = dim-1 ; i >= 0 ; --i) {
793 if (++pID[i] <= pUB[i])
794 break;
795
796 pID[i] = pLB[i];
797 if (i > 0) {
798 if (obj == Qnil)
799 obj = rb_ary_new();
800 rb_ary_push(obj, val2);
801 val2 = rb_ary_new();
802 }
803 }
804 }
805 SafeArrayUnlock(psa);
806 }
807 if(pID) free(pID);
808 if(pLB) free(pLB);
809 if(pUB) free(pUB);
810 return (obj == Qnil) ? val2 : obj;
811 }
812 switch(V_VT(pvar) & ~VT_BYREF){
813 case VT_EMPTY:
814 break;
815 case VT_NULL:
816 break;
817 case VT_UI1:
818 if(V_ISBYREF(pvar))
819 obj = INT2NUM((long)*V_UI1REF(pvar));
820 else
821 obj = INT2NUM((long)V_UI1(pvar));
822 break;
823
824 case VT_I2:
825 if(V_ISBYREF(pvar))
826 obj = INT2NUM((long)*V_I2REF(pvar));
827 else
828 obj = INT2NUM((long)V_I2(pvar));
829 break;
830
831 case VT_I4:
832 if(V_ISBYREF(pvar))
833 obj = INT2NUM((long)*V_I4REF(pvar));
834 else
835 obj = INT2NUM((long)V_I4(pvar));
836 break;
837
838 case VT_R4:
839 if(V_ISBYREF(pvar))
840 obj = rb_float_new(*V_R4REF(pvar));
841 else
842 obj = rb_float_new(V_R4(pvar));
843 break;
844
845 case VT_R8:
846 if(V_ISBYREF(pvar))
847 obj = rb_float_new(*V_R8REF(pvar));
848 else
849 obj = rb_float_new(V_R8(pvar));
850 break;
851
852 case VT_BSTR:
853 {
854 char *p;
855 if(V_ISBYREF(pvar))
856 p = ole_wc2mb(*V_BSTRREF(pvar));
857 else
858 p = ole_wc2mb(V_BSTR(pvar));
859 obj = rb_str_new2(p);
860 if(p) free(p);
861 break;
862 }
863
864 case VT_ERROR:
865 if(V_ISBYREF(pvar))
866 obj = INT2NUM(*V_ERRORREF(pvar));
867 else
868 obj = INT2NUM(V_ERROR(pvar));
869 break;
870
871 case VT_BOOL:
872 if (V_ISBYREF(pvar))
873 obj = (*V_BOOLREF(pvar) ? Qtrue : Qfalse);
874 else
875 obj = (V_BOOL(pvar) ? Qtrue : Qfalse);
876 break;
877
878 case VT_DISPATCH:
879 {
880 IDispatch *pDispatch;
881
882 if (V_ISBYREF(pvar))
883 pDispatch = *V_DISPATCHREF(pvar);
884 else
885 pDispatch = V_DISPATCH(pvar);
886
887 if (pDispatch != NULL ) {
888 OLE_ADDREF(pDispatch);
889 obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
890 }
891 break;
892 }
893
894 case VT_UNKNOWN:
895 {
896
897
898 IUnknown *punk;
899 IDispatch *pDispatch;
900 HRESULT hr;
901
902 if (V_ISBYREF(pvar))
903 punk = *V_UNKNOWNREF(pvar);
904 else
905 punk = V_UNKNOWN(pvar);
906
907 if(punk != NULL) {
908 hr = punk->lpVtbl->QueryInterface(punk, &IID_IDispatch,
909 (void **)&pDispatch);
910 if(SUCCEEDED(hr)) {
911 obj = create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
912 }
913 }
914 break;
915 }
916
917 case VT_DATE:
918 {
919 DATE date;
920 if(V_ISBYREF(pvar))
921 date = *V_DATEREF(pvar);
922 else
923 date = V_DATE(pvar);
924
925 obj = date2time_str(date);
926 break;
927 }
928 case VT_CY:
929 default:
930 {
931 HRESULT hr;
932 VARIANT variant;
933 VariantInit(&variant);
934 hr = VariantChangeTypeEx(&variant, pvar,
935 LOCALE_SYSTEM_DEFAULT, 0, VT_BSTR);
936 if (SUCCEEDED(hr) && V_VT(&variant) == VT_BSTR) {
937 char *p = ole_wc2mb(V_BSTR(&variant));
938 obj = rb_str_new2(p);
939 if(p) free(p);
940 }
941 VariantClear(&variant);
942 break;
943 }
944 }
945 return obj;
946 }
947
948 static LONG reg_open_key(hkey, name, phkey)
949 HKEY hkey;
950 const char *name;
951 HKEY *phkey;
952 {
953 return RegOpenKeyEx(hkey, name, 0, KEY_READ, phkey);
954 }
955
956 static LONG reg_open_vkey(hkey, key, phkey)
957 HKEY hkey;
958 VALUE key;
959 HKEY *phkey;
960 {
961 return reg_open_key(hkey, StringValuePtr(key), phkey);
962 }
963
964 static VALUE
965 reg_enum_key(hkey, i)
966 HKEY hkey;
967 DWORD i;
968 {
969 char buf[BUFSIZ];
970 DWORD size_buf = sizeof(buf);
971 FILETIME ft;
972 LONG err = RegEnumKeyEx(hkey, i, buf, &size_buf,
973 NULL, NULL, NULL, &ft);
974 if(err == ERROR_SUCCESS) {
975 return rb_str_new2(buf);
976 }
977 return Qnil;
978 }
979
980 static VALUE
981 reg_get_val(hkey, subkey)
982 HKEY hkey;
983 const char *subkey;
984 {
985 char buf[BUFSIZ];
986 LONG size_buf = sizeof(buf);
987 LONG err = RegQueryValue(hkey, subkey, buf, &size_buf);
988 if (err == ERROR_SUCCESS) {
989 return rb_str_new2(buf);
990 }
991 return Qnil;
992 }
993
994 static VALUE
995 typelib_file_from_clsid(ole)
996 VALUE ole;
997 {
998 OLECHAR *pbuf;
999 CLSID clsid;
1000 HRESULT hr;
1001 HKEY hroot, hclsid;
1002 LONG err;
1003 VALUE typelib;
1004 VALUE vclsid;
1005 char *pclsid = NULL;
1006
1007 pbuf = ole_mb2wc(StringValuePtr(ole), -1);
1008 hr = CLSIDFromProgID(pbuf, &clsid);
1009 SysFreeString(pbuf);
1010 if (FAILED(hr)) {
1011 return Qnil;
1012 }
1013 StringFromCLSID(&clsid, &pbuf);
1014 vclsid = WC2VSTR(pbuf);
1015 err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hroot);
1016 if (err != ERROR_SUCCESS) {
1017 return Qnil;
1018 }
1019 err = reg_open_key(hroot, StringValuePtr(vclsid), &hclsid);
1020 if (err != ERROR_SUCCESS) {
1021 RegCloseKey(hroot);
1022 return Qnil;
1023 }
1024 typelib = reg_get_val(hclsid, "InprocServer32");
1025 RegCloseKey(hroot);
1026 RegCloseKey(hclsid);
1027 return typelib;
1028 }
1029
1030 static VALUE
1031 typelib_file_from_typelib(ole)
1032 VALUE ole;
1033 {
1034 HKEY htypelib, hclsid, hversion, hlang;
1035 double fver;
1036 DWORD i, j, k;
1037 LONG err;
1038 BOOL found = FALSE;
1039 VALUE typelib;
1040 VALUE file = Qnil;
1041 VALUE clsid;
1042 VALUE ver;
1043 VALUE lang;
1044
1045 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
1046 if(err != ERROR_SUCCESS) {
1047 return Qnil;
1048 }
1049 for(i = 0; !found; i++) {
1050 clsid = reg_enum_key(htypelib, i);
1051 if (clsid == Qnil)
1052 break;
1053 err = reg_open_vkey(htypelib, clsid, &hclsid);
1054 if (err != ERROR_SUCCESS)
1055 continue;
1056 fver = 0;
1057 for(j = 0; !found; j++) {
1058 ver = reg_enum_key(hclsid, j);
1059 if (ver == Qnil)
1060 break;
1061 err = reg_open_vkey(hclsid, ver, &hversion);
1062 if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver)))
1063 continue;
1064 fver = atof(StringValuePtr(ver));
1065 typelib = reg_get_val(hversion, NULL);
1066 if (typelib == Qnil)
1067 continue;
1068 if (rb_str_cmp(typelib, ole) == 0) {
1069 for(k = 0; !found; k++) {
1070 lang = reg_enum_key(hversion, k);
1071 if (lang == Qnil)
1072 break;
1073 err = reg_open_vkey(hversion, lang, &hlang);
1074 if (err == ERROR_SUCCESS) {
1075 if ((file = reg_get_val(hlang, "win32")) != Qnil)
1076 found = TRUE;
1077 RegCloseKey(hlang);
1078 }
1079 }
1080 }
1081 RegCloseKey(hversion);
1082 }
1083 RegCloseKey(hclsid);
1084 }
1085 RegCloseKey(htypelib);
1086 return file;
1087 }
1088
1089 static VALUE
1090 typelib_file(ole)
1091 VALUE ole;
1092 {
1093 VALUE file = typelib_file_from_clsid(ole);
1094 if (file != Qnil) {
1095 return file;
1096 }
1097 return typelib_file_from_typelib(ole);
1098 }
1099
1100 static void
1101 ole_const_load(pTypeLib, klass, self)
1102 ITypeLib *pTypeLib;
1103 VALUE klass;
1104 VALUE self;
1105 {
1106 unsigned int count;
1107 unsigned int index;
1108 int iVar;
1109 ITypeInfo *pTypeInfo;
1110 TYPEATTR *pTypeAttr;
1111 VARDESC *pVarDesc;
1112 HRESULT hr;
1113 unsigned int len;
1114 BSTR bstr;
1115 char *pName = NULL;
1116 VALUE val;
1117 VALUE constant;
1118 ID id;
1119 constant = rb_hash_new();
1120 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
1121 for (index = 0; index < count; index++) {
1122 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, index, &pTypeInfo);
1123 if (FAILED(hr))
1124 continue;
1125 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
1126 if(FAILED(hr)) {
1127 OLE_RELEASE(pTypeInfo);
1128 continue;
1129 }
1130 for(iVar = 0; iVar < pTypeAttr->cVars; iVar++) {
1131 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, iVar, &pVarDesc);
1132 if(FAILED(hr))
1133 continue;
1134 if(pVarDesc->varkind == VAR_CONST &&
1135 !(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
1136 VARFLAG_FRESTRICTED |
1137 VARFLAG_FNONBROWSABLE))) {
1138 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
1139 1, &len);
1140 if(FAILED(hr) || len == 0 || !bstr)
1141 continue;
1142 pName = ole_wc2mb(bstr);
1143 val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));
1144 *pName = toupper(*pName);
1145 id = rb_intern(pName);
1146 if (rb_is_const_id(id)) {
1147 rb_define_const(klass, pName, val);
1148 }
1149 else {
1150 rb_hash_aset(constant, rb_str_new2(pName), val);
1151 }
1152 SysFreeString(bstr);
1153 if(pName) {
1154 free(pName);
1155 pName = NULL;
1156 }
1157 }
1158 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
1159 }
1160 pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
1161 OLE_RELEASE(pTypeInfo);
1162 }
1163 rb_define_const(klass, "CONSTANTS", constant);
1164 }
1165
1166 static HRESULT
1167 clsid_from_remote(host, com, pclsid)
1168 VALUE host;
1169 VALUE com;
1170 CLSID *pclsid;
1171 {
1172 HKEY hlm;
1173 HKEY hpid;
1174 VALUE subkey;
1175 LONG err;
1176 char clsid[100];
1177 OLECHAR *pbuf;
1178 DWORD len;
1179 DWORD dwtype;
1180 HRESULT hr = S_OK;
1181 err = RegConnectRegistry(StringValuePtr(host), HKEY_LOCAL_MACHINE, &hlm);
1182 if (err != ERROR_SUCCESS)
1183 return HRESULT_FROM_WIN32(err);
1184 subkey = rb_str_new2("SOFTWARE\\Classes\\");
1185 rb_str_concat(subkey, com);
1186 rb_str_cat2(subkey, "\\CLSID");
1187 err = RegOpenKeyEx(hlm, StringValuePtr(subkey), 0, KEY_READ, &hpid);
1188 if (err != ERROR_SUCCESS)
1189 hr = HRESULT_FROM_WIN32(err);
1190 else {
1191 len = sizeof(clsid);
1192 err = RegQueryValueEx(hpid, "", NULL, &dwtype, clsid, &len);
1193 if (err == ERROR_SUCCESS && dwtype == REG_SZ) {
1194 pbuf = ole_mb2wc(clsid, -1);
1195 hr = CLSIDFromString(pbuf, pclsid);
1196 SysFreeString(pbuf);
1197 }
1198 else {
1199 hr = HRESULT_FROM_WIN32(err);
1200 }
1201 RegCloseKey(hpid);
1202 }
1203 RegCloseKey(hlm);
1204 return hr;
1205 }
1206
1207 static VALUE
1208 ole_create_dcom(argc, argv, self)
1209 int argc;
1210 VALUE *argv;
1211 VALUE self;
1212 {
1213 VALUE ole, host, others;
1214 HRESULT hr;
1215 CLSID clsid;
1216 OLECHAR *pbuf;
1217
1218 COSERVERINFO serverinfo;
1219 MULTI_QI multi_qi;
1220 DWORD clsctx = CLSCTX_REMOTE_SERVER;
1221
1222 if (!gole32)
1223 gole32 = LoadLibrary("OLE32");
1224 if (!gole32)
1225 rb_raise(rb_eRuntimeError, "Fail to load OLE32.");
1226 if (!gCoCreateInstanceEx)
1227 gCoCreateInstanceEx = (FNCOCREATEINSTANCEEX*)
1228 GetProcAddress(gole32, "CoCreateInstanceEx");
1229 if (!gCoCreateInstanceEx)
1230 rb_raise(rb_eRuntimeError, "CoCreateInstanceEx is not supported in this environment.");
1231 rb_scan_args(argc, argv, "2*", &ole, &host, &others);
1232
1233 pbuf = ole_mb2wc(StringValuePtr(ole), -1);
1234 hr = CLSIDFromProgID(pbuf, &clsid);
1235 if (FAILED(hr))
1236 hr = clsid_from_remote(host, ole, &clsid);
1237 if (FAILED(hr))
1238 hr = CLSIDFromString(pbuf, &clsid);
1239 SysFreeString(pbuf);
1240 if (FAILED(hr))
1241 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,
1242 "Unknown OLE server : `%s'",
1243 StringValuePtr(ole));
1244 memset(&serverinfo, 0, sizeof(COSERVERINFO));
1245 serverinfo.pwszName = ole_mb2wc(StringValuePtr(host), -1);
1246 memset(&multi_qi, 0, sizeof(MULTI_QI));
1247 multi_qi.pIID = &IID_IDispatch;
1248 hr = gCoCreateInstanceEx(&clsid, NULL, clsctx, &serverinfo, 1, &multi_qi);
1249 SysFreeString(serverinfo.pwszName);
1250 if (FAILED(hr))
1251 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,
1252 "Fail to create DCOM server : `%s' in `%s'",
1253 StringValuePtr(ole),
1254 StringValuePtr(host));
1255
1256 ole_set_member(self, (IDispatch*)multi_qi.pItf);
1257 return self;
1258 }
1259
1260 static VALUE
1261 ole_bind_obj(moniker, argc, argv, self)
1262 VALUE moniker;
1263 int argc;
1264 VALUE *argv;
1265 VALUE self;
1266 {
1267 IBindCtx *pBindCtx;
1268 IMoniker *pMoniker;
1269 IDispatch *pDispatch;
1270 HRESULT hr;
1271 OLECHAR *pbuf;
1272 ULONG eaten = 0;
1273
1274 ole_initialize();
1275
1276 hr = CreateBindCtx(0, &pBindCtx);
1277 if(FAILED(hr)) {
1278 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,
1279 "Fail to create bind context");
1280 }
1281
1282 pbuf = ole_mb2wc(StringValuePtr(moniker), -1);
1283 hr = MkParseDisplayName(pBindCtx, pbuf, &eaten, &pMoniker);
1284 SysFreeString(pbuf);
1285 if(FAILED(hr)) {
1286 OLE_RELEASE(pBindCtx);
1287 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,
1288 "Faile to parse display name of moniker:%s",
1289 StringValuePtr(moniker));
1290 }
1291 hr = pMoniker->lpVtbl->BindToObject(pMoniker, pBindCtx, NULL,
1292 &IID_IDispatch,
1293 (void**)&pDispatch);
1294 OLE_RELEASE(pMoniker);
1295 OLE_RELEASE(pBindCtx);
1296
1297 if(FAILED(hr)) {
1298 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,
1299 "Faile to bind moniker:%s",
1300 StringValuePtr(moniker));
1301 }
1302 return create_win32ole_object(self, pDispatch, argc, argv);
1303 }
1304
1305
1306
1307
1308
1309
1310
1311 static VALUE
1312 fole_s_connect(argc, argv, self)
1313 int argc;
1314 VALUE *argv;
1315 VALUE self;
1316 {
1317 VALUE svr_name;
1318 VALUE others;
1319 HRESULT hr;
1320 CLSID clsid;
1321 OLECHAR *pBuf;
1322 IDispatch *pDispatch;
1323 IUnknown *pUnknown;
1324
1325
1326 ole_initialize();
1327
1328 rb_scan_args(argc, argv, "1*", &svr_name, &others);
1329
1330
1331 pBuf = ole_mb2wc(StringValuePtr(svr_name), -1);
1332 hr = CLSIDFromProgID(pBuf, &clsid);
1333 if(FAILED(hr)) {
1334 hr = CLSIDFromString(pBuf, &clsid);
1335 }
1336 SysFreeString(pBuf);
1337 if(FAILED(hr)) {
1338 return ole_bind_obj(svr_name, argc, argv, self);
1339 }
1340
1341 hr = GetActiveObject(&clsid, 0, &pUnknown);
1342 if (FAILED(hr)) {
1343 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,
1344 "Not Running OLE server : `%s'", StringValuePtr(svr_name));
1345 }
1346 hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch,
1347 (void **)&pDispatch);
1348 if(FAILED(hr)) {
1349 OLE_RELEASE(pUnknown);
1350 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,
1351 "Fail to create WIN32OLE server : `%s'",
1352 StringValuePtr(svr_name));
1353 }
1354
1355 OLE_RELEASE(pUnknown);
1356
1357 return create_win32ole_object(self, pDispatch, argc, argv);
1358 }
1359
1360
1361
1362
1363
1364
1365
1366 static VALUE
1367 fole_s_const_load(argc, argv, self)
1368 int argc;
1369 VALUE *argv;
1370 VALUE self;
1371 {
1372 VALUE ole;
1373 VALUE klass;
1374 struct oledata *pole;
1375 ITypeInfo *pTypeInfo;
1376 ITypeLib *pTypeLib;
1377 unsigned int index;
1378 HRESULT hr;
1379 OLECHAR *pBuf;
1380 VALUE file;
1381 LCID lcid = LOCALE_SYSTEM_DEFAULT;
1382
1383 rb_scan_args(argc, argv, "11", &ole, &klass);
1384 if (TYPE(klass) != T_CLASS &&
1385 TYPE(klass) != T_MODULE &&
1386 TYPE(klass) != T_NIL) {
1387 rb_raise(rb_eTypeError, "2nd paramator must be Class or Module.");
1388 }
1389 if (rb_obj_is_kind_of(ole, cWIN32OLE)) {
1390 OLEData_Get_Struct(ole, pole);
1391 hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
1392 0, lcid, &pTypeInfo);
1393 if(FAILED(hr)) {
1394 ole_raise(hr, rb_eRuntimeError, "fail to GetTypeInfo");
1395 }
1396 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
1397 if(FAILED(hr)) {
1398 OLE_RELEASE(pTypeInfo);
1399 ole_raise(hr, rb_eRuntimeError, "fail to GetContainingTypeLib");
1400 }
1401 OLE_RELEASE(pTypeInfo);
1402 if(TYPE(klass) != T_NIL) {
1403 ole_const_load(pTypeLib, klass, self);
1404 }
1405 else {
1406 ole_const_load(pTypeLib, cWIN32OLE, self);
1407 }
1408 OLE_RELEASE(pTypeLib);
1409 }
1410 else if(TYPE(ole) == T_STRING) {
1411 file = typelib_file(ole);
1412 if (file == Qnil) {
1413 file = ole;
1414 }
1415 pBuf = ole_mb2wc(StringValuePtr(file), -1);
1416 hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib);
1417 SysFreeString(pBuf);
1418 if (FAILED(hr))
1419 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to LoadTypeLibEx");
1420 if(TYPE(klass) != T_NIL) {
1421 ole_const_load(pTypeLib, klass, self);
1422 }
1423 else {
1424 ole_const_load(pTypeLib, cWIN32OLE, self);
1425 }
1426 OLE_RELEASE(pTypeLib);
1427 }
1428 else {
1429 rb_raise(rb_eTypeError, "1st paramator must be WIN32OLE instance");
1430 }
1431 return Qnil;
1432 }
1433
1434 static VALUE
1435 ole_classes_from_typelib(pTypeLib, classes)
1436 ITypeLib *pTypeLib;
1437 VALUE classes;
1438 {
1439
1440 long count;
1441 int i;
1442 HRESULT hr;
1443 BSTR bstr;
1444 ITypeInfo *pTypeInfo;
1445 VALUE type;
1446
1447 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
1448 for (i = 0; i < count; i++) {
1449 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
1450 &bstr, NULL, NULL, NULL);
1451 if (FAILED(hr))
1452 continue;
1453
1454 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
1455 if (FAILED(hr))
1456 continue;
1457
1458 type = foletype_s_allocate(cWIN32OLE_TYPE);
1459 oletype_set_member(type, pTypeInfo, WC2VSTR(bstr));
1460
1461 rb_ary_push(classes, type);
1462 OLE_RELEASE(pTypeInfo);
1463 }
1464 return classes;
1465 }
1466
1467 static ULONG
1468 reference_count(pole)
1469 struct oledata * pole;
1470 {
1471 ULONG n = 0;
1472 if(pole->pDispatch) {
1473 OLE_ADDREF(pole->pDispatch);
1474 n = OLE_RELEASE(pole->pDispatch);
1475 }
1476 return n;
1477 }
1478
1479
1480
1481
1482
1483
1484
1485
1486 static VALUE
1487 fole_s_reference_count(self, obj)
1488 VALUE self;
1489 VALUE obj;
1490 {
1491 struct oledata * pole;
1492 OLEData_Get_Struct(obj, pole);
1493 return INT2NUM(reference_count(pole));
1494 }
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504 static VALUE
1505 fole_s_free(self, obj)
1506 VALUE self;
1507 VALUE obj;
1508 {
1509 ULONG n = 0;
1510 struct oledata * pole;
1511 OLEData_Get_Struct(obj, pole);
1512 if(pole->pDispatch) {
1513 if (reference_count(pole) > 0) {
1514 n = OLE_RELEASE(pole->pDispatch);
1515 }
1516 }
1517 return INT2NUM(n);
1518 }
1519
1520 static HWND
1521 ole_show_help(helpfile, helpcontext)
1522 VALUE helpfile;
1523 VALUE helpcontext;
1524 {
1525 FNHTMLHELP *pfnHtmlHelp;
1526 HWND hwnd = 0;
1527
1528 if(!ghhctrl)
1529 ghhctrl = LoadLibrary("HHCTRL.OCX");
1530 if (!ghhctrl)
1531 return hwnd;
1532 pfnHtmlHelp = (FNHTMLHELP*)GetProcAddress(ghhctrl, "HtmlHelpA");
1533 if (!pfnHtmlHelp)
1534 return hwnd;
1535 hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile),
1536 0x0f, NUM2INT(helpcontext));
1537 if (hwnd == 0)
1538 hwnd = pfnHtmlHelp(GetDesktopWindow(), StringValuePtr(helpfile),
1539 0, NUM2INT(helpcontext));
1540 return hwnd;
1541 }
1542
1543
1544
1545
1546
1547
1548
1549 static VALUE
1550 fole_s_show_help(argc, argv, self)
1551 int argc;
1552 VALUE *argv;
1553 VALUE self;
1554 {
1555 VALUE target;
1556 VALUE helpcontext;
1557 VALUE helpfile;
1558 VALUE name;
1559 HWND hwnd;
1560 rb_scan_args(argc, argv, "11", &target, &helpcontext);
1561 if (rb_obj_is_kind_of(target, cWIN32OLE_TYPE) ||
1562 rb_obj_is_kind_of(target, cWIN32OLE_METHOD)) {
1563 helpfile = rb_funcall(target, rb_intern("helpfile"), 0);
1564 if(strlen(StringValuePtr(helpfile)) == 0) {
1565 name = rb_ivar_get(target, rb_intern("name"));
1566 rb_raise(rb_eRuntimeError, "no helpfile of `%s'",
1567 StringValuePtr(name));
1568 }
1569 helpcontext = rb_funcall(target, rb_intern("helpcontext"), 0);
1570 } else {
1571 helpfile = target;
1572 }
1573 if (TYPE(helpfile) != T_STRING) {
1574 rb_raise(rb_eTypeError, "1st parametor must be (String|WIN32OLE_TYPE|WIN32OLE_METHOD).");
1575 }
1576 hwnd = ole_show_help(helpfile, helpcontext);
1577 if(hwnd == 0) {
1578 rb_raise(rb_eRuntimeError, "fail to open help file:%s",
1579 StringValuePtr(helpfile));
1580 }
1581 return Qnil;
1582 }
1583
1584 static VALUE
1585 fole_initialize(argc, argv, self)
1586 int argc;
1587 VALUE *argv;
1588 VALUE self;
1589 {
1590 VALUE svr_name;
1591 VALUE host;
1592 VALUE others;
1593 HRESULT hr;
1594 CLSID clsid;
1595 OLECHAR *pBuf;
1596 IDispatch *pDispatch;
1597
1598 rb_call_super(0, 0);
1599 rb_scan_args(argc, argv, "11*", &svr_name, &host, &others);
1600
1601 if (!NIL_P(host))
1602 return ole_create_dcom(argc, argv, self);
1603
1604
1605 pBuf = ole_mb2wc(StringValuePtr(svr_name), -1);
1606 hr = CLSIDFromProgID(pBuf, &clsid);
1607 if(FAILED(hr)) {
1608 hr = CLSIDFromString(pBuf, &clsid);
1609 }
1610 SysFreeString(pBuf);
1611 if(FAILED(hr)) {
1612 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,
1613 "Unknown OLE server : `%s'",
1614 StringValuePtr(svr_name));
1615 }
1616
1617
1618 hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
1619 &IID_IDispatch, (void**)&pDispatch);
1620 if(FAILED(hr)) {
1621 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,
1622 "Fail to create WIN32OLE object from `%s'",
1623 StringValuePtr(svr_name));
1624 }
1625
1626 ole_set_member(self, pDispatch);
1627 return self;
1628 }
1629
1630 static VALUE
1631 hash2named_arg(pair, pOp)
1632 VALUE pair;
1633 struct oleparam* pOp;
1634 {
1635 unsigned int index, i;
1636 VALUE key, value;
1637 index = pOp->dp.cNamedArgs;
1638
1639
1640
1641
1642 key = rb_ary_entry(pair, 0);
1643 if(TYPE(key) != T_STRING) {
1644
1645 for(i = 1; i < index + 1; i++) {
1646 SysFreeString(pOp->pNamedArgs[i]);
1647 }
1648
1649 for(i = 0; i < index; i++ ) {
1650 VariantClear(&(pOp->dp.rgvarg[i]));
1651 }
1652
1653 Check_Type(key, T_STRING);
1654 }
1655
1656
1657 pOp->pNamedArgs[index + 1] = ole_mb2wc(StringValuePtr(key), -1);
1658
1659 value = rb_ary_entry(pair, 1);
1660 VariantInit(&(pOp->dp.rgvarg[index]));
1661 ole_val2variant(value, &(pOp->dp.rgvarg[index]));
1662
1663 pOp->dp.cNamedArgs += 1;
1664 return Qnil;
1665 }
1666
1667 static VALUE
1668 ole_invoke(argc, argv, self, wFlags)
1669 int argc;
1670 VALUE *argv;
1671 VALUE self;
1672 USHORT wFlags;
1673 {
1674 LCID lcid = LOCALE_SYSTEM_DEFAULT;
1675 struct oledata *pole;
1676 HRESULT hr;
1677 VALUE cmd;
1678 VALUE paramS;
1679 VALUE param;
1680 VALUE obj;
1681 VALUE v;
1682
1683 BSTR wcmdname;
1684
1685 DISPID DispID;
1686 DISPID* pDispID;
1687 EXCEPINFO excepinfo;
1688 VARIANT result;
1689 VALUE args;
1690 VARIANTARG* realargs = NULL;
1691 unsigned int argErr = 0;
1692 unsigned int i;
1693 unsigned int cNamedArgs;
1694 int n;
1695 struct oleparam op;
1696 memset(&excepinfo, 0, sizeof(EXCEPINFO));
1697
1698 VariantInit(&result);
1699
1700 op.dp.rgvarg = NULL;
1701 op.dp.rgdispidNamedArgs = NULL;
1702 op.dp.cNamedArgs = 0;
1703 op.dp.cArgs = 0;
1704
1705 rb_scan_args(argc, argv, "1*", &cmd, ¶mS);
1706 OLEData_Get_Struct(self, pole);
1707 if(!pole->pDispatch) {
1708 rb_raise(rb_eRuntimeError, "Fail to get dispatch interface.");
1709 }
1710 wcmdname = ole_mb2wc(StringValuePtr(cmd), -1);
1711 hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
1712 &wcmdname, 1, lcid, &DispID);
1713 SysFreeString(wcmdname);
1714 if(FAILED(hr)) {
1715 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,
1716 "Unknown property or method : `%s'",
1717 StringValuePtr(cmd));
1718 }
1719
1720
1721 param = rb_ary_entry(paramS, argc-2);
1722
1723 op.dp.cNamedArgs = 0;
1724
1725
1726 if(TYPE(param) == T_HASH) {
1727
1728
1729
1730 cNamedArgs = NUM2INT(rb_funcall(param, rb_intern("length"), 0));
1731 op.dp.cArgs = cNamedArgs + argc - 2;
1732 op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);
1733 op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs);
1734 rb_iterate(rb_each, param, hash2named_arg, (VALUE)&op);
1735
1736 pDispID = ALLOCA_N(DISPID, cNamedArgs + 1);
1737 op.pNamedArgs[0] = ole_mb2wc(StringValuePtr(cmd), -1);
1738 hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch,
1739 &IID_NULL,
1740 op.pNamedArgs,
1741 op.dp.cNamedArgs + 1,
1742 lcid, pDispID);
1743 for(i = 0; i < op.dp.cNamedArgs + 1; i++) {
1744 SysFreeString(op.pNamedArgs[i]);
1745 op.pNamedArgs[i] = NULL;
1746 }
1747 if(FAILED(hr)) {
1748
1749 for(i = 0; i < op.dp.cArgs; i++ ) {
1750 VariantClear(&op.dp.rgvarg[i]);
1751 }
1752 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,
1753 "FAIL to get named argument info : `%s'",
1754 StringValuePtr(cmd));
1755 }
1756 op.dp.rgdispidNamedArgs = &(pDispID[1]);
1757 }
1758 else {
1759 cNamedArgs = 0;
1760 op.dp.cArgs = argc - 1;
1761 op.pNamedArgs = ALLOCA_N(OLECHAR*, cNamedArgs + 1);
1762 if (op.dp.cArgs > 0) {
1763 op.dp.rgvarg = ALLOCA_N(VARIANTARG, op.dp.cArgs);
1764 }
1765 }
1766
1767
1768
1769 if(op.dp.cArgs > cNamedArgs) {
1770 realargs = ALLOCA_N(VARIANTARG, op.dp.cArgs-cNamedArgs+1);
1771 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
1772 n = op.dp.cArgs - i + cNamedArgs - 1;
1773 VariantInit(&realargs[n]);
1774 VariantInit(&op.dp.rgvarg[n]);
1775 param = rb_ary_entry(paramS, i-cNamedArgs);
1776
1777 ole_val2variant(param, &realargs[n]);
1778 V_VT(&op.dp.rgvarg[n]) = VT_VARIANT | VT_BYREF;
1779 V_VARIANTREF(&op.dp.rgvarg[n]) = &realargs[n];
1780
1781 }
1782 }
1783
1784 if (wFlags & DISPATCH_PROPERTYPUT) {
1785 if (op.dp.cArgs == 0)
1786 return ResultFromScode(E_INVALIDARG);
1787
1788 op.dp.cNamedArgs = 1;
1789 op.dp.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 );
1790 op.dp.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
1791 }
1792
1793 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
1794 &IID_NULL, lcid, wFlags, &op.dp,
1795 &result, &excepinfo, &argErr);
1796 if (FAILED(hr)) {
1797
1798 if(op.dp.cArgs > cNamedArgs) {
1799 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
1800 n = op.dp.cArgs - i + cNamedArgs - 1;
1801 param = rb_ary_entry(paramS, i-cNamedArgs);
1802 ole_val2variant(param, &op.dp.rgvarg[n]);
1803 }
1804 memset(&excepinfo, 0, sizeof(EXCEPINFO));
1805 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
1806 &IID_NULL, lcid, wFlags,
1807 &op.dp, NULL,
1808 &excepinfo, &argErr);
1809 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
1810 n = op.dp.cArgs - i + cNamedArgs - 1;
1811 VariantClear(&op.dp.rgvarg[n]);
1812 }
1813 }
1814
1815
1816
1817
1818 if (hr == DISP_E_EXCEPTION && DispID > 0x8000) {
1819 memset(&excepinfo, 0, sizeof(EXCEPINFO));
1820 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DispID,
1821 &IID_NULL, lcid, wFlags,
1822 &op.dp, NULL,
1823 &excepinfo, &argErr);
1824
1825 }
1826 }
1827
1828 if(op.dp.cArgs > cNamedArgs) {
1829 args = rb_cvar_get(cWIN32OLE, rb_intern("ARGV"));
1830 rb_funcall(args, rb_intern("clear"), 0);
1831 for(i = cNamedArgs; i < op.dp.cArgs; i++) {
1832 n = op.dp.cArgs - i + cNamedArgs - 1;
1833 rb_ary_push(args, ole_variant2val(&realargs[n]));
1834 VariantClear(&realargs[n]);
1835 }
1836 }
1837 else {
1838 for(i = 0; i < op.dp.cArgs; i++) {
1839 VariantClear(&op.dp.rgvarg[i]);
1840 }
1841 }
1842
1843 if (FAILED(hr)) {
1844 v = ole_excepinfo2msg(&excepinfo);
1845 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "%s%s",
1846 StringValuePtr(cmd), StringValuePtr(v));
1847 }
1848 obj = ole_variant2val(&result);
1849 VariantClear(&result);
1850 return obj;
1851 }
1852
1853 static VALUE
1854 fole_invoke(argc, argv, self)
1855 int argc;
1856 VALUE *argv;
1857 VALUE self;
1858 {
1859 return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET);
1860 }
1861
1862 static VALUE
1863 ole_invoke2(self, dispid, args, types, dispkind)
1864 VALUE self;
1865 VALUE dispid;
1866 VALUE args;
1867 VALUE types;
1868 USHORT dispkind;
1869 {
1870 HRESULT hr;
1871 struct oledata *pole;
1872 unsigned int argErr = 0;
1873 EXCEPINFO excepinfo;
1874 VARIANT result;
1875 DISPPARAMS dispParams;
1876 VARIANTARG* realargs = NULL;
1877 int i, j;
1878 VALUE obj = Qnil;
1879 VALUE tp, param;
1880 VALUE v;
1881 VARTYPE vt;
1882
1883 Check_Type(args, T_ARRAY);
1884 Check_Type(types, T_ARRAY);
1885
1886 memset(&excepinfo, 0, sizeof(EXCEPINFO));
1887 memset(&dispParams, 0, sizeof(DISPPARAMS));
1888 VariantInit(&result);
1889 OLEData_Get_Struct(self, pole);
1890
1891 dispParams.cArgs = RARRAY(args)->len;
1892 dispParams.rgvarg = ALLOCA_N(VARIANTARG, dispParams.cArgs);
1893 realargs = ALLOCA_N(VARIANTARG, dispParams.cArgs);
1894 for (i = 0, j = dispParams.cArgs - 1; i < (int)dispParams.cArgs; i++, j--)
1895 {
1896 VariantInit(&realargs[i]);
1897 VariantInit(&dispParams.rgvarg[i]);
1898 tp = rb_ary_entry(types, j);
1899 vt = (VARTYPE)FIX2INT(tp);
1900 V_VT(&dispParams.rgvarg[i]) = vt;
1901 param = rb_ary_entry(args, j);
1902 if (param == Qnil)
1903 {
1904
1905 V_VT(&dispParams.rgvarg[i]) = V_VT(&realargs[i]) = VT_ERROR;
1906 V_ERROR(&dispParams.rgvarg[i]) = V_ERROR(&realargs[i]) = DISP_E_PARAMNOTFOUND;
1907 }
1908 else
1909 {
1910 if (vt & VT_ARRAY)
1911 {
1912 int ent;
1913 LPBYTE pb;
1914 short* ps;
1915 LPLONG pl;
1916 VARIANT* pv;
1917 CY *py;
1918 VARTYPE v;
1919 SAFEARRAYBOUND rgsabound[1];
1920 Check_Type(param, T_ARRAY);
1921 rgsabound[0].lLbound = 0;
1922 rgsabound[0].cElements = RARRAY(param)->len;
1923 v = vt & ~(VT_ARRAY | VT_BYREF);
1924 V_ARRAY(&realargs[i]) = SafeArrayCreate(v, 1, rgsabound);
1925 V_VT(&realargs[i]) = VT_ARRAY | v;
1926 SafeArrayLock(V_ARRAY(&realargs[i]));
1927 pb = V_ARRAY(&realargs[i])->pvData;
1928 ps = V_ARRAY(&realargs[i])->pvData;
1929 pl = V_ARRAY(&realargs[i])->pvData;
1930 py = V_ARRAY(&realargs[i])->pvData;
1931 pv = V_ARRAY(&realargs[i])->pvData;
1932 for (ent = 0; ent < (int)rgsabound[0].cElements; ent++)
1933 {
1934 VARIANT velem;
1935 VALUE elem = rb_ary_entry(param, ent);
1936 ole_val2variant(elem, &velem);
1937 if (v != VT_VARIANT)
1938 {
1939 VariantChangeTypeEx(&velem, &velem,
1940 LOCALE_SYSTEM_DEFAULT, 0, v);
1941 }
1942 switch (v)
1943 {
1944
1945 case VT_VARIANT:
1946 *pv++ = velem;
1947 break;
1948
1949 case VT_R8:
1950 case VT_CY:
1951 case VT_DATE:
1952 *py++ = V_CY(&velem);
1953 break;
1954
1955 case VT_BOOL:
1956 case VT_I2:
1957 case VT_UI2:
1958 *ps++ = V_I2(&velem);
1959 break;
1960
1961 case VT_UI1:
1962 case VT_I1:
1963 *pb++ = V_UI1(&velem);
1964 break;
1965
1966 default:
1967 *pl++ = V_I4(&velem);
1968 break;
1969 }
1970 }
1971 SafeArrayUnlock(V_ARRAY(&realargs[i]));
1972 }
1973 else
1974 {
1975 ole_val2variant(param, &realargs[i]);
1976 if ((vt & (~VT_BYREF)) != VT_VARIANT)
1977 {
1978 hr = VariantChangeTypeEx(&realargs[i], &realargs[i],
1979 LOCALE_SYSTEM_DEFAULT, 0,
1980 (VARTYPE)(vt & (~VT_BYREF)));
1981 if (hr != S_OK)
1982 {
1983 rb_raise(rb_eTypeError, "not valid value");
1984 }
1985 }
1986 }
1987 if ((vt & VT_BYREF) || vt == VT_VARIANT)
1988 {
1989 if (vt == VT_VARIANT)
1990 V_VT(&dispParams.rgvarg[i]) = VT_VARIANT | VT_BYREF;
1991 switch (vt & (~VT_BYREF))
1992 {
1993
1994 case VT_VARIANT:
1995 V_VARIANTREF(&dispParams.rgvarg[i]) = &realargs[i];
1996 break;
1997
1998 case VT_R8:
1999 case VT_CY:
2000 case VT_DATE:
2001 V_CYREF(&dispParams.rgvarg[i]) = &V_CY(&realargs[i]);
2002 break;
2003
2004 case VT_BOOL:
2005 case VT_I2:
2006 case VT_UI2:
2007 V_I2REF(&dispParams.rgvarg[i]) = &V_I2(&realargs[i]);
2008 break;
2009
2010 case VT_UI1:
2011 case VT_I1:
2012 V_UI1REF(&dispParams.rgvarg[i]) = &V_UI1(&realargs[i]);
2013 break;
2014
2015 default:
2016 V_I4REF(&dispParams.rgvarg[i]) = &V_I4(&realargs[i]);
2017 break;
2018 }
2019 }
2020 else
2021 {
2022
2023 V_CY(&dispParams.rgvarg[i]) = V_CY(&realargs[i]);
2024 }
2025 }
2026 }
2027
2028 if (dispkind & DISPATCH_PROPERTYPUT) {
2029 dispParams.cNamedArgs = 1;
2030 dispParams.rgdispidNamedArgs = ALLOCA_N( DISPID, 1 );
2031 dispParams.rgdispidNamedArgs[0] = DISPID_PROPERTYPUT;
2032 }
2033
2034 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, FIX2INT(dispid),
2035 &IID_NULL, LOCALE_SYSTEM_DEFAULT,
2036 dispkind,
2037 &dispParams, &result,
2038 &excepinfo, &argErr);
2039
2040 if (FAILED(hr)) {
2041 v = ole_excepinfo2msg(&excepinfo);
2042 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "_invoke %s",
2043 StringValuePtr(v));
2044 }
2045
2046
2047 if(dispParams.cArgs > 0) {
2048 VALUE argv = rb_cvar_get(cWIN32OLE, rb_intern("ARGV"));
2049 rb_funcall(argv, rb_intern("clear"), 0);
2050 for(i = dispParams.cArgs - 1; i >= 0; i--) {
2051 rb_ary_push(argv, ole_variant2val(&realargs[i]));
2052 VariantClear(&realargs[i]);
2053 }
2054 }
2055
2056 obj = ole_variant2val(&result);
2057 VariantClear(&result);
2058 return obj;
2059 }
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069 static VALUE
2070 fole_invoke2(self, dispid, args, types)
2071 VALUE self;
2072 VALUE dispid;
2073 VALUE args;
2074 VALUE types;
2075 {
2076 return ole_invoke2(self, dispid, args, types, DISPATCH_METHOD);
2077 }
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087 static VALUE
2088 fole_getproperty2(self, dispid, args, types)
2089 VALUE self;
2090 VALUE dispid;
2091 VALUE args;
2092 VALUE types;
2093 {
2094 return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYGET);
2095 }
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105 static VALUE
2106 fole_setproperty2(self, dispid, args, types)
2107 VALUE self;
2108 VALUE dispid;
2109 VALUE args;
2110 VALUE types;
2111 {
2112 return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYPUT);
2113 }
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123 static VALUE
2124 fole_setproperty(argc, argv, self)
2125 int argc;
2126 VALUE *argv;
2127 VALUE self;
2128 {
2129 return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT);
2130 }
2131
2132
2133
2134
2135
2136
2137 static VALUE
2138 fole_getproperty(self, property)
2139 VALUE self, property;
2140 {
2141 return ole_invoke(1, &property, self, DISPATCH_PROPERTYGET);
2142 }
2143
2144 static VALUE
2145 ole_propertyput(self, property, value)
2146 VALUE self, property, value;
2147 {
2148 struct oledata *pole;
2149 unsigned argErr;
2150 unsigned int index;
2151 HRESULT hr;
2152 EXCEPINFO excepinfo;
2153 DISPID dispID = DISPID_VALUE;
2154 DISPID dispIDParam = DISPID_PROPERTYPUT;
2155 USHORT wFlags = DISPATCH_PROPERTYPUT;
2156 DISPPARAMS dispParams;
2157 VARIANTARG propertyValue[2];
2158 OLECHAR* pBuf[1];
2159 VALUE v;
2160 LCID lcid = LOCALE_SYSTEM_DEFAULT;
2161 dispParams.rgdispidNamedArgs = &dispIDParam;
2162 dispParams.rgvarg = propertyValue;
2163 dispParams.cNamedArgs = 1;
2164 dispParams.cArgs = 1;
2165
2166 VariantInit(&propertyValue[0]);
2167 VariantInit(&propertyValue[1]);
2168 memset(&excepinfo, 0, sizeof(excepinfo));
2169
2170 OLEData_Get_Struct(self, pole);
2171
2172
2173 pBuf[0] = ole_mb2wc(StringValuePtr(property), -1);
2174 hr = pole->pDispatch->lpVtbl->GetIDsOfNames(pole->pDispatch, &IID_NULL,
2175 pBuf, 1, lcid, &dispID);
2176 SysFreeString(pBuf[0]);
2177 pBuf[0] = NULL;
2178
2179 if(FAILED(hr)) {
2180 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR,
2181 "Unknown property or method : `%s'",
2182 StringValuePtr(property));
2183 }
2184
2185 ole_val2variant(value, &propertyValue[0]);
2186 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, dispID, &IID_NULL,
2187 lcid, wFlags, &dispParams,
2188 NULL, &excepinfo, &argErr);
2189
2190 for(index = 0; index < dispParams.cArgs; ++index) {
2191 VariantClear(&propertyValue[index]);
2192 }
2193 if (FAILED(hr)) {
2194 v = ole_excepinfo2msg(&excepinfo);
2195 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, StringValuePtr(v));
2196 }
2197 return Qnil;
2198 }
2199
2200 static VALUE
2201 fole_free(self)
2202 VALUE self;
2203 {
2204 struct oledata *pole;
2205 OLEData_Get_Struct(self, pole);
2206 OLE_FREE(pole->pDispatch);
2207 pole->pDispatch = NULL;
2208 return Qnil;
2209 }
2210
2211 static VALUE
2212 ole_each_sub(pEnumV)
2213 VALUE pEnumV;
2214 {
2215 VARIANT variant;
2216 VALUE obj = Qnil;
2217 IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
2218 VariantInit(&variant);
2219 while(pEnum->lpVtbl->Next(pEnum, 1, &variant, NULL) == S_OK) {
2220 obj = ole_variant2val(&variant);
2221 VariantClear(&variant);
2222 VariantInit(&variant);
2223 rb_yield(obj);
2224 }
2225 return Qnil;
2226 }
2227
2228 static VALUE
2229 ole_ienum_free(pEnumV)
2230 VALUE pEnumV;
2231 {
2232 IEnumVARIANT *pEnum = (IEnumVARIANT *)pEnumV;
2233 OLE_RELEASE(pEnum);
2234 return Qnil;
2235 }
2236
2237
2238
2239
2240
2241
2242 static VALUE
2243 fole_each(self)
2244 VALUE self;
2245 {
2246 LCID lcid = LOCALE_SYSTEM_DEFAULT;
2247
2248 struct oledata *pole;
2249
2250 unsigned int argErr;
2251 EXCEPINFO excepinfo;
2252 DISPPARAMS dispParams;
2253 VARIANT result;
2254 HRESULT hr;
2255 IEnumVARIANT *pEnum = NULL;
2256
2257 VariantInit(&result);
2258 dispParams.rgvarg = NULL;
2259 dispParams.rgdispidNamedArgs = NULL;
2260 dispParams.cNamedArgs = 0;
2261 dispParams.cArgs = 0;
2262 memset(&excepinfo, 0, sizeof(excepinfo));
2263
2264 OLEData_Get_Struct(self, pole);
2265 hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DISPID_NEWENUM,
2266 &IID_NULL, lcid,
2267 DISPATCH_METHOD | DISPATCH_PROPERTYGET,
2268 &dispParams, &result,
2269 &excepinfo, &argErr);
2270
2271 if (FAILED(hr)) {
2272 VariantClear(&result);
2273 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to get IEnum Interface");
2274 }
2275
2276 if (V_VT(&result) == VT_UNKNOWN)
2277 hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result),
2278 &IID_IEnumVARIANT,
2279 (void**)&pEnum);
2280 else if (V_VT(&result) == VT_DISPATCH)
2281 hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result),
2282 &IID_IEnumVARIANT,
2283 (void**)&pEnum);
2284 if (FAILED(hr) || !pEnum) {
2285 VariantClear(&result);
2286 ole_raise(hr, rb_eRuntimeError, "Fail to get IEnum Interface");
2287 }
2288
2289 VariantClear(&result);
2290 rb_ensure(ole_each_sub, (VALUE)pEnum, ole_ienum_free, (VALUE)pEnum);
2291 return Qnil;
2292 }
2293
2294
2295
2296
2297
2298
2299 static VALUE
2300 fole_missing(argc, argv, self)
2301 int argc;
2302 VALUE *argv;
2303 VALUE self;
2304 {
2305 ID id;
2306 char* mname;
2307 int n;
2308 id = rb_to_id(argv[0]);
2309 mname = rb_id2name(id);
2310 if(!mname) {
2311 rb_raise(rb_eRuntimeError, "Fail : Unknown method or property");
2312 }
2313 n = strlen(mname);
2314 if(mname[n-1] == '=') {
2315 argv[0] = rb_str_new(mname, n-1);
2316
2317 return ole_propertyput(self, argv[0], argv[1]);
2318 }
2319 else {
2320 argv[0] = rb_str_new2(mname);
2321 return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET);
2322 }
2323 }
2324
2325 static VALUE
2326 ole_method_sub(self, pOwnerTypeInfo, pTypeInfo, name)
2327 VALUE self;
2328 ITypeInfo *pOwnerTypeInfo;
2329 ITypeInfo *pTypeInfo;
2330 VALUE name;
2331 {
2332 HRESULT hr;
2333 TYPEATTR *pTypeAttr;
2334 BSTR bstr;
2335 FUNCDESC *pFuncDesc;
2336 WORD i;
2337 VALUE fname;
2338 VALUE method = Qnil;
2339 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
2340 if (FAILED(hr)) {
2341 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetTypeAttr");
2342 }
2343 for(i = 0; i < pTypeAttr->cFuncs && method == Qnil; i++) {
2344 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
2345 if (FAILED(hr))
2346 continue;
2347
2348 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
2349 &bstr, NULL, NULL, NULL);
2350 if (FAILED(hr)) {
2351 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
2352 continue;
2353 }
2354 fname = WC2VSTR(bstr);
2355 if (strcasecmp(StringValuePtr(name), StringValuePtr(fname)) == 0) {
2356 olemethod_set_member(self, pTypeInfo, pOwnerTypeInfo, i, fname);
2357 method = self;
2358 }
2359 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
2360 pFuncDesc=NULL;
2361 }
2362 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
2363 return method;
2364 }
2365
2366 static VALUE
2367 olemethod_from_typeinfo(self, pTypeInfo, name)
2368 VALUE self;
2369 ITypeInfo *pTypeInfo;
2370 VALUE name;
2371 {
2372 HRESULT hr;
2373 TYPEATTR *pTypeAttr;
2374 WORD i;
2375 HREFTYPE href;
2376 ITypeInfo *pRefTypeInfo;
2377 VALUE method = Qnil;
2378 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
2379 if (FAILED(hr)) {
2380 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetTypeAttr");
2381 }
2382 method = ole_method_sub(self, 0, pTypeInfo, name);
2383 if (method != Qnil) {
2384 return method;
2385 }
2386 for(i=0; i < pTypeAttr->cImplTypes && method == Qnil; i++){
2387 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
2388 if(FAILED(hr))
2389 continue;
2390 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
2391 if (FAILED(hr))
2392 continue;
2393 method = ole_method_sub(self, pTypeInfo, pRefTypeInfo, name);
2394 OLE_RELEASE(pRefTypeInfo);
2395 }
2396 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
2397 return method;
2398 }
2399
2400 static VALUE
2401 ole_methods_sub(pOwnerTypeInfo, pTypeInfo, methods, mask)
2402 ITypeInfo *pOwnerTypeInfo;
2403 ITypeInfo *pTypeInfo;
2404 VALUE methods;
2405 int mask;
2406 {
2407 HRESULT hr;
2408 TYPEATTR *pTypeAttr;
2409 BSTR bstr;
2410 char *pstr;
2411 FUNCDESC *pFuncDesc;
2412 VALUE method;
2413 WORD i;
2414 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
2415 if (FAILED(hr)) {
2416 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetTypeAttr");
2417 }
2418 for(i = 0; i < pTypeAttr->cFuncs; i++) {
2419 pstr = NULL;
2420 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, i, &pFuncDesc);
2421 if (FAILED(hr))
2422 continue;
2423
2424 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
2425 &bstr, NULL, NULL, NULL);
2426 if (FAILED(hr)) {
2427 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
2428 continue;
2429 }
2430 if(pFuncDesc->invkind & mask) {
2431 method = folemethod_s_allocate(cWIN32OLE_METHOD);
2432 olemethod_set_member(method, pTypeInfo, pOwnerTypeInfo,
2433 i, WC2VSTR(bstr));
2434 rb_ary_push(methods, method);
2435 }
2436 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
2437 pFuncDesc=NULL;
2438 }
2439 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
2440
2441 return methods;
2442 }
2443
2444 static VALUE
2445 ole_methods_from_typeinfo(pTypeInfo, mask)
2446 ITypeInfo *pTypeInfo;
2447 int mask;
2448 {
2449 HRESULT hr;
2450 TYPEATTR *pTypeAttr;
2451 WORD i;
2452 HREFTYPE href;
2453 ITypeInfo *pRefTypeInfo;
2454 VALUE methods = rb_ary_new();
2455 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
2456 if (FAILED(hr)) {
2457 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetTypeAttr");
2458 }
2459
2460 ole_methods_sub(0, pTypeInfo, methods, mask);
2461 for(i=0; i < pTypeAttr->cImplTypes; i++){
2462 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo, i, &href);
2463 if(FAILED(hr))
2464 continue;
2465 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo, href, &pRefTypeInfo);
2466 if (FAILED(hr))
2467 continue;
2468 ole_methods_sub(pTypeInfo, pRefTypeInfo, methods, mask);
2469 OLE_RELEASE(pRefTypeInfo);
2470 }
2471 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
2472 return methods;
2473 }
2474
2475 static HRESULT
2476 typeinfo_from_ole(pole, ppti)
2477 struct oledata *pole;
2478 ITypeInfo **ppti;
2479 {
2480 ITypeInfo *pTypeInfo;
2481 ITypeLib *pTypeLib;
2482 BSTR bstr;
2483 VALUE type;
2484 UINT i;
2485 UINT count;
2486 LCID lcid = LOCALE_SYSTEM_DEFAULT;
2487 HRESULT hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
2488 0, lcid, &pTypeInfo);
2489 if(FAILED(hr)) {
2490 ole_raise(hr, rb_eRuntimeError, "fail to GetTypeInfo");
2491 }
2492 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo,
2493 -1,
2494 &bstr,
2495 NULL, NULL, NULL);
2496 type = WC2VSTR(bstr);
2497 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
2498 OLE_RELEASE(pTypeInfo);
2499 if (FAILED(hr)) {
2500 ole_raise(hr, rb_eRuntimeError, "fail to GetContainingTypeLib");
2501 }
2502 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
2503 for (i = 0; i < count; i++) {
2504 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
2505 &bstr, NULL, NULL, NULL);
2506 if (SUCCEEDED(hr) && rb_str_cmp(WC2VSTR(bstr), type) == 0) {
2507 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
2508 if (SUCCEEDED(hr)) {
2509 *ppti = pTypeInfo;
2510 break;
2511 }
2512 }
2513 }
2514 OLE_RELEASE(pTypeLib);
2515 return hr;
2516 }
2517
2518 static VALUE
2519 ole_methods(self,mask)
2520 VALUE self;
2521 int mask;
2522 {
2523 ITypeInfo *pTypeInfo;
2524 HRESULT hr;
2525 VALUE methods;
2526 struct oledata *pole;
2527
2528 OLEData_Get_Struct(self, pole);
2529 methods = rb_ary_new();
2530
2531 hr = typeinfo_from_ole(pole, &pTypeInfo);
2532 if(FAILED(hr))
2533 return methods;
2534 rb_ary_concat(methods, ole_methods_from_typeinfo(pTypeInfo, mask));
2535 OLE_RELEASE(pTypeInfo);
2536 return methods;
2537 }
2538
2539
2540
2541
2542
2543
2544 static VALUE
2545 fole_methods( self )
2546 VALUE self;
2547 {
2548 return ole_methods( self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT);
2549 }
2550
2551
2552
2553
2554
2555
2556 static VALUE
2557 fole_get_methods( argc, argv, self )
2558 int argc;
2559 VALUE *argv;
2560 VALUE self;
2561 {
2562 return ole_methods( self, INVOKE_PROPERTYGET);
2563 }
2564
2565
2566
2567
2568
2569
2570 static VALUE
2571 fole_put_methods( argc, argv, self )
2572 int argc;
2573 VALUE *argv;
2574 VALUE self;
2575 {
2576 return ole_methods( self, INVOKE_PROPERTYPUT);
2577 }
2578
2579
2580
2581
2582
2583
2584 static VALUE
2585 fole_func_methods( argc, argv, self )
2586 int argc;
2587 VALUE *argv;
2588 VALUE self;
2589 {
2590 return ole_methods( self, INVOKE_FUNC);
2591 }
2592
2593
2594
2595
2596
2597
2598 static VALUE
2599 fole_obj_help( self )
2600 VALUE self;
2601 {
2602 unsigned int index;
2603 ITypeInfo *pTypeInfo;
2604 ITypeLib *pTypeLib;
2605 HRESULT hr;
2606 struct oledata *pole;
2607 BSTR bstr;
2608 LCID lcid = LOCALE_SYSTEM_DEFAULT;
2609 VALUE type = Qnil;
2610
2611 OLEData_Get_Struct(self, pole);
2612
2613 hr = pole->pDispatch->lpVtbl->GetTypeInfo( pole->pDispatch, 0, lcid, &pTypeInfo );
2614 if(FAILED(hr)) {
2615 ole_raise(hr, rb_eRuntimeError, "fail to GetTypeInfo");
2616 }
2617 hr = pTypeInfo->lpVtbl->GetContainingTypeLib( pTypeInfo, &pTypeLib, &index );
2618 if(FAILED(hr)) {
2619 OLE_RELEASE(pTypeInfo);
2620 ole_raise(hr, rb_eRuntimeError, "fail to GetContainingTypeLib");
2621 }
2622 hr = pTypeLib->lpVtbl->GetDocumentation( pTypeLib, index,
2623 &bstr, NULL, NULL, NULL);
2624 if (SUCCEEDED(hr)) {
2625 type = foletype_s_allocate(cWIN32OLE_TYPE);
2626 oletype_set_member(type, pTypeInfo, WC2VSTR(bstr));
2627 }
2628 OLE_RELEASE(pTypeLib);
2629 OLE_RELEASE(pTypeInfo);
2630
2631 return type;
2632 }
2633
2634 static HRESULT
2635 ole_docinfo_from_type(pTypeInfo, name, helpstr, helpcontext, helpfile)
2636 ITypeInfo *pTypeInfo;
2637 BSTR *name;
2638 BSTR *helpstr;
2639 DWORD *helpcontext;
2640 BSTR *helpfile;
2641 {
2642 HRESULT hr;
2643 ITypeLib *pTypeLib;
2644 UINT i;
2645
2646 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &i);
2647 if (FAILED(hr)) {
2648 return hr;
2649 }
2650
2651 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
2652 name, helpstr,
2653 helpcontext, helpfile);
2654 if (FAILED(hr)) {
2655 OLE_RELEASE(pTypeLib);
2656 return hr;
2657 }
2658 OLE_RELEASE(pTypeLib);
2659 return hr;
2660 }
2661
2662 static VALUE
2663 ole_usertype2val(pTypeInfo, pTypeDesc, typedetails)
2664 ITypeInfo *pTypeInfo;
2665 TYPEDESC *pTypeDesc;
2666 VALUE typedetails;
2667 {
2668 HRESULT hr;
2669 BSTR bstr;
2670 ITypeInfo *pRefTypeInfo;
2671 VALUE type = Qnil;
2672
2673 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
2674 V_UNION1(pTypeDesc, hreftype),
2675 &pRefTypeInfo);
2676 if(FAILED(hr))
2677 return Qnil;
2678 hr = ole_docinfo_from_type(pRefTypeInfo, &bstr, NULL, NULL, NULL);
2679 if(FAILED(hr)) {
2680 OLE_RELEASE(pRefTypeInfo);
2681 return Qnil;
2682 }
2683 OLE_RELEASE(pRefTypeInfo);
2684 type = WC2VSTR(bstr);
2685 if(typedetails != Qnil)
2686 rb_ary_push(typedetails, type);
2687 return type;
2688 }
2689
2690 static VALUE ole_typedesc2val();
2691 static VALUE
2692 ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails)
2693 ITypeInfo *pTypeInfo;
2694 TYPEDESC *pTypeDesc;
2695 VALUE typedetails;
2696 {
2697 TYPEDESC *p = pTypeDesc;
2698 VALUE type = rb_str_new2("");
2699 while(p->vt == VT_PTR || p->vt == VT_SAFEARRAY) {
2700 p = V_UNION1(p, lptdesc);
2701 if(strlen(StringValuePtr(type)) == 0) {
2702 type = ole_typedesc2val(pTypeInfo, p, typedetails);
2703 } else {
2704 rb_str_cat(type, ",", 1);
2705 rb_str_concat(type, ole_typedesc2val(pTypeInfo, p, typedetails));
2706 }
2707 }
2708 return type;
2709 }
2710
2711 static VALUE
2712 ole_typedesc2val(pTypeInfo, pTypeDesc, typedetails)
2713 ITypeInfo *pTypeInfo;
2714 TYPEDESC *pTypeDesc;
2715 VALUE typedetails;
2716 {
2717 VALUE str;
2718 switch(pTypeDesc->vt) {
2719 case VT_I2:
2720 if(typedetails != Qnil)
2721 rb_ary_push(typedetails, rb_str_new2("I2"));
2722 return rb_str_new2("I2");
2723 case VT_I4:
2724 if(typedetails != Qnil)
2725 rb_ary_push(typedetails, rb_str_new2("I4"));
2726 return rb_str_new2("I4");
2727 case VT_R4:
2728 if(typedetails != Qnil)
2729 rb_ary_push(typedetails, rb_str_new2("R4"));
2730 return rb_str_new2("R4");
2731 case VT_R8:
2732 if(typedetails != Qnil)
2733 rb_ary_push(typedetails, rb_str_new2("R8"));
2734 return rb_str_new2("R8");
2735 case VT_CY:
2736 if(typedetails != Qnil)
2737 rb_ary_push(typedetails, rb_str_new2("CY"));
2738 return rb_str_new2("CY");
2739 case VT_DATE:
2740 if(typedetails != Qnil)
2741 rb_ary_push(typedetails, rb_str_new2("DATE"));
2742 return rb_str_new2("DATE");
2743 case VT_BSTR:
2744 if(typedetails != Qnil)
2745 rb_ary_push(typedetails, rb_str_new2("BSTR"));
2746 return rb_str_new2("BSTR");
2747 case VT_BOOL:
2748 if(typedetails != Qnil)
2749 rb_ary_push(typedetails, rb_str_new2("BOOL"));
2750 return rb_str_new2("BOOL");
2751 case VT_VARIANT:
2752 if(typedetails != Qnil)
2753 rb_ary_push(typedetails, rb_str_new2("VARIANT"));
2754 return rb_str_new2("VARIANT");
2755 case VT_DECIMAL:
2756 if(typedetails != Qnil)
2757 rb_ary_push(typedetails, rb_str_new2("DECIMAL"));
2758 return rb_str_new2("DECIMAL");
2759 case VT_I1:
2760 if(typedetails != Qnil)
2761 rb_ary_push(typedetails, rb_str_new2("I1"));
2762 return rb_str_new2("I1");
2763 case VT_UI1:
2764 if(typedetails != Qnil)
2765 rb_ary_push(typedetails, rb_str_new2("UI1"));
2766 return rb_str_new2("UI1");
2767 case VT_UI2:
2768 if(typedetails != Qnil)
2769 rb_ary_push(typedetails, rb_str_new2("UI2"));
2770 return rb_str_new2("UI2");
2771 case VT_UI4:
2772 if(typedetails != Qnil)
2773 rb_ary_push(typedetails, rb_str_new2("UI4"));
2774 return rb_str_new2("UI4");
2775 case VT_I8:
2776 if(typedetails != Qnil)
2777 rb_ary_push(typedetails, rb_str_new2("I8"));
2778 return rb_str_new2("I8");
2779 case VT_UI8:
2780 if(typedetails != Qnil)
2781 rb_ary_push(typedetails, rb_str_new2("UI8"));
2782 return rb_str_new2("UI8");
2783 case VT_INT:
2784 if(typedetails != Qnil)
2785 rb_ary_push(typedetails, rb_str_new2("INT"));
2786 return rb_str_new2("INT");
2787 case VT_UINT:
2788 if(typedetails != Qnil)
2789 rb_ary_push(typedetails, rb_str_new2("UINT"));
2790 return rb_str_new2("UINT");
2791 case VT_VOID:
2792 if(typedetails != Qnil)
2793 rb_ary_push(typedetails, rb_str_new2("VOID"));
2794 return rb_str_new2("VOID");
2795 case VT_HRESULT:
2796 if(typedetails != Qnil)
2797 rb_ary_push(typedetails, rb_str_new2("HRESULT"));
2798 return rb_str_new2("HRESULT");
2799 case VT_PTR:
2800 if(typedetails != Qnil)
2801 rb_ary_push(typedetails, rb_str_new2("PTR"));
2802 return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
2803 case VT_SAFEARRAY:
2804 if(typedetails != Qnil)
2805 rb_ary_push(typedetails, rb_str_new2("SAFEARRAY"));
2806 return ole_ptrtype2val(pTypeInfo, pTypeDesc, typedetails);
2807 case VT_CARRAY:
2808 if(typedetails != Qnil)
2809 rb_ary_push(typedetails, rb_str_new2("CARRAY"));
2810 return rb_str_new2("CARRAY");
2811 case VT_USERDEFINED:
2812 if(typedetails != Qnil)
2813 rb_ary_push(typedetails, rb_str_new2("USERDEFINED"));
2814 str = ole_usertype2val(pTypeInfo, pTypeDesc, typedetails);
2815 if (str != Qnil) {
2816 return str;
2817 }
2818 return rb_str_new2("USERDEFINED");
2819 case VT_UNKNOWN:
2820 return rb_str_new2("UNKNOWN");
2821 case VT_DISPATCH:
2822 if(typedetails != Qnil)
2823 rb_ary_push(typedetails, rb_str_new2("DISPATCH"));
2824 return rb_str_new2("DISPATCH");
2825 default:
2826 str = rb_str_new2("Unknown Type ");
2827 rb_str_concat(str, rb_fix2str(INT2FIX(pTypeDesc->vt), 10));
2828 return str;
2829 }
2830 }
2831
2832
2833
2834
2835
2836
2837
2838 static VALUE
2839 fole_method_help( self, cmdname )
2840 VALUE self;
2841 VALUE cmdname;
2842 {
2843 ITypeInfo *pTypeInfo;
2844 HRESULT hr;
2845 struct oledata *pole;
2846 VALUE method, obj;
2847 LCID lcid = LOCALE_SYSTEM_DEFAULT;
2848
2849 Check_SafeStr(cmdname);
2850 OLEData_Get_Struct(self, pole);
2851 hr = typeinfo_from_ole(pole, &pTypeInfo);
2852 if(FAILED(hr))
2853 ole_raise(hr, rb_eRuntimeError, "fail to get ITypeInfo");
2854 method = folemethod_s_allocate(cWIN32OLE_METHOD);
2855 obj = olemethod_from_typeinfo(method, pTypeInfo, cmdname);
2856 OLE_RELEASE(pTypeInfo);
2857 if (obj == Qnil)
2858 rb_raise(eWIN32OLE_RUNTIME_ERROR, "Not found %s",
2859 StringValuePtr(cmdname));
2860 return obj;
2861 }
2862
2863
2864
2865
2866
2867
2868 static VALUE
2869 foletype_s_ole_classes(self, typelib)
2870 VALUE self;
2871 VALUE typelib;
2872 {
2873 VALUE file, classes;
2874 OLECHAR * pbuf;
2875 ITypeLib *pTypeLib;
2876 HRESULT hr;
2877
2878 classes = rb_ary_new();
2879 if(TYPE(typelib) == T_STRING) {
2880 file = typelib_file(typelib);
2881 if (file == Qnil) {
2882 file = typelib;
2883 }
2884 pbuf = ole_mb2wc(StringValuePtr(file), -1);
2885 hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
2886 if (FAILED(hr))
2887 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to LoadTypeLibEx");
2888 SysFreeString(pbuf);
2889 ole_classes_from_typelib(pTypeLib, classes);
2890 OLE_RELEASE(pTypeLib);
2891 } else {
2892 rb_raise(rb_eTypeError, "1st argument should be TypeLib string");
2893 }
2894 return classes;
2895 }
2896
2897
2898
2899
2900
2901
2902 static VALUE
2903 foletype_s_typelibs(self)
2904 VALUE self;
2905 {
2906 HKEY htypelib, hclsid;
2907 double fversion;
2908 DWORD i, j;
2909 LONG err;
2910 VALUE clsid;
2911 VALUE ver;
2912 VALUE v = Qnil;
2913 VALUE typelibs = rb_ary_new();
2914
2915 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
2916 if(err != ERROR_SUCCESS) {
2917 return typelibs;
2918 }
2919 for(i = 0; ; i++) {
2920 clsid = reg_enum_key(htypelib, i);
2921 if (clsid == Qnil)
2922 break;
2923 err = reg_open_vkey(htypelib, clsid, &hclsid);
2924 if (err != ERROR_SUCCESS)
2925 continue;
2926 fversion = 0;
2927 for(j = 0; ; j++) {
2928 ver = reg_enum_key(hclsid, j);
2929 if (ver == Qnil)
2930 break;
2931 if (fversion > atof(StringValuePtr(ver)))
2932 continue;
2933 fversion = atof(StringValuePtr(ver));
2934 if ( (v = reg_get_val(hclsid, StringValuePtr(ver))) != Qnil ) {
2935 rb_ary_push(typelibs, v);
2936 }
2937 }
2938 RegCloseKey(hclsid);
2939 }
2940 RegCloseKey(htypelib);
2941 return typelibs;
2942 }
2943
2944
2945
2946
2947
2948
2949 static VALUE
2950 foletype_s_progids(self)
2951 VALUE self;
2952 {
2953 HKEY hclsids, hclsid;
2954 DWORD i;
2955 LONG err;
2956 VALUE clsid;
2957 VALUE v = rb_str_new2("");
2958 VALUE progids = rb_ary_new();
2959
2960 err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hclsids);
2961 if(err != ERROR_SUCCESS) {
2962 return progids;
2963 }
2964 for(i = 0; ; i++) {
2965 clsid = reg_enum_key(hclsids, i);
2966 if (clsid == Qnil)
2967 break;
2968 err = reg_open_vkey(hclsids, clsid, &hclsid);
2969 if (err != ERROR_SUCCESS)
2970 continue;
2971 if ((v = reg_get_val(hclsid, "ProgID")) != Qnil)
2972 rb_ary_push(progids, v);
2973 if ((v = reg_get_val(hclsid, "VersionIndependentProgID")) != Qnil)
2974 rb_ary_push(progids, v);
2975 RegCloseKey(hclsid);
2976 }
2977 RegCloseKey(hclsids);
2978 return progids;
2979 }
2980
2981 static VALUE
2982 foletype_s_allocate(klass)
2983 VALUE klass;
2984 {
2985 struct oletypedata *poletype;
2986 VALUE obj;
2987 ole_initialize();
2988 obj = Data_Make_Struct(klass,struct oletypedata,0,oletype_free,poletype);
2989 poletype->pTypeInfo = NULL;
2990 return obj;
2991 }
2992
2993 static VALUE
2994 oletype_set_member(self, pTypeInfo, name)
2995 VALUE self;
2996 ITypeInfo *pTypeInfo;
2997 VALUE name;
2998 {
2999 struct oletypedata *ptype;
3000 Data_Get_Struct(self, struct oletypedata, ptype);
3001 rb_ivar_set(self, rb_intern("name"), name);
3002 ptype->pTypeInfo = pTypeInfo;
3003 if(pTypeInfo) OLE_ADDREF(pTypeInfo);
3004 return self;
3005 }
3006
3007 static VALUE
3008 oleclass_from_typelib(self, pTypeLib, oleclass)
3009 VALUE self;
3010 ITypeLib *pTypeLib;
3011 VALUE oleclass;
3012 {
3013
3014 long count;
3015 int i;
3016 HRESULT hr;
3017 BSTR bstr;
3018 VALUE typelib;
3019 ITypeInfo *pTypeInfo;
3020
3021 VALUE found = Qfalse;
3022
3023 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
3024 for (i = 0; i < count && found == Qfalse; i++) {
3025 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
3026 if (FAILED(hr))
3027 continue;
3028 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
3029 &bstr, NULL, NULL, NULL);
3030 if (FAILED(hr))
3031 continue;
3032 typelib = WC2VSTR(bstr);
3033 if (rb_str_cmp(oleclass, typelib) == 0) {
3034 oletype_set_member(self, pTypeInfo, typelib);
3035 found = Qtrue;
3036 }
3037 OLE_RELEASE(pTypeInfo);
3038 }
3039 return found;
3040 }
3041
3042 static VALUE
3043 foletype_initialize(self, typelib, oleclass)
3044 VALUE self;
3045 VALUE typelib;
3046 VALUE oleclass;
3047 {
3048 VALUE file;
3049 OLECHAR * pbuf;
3050 ITypeLib *pTypeLib;
3051 HRESULT hr;
3052
3053 Check_SafeStr(oleclass);
3054 Check_SafeStr(typelib);
3055 file = typelib_file(typelib);
3056 if (file == Qnil) {
3057 file = typelib;
3058 }
3059 pbuf = ole_mb2wc(StringValuePtr(file), -1);
3060 hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
3061 if (FAILED(hr))
3062 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to LoadTypeLibEx");
3063 SysFreeString(pbuf);
3064 if (oleclass_from_typelib(self, pTypeLib, oleclass) == Qfalse) {
3065 OLE_RELEASE(pTypeLib);
3066 rb_raise(eWIN32OLE_RUNTIME_ERROR, "Not found `%s` in `%s`",
3067 StringValuePtr(oleclass), StringValuePtr(typelib));
3068 }
3069 OLE_RELEASE(pTypeLib);
3070 return self;
3071 }
3072
3073
3074
3075
3076
3077
3078 static VALUE
3079 foletype_name(self)
3080 VALUE self;
3081 {
3082 return rb_ivar_get(self, rb_intern("name"));
3083 }
3084
3085 static VALUE
3086 ole_ole_type(pTypeInfo)
3087 ITypeInfo *pTypeInfo;
3088 {
3089 HRESULT hr;
3090 TYPEATTR *pTypeAttr;
3091 VALUE type = Qnil;
3092 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
3093 if(FAILED(hr)){
3094 return type;
3095 }
3096 switch(pTypeAttr->typekind) {
3097 case TKIND_ENUM:
3098 type = rb_str_new2("Enum");
3099 break;
3100 case TKIND_RECORD:
3101 type = rb_str_new2("Record");
3102 break;
3103 case TKIND_MODULE:
3104 type = rb_str_new2("Module");
3105 break;
3106 case TKIND_INTERFACE:
3107 type = rb_str_new2("Interface");
3108 break;
3109 case TKIND_DISPATCH:
3110 type = rb_str_new2("Dispatch");
3111 break;
3112 case TKIND_COCLASS:
3113 type = rb_str_new2("Class");
3114 break;
3115 case TKIND_ALIAS:
3116 type = rb_str_new2("Alias");
3117 break;
3118 case TKIND_UNION:
3119 type = rb_str_new2("Union");
3120 break;
3121 case TKIND_MAX:
3122 type = rb_str_new2("Max");
3123 break;
3124 default:
3125 type = Qnil;
3126 break;
3127 }
3128 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
3129 return type;
3130 }
3131
3132
3133
3134
3135
3136
3137 static VALUE
3138 foletype_ole_type(self)
3139 VALUE self;
3140 {
3141 struct oletypedata *ptype;
3142 Data_Get_Struct(self, struct oletypedata, ptype);
3143 return ole_ole_type(ptype->pTypeInfo);
3144 }
3145
3146 static VALUE
3147 ole_type_guid(pTypeInfo)
3148 ITypeInfo *pTypeInfo;
3149 {
3150 HRESULT hr;
3151 TYPEATTR *pTypeAttr;
3152 int len;
3153 OLECHAR bstr[80];
3154 VALUE guid = Qnil;
3155 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
3156 if (FAILED(hr))
3157 return guid;
3158 len = StringFromGUID2(&pTypeAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
3159 if (len > 3) {
3160 guid = ole_wc2vstr(bstr, FALSE);
3161 }
3162 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
3163 return guid;
3164 }
3165
3166
3167
3168
3169
3170
3171 static VALUE
3172 foletype_guid(self)
3173 {
3174 struct oletypedata *ptype;
3175 Data_Get_Struct(self, struct oletypedata, ptype);
3176 return ole_type_guid(ptype->pTypeInfo);
3177 }
3178
3179 static VALUE
3180 ole_type_progid(pTypeInfo)
3181 ITypeInfo *pTypeInfo;
3182 {
3183 HRESULT hr;
3184 TYPEATTR *pTypeAttr;
3185 OLECHAR *pbuf;
3186 VALUE progid = Qnil;
3187 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
3188 if (FAILED(hr))
3189 return progid;
3190 hr = ProgIDFromCLSID(&pTypeAttr->guid, &pbuf);
3191 if (SUCCEEDED(hr))
3192 progid = WC2VSTR(pbuf);
3193 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
3194 return progid;
3195 }
3196
3197
3198
3199
3200
3201
3202 static VALUE
3203 foletype_progid(self)
3204 {
3205 struct oletypedata *ptype;
3206 Data_Get_Struct(self, struct oletypedata, ptype);
3207 return ole_type_progid(ptype->pTypeInfo);
3208 }
3209
3210
3211 static VALUE
3212 ole_type_visible(pTypeInfo)
3213 ITypeInfo *pTypeInfo;
3214 {
3215 HRESULT hr;
3216 TYPEATTR *pTypeAttr;
3217 VALUE visible;
3218 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
3219 if (FAILED(hr))
3220 return Qtrue;
3221 if (pTypeAttr->wTypeFlags & (TYPEFLAG_FHIDDEN | TYPEFLAG_FRESTRICTED)) {
3222 visible = Qfalse;
3223 } else {
3224 visible = Qtrue;
3225 }
3226 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
3227 return visible;
3228 }
3229
3230
3231
3232
3233
3234
3235 static VALUE
3236 foletype_visible(self)
3237 VALUE self;
3238 {
3239 struct oletypedata *ptype;
3240 Data_Get_Struct(self, struct oletypedata, ptype);
3241 return ole_type_visible(ptype->pTypeInfo);
3242 }
3243
3244 static VALUE
3245 ole_type_major_version(pTypeInfo)
3246 ITypeInfo *pTypeInfo;
3247 {
3248 VALUE ver;
3249 TYPEATTR *pTypeAttr;
3250 HRESULT hr;
3251 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
3252 if (FAILED(hr))
3253 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetTypeAttr");
3254 ver = INT2FIX(pTypeAttr->wMajorVerNum);
3255 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
3256 return ver;
3257 }
3258
3259
3260
3261
3262
3263
3264 static VALUE
3265 foletype_major_version(self)
3266 VALUE self;
3267 {
3268 struct oletypedata *ptype;
3269 Data_Get_Struct(self, struct oletypedata, ptype);
3270 return ole_type_major_version(ptype->pTypeInfo);
3271 }
3272
3273 static VALUE
3274 ole_type_minor_version(pTypeInfo)
3275 ITypeInfo *pTypeInfo;
3276 {
3277 VALUE ver;
3278 TYPEATTR *pTypeAttr;
3279 HRESULT hr;
3280 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
3281 if (FAILED(hr))
3282 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetTypeAttr");
3283 ver = INT2FIX(pTypeAttr->wMinorVerNum);
3284 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
3285 return ver;
3286 }
3287
3288
3289
3290
3291
3292
3293 static VALUE
3294 foletype_minor_version(self)
3295 VALUE self;
3296 {
3297 struct oletypedata *ptype;
3298 Data_Get_Struct(self, struct oletypedata, ptype);
3299 return ole_type_minor_version(ptype->pTypeInfo);
3300 }
3301
3302 static VALUE
3303 ole_type_typekind(pTypeInfo)
3304 ITypeInfo *pTypeInfo;
3305 {
3306 VALUE typekind;
3307 TYPEATTR *pTypeAttr;
3308 HRESULT hr;
3309 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
3310 if (FAILED(hr))
3311 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetTypeAttr");
3312 typekind = INT2FIX(pTypeAttr->typekind);
3313 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
3314 return typekind;
3315 }
3316
3317
3318
3319
3320
3321
3322 static VALUE
3323 foletype_typekind(self)
3324 VALUE self;
3325 {
3326 struct oletypedata *ptype;
3327 Data_Get_Struct(self, struct oletypedata, ptype);
3328 return ole_type_typekind(ptype->pTypeInfo);
3329 }
3330
3331 static VALUE
3332 ole_type_helpstring(pTypeInfo)
3333 ITypeInfo *pTypeInfo;
3334 {
3335 HRESULT hr;
3336 BSTR bhelpstr;
3337 hr = ole_docinfo_from_type(pTypeInfo, NULL, &bhelpstr, NULL, NULL);
3338 if(FAILED(hr)) {
3339 return Qnil;
3340 }
3341 return WC2VSTR(bhelpstr);
3342 }
3343
3344
3345
3346
3347
3348
3349 static VALUE
3350 foletype_helpstring(self)
3351 VALUE self;
3352 {
3353 struct oletypedata *ptype;
3354 Data_Get_Struct(self, struct oletypedata, ptype);
3355 return ole_type_helpstring(ptype->pTypeInfo);
3356 }
3357
3358 static VALUE
3359 ole_type_src_type(pTypeInfo)
3360 ITypeInfo *pTypeInfo;
3361 {
3362 HRESULT hr;
3363 TYPEATTR *pTypeAttr;
3364 VALUE alias = Qnil;
3365 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
3366 if (FAILED(hr))
3367 return alias;
3368 if(pTypeAttr->typekind != TKIND_ALIAS) {
3369 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
3370 return alias;
3371 }
3372 alias = ole_typedesc2val(pTypeInfo, &(pTypeAttr->tdescAlias), Qnil);
3373 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
3374 return alias;
3375 }
3376
3377
3378
3379
3380
3381
3382 static VALUE
3383 foletype_src_type(self)
3384 VALUE self;
3385 {
3386 struct oletypedata *ptype;
3387 Data_Get_Struct(self, struct oletypedata, ptype);
3388 return ole_type_src_type(ptype->pTypeInfo);
3389 }
3390
3391 static VALUE
3392 ole_type_helpfile(pTypeInfo)
3393 ITypeInfo *pTypeInfo;
3394 {
3395 HRESULT hr;
3396 BSTR bhelpfile;
3397 hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL, NULL, &bhelpfile);
3398 if(FAILED(hr)) {
3399 return Qnil;
3400 }
3401 return WC2VSTR(bhelpfile);
3402 }
3403
3404
3405
3406
3407
3408
3409 static VALUE
3410 foletype_helpfile(self)
3411 VALUE self;
3412 {
3413 struct oletypedata *ptype;
3414 Data_Get_Struct(self, struct oletypedata, ptype);
3415 return ole_type_helpfile(ptype->pTypeInfo);
3416 }
3417
3418 static VALUE
3419 ole_type_helpcontext(pTypeInfo)
3420 ITypeInfo *pTypeInfo;
3421 {
3422 HRESULT hr;
3423 DWORD helpcontext;
3424 hr = ole_docinfo_from_type(pTypeInfo, NULL, NULL,
3425 &helpcontext, NULL);
3426 if(FAILED(hr))
3427 return Qnil;
3428 return INT2FIX(helpcontext);
3429 }
3430
3431
3432
3433
3434
3435
3436 static VALUE
3437 foletype_helpcontext(self)
3438 VALUE self;
3439 {
3440 struct oletypedata *ptype;
3441 Data_Get_Struct(self, struct oletypedata, ptype);
3442 return ole_type_helpcontext(ptype->pTypeInfo);
3443 }
3444
3445 static VALUE
3446 ole_variables(pTypeInfo)
3447 ITypeInfo *pTypeInfo;
3448 {
3449 HRESULT hr;
3450 TYPEATTR *pTypeAttr;
3451 WORD i;
3452 UINT len;
3453 BSTR bstr;
3454 char *pstr;
3455 VARDESC *pVarDesc;
3456 struct olevariabledata *pvar;
3457 VALUE var;
3458 VALUE variables = rb_ary_new();
3459 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
3460 if (FAILED(hr)) {
3461 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetTypeAttr");
3462 }
3463
3464 for(i = 0; i < pTypeAttr->cVars; i++) {
3465 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, i, &pVarDesc);
3466 if(FAILED(hr))
3467 continue;
3468 len = 0;
3469 pstr = NULL;
3470 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pVarDesc->memid, &bstr,
3471 1, &len);
3472 if(FAILED(hr) || len == 0 || !bstr)
3473 continue;
3474
3475 var = Data_Make_Struct(cWIN32OLE_VARIABLE, struct olevariabledata,
3476 0,olevariable_free,pvar);
3477 pvar->pTypeInfo = pTypeInfo;
3478 OLE_ADDREF(pTypeInfo);
3479 pvar->index = i;
3480 rb_ivar_set(var, rb_intern("name"), WC2VSTR(bstr));
3481 rb_ary_push(variables, var);
3482
3483 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
3484 pVarDesc = NULL;
3485 }
3486 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
3487 return variables;
3488 }
3489
3490
3491
3492
3493
3494
3495 static VALUE
3496 foletype_variables(self)
3497 VALUE self;
3498 {
3499 struct oletypedata *ptype;
3500 Data_Get_Struct(self, struct oletypedata, ptype);
3501 return ole_variables(ptype->pTypeInfo);
3502 }
3503
3504
3505
3506
3507
3508
3509 static VALUE
3510 foletype_methods(argc, argv, self)
3511 int argc;
3512 VALUE *argv;
3513 VALUE self;
3514 {
3515 struct oletypedata *ptype;
3516 Data_Get_Struct(self, struct oletypedata, ptype);
3517 return ole_methods_from_typeinfo(ptype->pTypeInfo, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
3518 }
3519
3520
3521
3522
3523
3524
3525 static VALUE
3526 folevariable_name(self)
3527 VALUE self;
3528 {
3529 return rb_ivar_get(self, rb_intern("name"));
3530 }
3531
3532 static ole_variable_ole_type(pTypeInfo, var_index)
3533 ITypeInfo *pTypeInfo;
3534 UINT var_index;
3535 {
3536 VARDESC *pVarDesc;
3537 HRESULT hr;
3538 VALUE type;
3539 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
3540 if (FAILED(hr))
3541 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetVarDesc");
3542 type = ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), Qnil);
3543 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
3544 return type;
3545 }
3546
3547
3548
3549
3550
3551
3552 static VALUE
3553 folevariable_ole_type(self)
3554 VALUE self;
3555 {
3556 struct olevariabledata *pvar;
3557 Data_Get_Struct(self, struct olevariabledata, pvar);
3558 return ole_variable_ole_type(pvar->pTypeInfo, pvar->index);
3559 }
3560
3561 static ole_variable_ole_type_detail(pTypeInfo, var_index)
3562 ITypeInfo *pTypeInfo;
3563 UINT var_index;
3564 {
3565 VARDESC *pVarDesc;
3566 HRESULT hr;
3567 VALUE type = rb_ary_new();
3568 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
3569 if (FAILED(hr))
3570 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetVarDesc");
3571 ole_typedesc2val(pTypeInfo, &(pVarDesc->elemdescVar.tdesc), type);
3572 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
3573 return type;
3574 }
3575
3576
3577
3578
3579
3580
3581 static VALUE
3582 folevariable_ole_type_detail(self)
3583 VALUE self;
3584 {
3585 struct olevariabledata *pvar;
3586 Data_Get_Struct(self, struct olevariabledata, pvar);
3587 return ole_variable_ole_type_detail(pvar->pTypeInfo, pvar->index);
3588 }
3589
3590 static ole_variable_value(pTypeInfo, var_index)
3591 ITypeInfo *pTypeInfo;
3592 UINT var_index;
3593 {
3594 VARDESC *pVarDesc;
3595 HRESULT hr;
3596 VALUE val = Qnil;
3597 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
3598 if (FAILED(hr))
3599 return Qnil;
3600 if(pVarDesc->varkind == VAR_CONST)
3601 val = ole_variant2val(V_UNION1(pVarDesc, lpvarValue));
3602 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
3603 return val;
3604 }
3605
3606
3607
3608
3609
3610
3611
3612 static VALUE
3613 folevariable_value(self)
3614 VALUE self;
3615 {
3616 struct olevariabledata *pvar;
3617 Data_Get_Struct(self, struct olevariabledata, pvar);
3618 return ole_variable_value(pvar->pTypeInfo, pvar->index);
3619 }
3620
3621 static ole_variable_visible(pTypeInfo, var_index)
3622 ITypeInfo *pTypeInfo;
3623 UINT var_index;
3624 {
3625 VARDESC *pVarDesc;
3626 HRESULT hr;
3627 VALUE visible = Qfalse;
3628 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
3629 if (FAILED(hr))
3630 return visible;
3631 if (!(pVarDesc->wVarFlags & (VARFLAG_FHIDDEN |
3632 VARFLAG_FRESTRICTED |
3633 VARFLAG_FNONBROWSABLE))) {
3634 visible = Qtrue;
3635 }
3636 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
3637 return visible;
3638 }
3639
3640
3641
3642
3643
3644
3645 static VALUE
3646 folevariable_visible(self)
3647 VALUE self;
3648 {
3649 struct olevariabledata *pvar;
3650 Data_Get_Struct(self, struct olevariabledata, pvar);
3651 return ole_variable_visible(pvar->pTypeInfo, pvar->index);
3652 }
3653
3654 static VALUE
3655 ole_variable_kind(pTypeInfo, var_index)
3656 ITypeInfo *pTypeInfo;
3657 UINT var_index;
3658 {
3659 VARDESC *pVarDesc;
3660 HRESULT hr;
3661 VALUE kind = rb_str_new2("UNKNOWN");
3662 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
3663 if (FAILED(hr))
3664 return kind;
3665 switch(pVarDesc->varkind) {
3666 case VAR_PERINSTANCE:
3667 kind = rb_str_new2("PERINSTANCE");
3668 break;
3669 case VAR_STATIC:
3670 kind = rb_str_new2("STATIC");
3671 break;
3672 case VAR_CONST:
3673 kind = rb_str_new2("CONSTANT");
3674 break;
3675 case VAR_DISPATCH:
3676 kind = rb_str_new2("DISPATCH");
3677 break;
3678 default:
3679 break;
3680 }
3681 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
3682 return kind;
3683 }
3684
3685
3686
3687
3688
3689
3690 static VALUE
3691 folevariable_variable_kind(self)
3692 VALUE self;
3693 {
3694 struct olevariabledata *pvar;
3695 Data_Get_Struct(self, struct olevariabledata, pvar);
3696 return ole_variable_kind(pvar->pTypeInfo, pvar->index);
3697 }
3698
3699 static VALUE
3700 ole_variable_varkind(pTypeInfo, var_index)
3701 ITypeInfo *pTypeInfo;
3702 UINT var_index;
3703 {
3704 VARDESC *pVarDesc;
3705 HRESULT hr;
3706 VALUE kind = Qnil;
3707 hr = pTypeInfo->lpVtbl->GetVarDesc(pTypeInfo, var_index, &pVarDesc);
3708 if (FAILED(hr))
3709 return kind;
3710 pTypeInfo->lpVtbl->ReleaseVarDesc(pTypeInfo, pVarDesc);
3711 kind = INT2FIX(pVarDesc->varkind);
3712 return kind;
3713 }
3714
3715
3716
3717
3718
3719
3720 static VALUE
3721 folevariable_varkind(self)
3722 VALUE self;
3723 {
3724 struct olevariabledata *pvar;
3725 Data_Get_Struct(self, struct olevariabledata, pvar);
3726 return ole_variable_varkind(pvar->pTypeInfo, pvar->index);
3727 }
3728
3729 static VALUE
3730 olemethod_set_member(self, pTypeInfo, pOwnerTypeInfo, index, name)
3731 VALUE self;
3732 ITypeInfo *pTypeInfo;
3733 ITypeInfo *pOwnerTypeInfo;
3734 int index;
3735 VALUE name;
3736 {
3737 struct olemethoddata *pmethod;
3738 Data_Get_Struct(self, struct olemethoddata, pmethod);
3739 pmethod->pTypeInfo = pTypeInfo;
3740 OLE_ADDREF(pTypeInfo);
3741 pmethod->pOwnerTypeInfo = pOwnerTypeInfo;
3742 if(pOwnerTypeInfo) OLE_ADDREF(pOwnerTypeInfo);
3743 pmethod->index = index;
3744 rb_ivar_set(self, rb_intern("name"), name);
3745 return self;
3746 }
3747
3748 static VALUE
3749 folemethod_s_allocate(klass)
3750 VALUE klass;
3751 {
3752 struct olemethoddata *pmethod;
3753 VALUE obj;
3754 obj = Data_Make_Struct(klass,
3755 struct olemethoddata,
3756 0, olemethod_free, pmethod);
3757 pmethod->pTypeInfo = NULL;
3758 pmethod->pOwnerTypeInfo = NULL;
3759 pmethod->index = 0;
3760 return obj;
3761 }
3762
3763 static VALUE
3764 folemethod_initialize(self, oletype, method)
3765 VALUE self;
3766 VALUE oletype;
3767 VALUE method;
3768 {
3769 struct oletypedata *ptype;
3770 VALUE obj = Qnil;
3771 if (rb_obj_is_kind_of(oletype, cWIN32OLE_TYPE)) {
3772 Check_SafeStr(method);
3773 Data_Get_Struct(oletype, struct oletypedata, ptype);
3774 obj = olemethod_from_typeinfo(self, ptype->pTypeInfo, method);
3775 if (obj == Qnil) {
3776 rb_raise(eWIN32OLE_RUNTIME_ERROR, "Not found %s",
3777 StringValuePtr(method));
3778 }
3779 }
3780 else {
3781 rb_raise(rb_eTypeError, "1st argument should be WIN32OLE_TYPE object.");
3782 }
3783 return obj;
3784 }
3785
3786
3787
3788
3789
3790
3791 static VALUE
3792 folemethod_name(self)
3793 VALUE self;
3794 {
3795 return rb_ivar_get(self, rb_intern("name"));
3796 }
3797
3798 static VALUE
3799 ole_method_return_type(pTypeInfo, method_index)
3800 ITypeInfo *pTypeInfo;
3801 UINT method_index;
3802 {
3803 FUNCDESC *pFuncDesc;
3804 HRESULT hr;
3805 VALUE type;
3806
3807 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
3808 if (FAILED(hr))
3809 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetFuncDesc");
3810
3811 type = ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), Qnil);
3812 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
3813 return type;
3814 }
3815
3816
3817
3818
3819
3820
3821 static VALUE
3822 folemethod_return_type(self)
3823 VALUE self;
3824 {
3825 struct olemethoddata *pmethod;
3826 Data_Get_Struct(self, struct olemethoddata, pmethod);
3827 return ole_method_return_type(pmethod->pTypeInfo, pmethod->index);
3828 }
3829
3830 static VALUE
3831 ole_method_return_vtype(pTypeInfo, method_index)
3832 ITypeInfo *pTypeInfo;
3833 UINT method_index;
3834 {
3835 FUNCDESC *pFuncDesc;
3836 HRESULT hr;
3837 VALUE vt;
3838
3839 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
3840 if (FAILED(hr))
3841 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetFuncDesc");
3842
3843 vt = INT2FIX(pFuncDesc->elemdescFunc.tdesc.vt);
3844 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
3845 return vt;
3846 }
3847
3848
3849
3850
3851
3852
3853 static VALUE
3854 folemethod_return_vtype(self)
3855 VALUE self;
3856 {
3857 struct olemethoddata *pmethod;
3858 Data_Get_Struct(self, struct olemethoddata, pmethod);
3859 return ole_method_return_vtype(pmethod->pTypeInfo, pmethod->index);
3860 }
3861
3862 static VALUE
3863 ole_method_return_type_detail(pTypeInfo, method_index)
3864 ITypeInfo *pTypeInfo;
3865 UINT method_index;
3866 {
3867 FUNCDESC *pFuncDesc;
3868 HRESULT hr;
3869 VALUE type = rb_ary_new();
3870
3871 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
3872 if (FAILED(hr))
3873 return type;
3874
3875 ole_typedesc2val(pTypeInfo, &(pFuncDesc->elemdescFunc.tdesc), type);
3876 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
3877 return type;
3878 }
3879
3880
3881
3882
3883
3884
3885
3886 static VALUE
3887 folemethod_return_type_detail(self)
3888 VALUE self;
3889 {
3890 struct olemethoddata *pmethod;
3891 Data_Get_Struct(self, struct olemethoddata, pmethod);
3892 return ole_method_return_type_detail(pmethod->pTypeInfo, pmethod->index);
3893 }
3894
3895 static VALUE
3896 ole_method_invkind(pTypeInfo, method_index)
3897 ITypeInfo *pTypeInfo;
3898 UINT method_index;
3899 {
3900 FUNCDESC *pFuncDesc;
3901 HRESULT hr;
3902 VALUE invkind;
3903 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
3904 if(FAILED(hr))
3905 ole_raise(hr, eWIN32OLE_RUNTIME_ERROR, "Fail to GetFuncDesc");
3906 invkind = INT2FIX(pFuncDesc->invkind);
3907 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
3908 return invkind;
3909 }
3910
3911 static VALUE
3912 ole_method_invoke_kind(pTypeInfo, method_index)
3913 ITypeInfo *pTypeInfo;
3914 WORD method_index;
3915 {
3916 VALUE type = rb_str_new2("UNKNOWN");
3917 VALUE invkind = ole_method_invkind(pTypeInfo, method_index);
3918 if((FIX2INT(invkind) & INVOKE_PROPERTYGET) &&
3919 (FIX2INT(invkind) & INVOKE_PROPERTYPUT) ) {
3920 type = rb_str_new2("PROPERTY");
3921 } else if(FIX2INT(invkind) & INVOKE_PROPERTYGET) {
3922 type = rb_str_new2("PROPERTYGET");
3923 } else if(FIX2INT(invkind) & INVOKE_PROPERTYPUT) {
3924 type = rb_str_new2("PROPERTYPUT");
3925 } else if(FIX2INT(invkind) & INVOKE_PROPERTYPUTREF) {
3926 type = rb_str_new2("PROPERTYPUTREF");
3927 } else if(FIX2INT(invkind) & INVOKE_FUNC) {
3928 type = rb_str_new2("FUNC");
3929 }
3930 return type;
3931 }
3932
3933
3934
3935
3936
3937
3938 static VALUE
3939 folemethod_invkind(self)
3940 VALUE self;
3941 {
3942 struct olemethoddata *pmethod;
3943 Data_Get_Struct(self, struct olemethoddata, pmethod);
3944 return ole_method_invkind(pmethod->pTypeInfo, pmethod->index);
3945 }
3946
3947
3948
3949
3950
3951
3952 static VALUE
3953 folemethod_invoke_kind(self)
3954 VALUE self;
3955 {
3956 struct olemethoddata *pmethod;
3957 Data_Get_Struct(self, struct olemethoddata, pmethod);
3958 return ole_method_invoke_kind(pmethod->pTypeInfo, pmethod->index);
3959 }
3960
3961 static VALUE
3962 ole_method_visible(pTypeInfo, method_index)
3963 ITypeInfo *pTypeInfo;
3964 UINT method_index;
3965 {
3966 FUNCDESC *pFuncDesc;
3967 HRESULT hr;
3968 VALUE visible;
3969 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
3970 if(FAILED(hr))
3971 return Qfalse;
3972 if (pFuncDesc->wFuncFlags & (FUNCFLAG_FRESTRICTED |
3973 FUNCFLAG_FHIDDEN |
3974 FUNCFLAG_FNONBROWSABLE)) {
3975 visible = Qfalse;
3976 } else {
3977 visible = Qtrue;
3978 }
3979 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
3980 return visible;
3981 }
3982
3983
3984
3985
3986
3987
3988 static VALUE
3989 folemethod_visible(self)
3990 VALUE self;
3991 {
3992 struct olemethoddata *pmethod;
3993 Data_Get_Struct(self, struct olemethoddata, pmethod);
3994 return ole_method_visible(pmethod->pTypeInfo, pmethod->index);
3995 }
3996
3997 static ole_method_event(pTypeInfo, method_index, method_name)
3998 ITypeInfo *pTypeInfo;
3999 WORD method_index;
4000 VALUE method_name;
4001 {
4002 TYPEATTR *pTypeAttr;
4003 HRESULT hr;
4004 WORD i;
4005 int flags;
4006 HREFTYPE href;
4007 ITypeInfo *pRefTypeInfo;
4008 FUNCDESC *pFuncDesc;
4009 BSTR bstr;
4010 VALUE name;
4011 VALUE event = Qfalse;
4012
4013 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
4014 if (FAILED(hr))
4015 return event;
4016 if(pTypeAttr->typekind != TKIND_COCLASS) {
4017 pTypeInfo->lpVtbl->ReleaseTypeAttr(pTypeInfo, pTypeAttr);
4018 return event;
4019 }
4020 for (i = 0; i < pTypeAttr->cImplTypes; i++) {
4021 hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &flags);
4022 if (FAILED(hr))
4023 continue;
4024
4025 if (flags & IMPLTYPEFLAG_FSOURCE) {
4026 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
4027 i, &href);
4028 if (FAILED(hr))
4029 continue;
4030 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
4031 href, &pRefTypeInfo);
4032 if (FAILED(hr))
4033 continue;
4034 hr = pRefTypeInfo->lpVtbl->GetFuncDesc(pRefTypeInfo, method_index,
4035 &pFuncDesc);
4036 if (FAILED(hr)) {
4037 OLE_RELEASE(pRefTypeInfo);
4038 continue;
4039 }
4040
4041 hr = pRefTypeInfo->lpVtbl->GetDocumentation(pRefTypeInfo,
4042 pFuncDesc->memid,
4043 &bstr, NULL, NULL, NULL);
4044 if (FAILED(hr)) {
4045 pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);
4046 OLE_RELEASE(pRefTypeInfo);
4047 continue;
4048 }
4049
4050 name = WC2VSTR(bstr);
4051 pRefTypeInfo->lpVtbl->ReleaseFuncDesc(pRefTypeInfo, pFuncDesc);
4052 OLE_RELEASE(pRefTypeInfo);
4053 if (rb_str_cmp(method_name, name) == 0) {
4054 event = Qtrue;
4055 break;
4056 }
4057 }
4058 }
4059 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
4060 return event;
4061 }
4062
4063
4064
4065
4066
4067
4068 static VALUE
4069 folemethod_event(self)
4070 VALUE self;
4071 {
4072 struct olemethoddata *pmethod;
4073 Data_Get_Struct(self, struct olemethoddata, pmethod);
4074 if (!pmethod->pOwnerTypeInfo)
4075 return Qfalse;
4076 return ole_method_event(pmethod->pOwnerTypeInfo,
4077 pmethod->index,
4078 rb_ivar_get(self, rb_intern("name")));
4079 }
4080
4081 static VALUE
4082 folemethod_event_interface(self)
4083 VALUE self;
4084 {
4085 BSTR name;
4086 struct olemethoddata *pmethod;
4087 HRESULT hr;
4088 Data_Get_Struct(self, struct olemethoddata, pmethod);
4089 if(folemethod_event(self) == Qtrue) {
4090 hr = ole_docinfo_from_type(pmethod->pTypeInfo, &name, NULL, NULL, NULL);
4091 if(SUCCEEDED(hr))
4092 return WC2VSTR(name);
4093 }
4094 return Qnil;
4095 }
4096
4097 static VALUE
4098 ole_method_docinfo_from_type(pTypeInfo, method_index, name, helpstr,
4099 helpcontext, helpfile)
4100 ITypeInfo *pTypeInfo;
4101 UINT method_index;
4102 BSTR *name;
4103 BSTR *helpstr;
4104 DWORD *helpcontext;
4105 BSTR *helpfile;
4106 {
4107 FUNCDESC *pFuncDesc;
4108 HRESULT hr;
4109 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
4110 if (FAILED(hr))
4111 return hr;
4112 hr = pTypeInfo->lpVtbl->GetDocumentation(pTypeInfo, pFuncDesc->memid,
4113 name, helpstr,
4114 helpcontext, helpfile);
4115 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4116 return hr;
4117 }
4118
4119 static VALUE
4120 ole_method_helpstring(pTypeInfo, method_index)
4121 ITypeInfo *pTypeInfo;
4122 UINT method_index;
4123 {
4124 HRESULT hr;
4125 BSTR bhelpstring;
4126 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, &bhelpstring,
4127 NULL, NULL);
4128 if (FAILED(hr))
4129 return Qnil;
4130 return WC2VSTR(bhelpstring);
4131 }
4132
4133 static VALUE
4134 folemethod_helpstring(self)
4135 VALUE self;
4136 {
4137 struct olemethoddata *pmethod;
4138 Data_Get_Struct(self, struct olemethoddata, pmethod);
4139 return ole_method_helpstring(pmethod->pTypeInfo, pmethod->index);
4140 }
4141
4142 static VALUE
4143 ole_method_helpfile(pTypeInfo, method_index)
4144 ITypeInfo *pTypeInfo;
4145 UINT method_index;
4146 {
4147 HRESULT hr;
4148 BSTR bhelpfile;
4149 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,
4150 NULL, &bhelpfile);
4151 if (FAILED(hr))
4152 return Qnil;
4153 return WC2VSTR(bhelpfile);
4154 }
4155
4156
4157
4158
4159
4160
4161 static VALUE
4162 folemethod_helpfile(self)
4163 VALUE self;
4164 {
4165 struct olemethoddata *pmethod;
4166 Data_Get_Struct(self, struct olemethoddata, pmethod);
4167
4168 return ole_method_helpfile(pmethod->pTypeInfo, pmethod->index);
4169 }
4170
4171 static VALUE
4172 ole_method_helpcontext(pTypeInfo, method_index)
4173 ITypeInfo *pTypeInfo;
4174 UINT method_index;
4175 {
4176 HRESULT hr;
4177 DWORD helpcontext = 0;
4178 hr = ole_method_docinfo_from_type(pTypeInfo, method_index, NULL, NULL,
4179 &helpcontext, NULL);
4180 if (FAILED(hr))
4181 return Qnil;
4182 return INT2FIX(helpcontext);
4183 }
4184
4185
4186
4187
4188
4189
4190 static VALUE
4191 folemethod_helpcontext(self)
4192 VALUE self;
4193 {
4194 struct olemethoddata *pmethod;
4195 Data_Get_Struct(self, struct olemethoddata, pmethod);
4196 return ole_method_helpcontext(pmethod->pTypeInfo, pmethod->index);
4197 }
4198
4199 static VALUE
4200 ole_method_dispid(pTypeInfo, method_index)
4201 ITypeInfo *pTypeInfo;
4202 UINT method_index;
4203 {
4204 FUNCDESC *pFuncDesc;
4205 HRESULT hr;
4206 VALUE dispid = Qnil;
4207 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
4208 if (FAILED(hr))
4209 return dispid;
4210 dispid = INT2FIX(pFuncDesc->memid);
4211 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4212 return dispid;
4213 }
4214
4215
4216
4217
4218
4219
4220 static VALUE
4221 folemethod_dispid(self)
4222 VALUE self;
4223 {
4224 struct olemethoddata *pmethod;
4225 Data_Get_Struct(self, struct olemethoddata, pmethod);
4226 return ole_method_dispid(pmethod->pTypeInfo, pmethod->index);
4227 }
4228
4229 static VALUE
4230 ole_method_offset_vtbl(pTypeInfo, method_index)
4231 ITypeInfo *pTypeInfo;
4232 UINT method_index;
4233 {
4234 FUNCDESC *pFuncDesc;
4235 HRESULT hr;
4236 VALUE offset_vtbl = Qnil;
4237 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
4238 if (FAILED(hr))
4239 return offset_vtbl;
4240 offset_vtbl = INT2FIX(pFuncDesc->oVft);
4241 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4242 return offset_vtbl;
4243 }
4244
4245
4246
4247
4248
4249
4250 static VALUE
4251 folemethod_offset_vtbl(self)
4252 VALUE self;
4253 {
4254 struct olemethoddata *pmethod;
4255 Data_Get_Struct(self, struct olemethoddata, pmethod);
4256 return ole_method_offset_vtbl(pmethod->pTypeInfo, pmethod->index);
4257 }
4258
4259 static VALUE
4260 ole_method_size_params(pTypeInfo, method_index)
4261 ITypeInfo *pTypeInfo;
4262 UINT method_index;
4263 {
4264 FUNCDESC *pFuncDesc;
4265 HRESULT hr;
4266 VALUE size_params = Qnil;
4267 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
4268 if (FAILED(hr))
4269 return size_params;
4270 size_params = INT2FIX(pFuncDesc->cParams);
4271 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4272 return size_params;
4273 }
4274
4275
4276
4277
4278
4279
4280 static VALUE
4281 folemethod_size_params(self)
4282 VALUE self;
4283 {
4284 struct olemethoddata *pmethod;
4285 Data_Get_Struct(self, struct olemethoddata, pmethod);
4286 return ole_method_size_params(pmethod->pTypeInfo, pmethod->index);
4287 }
4288
4289
4290
4291
4292
4293
4294 static VALUE
4295 ole_method_size_opt_params(pTypeInfo, method_index)
4296 ITypeInfo *pTypeInfo;
4297 UINT method_index;
4298 {
4299 FUNCDESC *pFuncDesc;
4300 HRESULT hr;
4301 VALUE size_opt_params = Qnil;
4302 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
4303 if (FAILED(hr))
4304 return size_opt_params;
4305 size_opt_params = INT2FIX(pFuncDesc->cParamsOpt);
4306 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4307 return size_opt_params;
4308 }
4309
4310 static VALUE
4311 folemethod_size_opt_params(self)
4312 VALUE self;
4313 {
4314 struct olemethoddata *pmethod;
4315 Data_Get_Struct(self, struct olemethoddata, pmethod);
4316 return ole_method_size_opt_params(pmethod->pTypeInfo, pmethod->index);
4317 }
4318
4319 static VALUE
4320 ole_method_params(pTypeInfo, method_index)
4321 ITypeInfo *pTypeInfo;
4322 UINT method_index;
4323 {
4324 FUNCDESC *pFuncDesc;
4325 HRESULT hr;
4326 BSTR *bstrs;
4327 UINT len, i;
4328 struct oleparamdata *pparam;
4329 VALUE param;
4330 VALUE params = rb_ary_new();
4331 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
4332 if (FAILED(hr))
4333 return params;
4334
4335 len = 0;
4336 bstrs = ALLOCA_N(BSTR, pFuncDesc->cParams + 1);
4337 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, pFuncDesc->memid,
4338 bstrs, pFuncDesc->cParams + 1,
4339 &len);
4340 if (FAILED(hr)) {
4341 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4342 return params;
4343 }
4344 SysFreeString(bstrs[0]);
4345 if (pFuncDesc->cParams > 0) {
4346 for(i = 1; i < len; i++) {
4347 param = Data_Make_Struct(cWIN32OLE_PARAM, struct oleparamdata, 0,
4348 oleparam_free, pparam);
4349 pparam->pTypeInfo = pTypeInfo;
4350 OLE_ADDREF(pTypeInfo);
4351 pparam->method_index = method_index;
4352 pparam->index = i - 1;
4353 rb_ivar_set(param, rb_intern("name"), WC2VSTR(bstrs[i]));
4354 rb_ary_push(params, param);
4355 }
4356 }
4357 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4358 return params;
4359 }
4360
4361
4362
4363
4364
4365
4366 static VALUE
4367 folemethod_params(self)
4368 VALUE self;
4369 {
4370 struct olemethoddata *pmethod;
4371 Data_Get_Struct(self, struct olemethoddata, pmethod);
4372 return ole_method_params(pmethod->pTypeInfo, pmethod->index);
4373 }
4374
4375
4376
4377
4378
4379
4380 static VALUE
4381 foleparam_name(self)
4382 VALUE self;
4383 {
4384 return rb_ivar_get(self, rb_intern("name"));
4385 }
4386
4387 static VALUE
4388 ole_param_ole_type(pTypeInfo, method_index, index)
4389 ITypeInfo *pTypeInfo;
4390 UINT method_index;
4391 UINT index;
4392 {
4393 FUNCDESC *pFuncDesc;
4394 HRESULT hr;
4395 VALUE type = rb_str_new2("UNKNOWN");
4396 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
4397 if (FAILED(hr))
4398 return type;
4399 type = ole_typedesc2val(pTypeInfo,
4400 &(pFuncDesc->lprgelemdescParam[index].tdesc), Qnil);
4401 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4402 return type;
4403 }
4404
4405 static VALUE
4406 foleparam_ole_type(self)
4407 VALUE self;
4408 {
4409 struct oleparamdata *pparam;
4410 Data_Get_Struct(self, struct oleparamdata, pparam);
4411 return ole_param_ole_type(pparam->pTypeInfo, pparam->method_index,
4412 pparam->index);
4413 }
4414
4415 static VALUE
4416 ole_param_ole_type_detail(pTypeInfo, method_index, index)
4417 ITypeInfo *pTypeInfo;
4418 UINT method_index;
4419 UINT index;
4420 {
4421 FUNCDESC *pFuncDesc;
4422 HRESULT hr;
4423 VALUE typedetail = rb_ary_new();
4424 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
4425 if (FAILED(hr))
4426 return typedetail;
4427 ole_typedesc2val(pTypeInfo,
4428 &(pFuncDesc->lprgelemdescParam[index].tdesc), typedetail);
4429 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4430 return typedetail;
4431 }
4432
4433 static VALUE
4434 foleparam_ole_type_detail(self)
4435 VALUE self;
4436 {
4437 struct oleparamdata *pparam;
4438 Data_Get_Struct(self, struct oleparamdata, pparam);
4439 return ole_param_ole_type_detail(pparam->pTypeInfo, pparam->method_index,
4440 pparam->index);
4441 }
4442
4443 static VALUE
4444 ole_param_flag_mask(pTypeInfo, method_index, index, mask)
4445 ITypeInfo *pTypeInfo;
4446 UINT method_index;
4447 UINT index;
4448 USHORT mask;
4449 {
4450 FUNCDESC *pFuncDesc;
4451 HRESULT hr;
4452 VALUE ret = Qfalse;
4453 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
4454 if(FAILED(hr))
4455 return ret;
4456 if (V_UNION1((&(pFuncDesc->lprgelemdescParam[index])), paramdesc).wParamFlags &mask)
4457 ret = Qtrue;
4458 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4459 return ret;
4460 }
4461
4462
4463
4464
4465
4466
4467 static VALUE foleparam_input(self)
4468 VALUE self;
4469 {
4470 struct oleparamdata *pparam;
4471 Data_Get_Struct(self, struct oleparamdata, pparam);
4472 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
4473 pparam->index, PARAMFLAG_FIN);
4474 }
4475
4476
4477
4478
4479
4480
4481 static VALUE foleparam_output(self)
4482 VALUE self;
4483 {
4484 struct oleparamdata *pparam;
4485 Data_Get_Struct(self, struct oleparamdata, pparam);
4486 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
4487 pparam->index, PARAMFLAG_FOUT);
4488 }
4489
4490
4491
4492
4493
4494
4495 static VALUE foleparam_optional(self)
4496 VALUE self;
4497 {
4498 struct oleparamdata *pparam;
4499 Data_Get_Struct(self, struct oleparamdata, pparam);
4500 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
4501 pparam->index, PARAMFLAG_FOPT);
4502 }
4503
4504 static VALUE foleparam_retval(self)
4505 VALUE self;
4506 {
4507 struct oleparamdata *pparam;
4508 Data_Get_Struct(self, struct oleparamdata, pparam);
4509 return ole_param_flag_mask(pparam->pTypeInfo, pparam->method_index,
4510 pparam->index, PARAMFLAG_FRETVAL);
4511 }
4512
4513 static VALUE
4514 ole_param_default(pTypeInfo, method_index, index)
4515 ITypeInfo *pTypeInfo;
4516 UINT method_index;
4517 UINT index;
4518 {
4519 FUNCDESC *pFuncDesc;
4520 ELEMDESC *pElemDesc;
4521 PARAMDESCEX * pParamDescEx;
4522 HRESULT hr;
4523 USHORT wParamFlags;
4524 USHORT mask = PARAMFLAG_FOPT|PARAMFLAG_FHASDEFAULT;
4525 VALUE defval = Qnil;
4526 hr = pTypeInfo->lpVtbl->GetFuncDesc(pTypeInfo, method_index, &pFuncDesc);
4527 if (FAILED(hr))
4528 return defval;
4529 pElemDesc = &pFuncDesc->lprgelemdescParam[index];
4530 wParamFlags = V_UNION1(pElemDesc, paramdesc).wParamFlags;
4531 if ((wParamFlags & mask) == mask) {
4532 pParamDescEx = V_UNION1(pElemDesc, paramdesc).pparamdescex;
4533 defval = ole_variant2val(&pParamDescEx->varDefaultValue);
4534 }
4535 pTypeInfo->lpVtbl->ReleaseFuncDesc(pTypeInfo, pFuncDesc);
4536 return defval;
4537 }
4538
4539
4540
4541
4542
4543
4544
4545 static VALUE foleparam_default(self)
4546 VALUE self;
4547 {
4548 struct oleparamdata *pparam;
4549 Data_Get_Struct(self, struct oleparamdata, pparam);
4550 return ole_param_default(pparam->pTypeInfo, pparam->method_index,
4551 pparam->index);
4552 }
4553
4554 static IEventSinkVtbl vtEventSink;
4555 static BOOL g_IsEventSinkVtblInitialized = FALSE;
4556
4557 void EVENTSINK_Destructor(PIEVENTSINKOBJ);
4558
4559 STDMETHODIMP
4560 EVENTSINK_QueryInterface(
4561 PEVENTSINK pEV,
4562 REFIID iid,
4563 LPVOID* ppv
4564 ) {
4565 if (IsEqualIID(iid, &IID_IUnknown) ||
4566 IsEqualIID(iid, &IID_IDispatch) ||
4567 IsEqualIID(iid, &((PIEVENTSINKOBJ)pEV)->m_iid)) {
4568 *ppv = pEV;
4569 }
4570 else {
4571 *ppv = NULL;
4572 return E_NOINTERFACE;
4573 }
4574 ((LPUNKNOWN)*ppv)->lpVtbl->AddRef((LPUNKNOWN)*ppv);
4575 return NOERROR;
4576 }
4577
4578 STDMETHODIMP_(ULONG)
4579 EVENTSINK_AddRef(
4580 PEVENTSINK pEV
4581 ){
4582 PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV;
4583 return ++pEVObj->m_cRef;
4584 }
4585
4586 STDMETHODIMP_(ULONG) EVENTSINK_Release(
4587 PEVENTSINK pEV
4588 ) {
4589 PIEVENTSINKOBJ pEVObj = (PIEVENTSINKOBJ)pEV;
4590 --pEVObj->m_cRef;
4591 if(pEVObj->m_cRef != 0)
4592 return pEVObj->m_cRef;
4593 EVENTSINK_Destructor(pEVObj);
4594 return 0;
4595 }
4596
4597 STDMETHODIMP EVENTSINK_GetTypeInfoCount(
4598 PEVENTSINK pEV,
4599 UINT *pct
4600 ) {
4601 *pct = 0;
4602 return NOERROR;
4603 }
4604
4605 STDMETHODIMP EVENTSINK_GetTypeInfo(
4606 PEVENTSINK pEV,
4607 UINT info,
4608 LCID lcid,
4609 ITypeInfo **pInfo
4610 ) {
4611 *pInfo = NULL;
4612 return DISP_E_BADINDEX;
4613 }
4614
4615 STDMETHODIMP EVENTSINK_GetIDsOfNames(
4616 PEVENTSINK pEV,
4617 REFIID riid,
4618 OLECHAR **szNames,
4619 UINT cNames,
4620 LCID lcid,
4621 DISPID *pDispID
4622 ) {
4623 return DISP_E_UNKNOWNNAME;
4624 }
4625
4626 static VALUE
4627 ole_search_event(ary, ev, is_default)
4628 VALUE ary;
4629 VALUE ev;
4630 BOOL *is_default;
4631 {
4632 VALUE event;
4633 VALUE def_event;
4634 VALUE event_name;
4635 int i, len;
4636 *is_default = FALSE;
4637 def_event = Qnil;
4638 len = RARRAY(ary)->len;
4639 for(i = 0; i < len; i++) {
4640 event = rb_ary_entry(ary, i);
4641 event_name = rb_ary_entry(event, 1);
4642 if(NIL_P(event_name)) {
4643 *is_default = TRUE;
4644 def_event = event;
4645 }
4646 else if (rb_str_cmp(ev, event_name) == 0) {
4647 *is_default = FALSE;
4648 return event;
4649 }
4650 }
4651 return def_event;
4652 }
4653
4654 static void
4655 val2ptr_variant(val, var)
4656 VALUE val;
4657 VARIANT *var;
4658 {
4659 switch (TYPE(val)) {
4660 case T_STRING:
4661 if (V_VT(var) == (VT_BSTR | VT_BYREF)) {
4662 *V_BSTRREF(var) = ole_mb2wc(StringValuePtr(val), -1);
4663 }
4664 break;
4665 case T_FIXNUM:
4666 switch(V_VT(var)) {
4667 case (VT_UI1 | VT_BYREF) :
4668 *V_UI1REF(var) = NUM2CHR(val);
4669 break;
4670 case (VT_I2 | VT_BYREF) :
4671 *V_I2REF(var) = (short)NUM2INT(val);
4672 break;
4673 case (VT_I4 | VT_BYREF) :
4674 *V_I4REF(var) = NUM2INT(val);
4675 break;
4676 case (VT_R4 | VT_BYREF) :
4677 *V_R4REF(var) = (float)NUM2INT(val);
4678 break;
4679 case (VT_R8 | VT_BYREF) :
4680 *V_R8REF(var) = NUM2INT(val);
4681 break;
4682 default:
4683 break;
4684 }
4685 break;
4686 case T_FLOAT:
4687 switch(V_VT(var)) {
4688 case (VT_I2 | VT_BYREF) :
4689 *V_I2REF(var) = (short)NUM2INT(val);
4690 break;
4691 case (VT_I4 | VT_BYREF) :
4692 *V_I4REF(var) = NUM2INT(val);
4693 break;
4694 case (VT_R4 | VT_BYREF) :
4695 *V_R4REF(var) = (float)NUM2DBL(val);
4696 break;
4697 case (VT_R8 | VT_BYREF) :
4698 *V_R8REF(var) = NUM2DBL(val);
4699 break;
4700 default:
4701 break;
4702 }
4703 break;
4704 case T_BIGNUM:
4705 if (V_VT(var) == (VT_R8 | VT_BYREF)) {
4706 *V_R8REF(var) = rb_big2dbl(val);
4707 }
4708 break;
4709 case T_TRUE:
4710 if (V_VT(var) == (VT_BOOL | VT_BYREF)) {
4711 *V_BOOLREF(var) = VARIANT_TRUE;
4712 }
4713 break;
4714 case T_FALSE:
4715 if (V_VT(var) == (VT_BOOL | VT_BYREF)) {
4716 *V_BOOLREF(var) = VARIANT_FALSE;
4717 }
4718 break;
4719 default:
4720 break;
4721 }
4722 }
4723
4724 static void
4725 ary2ptr_dispparams(ary, pdispparams)
4726 VALUE ary;
4727 DISPPARAMS *pdispparams;
4728 {
4729 int i;
4730 VALUE v;
4731 VARIANT *pvar;
4732 for(i = 0; i < RARRAY(ary)->len && (unsigned int) i < pdispparams->cArgs; i++) {
4733 v = rb_ary_entry(ary, i);
4734 pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
4735 val2ptr_variant(v, pvar);
4736 }
4737 }
4738
4739 STDMETHODIMP EVENTSINK_Invoke(
4740 PEVENTSINK pEventSink,
4741 DISPID dispid,
4742 REFIID riid,
4743 LCID lcid,
4744 WORD wFlags,
4745 DISPPARAMS *pdispparams,
4746 VARIANT *pvarResult,
4747 EXCEPINFO *pexcepinfo,
4748 UINT *puArgErr
4749 ) {
4750
4751 HRESULT hr;
4752 BSTR bstr;
4753 unsigned int count;
4754 unsigned int i;
4755 ITypeInfo *pTypeInfo;
4756 VARIANT *pvar;
4757 VALUE ary, obj, event, handler, args, argv, ev;
4758 BOOL is_default_handler = FALSE;
4759
4760 PIEVENTSINKOBJ pEV = (PIEVENTSINKOBJ)pEventSink;
4761 pTypeInfo = pEV->pTypeInfo;
4762
4763 obj = rb_ary_entry(ary_ole_event, pEV->m_event_id);
4764 if (!rb_obj_is_kind_of(obj, cWIN32OLE_EVENT)) {
4765 return NOERROR;
4766 }
4767
4768 ary = rb_ivar_get(obj, id_events);
4769 if (NIL_P(ary) || TYPE(ary) != T_ARRAY) {
4770 return NOERROR;
4771 }
4772 hr = pTypeInfo->lpVtbl->GetNames(pTypeInfo, dispid,
4773 &bstr, 1, &count);
4774 if (FAILED(hr)) {
4775 return NOERROR;
4776 }
4777 ev = WC2VSTR(bstr);
4778 event = ole_search_event(ary, ev, &is_default_handler);
4779 if (NIL_P(event)) {
4780 return NOERROR;
4781 }
4782 args = rb_ary_new();
4783 if (is_default_handler) {
4784 rb_ary_push(args, ev);
4785 }
4786
4787
4788 for (i = 0; i < pdispparams->cArgs; ++i) {
4789 pvar = &pdispparams->rgvarg[pdispparams->cArgs-i-1];
4790 rb_ary_push(args, ole_variant2val(pvar));
4791 }
4792 handler = rb_ary_entry(event, 0);
4793
4794 if (rb_ary_entry(event, 3) == Qtrue) {
4795 argv = rb_ary_new();
4796 rb_ary_push(args, argv);
4797 rb_apply(handler, rb_intern("call"), args);
4798 ary2ptr_dispparams(argv, pdispparams);
4799 }
4800 else {
4801 rb_apply(handler, rb_intern("call"), args);
4802 }
4803 return NOERROR;
4804 }
4805
4806 PIEVENTSINKOBJ
4807 EVENTSINK_Constructor() {
4808 PIEVENTSINKOBJ pEv;
4809 if (!g_IsEventSinkVtblInitialized) {
4810 vtEventSink.QueryInterface=EVENTSINK_QueryInterface;
4811 vtEventSink.AddRef = EVENTSINK_AddRef;
4812 vtEventSink.Release = EVENTSINK_Release;
4813 vtEventSink.Invoke = EVENTSINK_Invoke;
4814 vtEventSink.GetIDsOfNames = EVENTSINK_GetIDsOfNames;
4815 vtEventSink.GetTypeInfoCount = EVENTSINK_GetTypeInfoCount;
4816 vtEventSink.GetTypeInfo = EVENTSINK_GetTypeInfo;
4817
4818 g_IsEventSinkVtblInitialized = TRUE;
4819 }
4820 pEv = ALLOC_N(IEVENTSINKOBJ, 1);
4821 if(pEv == NULL) return NULL;
4822 pEv->lpVtbl = &vtEventSink;
4823 pEv->m_cRef = 0;
4824 pEv->m_event_id = 0;
4825 pEv->m_dwCookie = 0;
4826 pEv->pConnectionPoint = NULL;
4827 pEv->pTypeInfo = NULL;
4828 return pEv;
4829 }
4830
4831 void EVENTSINK_Destructor(
4832 PIEVENTSINKOBJ pEVObj
4833 ) {
4834 if(pEVObj != NULL) {
4835 free(pEVObj);
4836 }
4837 }
4838
4839 static HRESULT
4840 find_iid(ole, pitf, piid, ppTypeInfo)
4841 VALUE ole;
4842 char *pitf;
4843 IID *piid;
4844 ITypeInfo **ppTypeInfo;
4845 {
4846 HRESULT hr;
4847 IDispatch *pDispatch;
4848 ITypeInfo *pTypeInfo;
4849 ITypeLib *pTypeLib;
4850 TYPEATTR *pTypeAttr;
4851 HREFTYPE RefType;
4852 ITypeInfo *pImplTypeInfo;
4853 TYPEATTR *pImplTypeAttr;
4854
4855 struct oledata *pole;
4856 unsigned int index;
4857 unsigned int count;
4858 int type;
4859 BSTR bstr;
4860 char *pstr;
4861
4862 BOOL is_found = FALSE;
4863 LCID lcid = LOCALE_SYSTEM_DEFAULT;
4864
4865 OLEData_Get_Struct(ole, pole);
4866
4867 pDispatch = pole->pDispatch;
4868
4869 hr = pDispatch->lpVtbl->GetTypeInfo(pDispatch, 0, lcid, &pTypeInfo);
4870 if (FAILED(hr))
4871 return hr;
4872
4873 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo,
4874 &pTypeLib,
4875 &index);
4876 OLE_RELEASE(pTypeInfo);
4877 if (FAILED(hr))
4878 return hr;
4879
4880 if (!pitf) {
4881 hr = pTypeLib->lpVtbl->GetTypeInfoOfGuid(pTypeLib,
4882 piid,
4883 ppTypeInfo);
4884 OLE_RELEASE(pTypeLib);
4885 return hr;
4886 }
4887 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
4888 for (index = 0; index < count; index++) {
4889 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib,
4890 index,
4891 &pTypeInfo);
4892 if (FAILED(hr))
4893 break;
4894 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
4895
4896 if(FAILED(hr)) {
4897 OLE_RELEASE(pTypeInfo);
4898 break;
4899 }
4900 if(pTypeAttr->typekind == TKIND_COCLASS) {
4901 for (type = 0; type < pTypeAttr->cImplTypes; type++) {
4902 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
4903 type,
4904 &RefType);
4905 if (FAILED(hr))
4906 break;
4907 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
4908 RefType,
4909 &pImplTypeInfo);
4910 if (FAILED(hr))
4911 break;
4912
4913 hr = pImplTypeInfo->lpVtbl->GetDocumentation(pImplTypeInfo,
4914 -1,
4915 &bstr,
4916 NULL, NULL, NULL);
4917 if (FAILED(hr)) {
4918 OLE_RELEASE(pImplTypeInfo);
4919 break;
4920 }
4921 pstr = ole_wc2mb(bstr);
4922 if (strcmp(pitf, pstr) == 0) {
4923 hr = pImplTypeInfo->lpVtbl->GetTypeAttr(pImplTypeInfo,
4924 &pImplTypeAttr);
4925 if (SUCCEEDED(hr)) {
4926 is_found = TRUE;
4927 *piid = pImplTypeAttr->guid;
4928 if (ppTypeInfo) {
4929 *ppTypeInfo = pImplTypeInfo;
4930 (*ppTypeInfo)->lpVtbl->AddRef((*ppTypeInfo));
4931 }
4932 pImplTypeInfo->lpVtbl->ReleaseTypeAttr(pImplTypeInfo,
4933 pImplTypeAttr);
4934 }
4935 }
4936 free(pstr);
4937 OLE_RELEASE(pImplTypeInfo);
4938 if (is_found || FAILED(hr))
4939 break;
4940 }
4941 }
4942
4943 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
4944 OLE_RELEASE(pTypeInfo);
4945 if (is_found || FAILED(hr))
4946 break;
4947 }
4948 OLE_RELEASE(pTypeLib);
4949 if(!is_found)
4950 return E_NOINTERFACE;
4951 return hr;
4952 }
4953
4954 static HRESULT
4955 find_default_source(ole, piid, ppTypeInfo)
4956 VALUE ole;
4957 IID *piid;
4958 ITypeInfo **ppTypeInfo;
4959 {
4960 HRESULT hr;
4961 IProvideClassInfo2 *pProvideClassInfo2;
4962 IProvideClassInfo *pProvideClassInfo;
4963
4964 IDispatch *pDispatch;
4965 ITypeInfo *pTypeInfo;
4966 TYPEATTR *pTypeAttr;
4967 int i;
4968 int iFlags;
4969 HREFTYPE hRefType;
4970
4971 struct oledata *pole;
4972
4973 OLEData_Get_Struct(ole, pole);
4974 pDispatch = pole->pDispatch;
4975 hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
4976 &IID_IProvideClassInfo2,
4977 (void**)&pProvideClassInfo2);
4978 if (SUCCEEDED(hr)) {
4979 hr = pProvideClassInfo2->lpVtbl->GetGUID(pProvideClassInfo2,
4980 GUIDKIND_DEFAULT_SOURCE_DISP_IID,
4981 piid);
4982 OLE_RELEASE(pProvideClassInfo2);
4983 return find_iid(ole, NULL, piid, ppTypeInfo);
4984 }
4985 hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
4986 &IID_IProvideClassInfo,
4987 (void**)&pProvideClassInfo);
4988 if (FAILED(hr))
4989 return hr;
4990
4991 hr = pProvideClassInfo->lpVtbl->GetClassInfo(pProvideClassInfo,
4992 &pTypeInfo);
4993 OLE_RELEASE(pProvideClassInfo);
4994 if (FAILED(hr))
4995 return hr;
4996
4997 hr = OLE_GET_TYPEATTR(pTypeInfo, &pTypeAttr);
4998 if (FAILED(hr)) {
4999 OLE_RELEASE(pTypeInfo);
5000 return hr;
5001 }
5002
5003 for (i = 0; i < pTypeAttr->cImplTypes; i++) {
5004 hr = pTypeInfo->lpVtbl->GetImplTypeFlags(pTypeInfo, i, &iFlags);
5005 if (FAILED(hr))
5006 continue;
5007
5008
5009
5010
5011
5012 if ((iFlags & IMPLTYPEFLAG_FDEFAULT) &&
5013 (iFlags & IMPLTYPEFLAG_FSOURCE)) {
5014
5015 hr = pTypeInfo->lpVtbl->GetRefTypeOfImplType(pTypeInfo,
5016 i, &hRefType);
5017 if (FAILED(hr))
5018 continue;
5019 hr = pTypeInfo->lpVtbl->GetRefTypeInfo(pTypeInfo,
5020 hRefType, ppTypeInfo);
5021 if (SUCCEEDED(hr))
5022 break;
5023 }
5024 }
5025
5026 OLE_RELEASE_TYPEATTR(pTypeInfo, pTypeAttr);
5027 OLE_RELEASE(pTypeInfo);
5028
5029
5030 if (!*ppTypeInfo) {
5031 if (SUCCEEDED(hr))
5032 hr = E_UNEXPECTED;
5033 return hr;
5034 }
5035
5036
5037 hr = (*ppTypeInfo)->lpVtbl->GetTypeAttr(*ppTypeInfo, &pTypeAttr);
5038 if (SUCCEEDED(hr)) {
5039 *piid = pTypeAttr->guid;
5040 (*ppTypeInfo)->lpVtbl->ReleaseTypeAttr(*ppTypeInfo, pTypeAttr);
5041 }
5042 else
5043 OLE_RELEASE(*ppTypeInfo);
5044
5045 return hr;
5046
5047 }
5048
5049 static void
5050 ole_event_free(poleev)
5051 struct oleeventdata *poleev;
5052 {
5053 ITypeInfo *pti = NULL;
5054 IConnectionPoint *pcp = NULL;
5055
5056 if(poleev->pEvent) {
5057 pti = poleev->pEvent->pTypeInfo;
5058 if(pti) OLE_RELEASE(pti);
5059 pcp = poleev->pEvent->pConnectionPoint;
5060 if(pcp) {
5061 pcp->lpVtbl->Unadvise(pcp, poleev->pEvent->m_dwCookie);
5062 OLE_RELEASE(pcp);
5063 }
5064 ole_msg_loop();
5065 CoFreeUnusedLibraries();
5066 }
5067 }
5068
5069 static VALUE
5070 fev_s_allocate(klass)
5071 VALUE klass;
5072 {
5073 VALUE obj;
5074 struct oleeventdata *poleev;
5075 obj = Data_Make_Struct(klass,struct oleeventdata,0,ole_event_free,poleev);
5076 poleev->pEvent = NULL;
5077 return obj;
5078 }
5079
5080 static VALUE
5081 fev_initialize(argc, argv, self)
5082 int argc;
5083 VALUE *argv;
5084 VALUE self;
5085 {
5086 VALUE ole, itf;
5087 struct oledata *pole;
5088 char *pitf;
5089 HRESULT hr;
5090 IID iid;
5091 ITypeInfo *pTypeInfo;
5092 IDispatch *pDispatch;
5093 IConnectionPointContainer *pContainer;
5094 IConnectionPoint *pConnectionPoint;
5095 IEVENTSINKOBJ *pIEV;
5096 DWORD dwCookie;
5097 struct oleeventdata *poleev;
5098
5099 rb_scan_args(argc, argv, "11", &ole, &itf);
5100
5101 if (!rb_obj_is_kind_of(ole, cWIN32OLE)) {
5102 rb_raise(rb_eTypeError, "1st parametor must be WIN32OLE object.");
5103 }
5104
5105 if(TYPE(itf) != T_NIL) {
5106 Check_SafeStr(itf);
5107 pitf = StringValuePtr(itf);
5108 hr = find_iid(ole, pitf, &iid, &pTypeInfo);
5109 }
5110 else {
5111 hr = find_default_source(ole, &iid, &pTypeInfo);
5112 }
5113 if (FAILED(hr)) {
5114 ole_raise(hr, rb_eRuntimeError, "not found interface");
5115 }
5116
5117 OLEData_Get_Struct(ole, pole);
5118 pDispatch = pole->pDispatch;
5119 hr = pDispatch->lpVtbl->QueryInterface(pDispatch,
5120 &IID_IConnectionPointContainer,
5121 (void**)&pContainer);
5122 if (FAILED(hr)) {
5123 OLE_RELEASE(pTypeInfo);
5124 ole_raise(hr, rb_eRuntimeError,
5125 "fail to query IConnectionPointContainer");
5126 }
5127
5128 hr = pContainer->lpVtbl->FindConnectionPoint(pContainer,
5129 &iid,
5130 &pConnectionPoint);
5131 OLE_RELEASE(pContainer);
5132 if (FAILED(hr)) {
5133 OLE_RELEASE(pTypeInfo);
5134 ole_raise(hr, rb_eRuntimeError, "fail to query IConnectionPoint");
5135 }
5136 pIEV = EVENTSINK_Constructor();
5137 pIEV->m_iid = iid;
5138 hr = pConnectionPoint->lpVtbl->Advise(pConnectionPoint,
5139 (IUnknown*)pIEV,
5140 &dwCookie);
5141 if (FAILED(hr)) {
5142 ole_raise(hr, rb_eRuntimeError, "Advise Error");
5143 }
5144
5145 Data_Get_Struct(self, struct oleeventdata, poleev);
5146 poleev->pEvent = pIEV;
5147 poleev->pEvent->m_event_id
5148 = NUM2INT(rb_funcall(ary_ole_event, rb_intern("length"), 0));
5149 poleev->pEvent->pConnectionPoint = pConnectionPoint;
5150 poleev->pEvent->pTypeInfo = pTypeInfo;
5151 poleev->pEvent->m_dwCookie = dwCookie;
5152
5153 rb_ary_push(ary_ole_event, self);
5154 return self;
5155 }
5156
5157
5158
5159
5160
5161
5162 static VALUE
5163 fev_s_msg_loop(klass)
5164 VALUE klass;
5165 {
5166 ole_msg_loop();
5167 return Qnil;
5168 }
5169
5170
5171 static void
5172 add_event_call_back(obj, data)
5173 VALUE obj;
5174 VALUE data;
5175 {
5176 VALUE ary = rb_ivar_get(obj, id_events);
5177 if (NIL_P(ary) || TYPE(ary) != T_ARRAY) {
5178 ary = rb_ary_new();
5179 rb_ivar_set(obj, id_events, ary);
5180 }
5181 rb_ary_push(ary, data);
5182 }
5183
5184 static VALUE
5185 ev_on_event(argc, argv, self, is_ary_arg)
5186 int argc;
5187 VALUE *argv;
5188 VALUE self;
5189 VALUE is_ary_arg;
5190 {
5191 VALUE event, args, data;
5192 rb_scan_args(argc, argv, "01*", &event, &args);
5193 if(!NIL_P(event)) {
5194 Check_SafeStr(event);
5195 }
5196 data = rb_ary_new3(4, rb_f_lambda(), event, args, is_ary_arg);
5197 add_event_call_back(self, data);
5198 return Qnil;
5199 }
5200
5201
5202
5203
5204
5205
5206
5207 static VALUE
5208 fev_on_event(argc, argv, self)
5209 int argc;
5210 VALUE *argv;
5211 VALUE self;
5212 {
5213 return ev_on_event(argc, argv, self, Qfalse);
5214 }
5215
5216
5217
5218
5219
5220
5221
5222
5223 static VALUE
5224 fev_on_event_with_outargs(argc, argv, self)
5225 int argc;
5226 VALUE *argv;
5227 VALUE self;
5228 {
5229 return ev_on_event(argc, argv, self, Qtrue);
5230 }
5231
5232
5233 void
5234 Init_win32ole()
5235 {
5236 ary_ole_event = rb_ary_new();
5237 rb_global_variable(&ary_ole_event);
5238 id_events = rb_intern("events");
5239
5240 cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject);
5241
5242 rb_define_singleton_method(cWIN32OLE, "allocate", fole_s_allocate, 0);
5243
5244 rb_define_method(cWIN32OLE, "initialize", fole_initialize, -1);
5245 rb_enable_super(cWIN32OLE, "initialize");
5246
5247 rb_define_singleton_method(cWIN32OLE, "connect", fole_s_connect, -1);
5248 rb_define_singleton_method(cWIN32OLE, "const_load", fole_s_const_load, -1);
5249
5250 rb_define_singleton_method(cWIN32OLE, "ole_free", fole_s_free, 1);
5251 rb_define_singleton_method(cWIN32OLE, "ole_reference_count", fole_s_reference_count, 1);
5252 rb_define_singleton_method(cWIN32OLE, "ole_show_help", fole_s_show_help, -1);
5253
5254
5255 rb_define_method(cWIN32OLE, "invoke", fole_invoke, -1);
5256 rb_define_method(cWIN32OLE, "[]", fole_getproperty, 1);
5257 rb_define_method(cWIN32OLE, "_invoke", fole_invoke2, 3);
5258 rb_define_method(cWIN32OLE, "_getproperty", fole_getproperty2, 3);
5259 rb_define_method(cWIN32OLE, "_setproperty", fole_setproperty2, 3);
5260
5261
5262 rb_define_method(cWIN32OLE, "[]=", fole_setproperty, -1);
5263
5264 rb_define_method(cWIN32OLE, "ole_free", fole_free, 0);
5265
5266 rb_define_method(cWIN32OLE, "each", fole_each, 0);
5267 rb_define_method(cWIN32OLE, "method_missing", fole_missing, -1);
5268
5269
5270 rb_define_method(cWIN32OLE, "setproperty", fole_setproperty, -1);
5271
5272 rb_define_method(cWIN32OLE, "ole_methods", fole_methods, 0);
5273 rb_define_method(cWIN32OLE, "ole_get_methods", fole_get_methods, 0);
5274 rb_define_method(cWIN32OLE, "ole_put_methods", fole_put_methods, 0);
5275 rb_define_method(cWIN32OLE, "ole_func_methods", fole_func_methods, 0);
5276
5277 rb_define_method(cWIN32OLE, "ole_method", fole_method_help, 1);
5278 rb_define_alias(cWIN32OLE, "ole_method_help", "ole_method");
5279 rb_define_method(cWIN32OLE, "ole_obj_help", fole_obj_help, 0);
5280
5281 rb_define_const(cWIN32OLE, "VERSION", rb_str_new2(WIN32OLE_VERSION));
5282 rb_define_const(cWIN32OLE, "ARGV", rb_ary_new());
5283
5284 mWIN32OLE_VARIANT = rb_define_module_under(cWIN32OLE, "VARIANT");
5285 rb_define_const(mWIN32OLE_VARIANT, "VT_I2", INT2FIX(VT_I2));
5286 rb_define_const(mWIN32OLE_VARIANT, "VT_I4", INT2FIX(VT_I4));
5287 rb_define_const(mWIN32OLE_VARIANT, "VT_R4", INT2FIX(VT_R4));
5288 rb_define_const(mWIN32OLE_VARIANT, "VT_R8", INT2FIX(VT_R8));
5289 rb_define_const(mWIN32OLE_VARIANT, "VT_CY", INT2FIX(VT_CY));
5290 rb_define_const(mWIN32OLE_VARIANT, "VT_DATE", INT2FIX(VT_DATE));
5291 rb_define_const(mWIN32OLE_VARIANT, "VT_BSTR", INT2FIX(VT_BSTR));
5292 rb_define_const(mWIN32OLE_VARIANT, "VT_USERDEFINED", INT2FIX(VT_USERDEFINED));
5293 rb_define_const(mWIN32OLE_VARIANT, "VT_PTR", INT2FIX(VT_PTR));
5294 rb_define_const(mWIN32OLE_VARIANT, "VT_DISPATCH", INT2FIX(VT_DISPATCH));
5295 rb_define_const(mWIN32OLE_VARIANT, "VT_ERROR", INT2FIX(VT_ERROR));
5296 rb_define_const(mWIN32OLE_VARIANT, "VT_BOOL", INT2FIX(VT_BOOL));
5297 rb_define_const(mWIN32OLE_VARIANT, "VT_VARIANT", INT2FIX(VT_VARIANT));
5298 rb_define_const(mWIN32OLE_VARIANT, "VT_UNKNOWN", INT2FIX(VT_UNKNOWN));
5299 rb_define_const(mWIN32OLE_VARIANT, "VT_I1", INT2FIX(VT_I1));
5300 rb_define_const(mWIN32OLE_VARIANT, "VT_UI1", INT2FIX(VT_UI1));
5301 rb_define_const(mWIN32OLE_VARIANT, "VT_UI2", INT2FIX(VT_UI2));
5302 rb_define_const(mWIN32OLE_VARIANT, "VT_UI4", INT2FIX(VT_UI4));
5303 rb_define_const(mWIN32OLE_VARIANT, "VT_INT", INT2FIX(VT_INT));
5304 rb_define_const(mWIN32OLE_VARIANT, "VT_UINT", INT2FIX(VT_UINT));
5305 rb_define_const(mWIN32OLE_VARIANT, "VT_ARRAY", INT2FIX(VT_ARRAY));
5306 rb_define_const(mWIN32OLE_VARIANT, "VT_BYREF", INT2FIX(VT_BYREF));
5307
5308 cWIN32OLE_TYPE = rb_define_class("WIN32OLE_TYPE", rb_cObject);
5309 rb_define_singleton_method(cWIN32OLE_TYPE, "ole_classes", foletype_s_ole_classes, 1);
5310 rb_define_singleton_method(cWIN32OLE_TYPE, "typelibs", foletype_s_typelibs, 0);
5311 rb_define_singleton_method(cWIN32OLE_TYPE, "progids", foletype_s_progids, 0);
5312 rb_define_singleton_method(cWIN32OLE_TYPE, "allocate", foletype_s_allocate, 0);
5313 rb_define_method(cWIN32OLE_TYPE, "initialize", foletype_initialize, 2);
5314 rb_enable_super(cWIN32OLE_TYPE, "initialize");
5315 rb_define_method(cWIN32OLE_TYPE, "name", foletype_name, 0);
5316 rb_define_method(cWIN32OLE_TYPE, "ole_type", foletype_ole_type, 0);
5317 rb_define_method(cWIN32OLE_TYPE, "guid", foletype_guid, 0);
5318 rb_define_method(cWIN32OLE_TYPE, "progid", foletype_progid, 0);
5319 rb_define_method(cWIN32OLE_TYPE, "visible?", foletype_visible, 0);
5320
5321 rb_define_method(cWIN32OLE_TYPE, "major_version", foletype_major_version, 0);
5322 rb_define_method(cWIN32OLE_TYPE, "minor_version", foletype_minor_version, 0);
5323 rb_define_method(cWIN32OLE_TYPE, "typekind", foletype_typekind, 0);
5324 rb_define_method(cWIN32OLE_TYPE, "helpstring", foletype_helpstring, 0);
5325 rb_define_method(cWIN32OLE_TYPE, "src_type", foletype_src_type, 0);
5326 rb_define_method(cWIN32OLE_TYPE, "helpfile", foletype_helpfile, 0);
5327 rb_define_method(cWIN32OLE_TYPE, "helpcontext", foletype_helpcontext, 0);
5328 rb_define_method(cWIN32OLE_TYPE, "variables", foletype_variables, 0);
5329 rb_define_method(cWIN32OLE_TYPE, "ole_methods", foletype_methods, -1);
5330
5331 cWIN32OLE_VARIABLE = rb_define_class("WIN32OLE_VARIABLE", rb_cObject);
5332 rb_define_method(cWIN32OLE_VARIABLE, "name", folevariable_name, 0);
5333 rb_define_method(cWIN32OLE_VARIABLE, "ole_type", folevariable_ole_type, 0);
5334 rb_define_method(cWIN32OLE_VARIABLE, "ole_type_detail", folevariable_ole_type_detail, 0);
5335 rb_define_method(cWIN32OLE_VARIABLE, "value", folevariable_value, 0);
5336 rb_define_method(cWIN32OLE_VARIABLE, "visible?", folevariable_visible, 0);
5337 rb_define_method(cWIN32OLE_VARIABLE, "variable_kind", folevariable_variable_kind, 0);
5338 rb_define_method(cWIN32OLE_VARIABLE, "varkind", folevariable_varkind, 0);
5339
5340 cWIN32OLE_METHOD = rb_define_class("WIN32OLE_METHOD", rb_cObject);
5341 rb_define_singleton_method(cWIN32OLE_METHOD, "allocate", folemethod_s_allocate, 0);
5342 rb_define_method(cWIN32OLE_METHOD, "initialize", folemethod_initialize, 2);
5343 rb_enable_super(cWIN32OLE_METHOD, "initialize");
5344
5345 rb_define_method(cWIN32OLE_METHOD, "name", folemethod_name, 0);
5346 rb_define_method(cWIN32OLE_METHOD, "return_type", folemethod_return_type, 0);
5347 rb_define_method(cWIN32OLE_METHOD, "return_vtype", folemethod_return_vtype, 0);
5348 rb_define_method(cWIN32OLE_METHOD, "return_type_detail", folemethod_return_type_detail, 0);
5349 rb_define_method(cWIN32OLE_METHOD, "invoke_kind", folemethod_invoke_kind, 0);
5350 rb_define_method(cWIN32OLE_METHOD, "invkind", folemethod_invkind, 0);
5351 rb_define_method(cWIN32OLE_METHOD, "visible?", folemethod_visible, 0);
5352 rb_define_method(cWIN32OLE_METHOD, "event?", folemethod_event, 0);
5353 rb_define_method(cWIN32OLE_METHOD, "event_interface", folemethod_event_interface, 0);
5354 rb_define_method(cWIN32OLE_METHOD, "helpstring", folemethod_helpstring, 0);
5355 rb_define_method(cWIN32OLE_METHOD, "helpfile", folemethod_helpfile, 0);
5356 rb_define_method(cWIN32OLE_METHOD, "helpcontext", folemethod_helpcontext, 0);
5357 rb_define_method(cWIN32OLE_METHOD, "dispid", folemethod_dispid, 0);
5358 rb_define_method(cWIN32OLE_METHOD, "offset_vtbl", folemethod_offset_vtbl, 0);
5359 rb_define_method(cWIN32OLE_METHOD, "size_params", folemethod_size_params, 0);
5360 rb_define_method(cWIN32OLE_METHOD, "size_opt_params", folemethod_size_opt_params, 0);
5361 rb_define_method(cWIN32OLE_METHOD, "params", folemethod_params, 0);
5362
5363 cWIN32OLE_PARAM = rb_define_class("WIN32OLE_PARAM", rb_cObject);
5364 rb_define_method(cWIN32OLE_PARAM, "name", foleparam_name, 0);
5365 rb_define_method(cWIN32OLE_PARAM, "ole_type", foleparam_ole_type, 0);
5366 rb_define_method(cWIN32OLE_PARAM, "ole_type_detail", foleparam_ole_type_detail, 0);
5367 rb_define_method(cWIN32OLE_PARAM, "input?", foleparam_input, 0);
5368 rb_define_method(cWIN32OLE_PARAM, "output?", foleparam_output, 0);
5369 rb_define_method(cWIN32OLE_PARAM, "optional?", foleparam_optional, 0);
5370 rb_define_method(cWIN32OLE_PARAM, "retval?", foleparam_retval, 0);
5371 rb_define_method(cWIN32OLE_PARAM, "default", foleparam_default, 0);
5372
5373 cWIN32OLE_EVENT = rb_define_class("WIN32OLE_EVENT", rb_cObject);
5374
5375 rb_define_singleton_method(cWIN32OLE_EVENT, "allocate", fev_s_allocate, 0);
5376 rb_define_method(cWIN32OLE_EVENT, "initialize", fev_initialize, -1);
5377 rb_enable_super(cWIN32OLE_EVENT, "initialize");
5378 rb_define_singleton_method(cWIN32OLE_EVENT, "message_loop", fev_s_msg_loop, 0);
5379
5380 rb_define_method(cWIN32OLE_EVENT, "on_event", fev_on_event, -1);
5381 rb_define_method(cWIN32OLE_EVENT, "on_event_with_outargs", fev_on_event_with_outargs, -1);
5382 eWIN32OLE_RUNTIME_ERROR = rb_define_class("WIN32OLERuntimeError", rb_eRuntimeError);
5383 }