win32ole 1.8.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +56 -0
  7. data/Rakefile +10 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/ext/win32ole/depend +12 -0
  11. data/ext/win32ole/extconf.rb +45 -0
  12. data/ext/win32ole/sample/excel1.rb +37 -0
  13. data/ext/win32ole/sample/excel2.rb +31 -0
  14. data/ext/win32ole/sample/excel3.rb +21 -0
  15. data/ext/win32ole/sample/ie.rb +12 -0
  16. data/ext/win32ole/sample/ieconst.rb +33 -0
  17. data/ext/win32ole/sample/ienavi.rb +41 -0
  18. data/ext/win32ole/sample/ienavi2.rb +41 -0
  19. data/ext/win32ole/sample/oledirs.rb +24 -0
  20. data/ext/win32ole/sample/olegen.rb +348 -0
  21. data/ext/win32ole/sample/xml.rb +7307 -0
  22. data/ext/win32ole/win32ole.c +4140 -0
  23. data/ext/win32ole/win32ole.h +155 -0
  24. data/ext/win32ole/win32ole_error.c +84 -0
  25. data/ext/win32ole/win32ole_error.h +9 -0
  26. data/ext/win32ole/win32ole_event.c +1277 -0
  27. data/ext/win32ole/win32ole_event.h +6 -0
  28. data/ext/win32ole/win32ole_method.c +950 -0
  29. data/ext/win32ole/win32ole_method.h +16 -0
  30. data/ext/win32ole/win32ole_param.c +438 -0
  31. data/ext/win32ole/win32ole_param.h +8 -0
  32. data/ext/win32ole/win32ole_record.c +604 -0
  33. data/ext/win32ole/win32ole_record.h +10 -0
  34. data/ext/win32ole/win32ole_type.c +915 -0
  35. data/ext/win32ole/win32ole_type.h +8 -0
  36. data/ext/win32ole/win32ole_typelib.c +844 -0
  37. data/ext/win32ole/win32ole_typelib.h +11 -0
  38. data/ext/win32ole/win32ole_variable.c +380 -0
  39. data/ext/win32ole/win32ole_variable.h +8 -0
  40. data/ext/win32ole/win32ole_variant.c +733 -0
  41. data/ext/win32ole/win32ole_variant.h +9 -0
  42. data/ext/win32ole/win32ole_variant_m.c +149 -0
  43. data/ext/win32ole/win32ole_variant_m.h +7 -0
  44. data/lib/win32ole.rb +33 -0
  45. data/lib/win32ole/property.rb +17 -0
  46. data/win32ole.gemspec +22 -0
  47. metadata +91 -0
@@ -0,0 +1,8 @@
1
+ #ifndef WIN32OLE_TYPE_H
2
+ #define WIN32OLE_TYPE_H 1
3
+ VALUE cWIN32OLE_TYPE;
4
+ VALUE create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name);
5
+ ITypeInfo *itypeinfo(VALUE self);
6
+ VALUE ole_type_from_itypeinfo(ITypeInfo *pTypeInfo);
7
+ void Init_win32ole_type(void);
8
+ #endif
@@ -0,0 +1,844 @@
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
+ }