- Extend COM_OpenKeyForCLSID to open a subkey and return an HRESULT.

- Fix up the callers and reorganize CoGetClassObject to split out the
  inproc code into another function.
This commit is contained in:
Robert Shearman 2005-11-09 10:29:11 +00:00 committed by Alexandre Julliard
parent 8c4ead4d27
commit f7b65cc716
5 changed files with 128 additions and 136 deletions

View File

@ -978,14 +978,36 @@ INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax ); return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax );
} }
/* open HKCR\\CLSID\\{string form of clsid} key */ /* open HKCR\\CLSID\\{string form of clsid}\\{keyname} key */
DWORD COM_OpenKeyForCLSID(REFCLSID clsid, REGSAM access, HKEY *key) HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *subkey)
{ {
static const WCHAR wszCLSIDSlash[] = {'C','L','S','I','D','\\',0}; static const WCHAR wszCLSIDSlash[] = {'C','L','S','I','D','\\',0};
WCHAR path[CHARS_IN_GUID + ARRAYSIZE(wszCLSIDSlash) - 1]; WCHAR path[CHARS_IN_GUID + ARRAYSIZE(wszCLSIDSlash) - 1];
LONG res;
HKEY key;
strcpyW(path, wszCLSIDSlash); strcpyW(path, wszCLSIDSlash);
StringFromGUID2(clsid, path + strlenW(wszCLSIDSlash), CHARS_IN_GUID); StringFromGUID2(clsid, path + strlenW(wszCLSIDSlash), CHARS_IN_GUID);
return RegOpenKeyExW(HKEY_CLASSES_ROOT, path, 0, access, key); res = RegOpenKeyExW(HKEY_CLASSES_ROOT, path, 0, keyname ? KEY_READ : access, &key);
if (res == ERROR_FILE_NOT_FOUND)
return REGDB_E_CLASSNOTREG;
else if (res != ERROR_SUCCESS)
return REGDB_E_READREGDB;
if (!keyname)
{
*subkey = key;
return S_OK;
}
res = RegOpenKeyExW(key, keyname, 0, access, subkey);
RegCloseKey(key);
if (res == ERROR_FILE_NOT_FOUND)
return REGDB_E_KEYMISSING;
else if (res != ERROR_SUCCESS)
return REGDB_E_READREGDB;
return S_OK;
} }
/****************************************************************************** /******************************************************************************
@ -1004,25 +1026,15 @@ DWORD COM_OpenKeyForCLSID(REFCLSID clsid, REGSAM access, HKEY *key)
*/ */
HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID) HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID)
{ {
static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0}; static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0};
HKEY hkey = NULL; HKEY hkey;
HKEY hkey_clsid; HRESULT ret;
HRESULT ret = S_OK;
if (ERROR_SUCCESS != COM_OpenKeyForCLSID(clsid, KEY_READ, &hkey_clsid))
ret = REGDB_E_CLASSNOTREG;
if (ret == S_OK)
{
if (RegOpenKeyExW(hkey_clsid, wszProgID, 0, KEY_READ, &hkey))
ret = REGDB_E_CLASSNOTREG;
RegCloseKey(hkey_clsid);
}
if (ret == S_OK)
{
LONG progidlen = 0; LONG progidlen = 0;
ret = COM_OpenKeyForCLSID(clsid, wszProgID, KEY_READ, &hkey);
if (FAILED(ret))
return ret;
if (RegQueryValueW(hkey, NULL, NULL, &progidlen)) if (RegQueryValueW(hkey, NULL, NULL, &progidlen))
ret = REGDB_E_CLASSNOTREG; ret = REGDB_E_CLASSNOTREG;
@ -1037,10 +1049,9 @@ HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID)
else else
ret = E_OUTOFMEMORY; ret = E_OUTOFMEMORY;
} }
}
RegCloseKey(hkey); RegCloseKey(hkey);
return ret; return ret;
} }
/****************************************************************************** /******************************************************************************
@ -1526,6 +1537,40 @@ HRESULT COM_RegReadPath(HKEY hkeyroot, const WCHAR *keyname, const WCHAR *valuen
return hres; return hres;
} }
static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv)
{
HINSTANCE hLibrary;
typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
DllGetClassObjectFunc DllGetClassObject;
WCHAR dllpath[MAX_PATH+1];
if (COM_RegReadPath(hkeydll, NULL, NULL, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
{
/* failure: CLSID is not found in registry */
WARN("class %s not registered inproc\n", debugstr_guid(rclsid));
return REGDB_E_CLASSNOTREG;
}
if ((hLibrary = LoadLibraryExW(dllpath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0)
{
/* failure: DLL could not be loaded */
ERR("couldn't load InprocServer32 dll %s\n", debugstr_w(dllpath));
return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
}
if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject")))
{
/* failure: the dll did not export DllGetClassObject */
ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(dllpath));
FreeLibrary( hLibrary );
return CO_E_DLLNOTFOUND;
}
/* OK: get the ClassObject */
COMPOBJ_DLLList_Add( hLibrary );
return DllGetClassObject(rclsid, riid, ppv);
}
/*********************************************************************** /***********************************************************************
* CoGetClassObject [OLE32.@] * CoGetClassObject [OLE32.@]
* *
@ -1571,46 +1616,27 @@ HRESULT WINAPI CoGetClassObject(
if ((CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER) & dwClsContext) if ((CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER) & dwClsContext)
{ {
static const WCHAR wszInprocServer32[] = {'I','n','p','r','o','c','S','e','r','v','e','r','3','2',0}; static const WCHAR wszInprocServer32[] = {'I','n','p','r','o','c','S','e','r','v','e','r','3','2',0};
HINSTANCE hLibrary;
typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
DllGetClassObjectFunc DllGetClassObject;
WCHAR dllpath[MAX_PATH+1];
HKEY hkey; HKEY hkey;
if (ERROR_SUCCESS != COM_OpenKeyForCLSID(rclsid, KEY_READ, &hkey)) hres = COM_OpenKeyForCLSID(rclsid, wszInprocServer32, KEY_READ, &hkey);
if (FAILED(hres))
{ {
ERR("class %s not registered\n", debugstr_guid(rclsid)); if (hres == REGDB_E_CLASSNOTREG)
hres = REGDB_E_CLASSNOTREG; ERR("class %s not registered\n", debugstr_guid(rclsid));
else
WARN("class %s not registered inproc\n", debugstr_guid(rclsid));
} }
if (COM_RegReadPath(hkey, wszInprocServer32, NULL, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS) if (SUCCEEDED(hres))
{ {
/* failure: CLSID is not found in registry */ hres = get_inproc_class_object(hkey, rclsid, iid, ppv);
WARN("class %s not registered inproc\n", debugstr_guid(rclsid)); RegCloseKey(hkey);
hres = REGDB_E_CLASSNOTREG;
}
else
{
if ((hLibrary = LoadLibraryExW(dllpath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0)
{
/* failure: DLL could not be loaded */
ERR("couldn't load InprocServer32 dll %s\n", debugstr_w(dllpath));
hres = E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
}
else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject")))
{
/* failure: the dll did not export DllGetClassObject */
ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(dllpath));
FreeLibrary( hLibrary );
hres = CO_E_DLLNOTFOUND;
}
else
{
/* OK: get the ClassObject */
COMPOBJ_DLLList_Add( hLibrary );
return DllGetClassObject(rclsid, iid, ppv);
}
} }
/* return if we got a class, otherwise fall through to one of the
* other types */
if (SUCCEEDED(hres))
return hres;
} }
/* Next try out of process */ /* Next try out of process */
@ -2144,16 +2170,12 @@ HRESULT WINAPI OleGetAutoConvert(REFCLSID clsidOld, LPCLSID pClsidNew)
LONG len; LONG len;
HRESULT res = S_OK; HRESULT res = S_OK;
if (ERROR_SUCCESS != COM_OpenKeyForCLSID(clsidOld, KEY_READ, &hkey)) res = COM_OpenKeyForCLSID(clsidOld, wszAutoConvertTo, KEY_READ, &hkey);
{ if (FAILED(res))
res = REGDB_E_CLASSNOTREG;
goto done; goto done;
}
len = sizeof(buf); len = sizeof(buf);
/* we can just query for the default value of AutoConvertTo key like that, if (RegQueryValueW(hkey, NULL, buf, &len))
without opening the AutoConvertTo key and querying for NULL (default) */
if (RegQueryValueW(hkey, wszAutoConvertTo, buf, &len))
{ {
res = REGDB_E_KEYMISSING; res = REGDB_E_KEYMISSING;
goto done; goto done;
@ -2191,11 +2213,9 @@ HRESULT WINAPI CoTreatAsClass(REFCLSID clsidOld, REFCLSID clsidNew)
LONG auto_treat_as_size = sizeof(auto_treat_as); LONG auto_treat_as_size = sizeof(auto_treat_as);
CLSID id; CLSID id;
if (ERROR_SUCCESS != COM_OpenKeyForCLSID(clsidOld, KEY_READ | KEY_WRITE, &hkey)) res = COM_OpenKeyForCLSID(clsidOld, NULL, KEY_READ | KEY_WRITE, &hkey);
{ if (FAILED(res))
res = REGDB_E_CLASSNOTREG; goto done;
goto done;
}
if (!memcmp( clsidOld, clsidNew, sizeof(*clsidOld) )) if (!memcmp( clsidOld, clsidNew, sizeof(*clsidOld) ))
{ {
if (!RegQueryValueW(hkey, wszAutoTreatAs, auto_treat_as, &auto_treat_as_size) && if (!RegQueryValueW(hkey, wszAutoTreatAs, auto_treat_as, &auto_treat_as_size) &&
@ -2252,12 +2272,10 @@ HRESULT WINAPI CoGetTreatAsClass(REFCLSID clsidOld, LPCLSID clsidNew)
FIXME("(%s,%p)\n", debugstr_guid(clsidOld), clsidNew); FIXME("(%s,%p)\n", debugstr_guid(clsidOld), clsidNew);
memcpy(clsidNew,clsidOld,sizeof(CLSID)); /* copy over old value */ memcpy(clsidNew,clsidOld,sizeof(CLSID)); /* copy over old value */
if (COM_OpenKeyForCLSID(clsidOld, KEY_READ, &hkey)) res = COM_OpenKeyForCLSID(clsidOld, wszTreatAs, KEY_READ, &hkey);
{ if (FAILED(res))
res = REGDB_E_CLASSNOTREG; goto done;
goto done; if (RegQueryValueW(hkey, NULL, szClsidNew, &len))
}
if (RegQueryValueW(hkey, wszTreatAs, szClsidNew, &len))
{ {
res = S_FALSE; res = S_FALSE;
goto done; goto done;

View File

@ -171,7 +171,7 @@ extern void* StdGlobalInterfaceTableInstance;
extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr); extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr);
HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id); HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
DWORD COM_OpenKeyForCLSID(REFCLSID clsid, REGSAM access, HKEY *key); HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *key);
HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv); HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
/* Stub Manager */ /* Stub Manager */

View File

@ -353,34 +353,33 @@ HRESULT WINAPI ProgIDFromCLSID16(
LPOLESTR16 *lplpszProgID/* [out] associated Prog ID */ LPOLESTR16 *lplpszProgID/* [out] associated Prog ID */
) { ) {
static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0}; static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0};
HKEY xhkey;
HKEY hkey; HKEY hkey;
HRESULT ret = S_OK; HRESULT ret;
LONG len;
char *buffer;
if (COM_OpenKeyForCLSID(clsid, KEY_READ, &hkey)) ret = COM_OpenKeyForCLSID(clsid, wszProgID, KEY_READ, &hkey);
ret = REGDB_E_CLASSNOTREG; if (FAILED(ret))
return ret;
if ((ret == S_OK) && if (RegQueryValueA(hkey, NULL, NULL, &len))
RegOpenKeyW(hkey, wszProgID, &xhkey)) ret = REGDB_E_READREGDB;
ret = REGDB_E_CLASSNOTREG;
if (ret == S_OK) if (ret == S_OK)
{ {
LONG buf2len; buffer = HeapAlloc(GetProcessHeap(), 0, len);
char *buf2 = HeapAlloc(GetProcessHeap(), 0, 255); if (RegQueryValueA(hkey, NULL, buffer, &len))
buf2len = 255; ret = REGDB_E_READREGDB;
if (RegQueryValueA(xhkey, NULL, buf2, &buf2len))
ret = REGDB_E_CLASSNOTREG;
if (ret == S_OK) if (ret == S_OK)
{ {
ret = _xmalloc16(buf2len+1, (SEGPTR*)lplpszProgID); ret = _xmalloc16(len, (SEGPTR*)lplpszProgID);
if (ret == S_OK) if (ret == S_OK)
strcpy(MapSL((SEGPTR)*lplpszProgID),buf2); strcpy(MapSL((SEGPTR)*lplpszProgID),buffer);
} }
HeapFree(GetProcessHeap(), 0, buf2); HeapFree(GetProcessHeap(), 0, buffer);
} }
RegCloseKey(xhkey); RegCloseKey(hkey);
return ret; return ret;
} }

