ole32: COM_GetRegisteredClassObject should only retrieve objects that were registered in the current apartment.

This commit is contained in:
Rob Shearman 2007-05-07 23:59:09 +01:00 committed by Alexandre Julliard
parent e93c82e643
commit 51f85a765b
2 changed files with 15 additions and 12 deletions

View File

@ -76,9 +76,9 @@ HINSTANCE OLE32_hInstance = 0; /* FIXME: make static ... */
* TODO: Most of these things will have to be made thread-safe. * TODO: Most of these things will have to be made thread-safe.
*/ */
static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD dwClsContext, LPUNKNOWN* ppUnk); static HRESULT COM_GetRegisteredClassObject(struct apartment *apt, REFCLSID rclsid, DWORD dwClsContext, LPUNKNOWN* ppUnk);
static void COM_RevokeAllClasses(struct apartment *apt); static void COM_RevokeAllClasses(struct apartment *apt);
static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv); static HRESULT get_inproc_class_object(APARTMENT *apt, HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv);
static APARTMENT *MTA; /* protected by csApartment */ static APARTMENT *MTA; /* protected by csApartment */
static APARTMENT *MainApartment; /* the first STA apartment */ static APARTMENT *MainApartment; /* the first STA apartment */
@ -1583,6 +1583,7 @@ HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid)
* reference count on this object. * reference count on this object.
*/ */
static HRESULT COM_GetRegisteredClassObject( static HRESULT COM_GetRegisteredClassObject(
struct apartment *apt,
REFCLSID rclsid, REFCLSID rclsid,
DWORD dwClsContext, DWORD dwClsContext,
LPUNKNOWN* ppUnk) LPUNKNOWN* ppUnk)
@ -1602,7 +1603,8 @@ static HRESULT COM_GetRegisteredClassObject(
/* /*
* Check if we have a match on the class ID and context. * Check if we have a match on the class ID and context.
*/ */
if ((dwClsContext & curClass->runContext) && if ((apt->oxid == curClass->apartment_id) &&
(dwClsContext & curClass->runContext) &&
IsEqualGUID(&(curClass->classIdentifier), rclsid)) IsEqualGUID(&(curClass->classIdentifier), rclsid))
{ {
/* /*
@ -1699,7 +1701,7 @@ HRESULT WINAPI CoRegisterClassObject(
* First, check if the class is already registered. * First, check if the class is already registered.
* If it is, this should cause an error. * If it is, this should cause an error.
*/ */
hr = COM_GetRegisteredClassObject(rclsid, dwClsContext, &foundObject); hr = COM_GetRegisteredClassObject(apt, rclsid, dwClsContext, &foundObject);
if (hr == S_OK) { if (hr == S_OK) {
if (flags & REGCLS_MULTIPLEUSE) { if (flags & REGCLS_MULTIPLEUSE) {
if (dwClsContext & CLSCTX_LOCAL_SERVER) if (dwClsContext & CLSCTX_LOCAL_SERVER)
@ -1867,7 +1869,8 @@ static void get_threading_model(HKEY key, LPWSTR value, DWORD len)
value[0] = '\0'; value[0] = '\0';
} }
static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv) static HRESULT get_inproc_class_object(APARTMENT *apt, HKEY hkeydll,
REFCLSID rclsid, REFIID riid, void **ppv)
{ {
static const WCHAR wszApartment[] = {'A','p','a','r','t','m','e','n','t',0}; static const WCHAR wszApartment[] = {'A','p','a','r','t','m','e','n','t',0};
static const WCHAR wszFree[] = {'F','r','e','e',0}; static const WCHAR wszFree[] = {'F','r','e','e',0};
@ -1875,7 +1878,6 @@ static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID rii
WCHAR dllpath[MAX_PATH+1]; WCHAR dllpath[MAX_PATH+1];
WCHAR threading_model[10 /* strlenW(L"apartment")+1 */]; WCHAR threading_model[10 /* strlenW(L"apartment")+1 */];
HRESULT hr; HRESULT hr;
APARTMENT *apt = COM_CurrentApt();
get_threading_model(hkeydll, threading_model, ARRAYSIZE(threading_model)); get_threading_model(hkeydll, threading_model, ARRAYSIZE(threading_model));
/* "Apartment" */ /* "Apartment" */
@ -1991,6 +1993,7 @@ HRESULT WINAPI CoGetClassObject(
{ {
LPUNKNOWN regClassObject; LPUNKNOWN regClassObject;
HRESULT hres = E_UNEXPECTED; HRESULT hres = E_UNEXPECTED;
APARTMENT *apt;
TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid)); TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
@ -1999,7 +2002,8 @@ HRESULT WINAPI CoGetClassObject(
*ppv = NULL; *ppv = NULL;
if (!COM_CurrentApt()) apt = COM_CurrentApt();
if (!apt)
{ {
ERR("apartment not initialised\n"); ERR("apartment not initialised\n");
return CO_E_NOTINITIALIZED; return CO_E_NOTINITIALIZED;
@ -2014,7 +2018,8 @@ HRESULT WINAPI CoGetClassObject(
* First, try and see if we can't match the class ID with one of the * First, try and see if we can't match the class ID with one of the
* registered classes. * registered classes.
*/ */
if (S_OK == COM_GetRegisteredClassObject(rclsid, dwClsContext, &regClassObject)) if (S_OK == COM_GetRegisteredClassObject(apt, rclsid, dwClsContext,
&regClassObject))
{ {
/* Get the required interface from the retrieved pointer. */ /* Get the required interface from the retrieved pointer. */
hres = IUnknown_QueryInterface(regClassObject, iid, ppv); hres = IUnknown_QueryInterface(regClassObject, iid, ppv);
@ -2052,7 +2057,7 @@ HRESULT WINAPI CoGetClassObject(
if (SUCCEEDED(hres)) if (SUCCEEDED(hres))
{ {
hres = get_inproc_class_object(hkey, rclsid, iid, ppv); hres = get_inproc_class_object(apt, hkey, rclsid, iid, ppv);
RegCloseKey(hkey); RegCloseKey(hkey);
} }
@ -2082,7 +2087,7 @@ HRESULT WINAPI CoGetClassObject(
if (SUCCEEDED(hres)) if (SUCCEEDED(hres))
{ {
hres = get_inproc_class_object(hkey, rclsid, iid, ppv); hres = get_inproc_class_object(apt, hkey, rclsid, iid, ppv);
RegCloseKey(hkey); RegCloseKey(hkey);
} }

View File

@ -797,7 +797,6 @@ static void test_registered_object_thread_affinity(void)
WaitForSingleObject(thread, INFINITE); WaitForSingleObject(thread, INFINITE);
GetExitCodeThread(thread, &exitcode); GetExitCodeThread(thread, &exitcode);
hr = exitcode; hr = exitcode;
todo_wine
ok(hr == REGDB_E_CLASSNOTREG, "CoGetClassObject on inproc object " ok(hr == REGDB_E_CLASSNOTREG, "CoGetClassObject on inproc object "
"registered in different thread should return REGDB_E_CLASSNOTREG " "registered in different thread should return REGDB_E_CLASSNOTREG "
"instead of 0x%08x\n", hr); "instead of 0x%08x\n", hr);
@ -811,7 +810,6 @@ static void test_registered_object_thread_affinity(void)
WaitForSingleObject(thread, INFINITE); WaitForSingleObject(thread, INFINITE);
GetExitCodeThread(thread, &exitcode); GetExitCodeThread(thread, &exitcode);
hr = exitcode; hr = exitcode;
todo_wine
ok(hr == S_OK, "CoRegisterClassObject with same CLSID but in different thread should return S_OK instead of 0x%08x\n", hr); ok(hr == S_OK, "CoRegisterClassObject with same CLSID but in different thread should return S_OK instead of 0x%08x\n", hr);
hr = CoRevokeClassObject(cookie); hr = CoRevokeClassObject(cookie);