Ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5ad0e4688e963d9de019557c78feed9)
win32ole_typelib.c
Go to the documentation of this file.
1#include "win32ole.h"
2
4 ITypeLib *pTypeLib;
5};
6
7static VALUE reg_get_typelib_file_path(HKEY hkey);
8static VALUE oletypelib_path(VALUE guid, VALUE version);
9static HRESULT oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib);
10static VALUE foletypelib_s_typelibs(VALUE self);
11static VALUE oletypelib_set_member(VALUE self, ITypeLib *pTypeLib);
12static void oletypelib_free(void *ptr);
13static size_t oletypelib_size(const void *ptr);
14static VALUE foletypelib_s_allocate(VALUE klass);
15static VALUE oletypelib_search_registry(VALUE self, VALUE typelib);
16static void oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr);
17static VALUE oletypelib_search_registry2(VALUE self, VALUE args);
18static VALUE foletypelib_initialize(VALUE self, VALUE args);
19static VALUE foletypelib_guid(VALUE self);
20static VALUE foletypelib_name(VALUE self);
21static VALUE make_version_str(VALUE major, VALUE minor);
22static VALUE foletypelib_version(VALUE self);
23static VALUE foletypelib_major_version(VALUE self);
24static VALUE foletypelib_minor_version(VALUE self);
25static VALUE foletypelib_path(VALUE self);
26static VALUE foletypelib_visible(VALUE self);
27static VALUE foletypelib_library_name(VALUE self);
28static VALUE ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes);
29static VALUE typelib_file_from_typelib(VALUE ole);
30static VALUE typelib_file_from_clsid(VALUE ole);
31static VALUE foletypelib_ole_types(VALUE self);
32static VALUE foletypelib_inspect(VALUE self);
33
34static const rb_data_type_t oletypelib_datatype = {
35 "win32ole_typelib",
36 {NULL, oletypelib_free, oletypelib_size,},
38};
39
40static VALUE
41reg_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
56static VALUE
57oletypelib_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
89static HRESULT
90oletypelib_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
105ITypeLib *
107{
108 struct oletypelibdata *ptlib;
109 TypedData_Get_Struct(self, struct oletypelibdata, &oletypelib_datatype, ptlib);
110 return ptlib->pTypeLib;
111}
112
113VALUE
114ole_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 }
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 */
145static VALUE
146foletypelib_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)) {
178 rb_ary_push(typelibs, typelib);
179 }
180 }
181 }
182 RegCloseKey(hguid);
183 }
184 RegCloseKey(htypelib);
185 return typelibs;
186}
187
188static VALUE
189oletypelib_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
197static void
198oletypelib_free(void *ptr)
199{
200 struct oletypelibdata *poletypelib = ptr;
201 OLE_FREE(poletypelib->pTypeLib);
202 free(poletypelib);
203}
204
205static size_t
206oletypelib_size(const void *ptr)
207{
208 return ptr ? sizeof(struct oletypelibdata) : 0;
209}
210
211static VALUE
212foletypelib_s_allocate(VALUE klass)
213{
214 struct oletypelibdata *poletypelib;
215 VALUE obj;
217 obj = TypedData_Make_Struct(klass, struct oletypelibdata, &oletypelib_datatype, poletypelib);
218 poletypelib->pTypeLib = NULL;
219 return obj;
220}
221
222VALUE
224{
225 VALUE obj = foletypelib_s_allocate(cWIN32OLE_TYPELIB);
226 oletypelib_set_member(obj, pTypeLib);
227 return obj;
228}
229
230static VALUE
231oletypelib_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
281static void
282oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr)
283{
284 HRESULT hr;
285 hr = pTypeLib->lpVtbl->GetLibAttr(pTypeLib, ppTLibAttr);
286 if (FAILED(hr)) {
288 "failed to get library attribute(TLIBATTR) from ITypeLib");
289 }
290}
291
292static VALUE
293oletypelib_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 */
391static VALUE
392foletypelib_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 */
438static VALUE
439foletypelib_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 */
466static VALUE
467foletypelib_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
484static VALUE
485make_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 */
510static VALUE
511foletypelib_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 */
533static VALUE
534foletypelib_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 */
556static VALUE
557foletypelib_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 */
578static VALUE
579foletypelib_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 */
618static VALUE
619foletypelib_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 */
647static VALUE
648foletypelib_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
665static VALUE
666ole_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
694static VALUE
695typelib_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
752static VALUE
753typelib_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
780VALUE
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 */
800static VALUE
801foletypelib_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 */
819static VALUE
820foletypelib_inspect(VALUE self)
821{
822 return default_inspect(self, "WIN32OLE_TYPELIB");
823}
824
826
827void
829{
830 cWIN32OLE_TYPELIB = rb_define_class("WIN32OLE_TYPELIB", rb_cObject);
831 rb_define_singleton_method(cWIN32OLE_TYPELIB, "typelibs", foletypelib_s_typelibs, 0);
832 rb_define_alloc_func(cWIN32OLE_TYPELIB, foletypelib_s_allocate);
833 rb_define_method(cWIN32OLE_TYPELIB, "initialize", foletypelib_initialize, -2);
834 rb_define_method(cWIN32OLE_TYPELIB, "guid", foletypelib_guid, 0);
835 rb_define_method(cWIN32OLE_TYPELIB, "name", foletypelib_name, 0);
836 rb_define_method(cWIN32OLE_TYPELIB, "version", foletypelib_version, 0);
837 rb_define_method(cWIN32OLE_TYPELIB, "major_version", foletypelib_major_version, 0);
838 rb_define_method(cWIN32OLE_TYPELIB, "minor_version", foletypelib_minor_version, 0);
839 rb_define_method(cWIN32OLE_TYPELIB, "path", foletypelib_path, 0);
840 rb_define_method(cWIN32OLE_TYPELIB, "ole_types", foletypelib_ole_types, 0);
841 rb_define_alias(cWIN32OLE_TYPELIB, "ole_classes", "ole_types");
842 rb_define_method(cWIN32OLE_TYPELIB, "visible?", foletypelib_visible, 0);
843 rb_define_method(cWIN32OLE_TYPELIB, "library_name", foletypelib_library_name, 0);
844 rb_define_alias(cWIN32OLE_TYPELIB, "to_s", "name");
845 rb_define_method(cWIN32OLE_TYPELIB, "inspect", foletypelib_inspect, 0);
846}
struct RIMemo * ptr
Definition: debug.c:65
#define free(x)
Definition: dln.c:52
int count
Definition: encoding.c:57
VALUE rb_define_class(const char *, VALUE)
Defines a top-level class.
Definition: class.c:662
void rb_define_alias(VALUE, const char *, const char *)
Defines an alias of a method.
Definition: class.c:1818
VALUE rb_cObject
Object class.
Definition: ruby.h:2012
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2671
VALUE rb_String(VALUE)
Equivalent to Kernel#String in Ruby.
Definition: object.c:3652
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
const char * name
Definition: nkf.c:208
#define RARRAY_LEN(a)
#define SafeStringValue(v)
#define rb_str_new2
#define NULL
#define StringValuePtr(v)
VALUE rb_str_concat(VALUE, VALUE)
Definition: string.c:3065
#define minor(dev)
#define rb_str_cat2
const VALUE VALUE obj
VALUE rb_ary_push(VALUE, VALUE)
Definition: array.c:1195
#define RB_INT2NUM(v)
double atof(const char *__nptr)
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
uint32_t i
__inline__ const void *__restrict__ size_t len
void rb_define_singleton_method(VALUE, const char *, VALUE(*)(), int)
#define RUBY_TYPED_FREE_IMMEDIATELY
#define TypedData_Get_Struct(obj, type, data_type, sval)
VALUE rb_ary_new(void)
Definition: array.c:723
#define TRUE
#define FALSE
int rb_str_cmp(VALUE, VALUE)
Definition: string.c:3228
#define Qtrue
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2965
#define major(dev)
#define Qnil
#define Qfalse
#define TypedData_Make_Struct(klass, type, data_type, sval)
#define rb_check_arity
VALUE rb_sprintf(const char *,...) __attribute__((format(printf
void rb_define_method(VALUE, const char *, VALUE(*)(), int)
VALUE rb_ary_entry(VALUE, long)
Definition: array.c:1512
unsigned long VALUE
Definition: ruby.h:102
ITypeLib * pTypeLib
LPWSTR ole_vstr2wc(VALUE vstr)
Definition: win32ole.c:865
VALUE reg_get_val2(HKEY hkey, const char *subkey)
Definition: win32ole.c:1753
LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey)
Definition: win32ole.c:1698
typedef HRESULT(STDAPICALLTYPE FNCOCREATEINSTANCEEX)(REFCLSID
VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree)
Definition: win32ole.c:946
VALUE default_inspect(VALUE self, const char *class_name)
Definition: win32ole.c:1345
VALUE reg_get_val(HKEY hkey, const char *subkey)
Definition: win32ole.c:1725
void ole_initialize(void)
Definition: win32ole.c:813
IUnknown DWORD
Definition: win32ole.c:33
LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey)
Definition: win32ole.c:1704
LCID cWIN32OLE_lcid
Definition: win32ole.c:3965
VALUE reg_enum_key(HKEY hkey, DWORD i)
Definition: win32ole.c:1710
static UINT LCID lcid
Definition: win32ole.c:87
#define OLE_RELEASE(X)
Definition: win32ole.h:98
#define OLE_FREE(x)
Definition: win32ole.h:99
#define WC2VSTR(x)
Definition: win32ole.h:130
VALUE eWIN32OLERuntimeError
void ole_raise(HRESULT hr, VALUE ecs, const char *fmt,...)
VALUE create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name)
VALUE ole_typelib_from_itypeinfo(ITypeInfo *pTypeInfo)
void Init_win32ole_typelib(void)
VALUE cWIN32OLE_TYPELIB
VALUE typelib_file(VALUE ole)
VALUE create_win32ole_typelib(ITypeLib *pTypeLib)
ITypeLib * itypelib(VALUE self)