Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

win32ole_typelib.c
Go to the documentation of this file.
1 #include "win32ole.h"
2
3 struct oletypelibdata {
4 ITypeLib *pTypeLib;
5 };
6
7 static VALUE reg_get_typelib_file_path(HKEY hkey);
8 static VALUE oletypelib_path(VALUE guid, VALUE version);
9 static HRESULT oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib);
10 static VALUE foletypelib_s_typelibs(VALUE self);
11 static VALUE oletypelib_set_member(VALUE self, ITypeLib *pTypeLib);
12 static void oletypelib_free(void *ptr);
13 static size_t oletypelib_size(const void *ptr);
14 static VALUE foletypelib_s_allocate(VALUE klass);
15 static VALUE oletypelib_search_registry(VALUE self, VALUE typelib);
16 static void oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr);
17 static VALUE oletypelib_search_registry2(VALUE self, VALUE args);
18 static VALUE foletypelib_initialize(VALUE self, VALUE args);
19 static VALUE foletypelib_guid(VALUE self);
20 static VALUE foletypelib_name(VALUE self);
21 static VALUE make_version_str(VALUE major, VALUE minor);
22 static VALUE foletypelib_version(VALUE self);
23 static VALUE foletypelib_major_version(VALUE self);
24 static VALUE foletypelib_minor_version(VALUE self);
25 static VALUE foletypelib_path(VALUE self);
26 static VALUE foletypelib_visible(VALUE self);
27 static VALUE foletypelib_library_name(VALUE self);
28 static VALUE ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes);
29 static VALUE typelib_file_from_typelib(VALUE ole);
30 static VALUE typelib_file_from_clsid(VALUE ole);
31 static VALUE foletypelib_ole_types(VALUE self);
32 static VALUE foletypelib_inspect(VALUE self);
33
34 static const rb_data_type_t oletypelib_datatype = {
35 "win32ole_typelib",
36 {NULL, oletypelib_free, oletypelib_size,},
37 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
38 };
39
40 static VALUE
41 reg_get_typelib_file_path(HKEY hkey)
42 {
43 VALUE path = Qnil;
44 path = reg_get_val2(hkey, "win64");
45 if (path != Qnil) {
46 return path;
47 }
48 path = reg_get_val2(hkey, "win32");
49 if (path != Qnil) {
50 return path;
51 }
52 path = reg_get_val2(hkey, "win16");
53 return path;
54 }
55
56 static VALUE
57 oletypelib_path(VALUE guid, VALUE version)
58 {
59 int k;
60 LONG err;
61 HKEY hkey;
62 HKEY hlang;
63 VALUE lang;
64 VALUE path = Qnil;
65
66 VALUE key = rb_str_new2("TypeLib\\");
67 rb_str_concat(key, guid);
68 rb_str_cat2(key, "\\");
69 rb_str_concat(key, version);
70
71 err = reg_open_vkey(HKEY_CLASSES_ROOT, key, &hkey);
72 if (err != ERROR_SUCCESS) {
73 return Qnil;
74 }
75 for(k = 0; path == Qnil; k++) {
76 lang = reg_enum_key(hkey, k);
77 if (lang == Qnil)
78 break;
79 err = reg_open_vkey(hkey, lang, &hlang);
80 if (err == ERROR_SUCCESS) {
81 path = reg_get_typelib_file_path(hlang);
82 RegCloseKey(hlang);
83 }
84 }
85 RegCloseKey(hkey);
86 return path;
87 }
88
89 static HRESULT
90 oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib)
91 {
92 VALUE path;
93 OLECHAR *pBuf;
94 HRESULT hr;
95 path = oletypelib_path(guid, version);
96 if (path == Qnil) {
97 return E_UNEXPECTED;
98 }
99 pBuf = ole_vstr2wc(path);
100 hr = LoadTypeLibEx(pBuf, REGKIND_NONE, ppTypeLib);
101 SysFreeString(pBuf);
102 return hr;
103 }
104
105 ITypeLib *
106 itypelib(VALUE self)
107 {
108 struct oletypelibdata *ptlib;
109 TypedData_Get_Struct(self, struct oletypelibdata, &oletypelib_datatype, ptlib);
110 return ptlib->pTypeLib;
111 }
112
113 VALUE
114 ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo)
115 {
116 HRESULT hr;
117 ITypeLib *pTypeLib;
118 unsigned int index;
119 VALUE retval = Qnil;
120
121 hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
122 if(FAILED(hr)) {
123 return Qnil;
124 }
125 retval = create_win32ole_typelib(pTypeLib);
126 return retval;
127 }
128
129 /*
130 * Document-class: WIN32OLE_TYPELIB
131 *
132 * <code>WIN32OLE_TYPELIB</code> objects represent OLE tyblib information.
133 */
134
135 /*
136 * call-seq:
137 *
138 * WIN32OLE_TYPELIB.typelibs
139 *
140 * Returns the array of WIN32OLE_TYPELIB object.
141 *
142 * tlibs = WIN32OLE_TYPELIB.typelibs
143 *
144 */
145 static VALUE
146 foletypelib_s_typelibs(VALUE self)
147 {
148 HKEY htypelib, hguid;
149 DWORD i, j;
150 LONG err;
151 VALUE guid;
152 VALUE version;
153 VALUE name = Qnil;
154 VALUE typelibs = rb_ary_new();
155 VALUE typelib = Qnil;
156 HRESULT hr;
157 ITypeLib *pTypeLib;
158
159 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
160 if(err != ERROR_SUCCESS) {
161 return typelibs;
162 }
163 for(i = 0; ; i++) {
164 guid = reg_enum_key(htypelib, i);
165 if (guid == Qnil)
166 break;
167 err = reg_open_vkey(htypelib, guid, &hguid);
168 if (err != ERROR_SUCCESS)
169 continue;
170 for(j = 0; ; j++) {
171 version = reg_enum_key(hguid, j);
172 if (version == Qnil)
173 break;
174 if ( (name = reg_get_val2(hguid, StringValuePtr(version))) != Qnil ) {
175 hr = oletypelib_from_guid(guid, version, &pTypeLib);
176 if (SUCCEEDED(hr)) {
177 typelib = create_win32ole_typelib(pTypeLib);
178 rb_ary_push(typelibs, typelib);
179 }
180 }
181 }
182 RegCloseKey(hguid);
183 }
184 RegCloseKey(htypelib);
185 return typelibs;
186 }
187
188 static VALUE
189 oletypelib_set_member(VALUE self, ITypeLib *pTypeLib)
190 {
191 struct oletypelibdata *ptlib;
192 TypedData_Get_Struct(self, struct oletypelibdata, &oletypelib_datatype, ptlib);
193 ptlib->pTypeLib = pTypeLib;
194 return self;
195 }
196
197 static void
198 oletypelib_free(void *ptr)
199 {
200 struct oletypelibdata *poletypelib = ptr;
201 OLE_FREE(poletypelib->pTypeLib);
202 free(poletypelib);
203 }
204
205 static size_t
206 oletypelib_size(const void *ptr)
207 {
208 return ptr ? sizeof(struct oletypelibdata) : 0;
209 }
210
211 static VALUE
212 foletypelib_s_allocate(VALUE klass)
213 {
214 struct oletypelibdata *poletypelib;
215 VALUE obj;
216 ole_initialize();
217 obj = TypedData_Make_Struct(klass, struct oletypelibdata, &oletypelib_datatype, poletypelib);
218 poletypelib->pTypeLib = NULL;
219 return obj;
220 }
221
222 VALUE
223 create_win32ole_typelib(ITypeLib *pTypeLib)
224 {
225 VALUE obj = foletypelib_s_allocate(cWIN32OLE_TYPELIB);
226 oletypelib_set_member(obj, pTypeLib);
227 return obj;
228 }
229
230 static VALUE
231 oletypelib_search_registry(VALUE self, VALUE typelib)
232 {
233 HKEY htypelib, hguid, hversion;
234 DWORD i, j;
235 LONG err;
236 VALUE found = Qfalse;
237 VALUE tlib;
238 VALUE guid;
239 VALUE ver;
240 HRESULT hr;
241 ITypeLib *pTypeLib;
242
243 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
244 if(err != ERROR_SUCCESS) {
245 return Qfalse;
246 }
247 for(i = 0; !found; i++) {
248 guid = reg_enum_key(htypelib, i);
249 if (guid == Qnil)
250 break;
251 err = reg_open_vkey(htypelib, guid, &hguid);
252 if (err != ERROR_SUCCESS)
253 continue;
254 for(j = 0; found == Qfalse; j++) {
255 ver = reg_enum_key(hguid, j);
256 if (ver == Qnil)
257 break;
258 err = reg_open_vkey(hguid, ver, &hversion);
259 if (err != ERROR_SUCCESS)
260 continue;
261 tlib = reg_get_val(hversion, NULL);
262 if (tlib == Qnil) {
263 RegCloseKey(hversion);
264 continue;
265 }
266 if (rb_str_cmp(typelib, tlib) == 0) {
267 hr = oletypelib_from_guid(guid, ver, &pTypeLib);
268 if (SUCCEEDED(hr)) {
269 oletypelib_set_member(self, pTypeLib);
270 found = Qtrue;
271 }
272 }
273 RegCloseKey(hversion);
274 }
275 RegCloseKey(hguid);
276 }
277 RegCloseKey(htypelib);
278 return found;
279 }
280
281 static void
282 oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr)
283 {
284 HRESULT hr;
285 hr = pTypeLib->lpVtbl->GetLibAttr(pTypeLib, ppTLibAttr);
286 if (FAILED(hr)) {
287 ole_raise(hr, eWIN32OLERuntimeError,
288 "failed to get library attribute(TLIBATTR) from ITypeLib");
289 }
290 }
291
292 static VALUE
293 oletypelib_search_registry2(VALUE self, VALUE args)
294 {
295 HKEY htypelib, hguid, hversion;
296 double fver;
297 DWORD j;
298 LONG err;
299 VALUE found = Qfalse;
300 VALUE tlib;
301 VALUE ver;
302 VALUE version_str;
303 VALUE version = Qnil;
304 VALUE typelib = Qnil;
305 HRESULT hr;
306 ITypeLib *pTypeLib;
307
308 VALUE guid = rb_ary_entry(args, 0);
309 version_str = make_version_str(rb_ary_entry(args, 1), rb_ary_entry(args, 2));
310
311 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
312 if(err != ERROR_SUCCESS) {
313 return Qfalse;
314 }
315 err = reg_open_vkey(htypelib, guid, &hguid);
316 if (err != ERROR_SUCCESS) {
317 RegCloseKey(htypelib);
318 return Qfalse;
319 }
320 if (version_str != Qnil) {
321 err = reg_open_vkey(hguid, version_str, &hversion);
322 if (err == ERROR_SUCCESS) {
323 tlib = reg_get_val(hversion, NULL);
324 if (tlib != Qnil) {
325 typelib = tlib;
326 version = version_str;
327 }
328 }
329 RegCloseKey(hversion);
330 } else {
331 fver = 0.0;
332 for(j = 0; ;j++) {
333 ver = reg_enum_key(hguid, j);
334 if (ver == Qnil)
335 break;
336 err = reg_open_vkey(hguid, ver, &hversion);
337 if (err != ERROR_SUCCESS)
338 continue;
339 tlib = reg_get_val(hversion, NULL);
340 if (tlib == Qnil) {
341 RegCloseKey(hversion);
342 continue;
343 }
344 if (fver < atof(StringValuePtr(ver))) {
345 fver = atof(StringValuePtr(ver));
346 version = ver;
347 typelib = tlib;
348 }
349 RegCloseKey(hversion);
350 }
351 }
352 RegCloseKey(hguid);
353 RegCloseKey(htypelib);
354 if (typelib != Qnil) {
355 hr = oletypelib_from_guid(guid, version, &pTypeLib);
356 if (SUCCEEDED(hr)) {
357 found = Qtrue;
358 oletypelib_set_member(self, pTypeLib);
359 }
360 }
361 return found;
362 }
363
364
365 /*
366 * call-seq:
367 * WIN32OLE_TYPELIB.new(typelib [, version1, version2]) -> WIN32OLE_TYPELIB object
368 *
369 * Returns a new WIN32OLE_TYPELIB object.
370 *
371 * The first argument <i>typelib</i> specifies OLE type library name or GUID or
372 * OLE library file.
373 * The second argument is major version or version of the type library.
374 * The third argument is minor version.
375 * The second argument and third argument are optional.
376 * If the first argument is type library name, then the second and third argument
377 * are ignored.
378 *
379 * tlib1 = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
380 * tlib2 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}')
381 * tlib3 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1.3)
382 * tlib4 = WIN32OLE_TYPELIB.new('{00020813-0000-0000-C000-000000000046}', 1, 3)
383 * tlib5 = WIN32OLE_TYPELIB.new("C:\\WINNT\\SYSTEM32\\SHELL32.DLL")
384 * puts tlib1.name # -> 'Microsoft Excel 9.0 Object Library'
385 * puts tlib2.name # -> 'Microsoft Excel 9.0 Object Library'
386 * puts tlib3.name # -> 'Microsoft Excel 9.0 Object Library'
387 * puts tlib4.name # -> 'Microsoft Excel 9.0 Object Library'
388 * puts tlib5.name # -> 'Microsoft Shell Controls And Automation'
389 *
390 */
391 static VALUE
392 foletypelib_initialize(VALUE self, VALUE args)
393 {
394 VALUE found = Qfalse;
395 VALUE typelib = Qnil;
396 int len = 0;
397 OLECHAR * pbuf;
398 ITypeLib *pTypeLib;
399 HRESULT hr = S_OK;
400
401 len = RARRAY_LEN(args);
402 rb_check_arity(len, 1, 3);
403
404 typelib = rb_ary_entry(args, 0);
405
406 SafeStringValue(typelib);
407
408 found = oletypelib_search_registry(self, typelib);
409 if (found == Qfalse) {
410 found = oletypelib_search_registry2(self, args);
411 }
412 if (found == Qfalse) {
413 pbuf = ole_vstr2wc(typelib);
414 hr = LoadTypeLibEx(pbuf, REGKIND_NONE, &pTypeLib);
415 SysFreeString(pbuf);
416 if (SUCCEEDED(hr)) {
417 found = Qtrue;
418 oletypelib_set_member(self, pTypeLib);
419 }
420 }
421
422 if (found == Qfalse) {
423 rb_raise(eWIN32OLERuntimeError, "not found type library `%s`",
424 StringValuePtr(typelib));
425 }
426 return self;
427 }
428
429 /*
430 * call-seq:
431 * WIN32OLE_TYPELIB#guid -> The guid string.
432 *
433 * Returns guid string which specifies type library.
434 *
435 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
436 * guid = tlib.guid # -> '{00020813-0000-0000-C000-000000000046}'
437 */
438 static VALUE
439 foletypelib_guid(VALUE self)
440 {
441 ITypeLib *pTypeLib;
442 OLECHAR bstr[80];
443 VALUE guid = Qnil;
444 int len;
445 TLIBATTR *pTLibAttr;
446
447 pTypeLib = itypelib(self);
448 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
449 len = StringFromGUID2(&pTLibAttr->guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
450 if (len > 3) {
451 guid = ole_wc2vstr(bstr, FALSE);
452 }
453 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
454 return guid;
455 }
456
457 /*
458 * call-seq:
459 * WIN32OLE_TYPELIB#name -> The type library name
460 *
461 * Returns the type library name.
462 *
463 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
464 * name = tlib.name # -> 'Microsoft Excel 9.0 Object Library'
465 */
466 static VALUE
467 foletypelib_name(VALUE self)
468 {
469 ITypeLib *pTypeLib;
470 HRESULT hr;
471 BSTR bstr;
472 VALUE name;
473 pTypeLib = itypelib(self);
474 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
475 NULL, &bstr, NULL, NULL);
476
477 if (FAILED(hr)) {
478 ole_raise(hr, eWIN32OLERuntimeError, "failed to get name from ITypeLib");
479 }
480 name = WC2VSTR(bstr);
481 return name;
482 }
483
484 static VALUE
485 make_version_str(VALUE major, VALUE minor)
486 {
487 VALUE version_str = Qnil;
488 VALUE minor_str = Qnil;
489 if (major == Qnil) {
490 return Qnil;
491 }
492 version_str = rb_String(major);
493 if (minor != Qnil) {
494 minor_str = rb_String(minor);
495 rb_str_cat2(version_str, ".");
496 rb_str_append(version_str, minor_str);
497 }
498 return version_str;
499 }
500
501 /*
502 * call-seq:
503 * WIN32OLE_TYPELIB#version -> The type library version String object.
504 *
505 * Returns the type library version.
506 *
507 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
508 * puts tlib.version #-> "1.3"
509 */
510 static VALUE
511 foletypelib_version(VALUE self)
512 {
513 TLIBATTR *pTLibAttr;
514 ITypeLib *pTypeLib;
515 VALUE version;
516
517 pTypeLib = itypelib(self);
518 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
519 version = rb_sprintf("%d.%d", pTLibAttr->wMajorVerNum, pTLibAttr->wMinorVerNum);
520 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
521 return version;
522 }
523
524 /*
525 * call-seq:
526 * WIN32OLE_TYPELIB#major_version -> The type library major version.
527 *
528 * Returns the type library major version.
529 *
530 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
531 * puts tlib.major_version # -> 1
532 */
533 static VALUE
534 foletypelib_major_version(VALUE self)
535 {
536 TLIBATTR *pTLibAttr;
537 VALUE major;
538 ITypeLib *pTypeLib;
539 pTypeLib = itypelib(self);
540 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
541
542 major = RB_INT2NUM(pTLibAttr->wMajorVerNum);
543 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
544 return major;
545 }
546
547 /*
548 * call-seq:
549 * WIN32OLE_TYPELIB#minor_version -> The type library minor version.
550 *
551 * Returns the type library minor version.
552 *
553 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
554 * puts tlib.minor_version # -> 3
555 */
556 static VALUE
557 foletypelib_minor_version(VALUE self)
558 {
559 TLIBATTR *pTLibAttr;
560 VALUE minor;
561 ITypeLib *pTypeLib;
562 pTypeLib = itypelib(self);
563 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
564 minor = RB_INT2NUM(pTLibAttr->wMinorVerNum);
565 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
566 return minor;
567 }
568
569 /*
570 * call-seq:
571 * WIN32OLE_TYPELIB#path -> The type library file path.
572 *
573 * Returns the type library file path.
574 *
575 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
576 * puts tlib.path #-> 'C:\...\EXCEL9.OLB'
577 */
578 static VALUE
579 foletypelib_path(VALUE self)
580 {
581 TLIBATTR *pTLibAttr;
582 HRESULT hr = S_OK;
583 BSTR bstr;
584 LCID lcid = cWIN32OLE_lcid;
585 VALUE path;
586 ITypeLib *pTypeLib;
587
588 pTypeLib = itypelib(self);
589 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
590 hr = QueryPathOfRegTypeLib(&pTLibAttr->guid,
591 pTLibAttr->wMajorVerNum,
592 pTLibAttr->wMinorVerNum,
593 lcid,
594 &bstr);
595 if (FAILED(hr)) {
596 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
597 ole_raise(hr, eWIN32OLERuntimeError, "failed to QueryPathOfRegTypeTypeLib");
598 }
599
600 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
601 path = WC2VSTR(bstr);
602 return path;
603 }
604
605 /*
606 * call-seq:
607 * WIN32OLE_TYPELIB#visible?
608 *
609 * Returns true if the type library information is not hidden.
610 * If wLibFlags of TLIBATTR is 0 or LIBFLAG_FRESTRICTED or LIBFLAG_FHIDDEN,
611 * the method returns false, otherwise, returns true.
612 * If the method fails to access the TLIBATTR information, then
613 * WIN32OLERuntimeError is raised.
614 *
615 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
616 * tlib.visible? # => true
617 */
618 static VALUE
619 foletypelib_visible(VALUE self)
620 {
621 ITypeLib *pTypeLib = NULL;
622 VALUE visible = Qtrue;
623 TLIBATTR *pTLibAttr;
624
625 pTypeLib = itypelib(self);
626 oletypelib_get_libattr(pTypeLib, &pTLibAttr);
627
628 if ((pTLibAttr->wLibFlags == 0) ||
629 (pTLibAttr->wLibFlags & LIBFLAG_FRESTRICTED) ||
630 (pTLibAttr->wLibFlags & LIBFLAG_FHIDDEN)) {
631 visible = Qfalse;
632 }
633 pTypeLib->lpVtbl->ReleaseTLibAttr(pTypeLib, pTLibAttr);
634 return visible;
635 }
636
637 /*
638 * call-seq:
639 * WIN32OLE_TYPELIB#library_name
640 *
641 * Returns library name.
642 * If the method fails to access library name, WIN32OLERuntimeError is raised.
643 *
644 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
645 * tlib.library_name # => Excel
646 */
647 static VALUE
648 foletypelib_library_name(VALUE self)
649 {
650 HRESULT hr;
651 ITypeLib *pTypeLib = NULL;
652 VALUE libname = Qnil;
653 BSTR bstr;
654
655 pTypeLib = itypelib(self);
656 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, -1,
657 &bstr, NULL, NULL, NULL);
658 if (FAILED(hr)) {
659 ole_raise(hr, eWIN32OLERuntimeError, "failed to get library name");
660 }
661 libname = WC2VSTR(bstr);
662 return libname;
663 }
664
665 static VALUE
666 ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes)
667 {
668 long count;
669 int i;
670 HRESULT hr;
671 BSTR bstr;
672 ITypeInfo *pTypeInfo;
673 VALUE type;
674
675 count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib);
676 for (i = 0; i < count; i++) {
677 hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i,
678 &bstr, NULL, NULL, NULL);
679 if (FAILED(hr))
680 continue;
681
682 hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo);
683 if (FAILED(hr))
684 continue;
685
686 type = create_win32ole_type(pTypeInfo, WC2VSTR(bstr));
687
688 rb_ary_push(classes, type);
689 OLE_RELEASE(pTypeInfo);
690 }
691 return classes;
692 }
693
694 static VALUE
695 typelib_file_from_typelib(VALUE ole)
696 {
697 HKEY htypelib, hclsid, hversion, hlang;
698 double fver;
699 DWORD i, j, k;
700 LONG err;
701 BOOL found = FALSE;
702 VALUE typelib;
703 VALUE file = Qnil;
704 VALUE clsid;
705 VALUE ver;
706 VALUE lang;
707
708 err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib);
709 if(err != ERROR_SUCCESS) {
710 return Qnil;
711 }
712 for(i = 0; !found; i++) {
713 clsid = reg_enum_key(htypelib, i);
714 if (clsid == Qnil)
715 break;
716 err = reg_open_vkey(htypelib, clsid, &hclsid);
717 if (err != ERROR_SUCCESS)
718 continue;
719 fver = 0;
720 for(j = 0; !found; j++) {
721 ver = reg_enum_key(hclsid, j);
722 if (ver == Qnil)
723 break;
724 err = reg_open_vkey(hclsid, ver, &hversion);
725 if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver)))
726 continue;
727 fver = atof(StringValuePtr(ver));
728 typelib = reg_get_val(hversion, NULL);
729 if (typelib == Qnil)
730 continue;
731 if (rb_str_cmp(typelib, ole) == 0) {
732 for(k = 0; !found; k++) {
733 lang = reg_enum_key(hversion, k);
734 if (lang == Qnil)
735 break;
736 err = reg_open_vkey(hversion, lang, &hlang);
737 if (err == ERROR_SUCCESS) {
738 if ((file = reg_get_typelib_file_path(hlang)) != Qnil)
739 found = TRUE;
740 RegCloseKey(hlang);
741 }
742 }
743 }
744 RegCloseKey(hversion);
745 }
746 RegCloseKey(hclsid);
747 }
748 RegCloseKey(htypelib);
749 return file;
750 }
751
752 static VALUE
753 typelib_file_from_clsid(VALUE ole)
754 {
755 HKEY hroot, hclsid;
756 LONG err;
757 VALUE typelib;
758 char path[MAX_PATH + 1];
759
760 err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hroot);
761 if (err != ERROR_SUCCESS) {
762 return Qnil;
763 }
764 err = reg_open_key(hroot, StringValuePtr(ole), &hclsid);
765 if (err != ERROR_SUCCESS) {
766 RegCloseKey(hroot);
767 return Qnil;
768 }
769 typelib = reg_get_val2(hclsid, "InprocServer32");
770 RegCloseKey(hroot);
771 RegCloseKey(hclsid);
772 if (typelib != Qnil) {
773 ExpandEnvironmentStrings(StringValuePtr(typelib), path, sizeof(path));
774 path[MAX_PATH] = '\0';
775 typelib = rb_str_new2(path);
776 }
777 return typelib;
778 }
779
780 VALUE
781 typelib_file(VALUE ole)
782 {
783 VALUE file = typelib_file_from_clsid(ole);
784 if (file != Qnil) {
785 return file;
786 }
787 return typelib_file_from_typelib(ole);
788 }
789
790
791 /*
792 * call-seq:
793 * WIN32OLE_TYPELIB#ole_types -> The array of WIN32OLE_TYPE object included the type library.
794 *
795 * Returns the type library file path.
796 *
797 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
798 * classes = tlib.ole_types.collect{|k| k.name} # -> ['AddIn', 'AddIns' ...]
799 */
800 static VALUE
801 foletypelib_ole_types(VALUE self)
802 {
803 ITypeLib *pTypeLib = NULL;
804 VALUE classes = rb_ary_new();
805 pTypeLib = itypelib(self);
806 ole_types_from_typelib(pTypeLib, classes);
807 return classes;
808 }
809
810 /*
811 * call-seq:
812 * WIN32OLE_TYPELIB#inspect -> String
813 *
814 * Returns the type library name with class name.
815 *
816 * tlib = WIN32OLE_TYPELIB.new('Microsoft Excel 9.0 Object Library')
817 * tlib.inspect # => "<#WIN32OLE_TYPELIB:Microsoft Excel 9.0 Object Library>"
818 */
819 static VALUE
820 foletypelib_inspect(VALUE self)
821 {
822 return default_inspect(self, "WIN32OLE_TYPELIB");
823 }
824
825 void
826 Init_win32ole_typelib(void)
827 {
828 cWIN32OLE_TYPELIB = rb_define_class("WIN32OLE_TYPELIB", rb_cObject);
829 rb_define_singleton_method(cWIN32OLE_TYPELIB, "typelibs", foletypelib_s_typelibs, 0);
830 rb_define_alloc_func(cWIN32OLE_TYPELIB, foletypelib_s_allocate);
831 rb_define_method(cWIN32OLE_TYPELIB, "initialize", foletypelib_initialize, -2);
832 rb_define_method(cWIN32OLE_TYPELIB, "guid", foletypelib_guid, 0);
833 rb_define_method(cWIN32OLE_TYPELIB, "name", foletypelib_name, 0);
834 rb_define_method(cWIN32OLE_TYPELIB, "version", foletypelib_version, 0);
835 rb_define_method(cWIN32OLE_TYPELIB, "major_version", foletypelib_major_version, 0);
836 rb_define_method(cWIN32OLE_TYPELIB, "minor_version", foletypelib_minor_version, 0);
837 rb_define_method(cWIN32OLE_TYPELIB, "path", foletypelib_path, 0);
838 rb_define_method(cWIN32OLE_TYPELIB, "ole_types", foletypelib_ole_types, 0);
839 rb_define_alias(cWIN32OLE_TYPELIB, "ole_classes", "ole_types");
840 rb_define_method(cWIN32OLE_TYPELIB, "visible?", foletypelib_visible, 0);
841 rb_define_method(cWIN32OLE_TYPELIB, "library_name", foletypelib_library_name, 0);
842 rb_define_alias(cWIN32OLE_TYPELIB, "to_s", "name");
843 rb_define_method(cWIN32OLE_TYPELIB, "inspect", foletypelib_inspect, 0);
844 }
rb_str_concat
VALUE rb_str_concat(VALUE, VALUE)
Definition: string.c:3065
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:649
TypedData_Make_Struct
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1244
TRUE
#define TRUE
Definition: nkf.h:175
rb_str_new2
#define rb_str_new2
Definition: intern.h:903
win32ole.h
cWIN32OLE_TYPELIB
VALUE cWIN32OLE_TYPELIB
Definition: win32ole_typelib.h:4
create_win32ole_typelib
VALUE create_win32ole_typelib(ITypeLib *pTypeLib)
Definition: win32ole_typelib.c:223
path
VALUE path
Definition: rb_mjit_min_header-2.7.0.h:7351
create_win32ole_type
VALUE create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name)
Definition: win32ole_type.c:207
VALUE
unsigned long VALUE
Definition: ruby.h:102
index
int index
Definition: rb_mjit_min_header-2.7.0.h:11246
reg_open_key
LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey)
Definition: win32ole.c:1698
DWORD
IUnknown DWORD
Definition: win32ole.c:33
reg_get_val
VALUE reg_get_val(HKEY hkey, const char *subkey)
Definition: win32ole.c:1725
rb_str_cat2
#define rb_str_cat2
Definition: intern.h:912
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1755
WC2VSTR
#define WC2VSTR(x)
Definition: win32ole.h:130
ole_initialize
void ole_initialize(void)
Definition: win32ole.c:813
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
itypelib
ITypeLib * itypelib(VALUE self)
Definition: win32ole_typelib.c:106
ptr
struct RIMemo * ptr
Definition: debug.c:74
atof
double atof(const char *__nptr)
Qfalse
#define Qfalse
Definition: ruby.h:467
OLE_RELEASE
#define OLE_RELEASE(X)
Definition: win32ole.h:98
NULL
#define NULL
Definition: _sdbm.c:101
SafeStringValue
#define SafeStringValue(v)
Definition: ruby.h:607
oletypelibdata
Definition: win32ole_typelib.c:3
eWIN32OLERuntimeError
VALUE eWIN32OLERuntimeError
Definition: win32ole_error.h:4
reg_open_vkey
LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey)
Definition: win32ole.c:1704
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1800
major
#define major(dev)
Definition: rb_mjit_min_header-2.7.0.h:1436
rb_check_arity
#define rb_check_arity
Definition: intern.h:347
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
rb_ary_entry
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1512
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.0.h:5742
lcid
static UINT LCID lcid
Definition: win32ole.c:87
reg_get_val2
VALUE reg_get_val2(HKEY hkey, const char *subkey)
Definition: win32ole.c:1753
ole_typelib_from_itypeinfo
VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo)
Definition: win32ole_typelib.c:114
RB_INT2NUM
#define RB_INT2NUM(x)
Definition: ruby.h:1597
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1195
oletypelibdata::pTypeLib
ITypeLib * pTypeLib
Definition: win32ole_typelib.c:4
StringValuePtr
#define StringValuePtr(v)
Definition: ruby.h:603
default_inspect
VALUE default_inspect(VALUE self, const char *class_name)
Definition: win32ole.c:1345
FALSE
#define FALSE
Definition: nkf.h:174
ole_wc2vstr
VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree)
Definition: win32ole.c:946
Init_win32ole_typelib
void Init_win32ole_typelib(void)
Definition: win32ole_typelib.c:826
key
key
Definition: openssl_missing.h:181
RARRAY_LEN
#define RARRAY_LEN(a)
Definition: ruby.h:1070
OLE_FREE
#define OLE_FREE(x)
Definition: win32ole.h:99
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
TypedData_Get_Struct
#define TypedData_Get_Struct(obj, type, data_type, sval)
Definition: ruby.h:1252
rb_str_append
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2965
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1197
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.0.h:13254
HRESULT
typedef HRESULT(STDAPICALLTYPE FNCOCREATEINSTANCEEX)(REFCLSID
RUBY_TYPED_FREE_IMMEDIATELY
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1207
minor
#define minor(dev)
Definition: rb_mjit_min_header-2.7.0.h:1437
free
#define free(x)
Definition: dln.c:52
err
int err
Definition: win32.c:135
rb_data_type_struct
Definition: ruby.h:1148
rb_String
VALUE rb_String(VALUE)
Equivalent to Kernel#String in Ruby.
Definition: object.c:3652
ole_vstr2wc
LPWSTR ole_vstr2wc(VALUE vstr)
Definition: win32ole.c:865
count
int count
Definition: encoding.c:57
Qtrue
#define Qtrue
Definition: ruby.h:468
len
uint8_t len
Definition: escape.c:17
cWIN32OLE_lcid
LCID cWIN32OLE_lcid
Definition: win32ole.h:116
ole_raise
void ole_raise(HRESULT hr, VALUE ecs, const char *fmt,...)
Definition: win32ole_error.c:46
reg_enum_key
VALUE reg_enum_key(HKEY hkey, DWORD i)
Definition: win32ole.c:1710
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:723
Qnil
#define Qnil
Definition: ruby.h:469
typelib_file
VALUE typelib_file(VALUE ole)
Definition: win32ole_typelib.c:781
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
rb_str_cmp
int rb_str_cmp(VALUE, VALUE)
Definition: string.c:3228
name
const char * name
Definition: nkf.c:208