ruby-changes:35006
From: suke <ko1@a...>
Date: Wed, 6 Aug 2014 21:00:20 +0900 (JST)
Subject: [ruby-changes:35006] suke:r47088 (trunk): * ext/win32ole/win32ole.c: separate src of WIN32OLE_TYPELIB from
suke 2014-08-06 21:00:09 +0900 (Wed, 06 Aug 2014) New Revision: 47088 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47088 Log: * ext/win32ole/win32ole.c: separate src of WIN32OLE_TYPELIB from win32ole.c * ext/win32ole/win32ole.h: ditto. * ext/win32ole/win32ole_typelib.c: ditto. * ext/win32ole/win32ole_typelib.h: ditto. * ext/win32ole/depend: ditto. Added files: trunk/ext/win32ole/win32ole_typelib.c trunk/ext/win32ole/win32ole_typelib.h Modified files: trunk/ChangeLog trunk/ext/win32ole/depend trunk/ext/win32ole/win32ole.c trunk/ext/win32ole/win32ole.h Index: ChangeLog =================================================================== --- ChangeLog (revision 47087) +++ ChangeLog (revision 47088) @@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Aug 6 20:56:02 2014 Masaki Suketa <masaki.suketa@n...> + + * ext/win32ole/win32ole.c: separate src of WIN32OLE_TYPELIB from + win32ole.c + + * ext/win32ole/win32ole.h: ditto. + * ext/win32ole/win32ole_typelib.c: ditto. + * ext/win32ole/win32ole_typelib.h: ditto. + * ext/win32ole/depend: ditto. + Wed Aug 6 20:44:07 2014 Akinori MUSHA <knu@i...> * enum.c (enum_one): [DOC] Move enum.one? documentation before the Index: ext/win32ole/depend =================================================================== --- ext/win32ole/depend (revision 47087) +++ ext/win32ole/depend (revision 47088) @@ -2,3 +2,4 @@ WIN32OLE_HEADERS = $(HDRS) $(ruby_header https://github.com/ruby/ruby/blob/trunk/ext/win32ole/depend#L2 win32ole.o : win32ole.c $(WIN32OLE_HEADERS) win32ole_variant_m.o : win32ole_variant_m.c $(WIN32OLE_HEADERS) win32ole_error.o : win32ole_error.c $(WIN32OLE_HEADERS) +win32ole_typelib.o : win32ole_typelib.c $(WIN32OLE_HEADERS) Index: ext/win32ole/win32ole_typelib.h =================================================================== --- ext/win32ole/win32ole_typelib.h (revision 0) +++ ext/win32ole/win32ole_typelib.h (revision 47088) @@ -0,0 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole_typelib.h#L1 +#ifndef WIN32OLE_TYPELIB_H +#define WIN32OLE_TYPELIB_H 1 + +VALUE cWIN32OLE_TYPELIB; + +void Init_win32ole_typelib(); +ITypeLib * itypelib(VALUE self); +VALUE typelib_file(VALUE ole); +VALUE create_win32ole_typelib(ITypeLib *pTypeLib); +#endif Index: ext/win32ole/win32ole.c =================================================================== --- ext/win32ole/win32ole.c (revision 47087) +++ ext/win32ole/win32ole.c (revision 47088) @@ -26,21 +26,12 @@ https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L26 const IID IID_IMultiLanguage2 = {0xDCCFC164, 0x2B38, 0x11d2, {0xB7, 0xEC, 0x00, 0xC0, 0x4F, 0x8F, 0x5D, 0x9A}}; #endif -#define OLE_RELEASE(X) (X) ? ((X)->lpVtbl->Release(X)) : 0 #define OLE_ADDREF(X) (X) ? ((X)->lpVtbl->AddRef(X)) : 0 #define OLE_GET_TYPEATTR(X, Y) ((X)->lpVtbl->GetTypeAttr((X), (Y))) #define OLE_RELEASE_TYPEATTR(X, Y) ((X)->lpVtbl->ReleaseTypeAttr((X), (Y))) -#define OLE_FREE(x) {\ - if(g_ole_initialized == TRUE) {\ - if(x) {\ - OLE_RELEASE(x);\ - (x) = 0;\ - }\ - }\ -} #define OLEData_Get_Struct(obj, pole) {\ Data_Get_Struct(obj, struct oledata, pole);\ @@ -61,9 +52,7 @@ const IID IID_IMultiLanguage2 = {0xDCCFC https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L52 #define NUM2UI8 NUM2UINT #endif -#define WC2VSTR(x) ole_wc2vstr((x), TRUE) - -#define WIN32OLE_VERSION "1.7.4" +#define WIN32OLE_VERSION "1.7.6" typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX) (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); @@ -121,8 +110,6 @@ typedef struct tagIEVENTSINKOBJ { https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L110 }IEVENTSINKOBJ, *PIEVENTSINKOBJ; VALUE cWIN32OLE; -VALUE cWIN32OLE_TYPELIB; -VALUE cWIN32OLE_TYPE; VALUE cWIN32OLE_VARIABLE; VALUE cWIN32OLE_METHOD; VALUE cWIN32OLE_PARAM; @@ -143,6 +130,7 @@ static volatile DWORD g_ole_initialized_ https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L130 # define g_ole_initialized_init() (g_ole_initialized_key = TlsAlloc()) # define g_ole_initialized_set(val) TlsSetValue(g_ole_initialized_key, (void*)(val)) #endif + static BOOL g_uninitialize_hooked = FALSE; static BOOL g_cp_installed = FALSE; static BOOL g_lcid_installed = FALSE; @@ -173,10 +161,6 @@ struct oledata { https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L161 IDispatch *pDispatch; }; -struct oletypelibdata { - ITypeLib *pTypeLib; -}; - struct oletypedata { ITypeInfo *pTypeInfo; }; @@ -239,17 +223,13 @@ static UINT ole_init_cp(void); https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L223 static char *ole_wc2mb(LPWSTR pw); static void ole_freeexceptinfo(EXCEPINFO *pExInfo); static VALUE ole_excepinfo2msg(EXCEPINFO *pExInfo); -static void ole_initialize(void); static void ole_msg_loop(void); static void ole_free(struct oledata *pole); -static void oletypelib_free(struct oletypelibdata *poletypelib); static void oletype_free(struct oletypedata *poletype); static void olemethod_free(struct olemethoddata *polemethod); static void olevariable_free(struct olevariabledata *polevar); static void oleparam_free(struct oleparamdata *pole); -static LPWSTR ole_vstr2wc(VALUE vstr); static LPWSTR ole_mb2wc(char *pm, int len); -static VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree); static VALUE ole_ary_m_entry(VALUE val, LONG *pid); static void * get_ptr_of_variant(VARIANT *pvar); static VALUE is_all_index_under(LONG *pid, long *pub, long dim); @@ -266,28 +246,18 @@ static void ole_set_byref(VARIANT *realv https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L246 static void ole_val2olevariantdata(VALUE val, VARTYPE vt, struct olevariantdata *pvar); static void ole_val2variant2(VALUE val, VARIANT *var); static VALUE make_inspect(const char *class_name, VALUE detail); -static VALUE default_inspect(VALUE self, const char *class_name); static VALUE ole_set_member(VALUE self, IDispatch *dispatch); static VALUE fole_s_allocate(VALUE klass); static VALUE create_win32ole_object(VALUE klass, IDispatch *pDispatch, int argc, VALUE *argv); static VALUE ary_new_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim); static void ary_store_dim(VALUE myary, LONG *pid, LONG *plb, LONG dim, VALUE val); static VALUE ole_variant2val(VARIANT *pvar); -static LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey); -static LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey); -static VALUE reg_enum_key(HKEY hkey, DWORD i); -static VALUE reg_get_val(HKEY hkey, const char *subkey); -static VALUE reg_get_typelib_file_path(HKEY hkey); -static VALUE typelib_file_from_clsid(VALUE ole); -static VALUE typelib_file_from_typelib(VALUE ole); -static VALUE typelib_file(VALUE ole); static void ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self); static HRESULT clsid_from_remote(VALUE host, VALUE com, CLSID *pclsid); static VALUE ole_create_dcom(int argc, VALUE *argv, VALUE self); static VALUE ole_bind_obj(VALUE moniker, int argc, VALUE *argv, VALUE self); static VALUE fole_s_connect(int argc, VALUE *argv, VALUE self); static VALUE fole_s_const_load(int argc, VALUE *argv, VALUE self); -static VALUE ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes); static ULONG reference_count(struct oledata * pole); static VALUE fole_s_reference_count(VALUE self, VALUE obj); static VALUE fole_s_free(VALUE self, VALUE obj); @@ -350,27 +320,6 @@ static VALUE foletype_s_progids(VALUE se https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L320 static VALUE foletype_s_allocate(VALUE klass); static VALUE oletype_set_member(VALUE self, ITypeInfo *pTypeInfo, VALUE name); static VALUE oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass); -static VALUE oletypelib_set_member(VALUE self, ITypeLib *pTypeLib); -static ITypeLib * oletypelib_get_typelib(VALUE self); -static void oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr); -static VALUE foletypelib_s_typelibs(VALUE self); -static VALUE make_version_str(VALUE major, VALUE minor); -static VALUE oletypelib_search_registry2(VALUE self, VALUE args); -static VALUE oletypelib_search_registry(VALUE self, VALUE typelib); -static VALUE foletypelib_s_allocate(VALUE klass); -static VALUE foletypelib_initialize(VALUE self, VALUE args); -static VALUE foletypelib_guid(VALUE self); -static VALUE foletypelib_name(VALUE self); -static VALUE foletypelib_version(VALUE self); -static VALUE foletypelib_major_version(VALUE self); -static VALUE foletypelib_minor_version(VALUE self); -static VALUE oletypelib_path(VALUE guid, VALUE version); -static HRESULT oletypelib_from_guid(VALUE guid, VALUE version, ITypeLib **ppTypeLib); -static VALUE foletypelib_path(VALUE self); -static VALUE foletypelib_visible(VALUE self); -static VALUE foletypelib_library_name(VALUE self); -static VALUE foletypelib_ole_types(VALUE self); -static VALUE foletypelib_inspect(VALUE self); static VALUE foletype_initialize(VALUE self, VALUE typelib, VALUE oleclass); static VALUE foletype_name(VALUE self); static VALUE ole_ole_type(ITypeInfo *pTypeInfo); @@ -740,6 +689,12 @@ static /* [local] */ HRESULT ( STDMETHOD https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L689 return S_OK; } +BOOL +ole_initialized() +{ + return g_ole_initialized; +} + static IDispatch* val2dispatch(VALUE val) { @@ -1115,7 +1070,7 @@ ole_uninitialize_hook(rb_event_flag_t ev https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L1070 ole_uninitialize(); } -static void +void ole_initialize(void) { HRESULT hr; @@ -1157,13 +1112,6 @@ ole_free(struct oledata *pole) https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L1112 } static void -oletypelib_free(struct oletypelibdata *poletypelib) -{ - OLE_FREE(poletypelib->pTypeLib); - free(poletypelib); -} - -static void oletype_free(struct oletypedata *poletype) { OLE_FREE(poletype->pTypeInfo); @@ -1193,7 +1141,7 @@ oleparam_free(struct oleparamdata *pole) https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L1141 } -static LPWSTR +LPWSTR ole_vstr2wc(VALUE vstr) { rb_encoding *enc; @@ -1284,7 +1232,7 @@ ole_alloc_vstr(UINT size, void *arg) https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L1232 return RSTRING_PTR(str); } -static VALUE +VALUE ole_wc2vstr(LPWSTR pw, BOOL isfree) { VALUE vstr; @@ -1965,7 +1913,7 @@ make_inspect(const char *class_name, VAL https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L1913 return str; } -static VALUE +VALUE default_inspect(VALUE self, const char *class_name) { VALUE detail = rb_funcall(self, rb_intern("to_s"), 0); @@ -2315,19 +2263,19 @@ ole_variant2val(VARIANT *pvar) https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L2263 return obj; } -static LONG +LONG reg_open_key(HKEY hkey, const char *name, HKEY *phkey) { return RegOpenKeyEx(hkey, name, 0, KEY_READ, phkey); } -static LONG +LONG reg_open_vkey(HKEY hkey, VALUE key, HKEY *phkey) { return reg_open_key(hkey, StringValuePtr(key), phkey); } -static VALUE +VALUE reg_enum_key(HKEY hkey, DWORD i) { char buf[BUFSIZ + 1]; @@ -2342,7 +2290,7 @@ reg_enum_key(HKEY hkey, DWORD i) https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L2290 return Qnil; } -static VALUE +VALUE reg_get_val(HKEY hkey, const char *subkey) { char *pbuf; @@ -2370,7 +2318,7 @@ reg_get_val(HKEY hkey, const char *subke https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L2318 return val; } -static VALUE +VALUE reg_get_val2(HKEY hkey, const char *subkey) { HKEY hsubkey; @@ -2387,118 +2335,6 @@ reg_get_val2(HKEY hkey, const char *subk https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L2335 return val; } -static VALUE -reg_get_typelib_file_path(HKEY hkey) -{ - VALUE path = Qnil; - path = reg_get_val2(hkey, "win64"); - if (path != Qnil) { - return path; - } - path = reg_get_val2(hkey, "win32"); - if (path != Qnil) { - return path; - } - path = reg_get_val2(hkey, "win16"); - return path; -} - -static VALUE -typelib_file_from_clsid(VALUE ole) -{ - HKEY hroot, hclsid; - LONG err; - VALUE typelib; - char path[MAX_PATH + 1]; - - err = reg_open_key(HKEY_CLASSES_ROOT, "CLSID", &hroot); - if (err != ERROR_SUCCESS) { - return Qnil; - } - err = reg_open_key(hroot, StringValuePtr(ole), &hclsid); - if (err != ERROR_SUCCESS) { - RegCloseKey(hroot); - return Qnil; - } - typelib = reg_get_val2(hclsid, "InprocServer32"); - RegCloseKey(hroot); - RegCloseKey(hclsid); - if (typelib != Qnil) { - ExpandEnvironmentStrings(StringValuePtr(typelib), path, sizeof(path)); - path[MAX_PATH] = '\0'; - typelib = rb_str_new2(path); - } - return typelib; -} - -static VALUE -typelib_file_from_typelib(VALUE ole) -{ - HKEY htypelib, hclsid, hversion, hlang; - double fver; - DWORD i, j, k; - LONG err; - BOOL found = FALSE; - VALUE typelib; - VALUE file = Qnil; - VALUE clsid; - VALUE ver; - VALUE lang; - - err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib); - if(err != ERROR_SUCCESS) { - return Qnil; - } - for(i = 0; !found; i++) { - clsid = reg_enum_key(htypelib, i); - if (clsid == Qnil) - break; - err = reg_open_vkey(htypelib, clsid, &hclsid); - if (err != ERROR_SUCCESS) - continue; - fver = 0; - for(j = 0; !found; j++) { - ver = reg_enum_key(hclsid, j); - if (ver == Qnil) - break; - err = reg_open_vkey(hclsid, ver, &hversion); - if (err != ERROR_SUCCESS || fver > atof(StringValuePtr(ver))) - continue; - fver = atof(StringValuePtr(ver)); - typelib = reg_get_val(hversion, NULL); - if (typelib == Qnil) - continue; - if (rb_str_cmp(typelib, ole) == 0) { - for(k = 0; !found; k++) { - lang = reg_enum_key(hversion, k); - if (lang == Qnil) - break; - err = reg_open_vkey(hversion, lang, &hlang); - if (err == ERROR_SUCCESS) { - if ((file = reg_get_typelib_file_path(hlang)) != Qnil) - found = TRUE; - RegCloseKey(hlang); - } - } - } - RegCloseKey(hversion); - } - RegCloseKey(hclsid); - } - RegCloseKey(htypelib); - return file; -} - -static VALUE -typelib_file(VALUE ole) -{ - VALUE file = typelib_file_from_clsid(ole); - if (file != Qnil) { - return file; - } - return typelib_file_from_typelib(ole); -} - static void ole_const_load(ITypeLib *pTypeLib, VALUE klass, VALUE self) { @@ -2847,37 +2683,6 @@ fole_s_const_load(int argc, VALUE *argv, https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L2683 return Qnil; } -static VALUE -ole_types_from_typelib(ITypeLib *pTypeLib, VALUE classes) -{ - - long count; - int i; - HRESULT hr; - BSTR bstr; - ITypeInfo *pTypeInfo; - VALUE type; - - count = pTypeLib->lpVtbl->GetTypeInfoCount(pTypeLib); - for (i = 0; i < count; i++) { - hr = pTypeLib->lpVtbl->GetDocumentation(pTypeLib, i, - &bstr, NULL, NULL, NULL); - if (FAILED(hr)) - continue; - - hr = pTypeLib->lpVtbl->GetTypeInfo(pTypeLib, i, &pTypeInfo); - if (FAILED(hr)) - continue; - - type = foletype_s_allocate(cWIN32OLE_TYPE); - oletype_set_member(type, pTypeInfo, WC2VSTR(bstr)); - - rb_ary_push(classes, type); - OLE_RELEASE(pTypeInfo); - } - return classes; -} - static ULONG reference_count(struct oledata * pole) { @@ -4427,8 +4232,7 @@ ole_typelib_from_itypeinfo(ITypeInfo *pT https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L4232 if(FAILED(hr)) { return Qnil; } - retval = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("allocate"), 0); - oletypelib_set_member(retval, pTypeLib); + retval = create_win32ole_typelib(pTypeLib); return retval; } @@ -4901,6 +4705,14 @@ oletype_set_member(VALUE self, ITypeInfo https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L4705 return self; } +VALUE +create_win32ole_type(ITypeInfo *pTypeInfo, VALUE name) +{ + VALUE obj = foletype_s_allocate(cWIN32OLE_TYPE); + oletype_set_member(obj, pTypeInfo, name); + return obj; +} + static VALUE oleclass_from_typelib(VALUE self, ITypeLib *pTypeLib, VALUE oleclass) { @@ -4934,616 +4746,6 @@ oleclass_from_typelib(VALUE self, ITypeL https://github.com/ruby/ruby/blob/trunk/ext/win32ole/win32ole.c#L4746 } /* - * Document-class: WIN32OLE_TYPELIB - * - * <code>WIN32OLE_TYPELIB</code> objects represent OLE tyblib information. - */ - -static VALUE -oletypelib_set_member(VALUE self, ITypeLib *pTypeLib) -{ - struct oletypelibdata *ptlib; - Data_Get_Struct(self, struct oletypelibdata, ptlib); - ptlib->pTypeLib = pTypeLib; - return self; -} - -static ITypeLib * -oletypelib_get_typelib(VALUE self) -{ - struct oletypelibdata *ptlib; - Data_Get_Struct(self, struct oletypelibdata, ptlib); - return ptlib->pTypeLib; -} - -static void -oletypelib_get_libattr(ITypeLib *pTypeLib, TLIBATTR **ppTLibAttr) -{ - HRESULT hr; - hr = pTypeLib->lpVtbl->GetLibAttr(pTypeLib, ppTLibAttr); - if (FAILED(hr)) { - ole_raise(hr, eWIN32OLERuntimeError, - "failed to get library attribute(TLIBATTR) from ITypeLib"); - } -} - -/* - * call-seq: - * - * WIN32OLE_TYPELIB.typelibs - * - * Returns the array of WIN32OLE_TYPELIB object. - * - * tlibs = WIN32OLE_TYPELIB.typelibs - * - */ -static VALUE -foletypelib_s_typelibs(VALUE self) -{ - HKEY htypelib, hguid; - DWORD i, j; - LONG err; - VALUE guid; - VALUE version; - VALUE name = Qnil; - VALUE typelibs = rb_ary_new(); - VALUE typelib = Qnil; - HRESULT hr; - ITypeLib *pTypeLib; - - err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib); - if(err != ERROR_SUCCESS) { - return typelibs; - } - for(i = 0; ; i++) { - guid = reg_enum_key(htypelib, i); - if (guid == Qnil) - break; - err = reg_open_vkey(htypelib, guid, &hguid); - if (err != ERROR_SUCCESS) - continue; - for(j = 0; ; j++) { - version = reg_enum_key(hguid, j); - if (version == Qnil) - break; - if ( (name = reg_get_val2(hguid, StringValuePtr(version))) != Qnil ) { - hr = oletypelib_from_guid(guid, version, &pTypeLib); - if (SUCCEEDED(hr)) { - typelib = rb_funcall(cWIN32OLE_TYPELIB, rb_intern("allocate"), 0); - oletypelib_set_member(typelib, pTypeLib); - rb_ary_push(typelibs, typelib); - } - } - } - RegCloseKey(hguid); - } - RegCloseKey(htypelib); - return typelibs; -} - -static VALUE -make_version_str(VALUE major, VALUE minor) -{ - VALUE version_str = Qnil; - VALUE minor_str = Qnil; - if (major == Qnil) { - return Qnil; - } - version_str = rb_String(major); - if (minor != Qnil) { - minor_str = rb_String(minor); - rb_str_cat2(version_str, "."); - rb_str_append(version_str, minor_str); - } - return version_str; -} - -static VALUE -oletypelib_search_registry2(VALUE self, VALUE args) -{ - HKEY htypelib, hguid, hversion; - double fver; - DWORD j; - LONG err; - VALUE found = Qfalse; - VALUE tlib; - VALUE ver; - VALUE version_str; - VALUE version = Qnil; - VALUE typelib = Qnil; - HRESULT hr; - ITypeLib *pTypeLib; - - VALUE guid = rb_ary_entry(args, 0); - version_str = make_version_str(rb_ary_entry(args, 1), rb_ary_entry(args, 2)); - - err = reg_open_key(HKEY_CLASSES_ROOT, "TypeLib", &htypelib); - if(err != ERROR_SUCCESS) { - return Qfalse; - } - err = reg_open_vkey(htypelib, guid, &hguid); - if (err != ERROR_SUCCESS) { - RegCloseKey(htypelib); - return Qfalse; - } - if (version_str != Qnil) { - err = reg_open_vkey(hguid, version_str, &hversion); - if (err == ERROR_SUCCESS) { - tlib = reg_get_val(hv (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/