ole32: Fix behaviour of OLE init/uninit.
Signed-off-by: Paul Gofman <gofmanp@gmail.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a8d426e93a
commit
b4b0c138fe
|
@ -1972,6 +1972,8 @@ void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
|
||||||
|
|
||||||
if (!--info->inits)
|
if (!--info->inits)
|
||||||
{
|
{
|
||||||
|
if (info->ole_inits)
|
||||||
|
WARN("uninitializing apartment while Ole is still initialized\n");
|
||||||
apartment_release(info->apt);
|
apartment_release(info->apt);
|
||||||
info->apt = NULL;
|
info->apt = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,6 +186,8 @@ HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
|
||||||
|
|
||||||
if (!COM_CurrentInfo()->ole_inits)
|
if (!COM_CurrentInfo()->ole_inits)
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
|
else
|
||||||
|
hr = S_FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Then, it has to initialize the OLE specific modules.
|
* Then, it has to initialize the OLE specific modules.
|
||||||
|
@ -229,6 +231,11 @@ void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
|
||||||
{
|
{
|
||||||
TRACE("()\n");
|
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.
|
* If we hit the bottom of the lock stack, free the libraries.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2181,6 +2181,73 @@ static void test_CoInitializeEx(void)
|
||||||
OleUninitialize();
|
OleUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_OleInitialize_InitCounting(void)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
IUnknown *pUnk;
|
||||||
|
REFCLSID rclsid = &CLSID_InternetZoneManager;
|
||||||
|
|
||||||
|
/* 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)
|
static void test_OleRegGetMiscStatus(void)
|
||||||
{
|
{
|
||||||
ULONG_PTR cookie;
|
ULONG_PTR cookie;
|
||||||
|
@ -2871,6 +2938,7 @@ START_TEST(compobj)
|
||||||
test_CoGetContextToken();
|
test_CoGetContextToken();
|
||||||
test_TreatAsClass();
|
test_TreatAsClass();
|
||||||
test_CoInitializeEx();
|
test_CoInitializeEx();
|
||||||
|
test_OleInitialize_InitCounting();
|
||||||
test_OleRegGetMiscStatus();
|
test_OleRegGetMiscStatus();
|
||||||
test_CoCreateGuid();
|
test_CoCreateGuid();
|
||||||
test_CoWaitForMultipleHandles();
|
test_CoWaitForMultipleHandles();
|
||||||
|
|
Loading…
Reference in New Issue