Commit 1dcf3f8e authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

ole32/tests: Test calling CoDisconnectObject from within a COM call to the object.

parent 327100fe
...@@ -2927,6 +2927,63 @@ static void UnlockModuleOOP(void) ...@@ -2927,6 +2927,63 @@ static void UnlockModuleOOP(void)
static HWND hwnd_app; static HWND hwnd_app;
struct local_server
{
IPersist IPersist_iface; /* a nice short interface */
};
static HRESULT WINAPI local_server_QueryInterface(IPersist *iface, REFIID iid, void **obj)
{
*obj = NULL;
if (IsEqualGUID(iid, &IID_IUnknown) ||
IsEqualGUID(iid, &IID_IPersist))
*obj = iface;
if (*obj)
{
IPersist_AddRef(iface);
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI local_server_AddRef(IPersist *iface)
{
return 2;
}
static ULONG WINAPI local_server_Release(IPersist *iface)
{
return 1;
}
static HRESULT WINAPI local_server_GetClassID(IPersist *iface, CLSID *clsid)
{
HRESULT hr;
*clsid = IID_IUnknown;
/* Test calling CoDisconnectObject within a COM call */
hr = CoDisconnectObject((IUnknown *)iface, 0);
ok(hr == S_OK, "got %08x\n", hr);
return S_OK;
}
static const IPersistVtbl local_server_persist_vtbl =
{
local_server_QueryInterface,
local_server_AddRef,
local_server_Release,
local_server_GetClassID
};
struct local_server local_server_class =
{
{&local_server_persist_vtbl}
};
static HRESULT WINAPI TestOOP_IClassFactory_QueryInterface( static HRESULT WINAPI TestOOP_IClassFactory_QueryInterface(
LPCLASSFACTORY iface, LPCLASSFACTORY iface,
REFIID riid, REFIID riid,
...@@ -2961,12 +3018,12 @@ static HRESULT WINAPI TestOOP_IClassFactory_CreateInstance( ...@@ -2961,12 +3018,12 @@ static HRESULT WINAPI TestOOP_IClassFactory_CreateInstance(
REFIID riid, REFIID riid,
LPVOID *ppvObj) LPVOID *ppvObj)
{ {
if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown)) IPersist *persist = &local_server_class.IPersist_iface;
{ HRESULT hr;
*ppvObj = iface; IPersist_AddRef( persist );
return S_OK; hr = IPersist_QueryInterface( persist, riid, ppvObj );
} IPersist_Release( persist );
return CLASS_E_CLASSNOTAVAILABLE; return hr;
} }
static HRESULT WINAPI TestOOP_IClassFactory_LockServer( static HRESULT WINAPI TestOOP_IClassFactory_LockServer(
...@@ -2996,24 +3053,25 @@ static void test_register_local_server(void) ...@@ -2996,24 +3053,25 @@ static void test_register_local_server(void)
DWORD cookie; DWORD cookie;
HRESULT hr; HRESULT hr;
HANDLE ready_event; HANDLE ready_event;
HANDLE quit_event;
DWORD wait; DWORD wait;
HANDLE handles[2];
heventShutdown = CreateEventA(NULL, TRUE, FALSE, NULL); heventShutdown = CreateEventA(NULL, TRUE, FALSE, NULL);
ready_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Ready Event");
handles[0] = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Quit Event");
handles[1] = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Repeat Event");
again:
hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&TestOOP_ClassFactory, hr = CoRegisterClassObject(&CLSID_WineOOPTest, (IUnknown *)&TestOOP_ClassFactory,
CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie); CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
ok_ole_success(hr, CoRegisterClassObject); ok_ole_success(hr, CoRegisterClassObject);
ready_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Ready Event");
SetEvent(ready_event); SetEvent(ready_event);
quit_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Quit Event");
do do
{ {
wait = MsgWaitForMultipleObjects(1, &quit_event, FALSE, 30000, QS_ALLINPUT); wait = MsgWaitForMultipleObjects(2, handles, FALSE, 30000, QS_ALLINPUT);
if (wait == WAIT_OBJECT_0+1) if (wait == WAIT_OBJECT_0+2)
{ {
MSG msg; MSG msg;
...@@ -3024,12 +3082,20 @@ static void test_register_local_server(void) ...@@ -3024,12 +3082,20 @@ static void test_register_local_server(void)
DispatchMessageA(&msg); DispatchMessageA(&msg);
} }
} }
else if (wait == WAIT_OBJECT_0+1)
{
hr = CoRevokeClassObject(cookie);
ok_ole_success(hr, CoRevokeClassObject);
goto again;
}
} }
while (wait == WAIT_OBJECT_0+1); while (wait == WAIT_OBJECT_0+2);
ok( wait == WAIT_OBJECT_0, "quit event wait timed out\n" ); ok( wait == WAIT_OBJECT_0, "quit event wait timed out\n" );
hr = CoRevokeClassObject(cookie); hr = CoRevokeClassObject(cookie);
ok_ole_success(hr, CoRevokeClassObject); ok_ole_success(hr, CoRevokeClassObject);
CloseHandle(handles[0]);
CloseHandle(handles[1]);
} }
static HANDLE create_target_process(const char *arg) static HANDLE create_target_process(const char *arg)
...@@ -3057,10 +3123,13 @@ static void test_local_server(void) ...@@ -3057,10 +3123,13 @@ static void test_local_server(void)
DWORD cookie; DWORD cookie;
HRESULT hr; HRESULT hr;
IClassFactory * cf; IClassFactory * cf;
IPersist *persist;
DWORD ret; DWORD ret;
HANDLE process; HANDLE process;
HANDLE quit_event; HANDLE quit_event;
HANDLE ready_event; HANDLE ready_event;
HANDLE repeat_event;
CLSID clsid;
heventShutdown = CreateEventA(NULL, TRUE, FALSE, NULL); heventShutdown = CreateEventA(NULL, TRUE, FALSE, NULL);
...@@ -3127,16 +3196,30 @@ static void test_local_server(void) ...@@ -3127,16 +3196,30 @@ static void test_local_server(void)
ready_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Ready Event"); ready_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Ready Event");
ok( !WaitForSingleObject(ready_event, 10000), "wait timed out\n" ); ok( !WaitForSingleObject(ready_event, 10000), "wait timed out\n" );
CloseHandle(ready_event);
hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IClassFactory, (void **)&cf); hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IPersist, (void **)&persist);
ok_ole_success(hr, CoCreateInstance); ok_ole_success(hr, CoCreateInstance);
IClassFactory_Release(cf); IPersist_Release(persist);
hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IClassFactory, (void **)&cf); hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IPersist, (void **)&persist);
ok(hr == REGDB_E_CLASSNOTREG, "Second CoCreateInstance on REGCLS_SINGLEUSE object should have failed\n"); ok(hr == REGDB_E_CLASSNOTREG, "Second CoCreateInstance on REGCLS_SINGLEUSE object should have failed\n");
/* Re-register the class and try calling CoDisconnectObject from within a call to that object */
repeat_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Repeat Event");
SetEvent(repeat_event);
CloseHandle(repeat_event);
ok( !WaitForSingleObject(ready_event, 10000), "wait timed out\n" );
CloseHandle(ready_event);
hr = CoCreateInstance(&CLSID_WineOOPTest, NULL, CLSCTX_LOCAL_SERVER, &IID_IPersist, (void **)&persist);
ok_ole_success(hr, CoCreateInstance);
/* GetClassID will call CoDisconnectObject */
IPersist_GetClassID(persist, &clsid);
IPersist_Release(persist);
quit_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Quit Event"); quit_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Quit Event");
SetEvent(quit_event); SetEvent(quit_event);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment