ole32: Make CoGetInstanceFromFile() propagate failure codes to returned MULTI_QI data (Coverity).

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2016-03-20 21:07:40 +03:00 committed by Alexandre Julliard
parent 450a343f77
commit 7863247ec6
2 changed files with 273 additions and 13 deletions

View File

@ -3203,14 +3203,14 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(
return hres;
}
static void init_multi_qi(DWORD count, MULTI_QI *mqi)
static void init_multi_qi(DWORD count, MULTI_QI *mqi, HRESULT hr)
{
ULONG i;
for (i = 0; i < count; i++)
{
mqi[i].pItf = NULL;
mqi[i].hr = E_NOINTERFACE;
mqi[i].hr = hr;
}
}
@ -3266,7 +3266,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstanceEx(
if (pServerInfo)
FIXME("() non-NULL pServerInfo not supported!\n");
init_multi_qi(cmq, pResults);
init_multi_qi(cmq, pResults, E_NOINTERFACE);
hres = CoGetTreatAsClass(rclsid, &clsid);
if(FAILED(hres))
@ -3350,7 +3350,7 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetInstanceFromFile(
if (server_info)
FIXME("() non-NULL server_info not supported\n");
init_multi_qi(count, results);
init_multi_qi(count, results, E_NOINTERFACE);
/* optionally get CLSID from a file */
if (!rclsid)
@ -3372,20 +3372,30 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetInstanceFromFile(
(void**)&unk);
if (hr != S_OK)
return hr;
{
init_multi_qi(count, results, hr);
return hr;
}
/* init from file */
hr = IUnknown_QueryInterface(unk, &IID_IPersistFile, (void**)&pf);
if (FAILED(hr))
ERR("failed to get IPersistFile\n");
if (pf)
{
IPersistFile_Load(pf, filename, grfmode);
IPersistFile_Release(pf);
init_multi_qi(count, results, hr);
IUnknown_Release(unk);
return hr;
}
return return_multi_qi(unk, count, results, FALSE);
hr = IPersistFile_Load(pf, filename, grfmode);
IPersistFile_Release(pf);
if (SUCCEEDED(hr))
return return_multi_qi(unk, count, results, FALSE);
else
{
init_multi_qi(count, results, hr);
IUnknown_Release(unk);
return hr;
}
}
/***********************************************************************
@ -3412,7 +3422,7 @@ HRESULT WINAPI CoGetInstanceFromIStorage(
if (server_info)
FIXME("() non-NULL server_info not supported\n");
init_multi_qi(count, results);
init_multi_qi(count, results, E_NOINTERFACE);
/* optionally get CLSID from a file */
if (!rclsid)

View File

@ -95,6 +95,7 @@ static const GUID IID_Testiface6 = { 0x72222222, 0x1234, 0x1234, { 0x12, 0x34, 0
static const GUID IID_TestPS = { 0x66666666, 0x8888, 0x7777, { 0x66, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 } };
DEFINE_GUID(CLSID_InProcFreeMarshaler, 0x0000033a,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
DEFINE_GUID(CLSID_testclsid, 0xacd014c7,0x9535,0x4fac,0x8b,0x53,0xa4,0x8c,0xa7,0xf4,0xd7,0x26);
static const WCHAR stdfont[] = {'S','t','d','F','o','n','t',0};
static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0};
@ -2966,7 +2967,6 @@ static void test_CoGetApartmentType(void)
CoUninitialize();
}
static HRESULT WINAPI testspy_QI(IMallocSpy *iface, REFIID riid, void **obj)
{
if (IsEqualIID(riid, &IID_IMallocSpy) || IsEqualIID(riid, &IID_IUnknown))
@ -3261,6 +3261,255 @@ todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
}
static HRESULT g_persistfile_qi_ret;
static HRESULT g_persistfile_load_ret;
static HRESULT WINAPI testinstance_QI(IPersistFile *iface, REFIID riid, void **obj)
{
if (IsEqualIID(riid, &IID_IUnknown)) {
*obj = iface;
IUnknown_AddRef(iface);
return S_OK;
}
if (IsEqualIID(riid, &IID_IPersistFile)) {
if (SUCCEEDED(g_persistfile_qi_ret)) {
*obj = iface;
IUnknown_AddRef(iface);
}
else
*obj = NULL;
return g_persistfile_qi_ret;
}
ok(0, "unexpected riid %s\n", wine_dbgstr_guid(riid));
*obj = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI testinstance_AddRef(IPersistFile *iface)
{
return 2;
}
static ULONG WINAPI testinstance_Release(IPersistFile *iface)
{
return 1;
}
static HRESULT WINAPI testinstance_GetClassID(IPersistFile *iface, CLSID *clsid)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI testinstance_IsDirty(IPersistFile *iface)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI testinstance_Load(IPersistFile *iface, LPCOLESTR filename, DWORD mode)
{
return g_persistfile_load_ret;
}
static HRESULT WINAPI testinstance_Save(IPersistFile *iface, LPCOLESTR filename, BOOL remember)
{
return E_NOTIMPL;
}
static HRESULT WINAPI testinstance_SaveCompleted(IPersistFile *iface, LPCOLESTR filename)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI testinstance_GetCurFile(IPersistFile *iface, LPOLESTR *filename)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static const IPersistFileVtbl testpersistfilevtbl = {
testinstance_QI,
testinstance_AddRef,
testinstance_Release,
testinstance_GetClassID,
testinstance_IsDirty,
testinstance_Load,
testinstance_Save,
testinstance_SaveCompleted,
testinstance_GetCurFile
};
static IPersistFile testpersistfile = { &testpersistfilevtbl };
static HRESULT WINAPI getinstance_cf_QI(IClassFactory *iface, REFIID riid, void **obj)
{
if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) {
*obj = iface;
IClassFactory_AddRef(iface);
return S_OK;
}
*obj = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI getinstance_cf_AddRef(IClassFactory *iface)
{
return 2;
}
static ULONG WINAPI getinstance_cf_Release(IClassFactory *iface)
{
return 1;
}
static HRESULT WINAPI getinstance_cf_CreateInstance(IClassFactory *iface, IUnknown *outer,
REFIID riid, void **obj)
{
if (IsEqualIID(riid, &IID_IUnknown)) {
*obj = &testpersistfile;
return S_OK;
}
ok(0, "unexpected call, riid %s\n", wine_dbgstr_guid(riid));
*obj = NULL;
return E_NOTIMPL;
}
static HRESULT WINAPI getinstance_cf_LockServer(IClassFactory *iface, BOOL lock)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static const IClassFactoryVtbl getinstance_cf_vtbl = {
getinstance_cf_QI,
getinstance_cf_AddRef,
getinstance_cf_Release,
getinstance_cf_CreateInstance,
getinstance_cf_LockServer
};
static IClassFactory getinstance_cf = { &getinstance_cf_vtbl };
static void test_CoGetInstanceFromFile(void)
{
static const WCHAR filenameW[] = {'d','u','m','m','y','p','a','t','h',0};
CLSID *clsid = (CLSID*)&CLSID_testclsid;
MULTI_QI mqi[2];
DWORD cookie;
HRESULT hr;
hr = pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
ok(hr == S_OK, "got 0x%08x\n", hr);
/* CLSID is not specified, file does not exist */
mqi[0].pIID = &IID_IUnknown;
mqi[0].pItf = NULL;
mqi[0].hr = E_NOTIMPL;
hr = CoGetInstanceFromFile(NULL, NULL, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
todo_wine
ok(hr == MK_E_CANTOPENFILE, "got 0x%08x\n", hr);
ok(mqi[0].pItf == NULL, "got %p\n", mqi[0].pItf);
ok(mqi[0].hr == E_NOINTERFACE, "got 0x%08x\n", mqi[0].hr);
/* class is not available */
mqi[0].pIID = &IID_IUnknown;
mqi[0].pItf = NULL;
mqi[0].hr = E_NOTIMPL;
hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
ok(hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", hr);
ok(mqi[0].pItf == NULL, "got %p\n", mqi[0].pItf);
ok(mqi[0].hr == REGDB_E_CLASSNOTREG, "got 0x%08x\n", mqi[0].hr);
hr = CoRegisterClassObject(clsid, (IUnknown*)&getinstance_cf, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE,
&cookie);
ok(hr == S_OK, "got 0x%08x\n", hr);
mqi[0].pIID = &IID_IUnknown;
mqi[0].pItf = (void*)0xdeadbeef;
mqi[0].hr = S_OK;
hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
todo_wine {
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
ok(mqi[0].pItf == (void*)0xdeadbeef, "got %p\n", mqi[0].pItf);
}
ok(mqi[0].hr == S_OK, "got 0x%08x\n", mqi[0].hr);
mqi[0].pIID = &IID_IUnknown;
mqi[0].pItf = (void*)0xdeadbeef;
mqi[0].hr = E_NOTIMPL;
hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
todo_wine {
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
ok(mqi[0].pItf == (void*)0xdeadbeef, "got %p\n", mqi[0].pItf);
ok(mqi[0].hr == E_NOTIMPL, "got 0x%08x\n", mqi[0].hr);
}
mqi[0].pIID = &IID_IUnknown;
mqi[0].pItf = NULL;
mqi[0].hr = E_NOTIMPL;
hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(mqi[0].pItf != NULL, "got %p\n", mqi[0].pItf);
ok(mqi[0].hr == S_OK, "got 0x%08x\n", mqi[0].hr);
mqi[0].pIID = &IID_IUnknown;
mqi[0].pItf = NULL;
mqi[0].hr = S_OK;
hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(mqi[0].pItf != NULL, "got %p\n", mqi[0].pItf);
ok(mqi[0].hr == S_OK, "got 0x%08x\n", mqi[0].hr);
mqi[0].pIID = &IID_IUnknown;
mqi[0].pItf = NULL;
mqi[0].hr = S_OK;
g_persistfile_qi_ret = S_FALSE;
hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 1, mqi);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(mqi[0].pItf != NULL, "got %p\n", mqi[0].pItf);
ok(mqi[0].hr == S_OK, "got 0x%08x\n", mqi[0].hr);
g_persistfile_qi_ret = S_OK;
mqi[0].pIID = &IID_IUnknown;
mqi[0].pItf = NULL;
mqi[0].hr = S_OK;
mqi[1].pIID = &IID_IUnknown;
mqi[1].pItf = NULL;
mqi[1].hr = S_OK;
g_persistfile_qi_ret = 0x8000efef;
hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 2, mqi);
ok(hr == 0x8000efef, "got 0x%08x\n", hr);
ok(mqi[0].pItf == NULL, "got %p\n", mqi[0].pItf);
ok(mqi[0].hr == 0x8000efef, "got 0x%08x\n", mqi[0].hr);
ok(mqi[1].pItf == NULL, "got %p\n", mqi[1].pItf);
ok(mqi[1].hr == 0x8000efef, "got 0x%08x\n", mqi[1].hr);
g_persistfile_qi_ret = S_OK;
mqi[0].pIID = &IID_IUnknown;
mqi[0].pItf = NULL;
mqi[0].hr = S_OK;
mqi[1].pIID = &IID_IUnknown;
mqi[1].pItf = NULL;
mqi[1].hr = S_OK;
g_persistfile_load_ret = 0x8000fefe;
hr = CoGetInstanceFromFile(NULL, clsid, NULL, CLSCTX_INPROC_SERVER, STGM_READ, (OLECHAR*)filenameW, 2, mqi);
ok(hr == 0x8000fefe, "got 0x%08x\n", hr);
ok(mqi[0].pItf == NULL, "got %p\n", mqi[0].pItf);
ok(mqi[0].hr == 0x8000fefe, "got 0x%08x\n", mqi[0].hr);
ok(mqi[1].pItf == NULL, "got %p\n", mqi[1].pItf);
ok(mqi[1].hr == 0x8000fefe, "got 0x%08x\n", mqi[1].hr);
g_persistfile_load_ret = S_OK;
hr = CoRevokeClassObject(cookie);
ok(hr == S_OK, "got 0x%08x\n", hr);
CoUninitialize();
}
static void init_funcs(void)
{
HMODULE hOle32 = GetModuleHandleA("ole32");
@ -3331,4 +3580,5 @@ START_TEST(compobj)
test_IMallocSpy();
test_CoGetCurrentLogicalThreadId();
test_IInitializeSpy();
test_CoGetInstanceFromFile();
}