From: Maotong Zhang zmtong1988@gmail.com
--- dlls/combase/combase.c | 51 +++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 18 deletions(-)
diff --git a/dlls/combase/combase.c b/dlls/combase/combase.c index b3a1c9bd8fc..3ee0fd82544 100644 --- a/dlls/combase/combase.c +++ b/dlls/combase/combase.c @@ -1385,33 +1385,48 @@ static BOOL guid_from_string(LPCWSTR s, GUID *id)
static HRESULT clsid_from_string_reg(LPCOLESTR progid, CLSID *clsid) { - WCHAR buf2[CHARS_IN_GUID]; - LONG buf2len = sizeof(buf2); + HRESULT hr, ret; HKEY xhkey; - WCHAR *buf; + WCHAR szclsid[256] = {0}; + LONG cbclsid = sizeof(szclsid);
- memset(clsid, 0, sizeof(*clsid)); - buf = malloc((lstrlenW(progid) + 8) * sizeof(WCHAR)); - if (!buf) return E_OUTOFMEMORY; + if (!progid) + return E_INVALIDARG;
- lstrcpyW(buf, progid); - lstrcatW(buf, L"\CLSID"); - if (open_classes_key(HKEY_CLASSES_ROOT, buf, MAXIMUM_ALLOWED, &xhkey)) + hr = open_classes_key(HKEY_CLASSES_ROOT, progid, MAXIMUM_ALLOWED, &xhkey); + if (SUCCEEDED(hr)) { - free(buf); - WARN("couldn't open key for ProgID %s\n", debugstr_w(progid)); - return CO_E_CLASSSTRING; + if (RegQueryValueW(xhkey, L"CLSID", szclsid, &cbclsid) != ERROR_SUCCESS) + { + LONG cbcurver = 0; + if (RegQueryValueW(xhkey, L"CurVer", NULL, &cbcurver) == ERROR_SUCCESS && cbcurver > 0) + { + WCHAR *szcurver = (WCHAR *)LocalAlloc(LMEM_FIXED, cbcurver); + if (szcurver) + { + if (RegQueryValueW(xhkey, L"CurVer", szcurver, &cbcurver) == ERROR_SUCCESS) + { + if (lstrcmpiW(szcurver, progid) != 0) + { + RegCloseKey(xhkey); + ret = clsid_from_string_reg(szcurver, clsid); + LocalFree(szcurver); + if (SUCCEEDED(ret)) return ret; + } + } + LocalFree(szcurver); + } + } + } + RegCloseKey(xhkey); } - free(buf);
- if (RegQueryValueW(xhkey, NULL, buf2, &buf2len)) + if (!guid_from_string(szclsid, clsid)) { - RegCloseKey(xhkey); - WARN("couldn't query clsid value for ProgID %s\n", debugstr_w(progid)); + memset(clsid, 0, sizeof(*clsid)); return CO_E_CLASSSTRING; } - RegCloseKey(xhkey); - return guid_from_string(buf2, clsid) ? S_OK : CO_E_CLASSSTRING; + return S_OK; }
/******************************************************************************