ole32: Add a helper to map ProgID to CLSID using registry.

This commit is contained in:
Nikolay Sivov 2013-10-24 22:12:56 +04:00 committed by Alexandre Julliard
parent 5077fc895f
commit f96631e110
2 changed files with 41 additions and 29 deletions

View File

@ -2066,6 +2066,36 @@ static HRESULT __CLSIDFromString(LPCWSTR s, LPCLSID id)
/*****************************************************************************/ /*****************************************************************************/
static HRESULT clsid_from_string_reg(LPCOLESTR progid, CLSID *clsid)
{
static const WCHAR clsidW[] = { '\\','C','L','S','I','D',0 };
WCHAR buf2[CHARS_IN_GUID];
LONG buf2len = sizeof(buf2);
HKEY xhkey;
WCHAR *buf;
memset(clsid, 0, sizeof(*clsid));
buf = HeapAlloc( GetProcessHeap(),0,(strlenW(progid)+8) * sizeof(WCHAR) );
strcpyW( buf, progid );
strcatW( buf, clsidW );
if (open_classes_key(HKEY_CLASSES_ROOT, buf, MAXIMUM_ALLOWED, &xhkey))
{
HeapFree(GetProcessHeap(),0,buf);
WARN("couldn't open key for ProgID %s\n", debugstr_w(progid));
return CO_E_CLASSSTRING;
}
HeapFree(GetProcessHeap(),0,buf);
if (RegQueryValueW(xhkey,NULL,buf2,&buf2len))
{
RegCloseKey(xhkey);
WARN("couldn't query clsid value for ProgID %s\n", debugstr_w(progid));
return CO_E_CLASSSTRING;
}
RegCloseKey(xhkey);
return __CLSIDFromString(buf2,clsid);
}
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id ) HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id )
{ {
HRESULT ret; HRESULT ret;
@ -2076,7 +2106,7 @@ HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id )
ret = __CLSIDFromString(idstr, id); ret = __CLSIDFromString(idstr, id);
if(ret != S_OK) { /* It appears a ProgID is also valid */ if(ret != S_OK) { /* It appears a ProgID is also valid */
CLSID tmp_id; CLSID tmp_id;
ret = CLSIDFromProgID(idstr, &tmp_id); ret = clsid_from_string_reg(idstr, &tmp_id);
if(SUCCEEDED(ret)) if(SUCCEEDED(ret))
*id = tmp_id; *id = tmp_id;
} }
@ -2301,40 +2331,13 @@ HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *ppszProgID)
*/ */
HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID clsid) HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID clsid)
{ {
static const WCHAR clsidW[] = { '\\','C','L','S','I','D',0 };
WCHAR buf2[CHARS_IN_GUID];
LONG buf2len = sizeof(buf2);
HKEY xhkey;
WCHAR *buf;
if (!progid || !clsid) if (!progid || !clsid)
{ {
ERR("neither progid (%p) nor clsid (%p) are optional\n", progid, clsid); ERR("neither progid (%p) nor clsid (%p) are optional\n", progid, clsid);
return E_INVALIDARG; return E_INVALIDARG;
} }
/* initialise clsid in case of failure */ return clsid_from_string_reg(progid, clsid);
memset(clsid, 0, sizeof(*clsid));
buf = HeapAlloc( GetProcessHeap(),0,(strlenW(progid)+8) * sizeof(WCHAR) );
strcpyW( buf, progid );
strcatW( buf, clsidW );
if (open_classes_key(HKEY_CLASSES_ROOT, buf, MAXIMUM_ALLOWED, &xhkey))
{
HeapFree(GetProcessHeap(),0,buf);
WARN("couldn't open key for ProgID %s\n", debugstr_w(progid));
return CO_E_CLASSSTRING;
}
HeapFree(GetProcessHeap(),0,buf);
if (RegQueryValueW(xhkey,NULL,buf2,&buf2len))
{
RegCloseKey(xhkey);
WARN("couldn't query clsid value for ProgID %s\n", debugstr_w(progid));
return CO_E_CLASSSTRING;
}
RegCloseKey(xhkey);
return __CLSIDFromString(buf2,clsid);
} }
/****************************************************************************** /******************************************************************************

View File

@ -368,6 +368,15 @@ static void test_CLSIDFromProgID(void)
{ {
GUID clsid1; GUID clsid1;
memset(&clsid, 0xcc, sizeof(clsid));
hr = CLSIDFromProgID(wszNonExistent, &clsid);
ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
ok(IsEqualCLSID(&clsid, &CLSID_NULL), "should have zero CLSID on failure\n");
/* CLSIDFromString() doesn't check activation context */
hr = CLSIDFromString(progidW, &clsid);
ok(hr == CO_E_CLASSSTRING, "got 0x%08x\n", hr);
clsid = CLSID_NULL; clsid = CLSID_NULL;
hr = CLSIDFromProgID(progidW, &clsid); hr = CLSIDFromProgID(progidW, &clsid);
todo_wine todo_wine