From a58bf9591479f9feff3609ef846af9d7563b9caa Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sun, 26 Jan 2025 19:24:24 +0900 Subject: [PATCH] [SHELL32][SHELL32_APITEST][SDK] SHIsBadInterfacePtr (#7664) Implementing missing features... JIRA issue: CORE-19278 - Move function definition from stubs.cpp to utils.cpp. - Implement SHIsBadInterfacePtr function in utils.cpp. - Add prototype to . --- dll/win32/shell32/stubs.cpp | 11 ---- dll/win32/shell32/utils.cpp | 24 +++++++++ .../rostests/apitests/shell32/CMakeLists.txt | 1 + .../apitests/shell32/SHIsBadInterfacePtr.cpp | 53 +++++++++++++++++++ modules/rostests/apitests/shell32/testlist.c | 2 + sdk/include/reactos/undocshell.h | 5 ++ 6 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 modules/rostests/apitests/shell32/SHIsBadInterfacePtr.cpp diff --git a/dll/win32/shell32/stubs.cpp b/dll/win32/shell32/stubs.cpp index f9ef73a2d7e..3034c25d9fd 100644 --- a/dll/win32/shell32/stubs.cpp +++ b/dll/win32/shell32/stubs.cpp @@ -566,17 +566,6 @@ DDECreatePostNotify(LPVOID lpUnknown) return NULL; } -/* - * Unimplemented - */ -EXTERN_C BOOL -WINAPI -SHIsBadInterfacePtr(LPVOID pv, UINT ucb) -{ - FIXME("SHIsBadInterfacePtr() stub\n"); - return FALSE; -} - /* * Unimplemented */ diff --git a/dll/win32/shell32/utils.cpp b/dll/win32/shell32/utils.cpp index 8214a9bb10c..693a8619aff 100644 --- a/dll/win32/shell32/utils.cpp +++ b/dll/win32/shell32/utils.cpp @@ -1809,6 +1809,30 @@ SHELL_CreateShell32DefaultExtractIcon(int IconIndex, REFIID riid, LPVOID *ppvOut return initIcon->QueryInterface(riid, ppvOut); } +/************************************************************************* + * SHIsBadInterfacePtr [SHELL32.84] + * + * Retired in 6.0 from Windows Vista and higher. + */ +EXTERN_C +BOOL WINAPI +SHIsBadInterfacePtr( + _In_ LPCVOID pv, + _In_ UINT_PTR ucb) +{ + struct CUnknownVtbl + { + HRESULT (STDMETHODCALLTYPE *QueryInterface)(REFIID riid, LPVOID *ppvObj); + ULONG (STDMETHODCALLTYPE *AddRef)(); + ULONG (STDMETHODCALLTYPE *Release)(); + }; + struct CUnknown { CUnknownVtbl *lpVtbl; }; + const CUnknown *punk = reinterpret_cast(pv); + return !punk || IsBadReadPtr(punk, sizeof(punk->lpVtbl)) || + IsBadReadPtr(punk->lpVtbl, ucb) || + IsBadCodePtr((FARPROC)punk->lpVtbl->Release); +} + /************************************************************************* * SHGetUserDisplayName [SHELL32.241] * diff --git a/modules/rostests/apitests/shell32/CMakeLists.txt b/modules/rostests/apitests/shell32/CMakeLists.txt index 3c9a2e73dcf..6f4dfdb00f3 100644 --- a/modules/rostests/apitests/shell32/CMakeLists.txt +++ b/modules/rostests/apitests/shell32/CMakeLists.txt @@ -32,6 +32,7 @@ list(APPEND SOURCE SHCreateFileDataObject.cpp SHCreateFileExtractIconW.cpp SHGetUnreadMailCountW.cpp + SHIsBadInterfacePtr.cpp SHParseDisplayName.cpp SHRestricted.cpp SHShouldShowWizards.cpp diff --git a/modules/rostests/apitests/shell32/SHIsBadInterfacePtr.cpp b/modules/rostests/apitests/shell32/SHIsBadInterfacePtr.cpp new file mode 100644 index 00000000000..d90ad1dfb01 --- /dev/null +++ b/modules/rostests/apitests/shell32/SHIsBadInterfacePtr.cpp @@ -0,0 +1,53 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Test for SHIsBadInterfacePtr + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include "shelltest.h" +#include + +typedef BOOL (WINAPI *FN_SHIsBadInterfacePtr)(LPCVOID, UINT_PTR); + +static HRESULT STDMETHODCALLTYPE dummy_QueryInterface(REFIID riid, LPVOID *ppvObj) { return S_OK; } +static ULONG STDMETHODCALLTYPE dummy_AddRef() { return S_OK; } +static ULONG STDMETHODCALLTYPE dummy_Release() { return S_OK; } + +START_TEST(SHIsBadInterfacePtr) +{ + struct CUnknownVtbl + { + HRESULT (STDMETHODCALLTYPE *QueryInterface)(REFIID riid, LPVOID *ppvObj); + ULONG (STDMETHODCALLTYPE *AddRef)(); + ULONG (STDMETHODCALLTYPE *Release)(); + }; + struct CUnknown { CUnknownVtbl *lpVtbl; }; + + BOOL ret; + FN_SHIsBadInterfacePtr SHIsBadInterfacePtr = + (FN_SHIsBadInterfacePtr)GetProcAddress(GetModuleHandleW(L"shell32"), MAKEINTRESOURCEA(84)); + + if (!SHIsBadInterfacePtr) + { + skip("There is no SHIsBadInterfacePtr\n"); + return; + } + + ret = SHIsBadInterfacePtr(NULL, 1); + ok_int(ret, TRUE); + + CUnknown unk1 = { NULL }; + ret = SHIsBadInterfacePtr(&unk1, 1); + ok_int(ret, TRUE); + + CUnknownVtbl vtbl1 = { dummy_QueryInterface, dummy_AddRef, NULL }; + CUnknown unk2 = { &vtbl1 }; + ret = SHIsBadInterfacePtr(&unk2, 1); + ok_int(ret, TRUE); + + CUnknownVtbl vtbl2 = { dummy_QueryInterface, dummy_AddRef, dummy_Release }; + CUnknown unk3 = { &vtbl2 }; + ret = SHIsBadInterfacePtr(&unk3, 1); + ok_int(ret, FALSE); +} diff --git a/modules/rostests/apitests/shell32/testlist.c b/modules/rostests/apitests/shell32/testlist.c index 3c1cbd7e045..91078fb8cc1 100644 --- a/modules/rostests/apitests/shell32/testlist.c +++ b/modules/rostests/apitests/shell32/testlist.c @@ -46,6 +46,7 @@ extern void func_SHGetAttributesFromDataObject(void); extern void func_SHGetFileInfo(void); extern void func_SHGetUnreadMailCountW(void); extern void func_SHGetUserDisplayName(void); +extern void func_SHIsBadInterfacePtr(void); extern void func_SHLimitInputEdit(void); extern void func_SHParseDisplayName(void); extern void func_SHShouldShowWizards(void); @@ -99,6 +100,7 @@ const struct test winetest_testlist[] = { "SHGetFileInfo", func_SHGetFileInfo }, { "SHGetUnreadMailCountW", func_SHGetUnreadMailCountW }, { "SHGetUserDisplayName", func_SHGetUserDisplayName }, + { "SHIsBadInterfacePtr", func_SHIsBadInterfacePtr }, { "SHLimitInputEdit", func_SHLimitInputEdit }, { "SHParseDisplayName", func_SHParseDisplayName }, { "SHShouldShowWizards", func_SHShouldShowWizards }, diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h index 797979334ee..574f4851e1a 100644 --- a/sdk/include/reactos/undocshell.h +++ b/sdk/include/reactos/undocshell.h @@ -954,6 +954,11 @@ LONG WINAPI SHRegQueryValueExW( #define SHRegQueryValueEx SHRegQueryValueExA #endif +BOOL WINAPI +SHIsBadInterfacePtr( + _In_ LPCVOID pv, + _In_ UINT_PTR ucb); + HRESULT WINAPI CopyStreamUI( _In_ IStream *pSrc,