shell32: Check for internal shell classes before querying the registry in SHCoCreateInstance.
This commit is contained in:
parent
9984ac8a12
commit
d7892ccf2b
|
@ -128,10 +128,8 @@ HRESULT WINAPI SHCoCreateInstance(
|
||||||
const WCHAR sInProcServer32[16] ={'\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2','\0'};
|
const WCHAR sInProcServer32[16] ={'\\','I','n','p','r','o','c','S','e','r','v','e','r','3','2','\0'};
|
||||||
const WCHAR sLoadWithoutCOM[15] ={'L','o','a','d','W','i','t','h','o','u','t','C','O','M','\0'};
|
const WCHAR sLoadWithoutCOM[15] ={'L','o','a','d','W','i','t','h','o','u','t','C','O','M','\0'};
|
||||||
WCHAR sDllPath[MAX_PATH];
|
WCHAR sDllPath[MAX_PATH];
|
||||||
HKEY hKey;
|
HKEY hKey = 0;
|
||||||
DWORD dwSize;
|
DWORD dwSize;
|
||||||
BOOLEAN bLoadFromShell32 = FALSE;
|
|
||||||
BOOLEAN bLoadWithoutCOM = FALSE;
|
|
||||||
IClassFactory * pcf = NULL;
|
IClassFactory * pcf = NULL;
|
||||||
|
|
||||||
if(!ppv) return E_POINTER;
|
if(!ppv) return E_POINTER;
|
||||||
|
@ -148,42 +146,33 @@ HRESULT WINAPI SHCoCreateInstance(
|
||||||
TRACE("(%p,%s,unk:%p,%s,%p)\n",
|
TRACE("(%p,%s,unk:%p,%s,%p)\n",
|
||||||
aclsid,shdebugstr_guid(myclsid),pUnkOuter,shdebugstr_guid(refiid),ppv);
|
aclsid,shdebugstr_guid(myclsid),pUnkOuter,shdebugstr_guid(refiid),ppv);
|
||||||
|
|
||||||
|
if (SUCCEEDED(DllGetClassObject(myclsid, &IID_IClassFactory,(LPVOID*)&pcf)))
|
||||||
|
{
|
||||||
|
hres = IClassFactory_CreateInstance(pcf, pUnkOuter, refiid, ppv);
|
||||||
|
IClassFactory_Release(pcf);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
/* we look up the dll path in the registry */
|
/* we look up the dll path in the registry */
|
||||||
__SHGUIDToStringW(myclsid, sClassID);
|
__SHGUIDToStringW(myclsid, sClassID);
|
||||||
lstrcpyW(sKeyName, sCLSID);
|
lstrcpyW(sKeyName, sCLSID);
|
||||||
lstrcatW(sKeyName, sClassID);
|
lstrcatW(sKeyName, sClassID);
|
||||||
lstrcatW(sKeyName, sInProcServer32);
|
lstrcatW(sKeyName, sInProcServer32);
|
||||||
|
|
||||||
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_CLASSES_ROOT, sKeyName, 0, KEY_READ, &hKey)) {
|
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, sKeyName, 0, KEY_READ, &hKey))
|
||||||
dwSize = sizeof(sDllPath);
|
return E_ACCESSDENIED;
|
||||||
SHQueryValueExW(hKey, NULL, 0,0, sDllPath, &dwSize );
|
|
||||||
|
|
||||||
/* if a special registry key is set, we load a shell extension without help of OLE32 */
|
|
||||||
bLoadWithoutCOM = (ERROR_SUCCESS == SHQueryValueExW(hKey, sLoadWithoutCOM, 0, 0, 0, 0));
|
|
||||||
|
|
||||||
/* if the com object is inside shell32, omit use of ole32 */
|
|
||||||
bLoadFromShell32 = (0==lstrcmpiW( PathFindFileNameW(sDllPath), sShell32));
|
|
||||||
|
|
||||||
RegCloseKey (hKey);
|
|
||||||
} else {
|
|
||||||
/* since we can't find it in the registry we try internally */
|
|
||||||
bLoadFromShell32 = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
TRACE("WithoutCom=%u FromShell=%u\n", bLoadWithoutCOM, bLoadFromShell32);
|
|
||||||
|
|
||||||
/* now we create an instance */
|
|
||||||
if (bLoadFromShell32) {
|
|
||||||
if (! SUCCEEDED(DllGetClassObject(myclsid, &IID_IClassFactory,(LPVOID*)&pcf))) {
|
|
||||||
ERR("LoadFromShell failed for CLSID=%s\n", shdebugstr_guid(myclsid));
|
|
||||||
}
|
|
||||||
} else if (bLoadWithoutCOM) {
|
|
||||||
|
|
||||||
|
/* if a special registry key is set, we load a shell extension without help of OLE32 */
|
||||||
|
if (!SHQueryValueExW(hKey, sLoadWithoutCOM, 0, 0, 0, 0))
|
||||||
|
{
|
||||||
/* load an external dll without ole32 */
|
/* load an external dll without ole32 */
|
||||||
HANDLE hLibrary;
|
HANDLE hLibrary;
|
||||||
typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
|
typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
|
||||||
DllGetClassObjectFunc DllGetClassObject;
|
DllGetClassObjectFunc DllGetClassObject;
|
||||||
|
|
||||||
|
dwSize = sizeof(sDllPath);
|
||||||
|
SHQueryValueExW(hKey, NULL, 0,0, sDllPath, &dwSize );
|
||||||
|
|
||||||
if ((hLibrary = LoadLibraryExW(sDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) {
|
if ((hLibrary = LoadLibraryExW(sDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) {
|
||||||
ERR("couldn't load InprocServer32 dll %s\n", debugstr_w(sDllPath));
|
ERR("couldn't load InprocServer32 dll %s\n", debugstr_w(sDllPath));
|
||||||
hres = E_ACCESSDENIED;
|
hres = E_ACCESSDENIED;
|
||||||
|
@ -198,19 +187,16 @@ HRESULT WINAPI SHCoCreateInstance(
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hres = IClassFactory_CreateInstance(pcf, pUnkOuter, refiid, ppv);
|
||||||
|
IClassFactory_Release(pcf);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* load an external dll in the usual way */
|
/* load an external dll in the usual way */
|
||||||
hres = CoCreateInstance(myclsid, pUnkOuter, CLSCTX_INPROC_SERVER, refiid, ppv);
|
hres = CoCreateInstance(myclsid, pUnkOuter, CLSCTX_INPROC_SERVER, refiid, ppv);
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* here we should have a ClassFactory */
|
|
||||||
if (!pcf) return E_ACCESSDENIED;
|
|
||||||
|
|
||||||
hres = IClassFactory_CreateInstance(pcf, pUnkOuter, refiid, ppv);
|
|
||||||
IClassFactory_Release(pcf);
|
|
||||||
end:
|
end:
|
||||||
|
if (hKey) RegCloseKey(hKey);
|
||||||
if(hres!=S_OK)
|
if(hres!=S_OK)
|
||||||
{
|
{
|
||||||
ERR("failed (0x%08x) to create CLSID:%s IID:%s\n",
|
ERR("failed (0x%08x) to create CLSID:%s IID:%s\n",
|
||||||
|
|
Loading…
Reference in New Issue