- 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:
parent
8c4ead4d27
commit
f7b65cc716
|
@ -978,14 +978,36 @@ INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
|
|||
return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax );
|
||||
}
|
||||
|
||||
/* open HKCR\\CLSID\\{string form of clsid} key */
|
||||
DWORD COM_OpenKeyForCLSID(REFCLSID clsid, REGSAM access, HKEY *key)
|
||||
/* open HKCR\\CLSID\\{string form of clsid}\\{keyname} key */
|
||||
HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *subkey)
|
||||
{
|
||||
static const WCHAR wszCLSIDSlash[] = {'C','L','S','I','D','\\',0};
|
||||
WCHAR path[CHARS_IN_GUID + ARRAYSIZE(wszCLSIDSlash) - 1];
|
||||
LONG res;
|
||||
HKEY key;
|
||||
|
||||
strcpyW(path, wszCLSIDSlash);
|
||||
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)
|
||||
{
|
||||
static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0};
|
||||
HKEY hkey = NULL;
|
||||
HKEY hkey_clsid;
|
||||
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)
|
||||
{
|
||||
static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0};
|
||||
HKEY hkey;
|
||||
HRESULT ret;
|
||||
LONG progidlen = 0;
|
||||
|
||||
ret = COM_OpenKeyForCLSID(clsid, wszProgID, KEY_READ, &hkey);
|
||||
if (FAILED(ret))
|
||||
return ret;
|
||||
|
||||
if (RegQueryValueW(hkey, NULL, NULL, &progidlen))
|
||||
ret = REGDB_E_CLASSNOTREG;
|
||||
|
||||
|
@ -1037,10 +1049,9 @@ HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID)
|
|||
else
|
||||
ret = E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
RegCloseKey(hkey);
|
||||
return ret;
|
||||
RegCloseKey(hkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -1526,6 +1537,40 @@ HRESULT COM_RegReadPath(HKEY hkeyroot, const WCHAR *keyname, const WCHAR *valuen
|
|||
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.@]
|
||||
*
|
||||
|
@ -1571,46 +1616,27 @@ HRESULT WINAPI CoGetClassObject(
|
|||
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};
|
||||
HINSTANCE hLibrary;
|
||||
typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
|
||||
DllGetClassObjectFunc DllGetClassObject;
|
||||
WCHAR dllpath[MAX_PATH+1];
|
||||
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));
|
||||
hres = REGDB_E_CLASSNOTREG;
|
||||
if (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 */
|
||||
WARN("class %s not registered inproc\n", debugstr_guid(rclsid));
|
||||
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);
|
||||
}
|
||||
hres = get_inproc_class_object(hkey, rclsid, iid, ppv);
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
@ -2144,16 +2170,12 @@ HRESULT WINAPI OleGetAutoConvert(REFCLSID clsidOld, LPCLSID pClsidNew)
|
|||
LONG len;
|
||||
HRESULT res = S_OK;
|
||||
|
||||
if (ERROR_SUCCESS != COM_OpenKeyForCLSID(clsidOld, KEY_READ, &hkey))
|
||||
{
|
||||
res = REGDB_E_CLASSNOTREG;
|
||||
res = COM_OpenKeyForCLSID(clsidOld, wszAutoConvertTo, KEY_READ, &hkey);
|
||||
if (FAILED(res))
|
||||
goto done;
|
||||
}
|
||||
|
||||
len = sizeof(buf);
|
||||
/* we can just query for the default value of AutoConvertTo key like that,
|
||||
without opening the AutoConvertTo key and querying for NULL (default) */
|
||||
if (RegQueryValueW(hkey, wszAutoConvertTo, buf, &len))
|
||||
if (RegQueryValueW(hkey, NULL, buf, &len))
|
||||
{
|
||||
res = REGDB_E_KEYMISSING;
|
||||
goto done;
|
||||
|
@ -2191,11 +2213,9 @@ HRESULT WINAPI CoTreatAsClass(REFCLSID clsidOld, REFCLSID clsidNew)
|
|||
LONG auto_treat_as_size = sizeof(auto_treat_as);
|
||||
CLSID id;
|
||||
|
||||
if (ERROR_SUCCESS != COM_OpenKeyForCLSID(clsidOld, KEY_READ | KEY_WRITE, &hkey))
|
||||
{
|
||||
res = REGDB_E_CLASSNOTREG;
|
||||
goto done;
|
||||
}
|
||||
res = COM_OpenKeyForCLSID(clsidOld, NULL, KEY_READ | KEY_WRITE, &hkey);
|
||||
if (FAILED(res))
|
||||
goto done;
|
||||
if (!memcmp( clsidOld, clsidNew, sizeof(*clsidOld) ))
|
||||
{
|
||||
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);
|
||||
memcpy(clsidNew,clsidOld,sizeof(CLSID)); /* copy over old value */
|
||||
|
||||
if (COM_OpenKeyForCLSID(clsidOld, KEY_READ, &hkey))
|
||||
{
|
||||
res = REGDB_E_CLASSNOTREG;
|
||||
goto done;
|
||||
}
|
||||
if (RegQueryValueW(hkey, wszTreatAs, szClsidNew, &len))
|
||||
res = COM_OpenKeyForCLSID(clsidOld, wszTreatAs, KEY_READ, &hkey);
|
||||
if (FAILED(res))
|
||||
goto done;
|
||||
if (RegQueryValueW(hkey, NULL, szClsidNew, &len))
|
||||
{
|
||||
res = S_FALSE;
|
||||
goto done;
|
||||
|
|
|
@ -171,7 +171,7 @@ extern void* StdGlobalInterfaceTableInstance;
|
|||
extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr);
|
||||
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);
|
||||
|
||||
/* Stub Manager */
|
||||
|
|
|
@ -353,34 +353,33 @@ HRESULT WINAPI ProgIDFromCLSID16(
|
|||
LPOLESTR16 *lplpszProgID/* [out] associated Prog ID */
|
||||
) {
|
||||
static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0};
|
||||
HKEY xhkey;
|
||||
HKEY hkey;
|
||||
HRESULT ret = S_OK;
|
||||
HRESULT ret;
|
||||
LONG len;
|
||||
char *buffer;
|
||||
|
||||
if (COM_OpenKeyForCLSID(clsid, KEY_READ, &hkey))
|
||||
ret = REGDB_E_CLASSNOTREG;
|
||||
ret = COM_OpenKeyForCLSID(clsid, wszProgID, KEY_READ, &hkey);
|
||||
if (FAILED(ret))
|
||||
return ret;
|
||||
|
||||
if ((ret == S_OK) &&
|
||||
RegOpenKeyW(hkey, wszProgID, &xhkey))
|
||||
ret = REGDB_E_CLASSNOTREG;
|
||||
if (RegQueryValueA(hkey, NULL, NULL, &len))
|
||||
ret = REGDB_E_READREGDB;
|
||||
|
||||
if (ret == S_OK)
|
||||
{
|
||||
LONG buf2len;
|
||||
char *buf2 = HeapAlloc(GetProcessHeap(), 0, 255);
|
||||
buf2len = 255;
|
||||
if (RegQueryValueA(xhkey, NULL, buf2, &buf2len))
|
||||
ret = REGDB_E_CLASSNOTREG;
|
||||
buffer = HeapAlloc(GetProcessHeap(), 0, len);
|
||||
if (RegQueryValueA(hkey, NULL, buffer, &len))
|
||||
ret = REGDB_E_READREGDB;
|
||||
|
||||
if (ret == S_OK)
|
||||
{
|
||||
ret = _xmalloc16(buf2len+1, (SEGPTR*)lplpszProgID);
|
||||
ret = _xmalloc16(len, (SEGPTR*)lplpszProgID);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -882,37 +882,23 @@ static HRESULT EnumOLEVERB_Construct(HKEY hkeyVerb, ULONG index, IEnumOLEVERB **
|
|||
HRESULT WINAPI OleRegEnumVerbs (REFCLSID clsid, LPENUMOLEVERB* ppenum)
|
||||
{
|
||||
LONG res;
|
||||
HKEY hkeyClass;
|
||||
HKEY hkeyVerb;
|
||||
DWORD dwSubKeys;
|
||||
static const WCHAR wszVerb[] = {'V','e','r','b',0};
|
||||
|
||||
TRACE("(%s, %p)\n", debugstr_guid(clsid), ppenum);
|
||||
|
||||
res = COM_OpenKeyForCLSID(clsid, KEY_READ, &hkeyClass);
|
||||
if (res == ERROR_FILE_NOT_FOUND)
|
||||
res = COM_OpenKeyForCLSID(clsid, wszVerb, KEY_READ, &hkeyVerb);
|
||||
if (FAILED(res))
|
||||
{
|
||||
ERR("CLSID %s not registered\n", debugstr_guid(clsid));
|
||||
return REGDB_E_CLASSNOTREG;
|
||||
}
|
||||
else if (res != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("failed to open key for CLSID %s with error %ld\n",
|
||||
debugstr_guid(clsid), res);
|
||||
return REGDB_E_READREGDB;
|
||||
}
|
||||
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;
|
||||
if (res == REGDB_E_CLASSNOTREG)
|
||||
ERR("CLSID %s not registered\n", debugstr_guid(clsid));
|
||||
else if (res == REGDB_E_KEYMISSING)
|
||||
ERR("no Verbs key for class %s\n", debugstr_guid(clsid));
|
||||
else
|
||||
ERR("failed to open Verbs key for CLSID %s with error %ld\n",
|
||||
debugstr_guid(clsid), res);
|
||||
return res;
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
if (COM_OpenKeyForCLSID(clsidOld, KEY_READ | KEY_WRITE, &hkey))
|
||||
{
|
||||
res = REGDB_E_CLASSNOTREG;
|
||||
goto done;
|
||||
}
|
||||
res = COM_OpenKeyForCLSID(clsidOld, NULL, KEY_READ | KEY_WRITE, &hkey);
|
||||
if (FAILED(res))
|
||||
goto done;
|
||||
StringFromGUID2(clsidNew, szClsidNew, CHARS_IN_GUID);
|
||||
if (RegSetValueW(hkey, wszAutoConvertTo, REG_SZ, szClsidNew, (strlenW(szClsidNew)+1) * sizeof(WCHAR)))
|
||||
{
|
||||
|
|
|
@ -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 embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 };
|
||||
HKEY hkeyclsid;
|
||||
HKEY key;
|
||||
HRESULT hres;
|
||||
WCHAR command[MAX_PATH+sizeof(embedding)/sizeof(WCHAR)];
|
||||
|
@ -629,18 +628,10 @@ static HRESULT create_server(REFCLSID rclsid)
|
|||
STARTUPINFOW sinfo;
|
||||
PROCESS_INFORMATION pinfo;
|
||||
|
||||
hres = HRESULT_FROM_WIN32(COM_OpenKeyForCLSID(rclsid, KEY_READ, &hkeyclsid));
|
||||
if (hres != S_OK) {
|
||||
hres = COM_OpenKeyForCLSID(rclsid, wszLocalServer32, KEY_READ, &key);
|
||||
if (FAILED(hres)) {
|
||||
ERR("class %s not registered\n", debugstr_guid(rclsid));
|
||||
return REGDB_E_READREGDB;
|
||||
}
|
||||
|
||||
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 */
|
||||
return hres;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
HRESULT hres = REGDB_E_READREGDB;
|
||||
HRESULT hres;
|
||||
WCHAR buf[CHARS_IN_GUID], keyname[50];
|
||||
static const WCHAR szAppId[] = { '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));
|
||||
|
||||
/* read the AppID value under the class's key */
|
||||
r = COM_OpenKeyForCLSID(rclsid, KEY_READ, &hkey);
|
||||
if (r!=ERROR_SUCCESS)
|
||||
hres = COM_OpenKeyForCLSID(rclsid, szAppId, KEY_READ, &hkey);
|
||||
if (FAILED(hres))
|
||||
return hres;
|
||||
sz = sizeof buf;
|
||||
r = RegQueryValueExW(hkey, szAppId, NULL, &type, (LPBYTE)buf, &sz);
|
||||
r = RegQueryValueExW(hkey, NULL, NULL, &type, (LPBYTE)buf, &sz);
|
||||
RegCloseKey(hkey);
|
||||
if (r!=ERROR_SUCCESS || type!=REG_SZ)
|
||||
return hres;
|
||||
|
|
Loading…
Reference in New Issue