View File

@ -882,37 +882,23 @@ static HRESULT EnumOLEVERB_Construct(HKEY hkeyVerb, ULONG index, IEnumOLEVERB **
HRESULT WINAPI OleRegEnumVerbs (REFCLSID clsid, LPENUMOLEVERB* ppenum) HRESULT WINAPI OleRegEnumVerbs (REFCLSID clsid, LPENUMOLEVERB* ppenum)
{ {
LONG res; LONG res;
HKEY hkeyClass;
HKEY hkeyVerb; HKEY hkeyVerb;
DWORD dwSubKeys; DWORD dwSubKeys;
static const WCHAR wszVerb[] = {'V','e','r','b',0}; static const WCHAR wszVerb[] = {'V','e','r','b',0};
TRACE("(%s, %p)\n", debugstr_guid(clsid), ppenum); TRACE("(%s, %p)\n", debugstr_guid(clsid), ppenum);
res = COM_OpenKeyForCLSID(clsid, KEY_READ, &hkeyClass); res = COM_OpenKeyForCLSID(clsid, wszVerb, KEY_READ, &hkeyVerb);
if (res == ERROR_FILE_NOT_FOUND) if (FAILED(res))
{ {
ERR("CLSID %s not registered\n", debugstr_guid(clsid)); if (res == REGDB_E_CLASSNOTREG)
return REGDB_E_CLASSNOTREG; ERR("CLSID %s not registered\n", debugstr_guid(clsid));
} else if (res == REGDB_E_KEYMISSING)
else if (res != ERROR_SUCCESS) ERR("no Verbs key for class %s\n", debugstr_guid(clsid));
{ else
ERR("failed to open key for CLSID %s with error %ld\n", ERR("failed to open Verbs key for CLSID %s with error %ld\n",
debugstr_guid(clsid), res); debugstr_guid(clsid), res);
return REGDB_E_READREGDB; return res;
}
res = RegOpenKeyExW(hkeyClass, wszVerb, 0, KEY_READ, &hkeyVerb);
RegCloseKey(hkeyClass);
if (res == ERROR_FILE_NOT_FOUND)
{
ERR("no Verbs key for class %s\n", debugstr_guid(clsid));
return REGDB_E_KEYMISSING;
}
else if (res != ERROR_SUCCESS)
{
ERR("failed to open Verbs key for CLSID %s with error %ld\n",
debugstr_guid(clsid), res);
return REGDB_E_READREGDB;
} }
res = RegQueryInfoKeyW(hkeyVerb, NULL, NULL, NULL, &dwSubKeys, NULL, res = RegQueryInfoKeyW(hkeyVerb, NULL, NULL, NULL, &dwSubKeys, NULL,
@ -2561,11 +2547,9 @@ HRESULT WINAPI OleSetAutoConvert(REFCLSID clsidOld, REFCLSID clsidNew)
TRACE("(%s,%s)\n", debugstr_guid(clsidOld), debugstr_guid(clsidNew)); TRACE("(%s,%s)\n", debugstr_guid(clsidOld), debugstr_guid(clsidNew));
if (COM_OpenKeyForCLSID(clsidOld, KEY_READ | KEY_WRITE, &hkey)) res = COM_OpenKeyForCLSID(clsidOld, NULL, KEY_READ | KEY_WRITE, &hkey);
{ if (FAILED(res))
res = REGDB_E_CLASSNOTREG; goto done;
goto done;
}
StringFromGUID2(clsidNew, szClsidNew, CHARS_IN_GUID); StringFromGUID2(clsidNew, szClsidNew, CHARS_IN_GUID);
if (RegSetValueW(hkey, wszAutoConvertTo, REG_SZ, szClsidNew, (strlenW(szClsidNew)+1) * sizeof(WCHAR))) if (RegSetValueW(hkey, wszAutoConvertTo, REG_SZ, szClsidNew, (strlenW(szClsidNew)+1) * sizeof(WCHAR)))
{ {

View File

@ -621,7 +621,6 @@ static HRESULT create_server(REFCLSID rclsid)
{ {
static const WCHAR wszLocalServer32[] = { 'L','o','c','a','l','S','e','r','v','e','r','3','2',0 }; static const WCHAR wszLocalServer32[] = { 'L','o','c','a','l','S','e','r','v','e','r','3','2',0 };
static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 }; static const WCHAR embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 };
HKEY hkeyclsid;
HKEY key; HKEY key;
HRESULT hres; HRESULT hres;
WCHAR command[MAX_PATH+sizeof(embedding)/sizeof(WCHAR)]; WCHAR command[MAX_PATH+sizeof(embedding)/sizeof(WCHAR)];
@ -629,18 +628,10 @@ static HRESULT create_server(REFCLSID rclsid)
STARTUPINFOW sinfo; STARTUPINFOW sinfo;
PROCESS_INFORMATION pinfo; PROCESS_INFORMATION pinfo;
hres = HRESULT_FROM_WIN32(COM_OpenKeyForCLSID(rclsid, KEY_READ, &hkeyclsid)); hres = COM_OpenKeyForCLSID(rclsid, wszLocalServer32, KEY_READ, &key);
if (hres != S_OK) { if (FAILED(hres)) {
ERR("class %s not registered\n", debugstr_guid(rclsid)); ERR("class %s not registered\n", debugstr_guid(rclsid));
return REGDB_E_READREGDB; return hres;
}
hres = RegOpenKeyExW(hkeyclsid, wszLocalServer32, 0, KEY_READ, &key);
RegCloseKey(hkeyclsid);
if (hres != ERROR_SUCCESS) {
WARN("class %s not registered as LocalServer32\n", debugstr_guid(rclsid));
return REGDB_E_READREGDB; /* Probably */
} }
hres = RegQueryValueExW(key, NULL, NULL, NULL, (LPBYTE)command, &size); hres = RegQueryValueExW(key, NULL, NULL, NULL, (LPBYTE)command, &size);
@ -713,7 +704,7 @@ static DWORD start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)
*/ */
static HRESULT create_local_service(REFCLSID rclsid) static HRESULT create_local_service(REFCLSID rclsid)
{ {
HRESULT hres = REGDB_E_READREGDB; HRESULT hres;
WCHAR buf[CHARS_IN_GUID], keyname[50]; WCHAR buf[CHARS_IN_GUID], keyname[50];
static const WCHAR szAppId[] = { 'A','p','p','I','d',0 }; static const WCHAR szAppId[] = { 'A','p','p','I','d',0 };
static const WCHAR szAppIdKey[] = { 'A','p','p','I','d','\\',0 }; static const WCHAR szAppIdKey[] = { 'A','p','p','I','d','\\',0 };
@ -726,11 +717,11 @@ static HRESULT create_local_service(REFCLSID rclsid)
TRACE("Attempting to start Local service for %s\n", debugstr_guid(rclsid)); TRACE("Attempting to start Local service for %s\n", debugstr_guid(rclsid));
/* read the AppID value under the class's key */ /* read the AppID value under the class's key */
r = COM_OpenKeyForCLSID(rclsid, KEY_READ, &hkey); hres = COM_OpenKeyForCLSID(rclsid, szAppId, KEY_READ, &hkey);
if (r!=ERROR_SUCCESS) if (FAILED(hres))
return hres; return hres;
sz = sizeof buf; sz = sizeof buf;
r = RegQueryValueExW(hkey, szAppId, NULL, &type, (LPBYTE)buf, &sz); r = RegQueryValueExW(hkey, NULL, NULL, &type, (LPBYTE)buf, &sz);
RegCloseKey(hkey); RegCloseKey(hkey);
if (r!=ERROR_SUCCESS || type!=REG_SZ) if (r!=ERROR_SUCCESS || type!=REG_SZ)
return hres; return hres;