diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index a62bf88d738..91fe4198dae 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -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; diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h index 6947ef485f5..8364c6caae6 100644 --- a/dlls/ole32/compobj_private.h +++ b/dlls/ole32/compobj_private.h @@ -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 */ diff --git a/dlls/ole32/ole16.c b/dlls/ole32/ole16.c index 64f5a250d93..b70d55a1c40 100644 --- a/dlls/ole32/ole16.c +++ b/dlls/ole32/ole16.c @@ -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; } diff --git a/dlls/ole32/ole2.c b/dlls/ole32/ole2.c index 552d9da109b..13ebc38a58d 100644 --- a/dlls/ole32/ole2.c +++ b/dlls/ole32/ole2.c @@ -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))) { diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c index 2196337e30a..b50c594d932 100644 --- a/dlls/ole32/rpc.c +++ b/dlls/ole32/rpc.c @@ -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;