[PATCH v2] ole32: better match native behaviour in OLE init/uninit ole32/tests: check COM/OLE init state after mixed COM/OLE init/uninit
Paul Gofman
gofmanp at gmail.com
Wed Jan 13 04:16:42 CST 2016
Native OleUnitialize never uninits apartment inited by CoInitializeEx.
CoUnitialize after OleInitialize uninits apartment, but Ole is still considered
inited.
Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
dlls/ole32/compobj.c | 2 ++
dlls/ole32/ole2.c | 7 +++++
dlls/ole32/tests/compobj.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 79 insertions(+)
diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 90b049a..78fc30d 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -1972,6 +1972,8 @@ void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
if (!--info->inits)
{
+ if (info->ole_inits)
+ ERR("uninitializing apartment while Ole is still initialized\n");
apartment_release(info->apt);
info->apt = NULL;
}
diff --git a/dlls/ole32/ole2.c b/dlls/ole32/ole2.c
index 7929d3d..f078fb6 100644
--- a/dlls/ole32/ole2.c
+++ b/dlls/ole32/ole2.c
@@ -186,6 +186,8 @@ HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
if (!COM_CurrentInfo()->ole_inits)
hr = S_OK;
+ else
+ hr = S_FALSE;
/*
* Then, it has to initialize the OLE specific modules.
@@ -229,6 +231,11 @@ void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
{
TRACE("()\n");
+ if (COM_CurrentInfo()->ole_inits == 0)
+ {
+ WARN("ole_inits is already 0\n");
+ return ;
+ }
/*
* If we hit the bottom of the lock stack, free the libraries.
*/
diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c
index 5fe9876..3ee5470 100644
--- a/dlls/ole32/tests/compobj.c
+++ b/dlls/ole32/tests/compobj.c
@@ -2181,6 +2181,75 @@ static void test_CoInitializeEx(void)
OleUninitialize();
}
+static void test_OleInitialize_InitCounting(void)
+{
+ HRESULT hr;
+ HANDLE thread;
+ IUnknown *pUnk;
+ REFCLSID rclsid = &CLSID_InternetZoneManager;
+ IDataObject *pDObj;
+
+ /* 1. OleInitialize fails but OleUnintialize is still called: apartment stays inited */
+ hr = pCoInitializeEx(NULL, COINIT_MULTITHREADED);
+ ok(hr == S_OK, "CoInitializeEx(COINIT_MULTITHREADED) failed with error 0x%08x\n", hr);
+
+ hr = OleInitialize(NULL);
+ ok(hr == RPC_E_CHANGED_MODE, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", RPC_E_CHANGED_MODE, hr);
+ OleUninitialize();
+
+ pUnk = (IUnknown *)0xdeadbeef;
+ hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
+ ok(hr == S_OK, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", S_OK, hr);
+ if (pUnk) IUnknown_Release(pUnk);
+
+ CoUninitialize();
+
+ /* 2. Extra multiple OleUninitialize: apartment stays inited until CoUnitialize */
+ hr = CoInitialize(NULL);
+ ok(hr == S_OK, "CoInitialize() failed with error 0x%08x\n", hr);
+
+ hr = OleInitialize(NULL);
+ ok(hr == S_OK, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_OK, hr);
+ OleUninitialize();
+ OleUninitialize();
+ OleUninitialize();
+
+ pUnk = (IUnknown *)0xdeadbeef;
+ hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
+ ok(hr == S_OK, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", S_OK, hr);
+ if (pUnk) IUnknown_Release(pUnk);
+
+ CoUninitialize();
+
+ pUnk = (IUnknown *)0xdeadbeef;
+ hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
+ ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", CO_E_NOTINITIALIZED, hr);
+ if (pUnk) IUnknown_Release(pUnk);
+
+ /* 3. CoUninitialize does not formally deinit Ole */
+ hr = CoInitialize(NULL);
+ ok(hr == S_OK, "CoInitialize() failed with error 0x%08x\n", hr);
+
+ hr = OleInitialize(NULL);
+ ok(hr == S_OK, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_OK, hr);
+
+ CoUninitialize();
+ CoUninitialize();
+
+ pUnk = (IUnknown *)0xdeadbeef;
+ hr = CoCreateInstance(rclsid, NULL, 0x17, &IID_IUnknown, (void **)&pUnk);
+ ok(hr == CO_E_NOTINITIALIZED, "CoCreateInstance should have returned 0x%08x instead of 0x%08x\n", CO_E_NOTINITIALIZED, hr);
+ /* COM is not initialized anymore */
+ if (pUnk) IUnknown_Release(pUnk);
+
+ hr = OleInitialize(NULL);
+ ok(hr == S_FALSE, "OleInitialize should have returned 0x%08x instead of 0x%08x\n", S_FALSE, hr);
+ /* ... but native OleInit returns S_FALSE as if Ole is considered initialized */
+
+ OleUninitialize();
+
+}
+
static void test_OleRegGetMiscStatus(void)
{
ULONG_PTR cookie;
@@ -2871,6 +2940,7 @@ START_TEST(compobj)
test_CoGetContextToken();
test_TreatAsClass();
test_CoInitializeEx();
+ test_OleInitialize_InitCounting();
test_OleRegGetMiscStatus();
test_CoCreateGuid();
test_CoWaitForMultipleHandles();
--
2.5.0
More information about the wine-patches
mailing list