If the read ProgID only has a CurVer key and no CLSID key, it will directly return CO_E_CCLASSSTRING, causing the program to fail to continue running. Add CurVer key value ProgID.x recognition and read the CLSID key value of ProgID.x
-- v3: ole32/tests:add CurVer in CLSIDFromProgID
From: Maotong Zhang zmtong1988@gmail.com
If the read ProgID only has a CurVer key and no CLSID key, it will directly return CO_E_CCLASSSTRING, causing the program to fail to continue running. Add CurVer key value ProgID.x recognition and read the CLSID key value of ProgID.x --- dlls/combase/combase.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c index b3a1c9bd8fc..796220936c9 100644 --- a/dlls/combase/combase.c +++ b/dlls/combase/combase.c @@ -1385,8 +1385,9 @@ static BOOL guid_from_string(LPCWSTR s, GUID *id)
static HRESULT clsid_from_string_reg(LPCOLESTR progid, CLSID *clsid) { - WCHAR buf2[CHARS_IN_GUID]; + WCHAR buf2[CHARS_IN_GUID],buf3[CHARS_IN_GUID]; LONG buf2len = sizeof(buf2); + LONG buf3len = sizeof(buf3); HKEY xhkey; WCHAR *buf;
@@ -1398,9 +1399,23 @@ static HRESULT clsid_from_string_reg(LPCOLESTR progid, CLSID *clsid) lstrcatW(buf, L"\CLSID"); if (open_classes_key(HKEY_CLASSES_ROOT, buf, MAXIMUM_ALLOWED, &xhkey)) { - free(buf); - WARN("couldn't open key for ProgID %s\n", debugstr_w(progid)); - return CO_E_CLASSSTRING; + lstrcpyW(buf, progid); + lstrcatW(buf, L"\CurVer"); + if (RegQueryValueW(HKEY_CLASSES_ROOT, buf, buf3, &buf3len)) + { + free(buf); + WARN("couldn't query CurVer value for ProgID %s\n", debugstr_w(progid)); + return CO_E_CLASSSTRING; + } + + lstrcpyW(buf, buf3); + lstrcatW(buf, L"\CLSID"); + if (open_classes_key(HKEY_CLASSES_ROOT, buf, MAXIMUM_ALLOWED, &xhkey)) + { + WARN("couldn't open CLSID key for CurVer %s\n", debugstr_w(buf)); + free(buf); + return CO_E_CLASSSTRING; + } } free(buf);
From: Maotong Zhang zmtong1988@gmail.com
When using CLSIDFromProgID to search for a CLSID, if the CLSID does not exist, there is a CurVer identifier. Add CLSID lookup for ProgID.x corresponding to CurVer --- dlls/ole32/tests/compobj.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c index 94b83024b91..57b660b72ca 100644 --- a/dlls/ole32/tests/compobj.c +++ b/dlls/ole32/tests/compobj.c @@ -433,6 +433,8 @@ static void test_CLSIDFromProgID(void) ULONG_PTR cookie = 0; HANDLE handle; CLSID clsid; + HKEY hKey; + WCHAR clsidstr[39]; HRESULT hr = CLSIDFromProgID(stdfont, &clsid); ok(hr == S_OK, "CLSIDFromProgID failed with error 0x%08lx\n", hr); ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n"); @@ -442,6 +444,18 @@ static void test_CLSIDFromProgID(void) ok(IsEqualCLSID(&clsid, &CLSID_StdFont), "clsid wasn't equal to CLSID_StdFont\n");
/* test some failure cases */ + StringFromGUID2(&CLSID_non_existent, clsidstr, ARRAYSIZE(clsidstr)); + if (RegCreateKeyExW(HKEY_CLASSES_ROOT, L"MyApp.DocumentTest\CurVer", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS) { + RegSetValueExW(hKey, NULL, 0, REG_SZ, (const BYTE *)L"MyApp.DocumentTest.1", (wcslen(L"MyApp.DocumentTest.1") + 1) * sizeof(WCHAR)); + RegCloseKey(hKey); + } + if (RegCreateKeyExW(HKEY_CLASSES_ROOT, L"MyApp.DocumentTest.1\CLSID", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS) { + RegSetValueExW(hKey, NULL, 0, REG_SZ, (const BYTE *)clsidstr, (wcslen(clsidstr) + 1) * sizeof(WCHAR)); + RegCloseKey(hKey); + } + hr = CLSIDFromProgID(L"MyApp.DocumentTest", &clsid); + ok(hr == S_OK, "CLSIDFromProgID failed with error 0x%08lx\n", hr); + ok(IsEqualCLSID(&clsid, &CLSID_non_existent), "got wrong clsid %s\n", wine_dbgstr_guid(&clsid));
hr = CLSIDFromProgID(wszNonExistent, NULL); ok(hr == E_INVALIDARG, "CLSIDFromProgID should have returned E_INVALIDARG instead of 0x%08lx\n", hr);