[PATCH 3/4] ole32/tests: Test calling CoDisconnectObject from within a COM call to the object.
Huw Davies
huw at codeweavers.com
Tue Oct 13 08:49:16 CDT 2015
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/ole32/tests/marshal.c | 117 ++++++++++++++++++++++++++++++++++++++-------
1 file changed, 100 insertions(+), 17 deletions(-)
diff --git a/dlls/ole32/tests/marshal.c b/dlls/ole32/tests/marshal.c
index 55c32d6..afa58a5 100644
--- a/dlls/ole32/tests/marshal.c
+++ b/dlls/ole32/tests/marshal.c
@@ -2927,6 +2927,63 @@ static void UnlockModuleOOP(void)
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(
LPCLASSFACTORY iface,
REFIID riid,
@@ -2961,12 +3018,12 @@ static HRESULT WINAPI TestOOP_IClassFactory_CreateInstance(
REFIID riid,
LPVOID *ppvObj)
{
- if (IsEqualIID(riid, &IID_IClassFactory) || IsEqualIID(riid, &IID_IUnknown))
- {
- *ppvObj = iface;
- return S_OK;
- }
- return CLASS_E_CLASSNOTAVAILABLE;
+ IPersist *persist = &local_server_class.IPersist_iface;
+ HRESULT hr;
+ IPersist_AddRef( persist );
+ hr = IPersist_QueryInterface( persist, riid, ppvObj );
+ IPersist_Release( persist );
+ return hr;
}
static HRESULT WINAPI TestOOP_IClassFactory_LockServer(
@@ -2996,24 +3053,25 @@ static void test_register_local_server(void)
DWORD cookie;
HRESULT hr;
HANDLE ready_event;
- HANDLE quit_event;
DWORD wait;
+ HANDLE handles[2];
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,
CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &cookie);
ok_ole_success(hr, CoRegisterClassObject);
- ready_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Ready Event");
SetEvent(ready_event);
- quit_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Quit Event");
-
do
{
- wait = MsgWaitForMultipleObjects(1, &quit_event, FALSE, 30000, QS_ALLINPUT);
- if (wait == WAIT_OBJECT_0+1)
+ wait = MsgWaitForMultipleObjects(2, handles, FALSE, 30000, QS_ALLINPUT);
+ if (wait == WAIT_OBJECT_0+2)
{
MSG msg;
@@ -3024,12 +3082,20 @@ static void test_register_local_server(void)
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" );
hr = CoRevokeClassObject(cookie);
ok_ole_success(hr, CoRevokeClassObject);
+ CloseHandle(handles[0]);
+ CloseHandle(handles[1]);
}
static HANDLE create_target_process(const char *arg)
@@ -3057,10 +3123,13 @@ static void test_local_server(void)
DWORD cookie;
HRESULT hr;
IClassFactory * cf;
+ IPersist *persist;
DWORD ret;
HANDLE process;
HANDLE quit_event;
HANDLE ready_event;
+ HANDLE repeat_event;
+ CLSID clsid;
heventShutdown = CreateEventA(NULL, TRUE, FALSE, NULL);
@@ -3127,16 +3196,30 @@ static void test_local_server(void)
ready_event = CreateEventA(NULL, FALSE, FALSE, "Wine COM Test Ready Event");
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);
- 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");
+ /* 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");
SetEvent(quit_event);
--
1.8.0
More information about the wine-patches
mailing list