Nikolay Sivov : shlwapi: Fix error handling in IUnknown_GetClassID ( Coverity).
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Jun 8 07:49:55 CDT 2015
Module: wine
Branch: master
Commit: b5c2c0b05ad288e933428d08f300fb024bdee6b9
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b5c2c0b05ad288e933428d08f300fb024bdee6b9
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Fri Jun 5 16:21:05 2015 +0300
shlwapi: Fix error handling in IUnknown_GetClassID (Coverity).
---
dlls/shlwapi/ordinal.c | 31 ++++++++-------
dlls/shlwapi/tests/ordinal.c | 92 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 110 insertions(+), 13 deletions(-)
diff --git a/dlls/shlwapi/ordinal.c b/dlls/shlwapi/ordinal.c
index 3da25b4..68b66e3 100644
--- a/dlls/shlwapi/ordinal.c
+++ b/dlls/shlwapi/ordinal.c
@@ -1384,7 +1384,7 @@ HRESULT WINAPI IUnknown_SetSite(
*
* PARAMS
* lpUnknown [I] Object supporting the IPersist interface
- * lpClassId [O] Destination for Class Id
+ * clsid [O] Destination for Class Id
*
* RETURNS
* Success: S_OK. lpClassId contains the Class Id requested.
@@ -1392,23 +1392,28 @@ HRESULT WINAPI IUnknown_SetSite(
* E_NOINTERFACE If lpUnknown does not support IPersist,
* Or an HRESULT error code.
*/
-HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID* lpClassId)
+HRESULT WINAPI IUnknown_GetClassID(IUnknown *lpUnknown, CLSID *clsid)
{
- IPersist* lpPersist;
- HRESULT hRet = E_FAIL;
+ IPersist *persist;
+ HRESULT hr;
- TRACE("(%p,%s)\n", lpUnknown, debugstr_guid(lpClassId));
+ TRACE("(%p, %p)\n", lpUnknown, clsid);
- if (lpUnknown)
- {
- hRet = IUnknown_QueryInterface(lpUnknown,&IID_IPersist,(void**)&lpPersist);
- if (SUCCEEDED(hRet))
+ if (!lpUnknown)
{
- IPersist_GetClassID(lpPersist, lpClassId);
- IPersist_Release(lpPersist);
+ memset(clsid, 0, sizeof(*clsid));
+ return E_FAIL;
}
- }
- return hRet;
+
+ hr = IUnknown_QueryInterface(lpUnknown, &IID_IPersist, (void**)&persist);
+ if (hr != S_OK)
+ hr = IUnknown_QueryInterface(lpUnknown, &IID_IPersistFolder, (void**)&persist);
+ if (hr != S_OK)
+ return hr;
+
+ hr = IPersist_GetClassID(persist, clsid);
+ IPersist_Release(persist);
+ return hr;
}
/*************************************************************************
diff --git a/dlls/shlwapi/tests/ordinal.c b/dlls/shlwapi/tests/ordinal.c
index d8a4f68..9225219 100644
--- a/dlls/shlwapi/tests/ordinal.c
+++ b/dlls/shlwapi/tests/ordinal.c
@@ -69,6 +69,7 @@ static HRESULT (WINAPI *pSKSetValueW)(DWORD, LPCWSTR, LPCWSTR, DWORD, void*, DWO
static HRESULT (WINAPI *pSKDeleteValueW)(DWORD, LPCWSTR, LPCWSTR);
static HRESULT (WINAPI *pSKAllocValueW)(DWORD, LPCWSTR, LPCWSTR, DWORD*, void**, DWORD*);
static HWND (WINAPI *pSHSetParentHwnd)(HWND, HWND);
+static HRESULT (WINAPI *pIUnknown_GetClassID)(IUnknown*, CLSID*);
static HMODULE hmlang;
static HRESULT (WINAPI *pLcidToRfc1766A)(LCID, LPSTR, INT);
@@ -3047,6 +3048,7 @@ static void init_pointers(void)
MAKEFUNC(SHSetWindowBits, 165);
MAKEFUNC(SHSetParentHwnd, 167);
MAKEFUNC(ConnectToConnectionPoint, 168);
+ MAKEFUNC(IUnknown_GetClassID, 175);
MAKEFUNC(SHSearchMapInt, 198);
MAKEFUNC(SHCreateWorkerWindowA, 257);
MAKEFUNC(GUIDFromStringA, 269);
@@ -3152,6 +3154,95 @@ static void test_SHSetParentHwnd(void)
DestroyWindow(hwnd2);
}
+static HRESULT WINAPI testpersist_QI(IPersist *iface, REFIID riid, void **obj)
+{
+ if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPersist)) {
+ *obj = iface;
+ IPersist_AddRef(iface);
+ return S_OK;
+ }
+
+ *obj = NULL;
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI testpersist_QI2(IPersist *iface, REFIID riid, void **obj)
+{
+ if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPersistFolder)) {
+ *obj = iface;
+ IPersist_AddRef(iface);
+ return S_OK;
+ }
+
+ *obj = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI testpersist_AddRef(IPersist *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI testpersist_Release(IPersist *iface)
+{
+ return 1;
+}
+
+static HRESULT WINAPI testpersist_GetClassID(IPersist *iface, CLSID *clsid)
+{
+ memset(clsid, 0xab, sizeof(*clsid));
+ return 0x8fff2222;
+}
+
+static IPersistVtbl testpersistvtbl = {
+ testpersist_QI,
+ testpersist_AddRef,
+ testpersist_Release,
+ testpersist_GetClassID
+};
+
+static IPersistVtbl testpersist2vtbl = {
+ testpersist_QI2,
+ testpersist_AddRef,
+ testpersist_Release,
+ testpersist_GetClassID
+};
+
+static IPersist testpersist = { &testpersistvtbl };
+static IPersist testpersist2 = { &testpersist2vtbl };
+
+static void test_IUnknown_GetClassID(void)
+{
+ CLSID clsid, clsid2, clsid3;
+ HRESULT hr;
+
+if (0) /* crashes on native systems */
+ hr = pIUnknown_GetClassID(NULL, NULL);
+
+ memset(&clsid, 0xcc, sizeof(clsid));
+ memset(&clsid3, 0xcc, sizeof(clsid3));
+ hr = pIUnknown_GetClassID(NULL, &clsid);
+ ok(hr == E_FAIL, "got 0x%08x\n", hr);
+ ok(IsEqualCLSID(&clsid, &CLSID_NULL) || broken(IsEqualCLSID(&clsid, &clsid3)) /* win2k, winxp, win2k3 */,
+ "got wrong clsid %s\n", wine_dbgstr_guid(&clsid));
+
+ memset(&clsid, 0xcc, sizeof(clsid));
+ memset(&clsid2, 0xab, sizeof(clsid2));
+ hr = pIUnknown_GetClassID((IUnknown*)&testpersist, &clsid);
+ ok(hr == 0x8fff2222, "got 0x%08x\n", hr);
+ ok(IsEqualCLSID(&clsid, &clsid2) || broken(IsEqualCLSID(&clsid, &clsid3)) /* win2k3 */,
+ "got wrong clsid %s\n", wine_dbgstr_guid(&clsid));
+
+ /* IPersistFolder is also supported */
+ memset(&clsid, 0xcc, sizeof(clsid));
+ memset(&clsid2, 0xab, sizeof(clsid2));
+ memset(&clsid3, 0xcc, sizeof(clsid3));
+ hr = pIUnknown_GetClassID((IUnknown*)&testpersist2, &clsid);
+ ok(hr == 0x8fff2222, "got 0x%08x\n", hr);
+ ok(IsEqualCLSID(&clsid, &clsid2) || broken(IsEqualCLSID(&clsid, &clsid3)) /* win2k3 */,
+ "got wrong clsid %s\n", wine_dbgstr_guid(&clsid));
+}
+
START_TEST(ordinal)
{
char **argv;
@@ -3206,6 +3297,7 @@ START_TEST(ordinal)
test_SHSetIniString();
test_SHGetShellKey();
test_SHSetParentHwnd();
+ test_IUnknown_GetClassID();
FreeLibrary(hshell32);
FreeLibrary(hmlang);
More information about the wine-cvs
mailing list