ole32: Implement CoRegisterPSClsid.
This commit is contained in:
parent
fb6bd2414b
commit
2308d49bcb
|
@ -94,6 +94,13 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
|
|||
};
|
||||
static CRITICAL_SECTION csApartment = { &critsect_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
struct registered_psclsid
|
||||
{
|
||||
struct list entry;
|
||||
IID iid;
|
||||
CLSID clsid;
|
||||
};
|
||||
|
||||
/*
|
||||
* This lock count counts the number of times CoInitialize is called. It is
|
||||
* decreased every time CoUninitialize is called. When it hits 0, the COM
|
||||
|
@ -220,6 +227,7 @@ static APARTMENT *apartment_construct(DWORD model)
|
|||
|
||||
list_init(&apt->proxies);
|
||||
list_init(&apt->stubmgrs);
|
||||
list_init(&apt->psclsids);
|
||||
apt->ipidc = 0;
|
||||
apt->refs = 1;
|
||||
apt->remunk_exported = FALSE;
|
||||
|
@ -343,6 +351,15 @@ DWORD apartment_release(struct apartment *apt)
|
|||
stub_manager_int_release(stubmgr);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_SAFE(cursor, cursor2, &apt->psclsids)
|
||||
{
|
||||
struct registered_psclsid *registered_psclsid =
|
||||
LIST_ENTRY(cursor, struct registered_psclsid, entry);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, registered_psclsid);
|
||||
list_remove(®istered_psclsid->entry);
|
||||
}
|
||||
|
||||
/* if this assert fires, then another thread took a reference to a
|
||||
* stub manager without taking a reference to the containing
|
||||
* apartment, which it must do. */
|
||||
|
@ -1147,11 +1164,12 @@ HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID riid)
|
|||
*
|
||||
* BUGS
|
||||
*
|
||||
* We only search the registry, not ids registered with
|
||||
* CoRegisterPSClsid.
|
||||
* Also, native returns S_OK for interfaces with a key in HKCR\Interface, but
|
||||
* Native returns S_OK for interfaces with a key in HKCR\Interface, but
|
||||
* without a ProxyStubClsid32 key and leaves garbage in pclsid. This should be
|
||||
* considered a bug in native unless an application depends on this (unlikely).
|
||||
*
|
||||
* SEE ALSO
|
||||
* CoRegisterPSClsid.
|
||||
*/
|
||||
HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
|
||||
{
|
||||
|
@ -1161,9 +1179,29 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
|
|||
WCHAR value[CHARS_IN_GUID];
|
||||
LONG len;
|
||||
HKEY hkey;
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
struct registered_psclsid *registered_psclsid;
|
||||
|
||||
TRACE("() riid=%s, pclsid=%p\n", debugstr_guid(riid), pclsid);
|
||||
|
||||
if (!apt)
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&apt->cs);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(registered_psclsid, &apt->psclsids, struct registered_psclsid, entry)
|
||||
if (IsEqualIID(®istered_psclsid->iid, riid))
|
||||
{
|
||||
*pclsid = registered_psclsid->clsid;
|
||||
LeaveCriticalSection(&apt->cs);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&apt->cs);
|
||||
|
||||
/* Interface\\{string form of riid}\\ProxyStubClsid32 */
|
||||
strcpyW(path, wszInterface);
|
||||
StringFromGUID2(riid, path + ARRAYSIZE(wszInterface) - 1, CHARS_IN_GUID);
|
||||
|
@ -1196,6 +1234,67 @@ HRESULT WINAPI CoGetPSClsid(REFIID riid, CLSID *pclsid)
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* CoRegisterPSClsid [OLE32.@]
|
||||
*
|
||||
* Register a proxy/stub CLSID for the given interface in the current process
|
||||
* only.
|
||||
*
|
||||
* PARAMS
|
||||
* riid [I] Interface whose proxy/stub CLSID is to be registered.
|
||||
* rclsid [I] CLSID of the proxy/stub.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK
|
||||
* Failure: E_OUTOFMEMORY
|
||||
*
|
||||
* NOTES
|
||||
*
|
||||
* This function does not add anything to the registry and the effects are
|
||||
* limited to the lifetime of the current process.
|
||||
*
|
||||
* SEE ALSO
|
||||
* CoGetPSClsid.
|
||||
*/
|
||||
HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid)
|
||||
{
|
||||
APARTMENT *apt = COM_CurrentApt();
|
||||
struct registered_psclsid *registered_psclsid;
|
||||
|
||||
TRACE("(%s, %s)\n", debugstr_guid(riid), debugstr_guid(rclsid));
|
||||
|
||||
if (!apt)
|
||||
{
|
||||
ERR("apartment not initialised\n");
|
||||
return CO_E_NOTINITIALIZED;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&apt->cs);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(registered_psclsid, &apt->psclsids, struct registered_psclsid, entry)
|
||||
if (IsEqualIID(®istered_psclsid->iid, riid))
|
||||
{
|
||||
registered_psclsid->clsid = *rclsid;
|
||||
LeaveCriticalSection(&apt->cs);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
registered_psclsid = HeapAlloc(GetProcessHeap(), 0, sizeof(struct registered_psclsid));
|
||||
if (!registered_psclsid)
|
||||
{
|
||||
LeaveCriticalSection(&apt->cs);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
registered_psclsid->iid = *riid;
|
||||
registered_psclsid->clsid = *rclsid;
|
||||
list_add_head(&apt->psclsids, ®istered_psclsid->entry);
|
||||
|
||||
LeaveCriticalSection(&apt->cs);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -152,6 +152,7 @@ struct apartment
|
|||
struct list stubmgrs; /* stub managers for exported objects (CS cs) */
|
||||
BOOL remunk_exported; /* has the IRemUnknown interface for this apartment been created yet? (CS cs) */
|
||||
LONG remoting_started; /* has the RPC system been started for this apartment? (LOCK) */
|
||||
struct list psclsids; /* list of registered PS CLSIDs (CS cs) */
|
||||
|
||||
/* FIXME: OID's should be given out by RPCSS */
|
||||
OID oidc; /* object ID counter, starts at 1, zero is invalid OID (CS cs) */
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
@ stdcall CoRegisterClassObject(ptr ptr long long ptr)
|
||||
@ stdcall CoRegisterMallocSpy (ptr)
|
||||
@ stdcall CoRegisterMessageFilter(ptr ptr)
|
||||
@ stub CoRegisterPSClsid #@ stdcall (ptr ptr) return 0,ERR_NOTIMPLEMENTED
|
||||
@ stdcall CoRegisterPSClsid(ptr ptr)
|
||||
@ stub CoRegisterSurrogate
|
||||
@ stdcall CoReleaseMarshalData(ptr)
|
||||
@ stdcall CoReleaseServerProcess()
|
||||
|
|
|
@ -48,6 +48,15 @@ static const WCHAR wszCLSID_CDeviceMoniker[] =
|
|||
'}',0
|
||||
};
|
||||
|
||||
static const IID IID_IWineTest =
|
||||
{
|
||||
0x5201163f,
|
||||
0x8164,
|
||||
0x4fd0,
|
||||
{0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
|
||||
}; /* 5201163f-8164-4fd0-a1a2-5d5a3654d3bd */
|
||||
|
||||
|
||||
static void test_ProgIDFromCLSID(void)
|
||||
{
|
||||
LPWSTR progid;
|
||||
|
@ -253,6 +262,148 @@ static void test_CoRegisterMessageFilter(void)
|
|||
CoUninitialize();
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Test_IUnknown_QueryInterface(
|
||||
LPUNKNOWN iface,
|
||||
REFIID riid,
|
||||
LPVOID *ppvObj)
|
||||
{
|
||||
if (ppvObj == NULL) return E_POINTER;
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IWineTest))
|
||||
{
|
||||
*ppvObj = (LPVOID)iface;
|
||||
IUnknown_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*ppvObj = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI Test_IUnknown_AddRef(LPUNKNOWN iface)
|
||||
{
|
||||
return 2; /* non-heap-based object */
|
||||
}
|
||||
|
||||
static ULONG WINAPI Test_IUnknown_Release(LPUNKNOWN iface)
|
||||
{
|
||||
return 1; /* non-heap-based object */
|
||||
}
|
||||
|
||||
static const IUnknownVtbl TestUnknown_Vtbl =
|
||||
{
|
||||
Test_IUnknown_QueryInterface,
|
||||
Test_IUnknown_AddRef,
|
||||
Test_IUnknown_Release,
|
||||
};
|
||||
|
||||
static IUnknown Test_Unknown = { &TestUnknown_Vtbl };
|
||||
|
||||
static HRESULT WINAPI PSFactoryBuffer_QueryInterface(
|
||||
IPSFactoryBuffer * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [iid_is][out] */ void **ppvObject)
|
||||
{
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IPSFactoryBuffer))
|
||||
{
|
||||
*ppvObject = This;
|
||||
IPSFactoryBuffer_AddRef(This);
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static ULONG WINAPI PSFactoryBuffer_AddRef(
|
||||
IPSFactoryBuffer * This)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI PSFactoryBuffer_Release(
|
||||
IPSFactoryBuffer * This)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PSFactoryBuffer_CreateProxy(
|
||||
IPSFactoryBuffer * This,
|
||||
/* [in] */ IUnknown *pUnkOuter,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [out] */ IRpcProxyBuffer **ppProxy,
|
||||
/* [out] */ void **ppv)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI PSFactoryBuffer_CreateStub(
|
||||
IPSFactoryBuffer * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [unique][in] */ IUnknown *pUnkServer,
|
||||
/* [out] */ IRpcStubBuffer **ppStub)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static IPSFactoryBufferVtbl PSFactoryBufferVtbl =
|
||||
{
|
||||
PSFactoryBuffer_QueryInterface,
|
||||
PSFactoryBuffer_AddRef,
|
||||
PSFactoryBuffer_Release,
|
||||
PSFactoryBuffer_CreateProxy,
|
||||
PSFactoryBuffer_CreateStub
|
||||
};
|
||||
|
||||
static IPSFactoryBuffer PSFactoryBuffer = { &PSFactoryBufferVtbl };
|
||||
|
||||
static const CLSID CLSID_WineTestPSFactoryBuffer =
|
||||
{
|
||||
0x52011640,
|
||||
0x8164,
|
||||
0x4fd0,
|
||||
{0xa1, 0xa2, 0x5d, 0x5a, 0x36, 0x54, 0xd3, 0xbd}
|
||||
}; /* 52011640-8164-4fd0-a1a2-5d5a3654d3bd */
|
||||
|
||||
static void test_CoRegisterPSClsid(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
DWORD dwRegistrationKey;
|
||||
IStream *stream;
|
||||
CLSID clsid;
|
||||
|
||||
hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
|
||||
ok(hr == CO_E_NOTINITIALIZED, "CoRegisterPSClsid should have returened CO_E_NOTINITIALIZED instead of 0x%08lx\n", hr);
|
||||
|
||||
pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
hr = CoRegisterClassObject(&CLSID_WineTestPSFactoryBuffer, (IUnknown *)&PSFactoryBuffer,
|
||||
CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegistrationKey);
|
||||
ok_ole_success(hr, "CoRegisterClassObject");
|
||||
|
||||
hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
|
||||
ok_ole_success(hr, "CoRegisterPSClsid");
|
||||
|
||||
hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
|
||||
ok_ole_success(hr, "CreateStreamOnHGlobal");
|
||||
|
||||
hr = CoMarshalInterface(stream, &IID_IWineTest, (IUnknown *)&Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
|
||||
ok(hr == E_NOTIMPL, "CoMarshalInterface should have returned E_NOTIMPL instead of 0x%08lx\n", hr);
|
||||
IStream_Release(stream);
|
||||
|
||||
hr = CoRevokeClassObject(dwRegistrationKey);
|
||||
ok_ole_success(hr, "CoRevokeClassObject");
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
hr = CoGetPSClsid(&IID_IWineTest, &clsid);
|
||||
ok(hr == REGDB_E_IIDNOTREG, "CoGetPSClsid should have returned REGDB_E_IIDNOTREG instead of 0x%08lx\n", hr);
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
START_TEST(compobj)
|
||||
{
|
||||
HMODULE hOle32 = GetModuleHandle("ole32");
|
||||
|
@ -269,4 +420,5 @@ START_TEST(compobj)
|
|||
test_ole_menu();
|
||||
test_CoGetClassObject();
|
||||
test_CoRegisterMessageFilter();
|
||||
test_CoRegisterPSClsid();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue