win32ole 1.8.8

Sign up to get free protection for your applications and to get access to all the features.
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
+ }