Windows allows the registration of 64bit typelibs from 32bit programs even on a pure Win32 install.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51864
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/oleaut32/tests/typelib.c | 175 ++++++++++++++++++++++++++++++++++ dlls/oleaut32/typelib.c | 4 - 2 files changed, 175 insertions(+), 4 deletions(-)
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index 825851c948e..bf38e71a259 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -6848,6 +6848,180 @@ static void test_register_typelib(BOOL system_registration) DeleteFileW(filename); }
+static void test_RegisterTypeLib64(void) +{ + ITypeInfo *unknown, *tinfo; + ICreateTypeLib2 *createtl; + ICreateTypeInfo *createti, *createti_co; + ITypeLib *stdole, *typeLib; + FUNCDESC funcdesc, funcdesc2; + ELEMDESC elemdesc[5], elemdesc2[5]; + HREFTYPE hreftype; + HRESULT hr; + char filename[MAX_PATH]; + WCHAR filenameW[MAX_PATH]; + + static const WCHAR wszStdOle2[] = { 's','t','d','o','l','e','2','.','t','l','b',0 }; + + static OLECHAR typelibW[] = { 'W','i','n','e','T','e','s','t','T','y','p','e','L','i','b',0}; + static OLECHAR helpfileW[] = { 'C',':','\','b','o','g','u','s','.','h','l','p',0 }; + static OLECHAR dllfileW[] = { 'C',':','\','b','o','g','u','s','.','d','l','l',0 }; + static OLECHAR interface1W[] = { 'I','T','e','s','t','W','i','n','e','6', '4', 0}; + static OLECHAR coclassW[] = {'W','i','n','e','T','e','s','t','C','o','c','l','a','s','s',0 }; + static OLECHAR func1W[] = { 'f','u','n','c','1',0 }; + static OLECHAR func2W[] = { 'f','u','n','c','2',0 }; + static OLECHAR param1W[] = { 'p','a','r','a','m','1',0 }; + static OLECHAR param2W[] = { 'p','a','r','a','m','2',0 }; + static OLECHAR *names1[] = { func1W, param1W, param2W }; + static OLECHAR *names2[] = { func2W, param1W }; + static const GUID tlcustguid = { 0x512d2fec,0xcaf6,0x4c33,{0xbc,0x38,0x84,0x2f,0x2e,0x37,0x0d,0x7b} }; + static const GUID coclassguid = { 0x317cd4dd,0x0ce0,0x4525,{0x8d,0x33,0x68,0x14,0x4c,0x53,0x60,0xe9} }; + static const GUID interfaceguid = { 0x35cc5cea,0x11cc,0x4bca,{0x89,0x8c,0xf8,0x92,0x8e,0xb8,0xda,0x24} }; + + const SYSKIND sys = SYS_WIN64; + + hr = LoadTypeLib(wszStdOle2, &stdole); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ITypeLib_GetTypeInfoOfGuid(stdole, &IID_IDispatch, &unknown); + ok(hr == S_OK, "got %08x\n", hr); + + GetTempFileNameA(".", "tlb", 0, filename); + MultiByteToWideChar(CP_ACP, 0, filename, -1, filenameW, MAX_PATH); + + hr = CreateTypeLib2(sys, filenameW, &createtl); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeLib2_SetName(createtl, typelibW); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeLib2_SetHelpFileName(createtl, helpfileW); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeLib2_SetHelpStringDll(createtl, dllfileW); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeLib2_SetGuid(createtl, &tlcustguid); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeLib2_SetVersion(createtl, 1, 0); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeLib2_CreateTypeInfo(createtl, coclassW, TKIND_COCLASS, &createti_co); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeLib2_CreateTypeInfo(createtl, interface1W, TKIND_INTERFACE, &createti); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_LayOut(createti); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_SetGuid(createti, &interfaceguid); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_SetVersion(createti, 1, 0); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_AddRefTypeInfo(createti, unknown, &hreftype); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_AddImplType(createti, 0, hreftype); + ok(hr == S_OK, "got %08x\n", hr); + + elemdesc[0].tdesc.vt = VT_UINT; + U(elemdesc[0]).idldesc.dwReserved = 0; + U(elemdesc[0]).idldesc.wIDLFlags = IDLFLAG_FIN; + + elemdesc[1].tdesc.vt = VT_DECIMAL; + U(elemdesc[1]).idldesc.dwReserved = 0; + U(elemdesc[1]).idldesc.wIDLFlags = IDLFLAG_FIN; + + memset(&funcdesc, 0, sizeof(FUNCDESC)); + funcdesc.funckind = FUNC_PUREVIRTUAL; + funcdesc.invkind = INVOKE_FUNC; + funcdesc.callconv = CC_STDCALL; + funcdesc.cParams = 2; + funcdesc.memid = 0x1; + funcdesc.elemdescFunc.tdesc.vt = VT_HRESULT; + funcdesc.lprgelemdescParam = elemdesc; + + hr = ICreateTypeInfo_AddFuncDesc(createti, 0, &funcdesc); + ok(hr == S_OK, "got %08x\n", hr); + + elemdesc2[0].tdesc.vt = VT_UINT; + U(elemdesc2[0]).idldesc.dwReserved = 0; + U(elemdesc2[0]).idldesc.wIDLFlags = IDLFLAG_FIN | IDLFLAG_FOUT; + + memset(&funcdesc2, 0, sizeof(FUNCDESC)); + funcdesc2.funckind = FUNC_PUREVIRTUAL; + funcdesc2.invkind = INVOKE_FUNC; + funcdesc.callconv = CC_STDCALL; + funcdesc2.cParams = 1; + funcdesc2.memid = 0x2; + funcdesc2.elemdescFunc.tdesc.vt = VT_HRESULT; + funcdesc2.lprgelemdescParam = elemdesc2; + + hr = ICreateTypeInfo_AddFuncDesc(createti, 1, &funcdesc2); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_SetFuncHelpContext(createti, 0, 0xabcdefab); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_SetFuncHelpContext(createti, 1, 0xabcdefab); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_SetFuncAndParamNames(createti, 0, names1, 3); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_SetFuncAndParamNames(createti, 1, names2, 2); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_SetTypeFlags(createti, TYPEFLAG_FOLEAUTOMATION | TYPEFLAG_FNONEXTENSIBLE | TYPEFLAG_FDUAL); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_QueryInterface(createti, &IID_ITypeInfo, (void**)&tinfo); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ITypeInfo_GetRefTypeOfImplType(tinfo, 0, &hreftype); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_SetGuid(createti_co, &coclassguid); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_AddRefTypeInfo(createti_co, tinfo, &hreftype); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_AddImplType(createti_co, 0, hreftype); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_SetImplTypeFlags(createti_co, 0, IMPLTYPEFLAG_FDEFAULT); + ok(hr == S_OK, "got %08x\n", hr); + + hr = ICreateTypeInfo_Release(createti_co); + ok(hr == S_OK, "got %08x\n", hr); + + ICreateTypeInfo_Release(createti); + + hr = ICreateTypeLib2_SaveAllChanges(createtl); + ok(hr == S_OK, "got %08x\n", hr); + + ICreateTypeLib2_Release(createtl); + + trace("TypeLib to load: %ls\n", filenameW); + hr = LoadTypeLib(filenameW, &typeLib); + ok(hr == S_OK, "LoadTypeLib returned: %08x\n", hr); + + if(typeLib) + { + hr = RegisterTypeLib(typeLib, filenameW, NULL); + ok(hr == S_OK, "RegisterTypeLib returned: %08x\n", hr); + + ITypeLib_Release(typeLib); + } + + DeleteFileW(filenameW); +} + static void test_LoadTypeLib(void) { ITypeLib *tl; @@ -8351,6 +8525,7 @@ START_TEST(typelib)
test_register_typelib(TRUE); test_register_typelib(FALSE); + test_RegisterTypeLib64(); test_create_typelibs(); test_LoadTypeLib(); test_TypeInfo2_GetContainingTypeLib(); diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index 70f15679811..ef546379174 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -629,10 +629,6 @@ HRESULT WINAPI RegisterTypeLib(ITypeLib *ptlib, const WCHAR *szFullPath, const W if (FAILED(ITypeLib_GetLibAttr(ptlib, &attr))) return E_FAIL;
-#ifndef _WIN64 - if (attr->syskind == SYS_WIN64) return TYPE_E_BADMODULEKIND; -#endif - get_typelib_key( &attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, keyName );
res = S_OK;
Windows writes a typelib's name into the registry when the typelib doesn't provide a documentation.
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/oleaut32/tests/typelib.c | 34 ++++++++++++++++++++++++++++++++++ dlls/oleaut32/typelib.c | 34 ++++++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 8 deletions(-)
diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index bf38e71a259..d343928e054 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -6860,6 +6860,8 @@ static void test_RegisterTypeLib64(void) HRESULT hr; char filename[MAX_PATH]; WCHAR filenameW[MAX_PATH]; + REGSAM opposite = (sizeof(void*) == 8 ? KEY_WOW64_32KEY : KEY_WOW64_64KEY); + BOOL is_wow64 = FALSE;
static const WCHAR wszStdOle2[] = { 's','t','d','o','l','e','2','.','t','l','b',0 };
@@ -6880,6 +6882,9 @@ static void test_RegisterTypeLib64(void)
const SYSKIND sys = SYS_WIN64;
+ if (pIsWow64Process) + pIsWow64Process(GetCurrentProcess(), &is_wow64); + hr = LoadTypeLib(wszStdOle2, &stdole); ok(hr == S_OK, "got %08x\n", hr);
@@ -7013,10 +7018,39 @@ static void test_RegisterTypeLib64(void)
if(typeLib) { + WCHAR key_name[MAX_PATH], uuidW[40]; + OLECHAR tlbName[16]; + HKEY hkey; + LONG size; + hr = RegisterTypeLib(typeLib, filenameW, NULL); ok(hr == S_OK, "RegisterTypeLib returned: %08x\n", hr);
ITypeLib_Release(typeLib); + + StringFromGUID2(&tlcustguid, uuidW, ARRAY_SIZE(uuidW)); + swprintf(key_name, sizeof(key_name), L"TypeLib\%ls\1.0", uuidW); + + hr = RegOpenKeyExW(HKEY_CLASSES_ROOT, key_name, 0, KEY_READ, &hkey); + ok(hr == S_OK, "got %08x\n", hr); + + size = sizeof(tlbName); + hr = RegQueryValueW(hkey, L"", tlbName, &size); + ok(hr == S_OK, "got %08x\n", hr); + + /* The typelib should be registered in WoW64_32 and WoW64_64 mode */ + if(is_win64 || is_wow64) + { + hr = RegOpenKeyExW(HKEY_CLASSES_ROOT, key_name, 0, KEY_READ | opposite, &hkey); + ok(hr == S_OK, "got %08x\n", hr); + + size = sizeof(tlbName); + hr = RegQueryValueW(hkey, L"", tlbName, &size); + ok(hr == S_OK, "got %08x\n", hr); + } + + ok(!wcscmp(tlbName, typelibW), + "Got unexpected TypLib description: %ls\n", tlbName); }
DeleteFileW(filenameW); diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index ef546379174..9c18a383285 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -636,18 +636,36 @@ HRESULT WINAPI RegisterTypeLib(ITypeLib *ptlib, const WCHAR *szFullPath, const W KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) { LPOLESTR doc; + LPOLESTR libName; + BOOL nameSet = FALSE;
- /* Set the human-readable name of the typelib */ - if (FAILED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL))) - res = E_FAIL; - else if (doc) + /* Set the human-readable name of the typelib to + the typelib's doc, if it exists, else to the typelib's name. */ + if (SUCCEEDED(ITypeLib_GetDocumentation(ptlib, -1, &libName, &doc, NULL, NULL))) { - if (RegSetValueExW(key, NULL, 0, REG_SZ, - (BYTE *)doc, (lstrlenW(doc)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS) - res = E_FAIL; + if (doc) + { + if (RegSetValueExW(key, NULL, 0, REG_SZ, + (BYTE *)doc, (lstrlenW(doc)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS) + res = E_FAIL; + + nameSet = TRUE; + SysFreeString(doc); + } + if(libName) + { + if(!nameSet) + { + if (RegSetValueExW(key, NULL, 0, REG_SZ, + (BYTE *)libName, (lstrlenW(libName)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS) + res = E_FAIL; + }
- SysFreeString(doc); + SysFreeString(libName); + } } + else + res = E_FAIL;
/* Make up the name of the typelib path subkey */ if (!get_lcid_subkey( attr->lcid, attr->syskind, tmp )) res = E_FAIL;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=100389
Your paranoid android.
=== w7u_adm (32 bit report) ===
oleaut32: typelib.c:7027: Test failed: RegisterTypeLib returned: 8002801c typelib.c:7035: Test failed: got 00000002 typelib.c:7039: Test failed: got 00000006 typelib.c:7052: Test failed: Got unexpected TypLib description: typelib.c:8168: Tests skipped: Insufficient privileges to register typelib in the registry
=== w8adm (32 bit report) ===
oleaut32: typelib.c:7027: Test failed: RegisterTypeLib returned: 8002801c typelib.c:7035: Test failed: got 00000002 typelib.c:7039: Test failed: got 00000006 typelib.c:7052: Test failed: Got unexpected TypLib description: typelib.c:8168: Tests skipped: Insufficient privileges to register typelib in the registry
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=100388
Your paranoid android.
=== w7u_adm (32 bit report) ===
oleaut32: typelib.c:7017: Test failed: RegisterTypeLib returned: 8002801c
=== w8adm (32 bit report) ===
oleaut32: typelib.c:7017: Test failed: RegisterTypeLib returned: 8002801c