[PATCH] ole32: Make CoGetInstanceFromFile() propagate failure codes to returned MULTI_QI data (Coverity)

Nikolay Sivov nsivov at codeweavers.com
Sun Mar 20 13:07:40 CDT 2016


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/ole32/compobj.c       |  34 +++---
 dlls/ole32/tests/compobj.c | 252 ++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 273 insertions(+), 13 deletions(-)

diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index 857f985..ced6f7d 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -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)
diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c
index 43556d9..215d68f 100644
--- a/dlls/ole32/tests/compobj.c
+++ b/dlls/ole32/tests/compobj.c
@@ -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();
 }
-- 
2.7.0




More information about the wine-patches mailing list