https://git.reactos.org/?p=reactos.git;a=commitdiff;h=57ce30b85fadf28888fdf9...
commit 57ce30b85fadf28888fdf97b094fd2ab94940673 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Tue Jul 25 18:19:22 2023 +0900 Commit: GitHub noreply@github.com CommitDate: Tue Jul 25 18:19:22 2023 +0900
[SHLWAPI][SHLWAPI_APITEST][SDK] Implement SHPropertyBag_WritePOINTL etc. (#5474)
- Implement SHPropertyBag_Delete, SHPropertyBag_WritePOINTL, SHPropertyBag_WritePOINTS, and SHPropertyBag_WriteRECTL functions. - SHPropertyBag_WriteInt is an alias to SHPropertyBag_WriteLONG. - Modify shlwapi.spec. - Modify shlwapi_undoc.h. - Add SHPropertyBag testcase to shlwapi_apitest.exe. CORE-9283 --- dll/win32/shlwapi/ordinal.c | 151 ++++++++++++++++++++ dll/win32/shlwapi/shlwapi.spec | 10 +- modules/rostests/apitests/shlwapi/CMakeLists.txt | 1 + .../rostests/apitests/shlwapi/SHPropertyBag.cpp | 155 +++++++++++++++++++++ modules/rostests/apitests/shlwapi/testlist.c | 2 + sdk/include/reactos/shlwapi_undoc.h | 4 + 6 files changed, 318 insertions(+), 5 deletions(-)
diff --git a/dll/win32/shlwapi/ordinal.c b/dll/win32/shlwapi/ordinal.c index 981d9f68e4f..c7ba39c5cee 100644 --- a/dll/win32/shlwapi/ordinal.c +++ b/dll/win32/shlwapi/ordinal.c @@ -5322,6 +5322,25 @@ HRESULT WINAPI SHPropertyBag_ReadLONG(IPropertyBag *ppb, LPCWSTR pszPropName, LP }
#ifdef __REACTOS__ +/************************************************************************** + * SHPropertyBag_Delete (SHLWAPI.535) + */ +HRESULT WINAPI SHPropertyBag_Delete(IPropertyBag *ppb, LPCWSTR pszPropName) +{ + VARIANT vari; + + TRACE("%p %s\n", ppb, debugstr_w(pszPropName)); + + if (!ppb || !pszPropName) + { + ERR("%p %s\n", ppb, debugstr_w(pszPropName)); + return E_INVALIDARG; + } + + V_VT(&vari) = VT_EMPTY; + return IPropertyBag_Write(ppb, pszPropName, &vari); +} + /************************************************************************** * SHPropertyBag_WriteBOOL (SHLWAPI.499) */ @@ -5471,6 +5490,138 @@ HRESULT WINAPI SHPropertyBag_WriteStream(IPropertyBag *ppb, LPCWSTR pszPropName, V_UNKNOWN(&vari) = (IUnknown*)pStream; return IPropertyBag_Write(ppb, pszPropName, &vari); } + +/************************************************************************** + * SHPropertyBag_WritePOINTL (SHLWAPI.522) + */ +HRESULT WINAPI SHPropertyBag_WritePOINTL(IPropertyBag *ppb, LPCWSTR pszPropName, const POINTL *pptl) +{ + HRESULT hr; + int cch, cch2; + WCHAR *pch, szBuff[MAX_PATH]; + + TRACE("%p %s %p\n", ppb, debugstr_w(pszPropName), pptl); + + if (!ppb || !pszPropName || !pptl) + { + ERR("%p %s %p\n", ppb, debugstr_w(pszPropName), pptl); + return E_INVALIDARG; + } + + StrCpyNW(szBuff, pszPropName, _countof(szBuff)); + + cch = lstrlenW(szBuff); + cch2 = _countof(szBuff) - cch; + if (cch2 < _countof(L".x")) + { + ERR("%s is too long\n", debugstr_w(pszPropName)); + return E_FAIL; + } + + pch = &szBuff[cch]; + + StrCpyNW(pch, L".x", cch2); + hr = SHPropertyBag_WriteLONG(ppb, szBuff, pptl->x); + if (FAILED(hr)) + return hr; + + StrCpyNW(pch, L".y", cch2); + hr = SHPropertyBag_WriteLONG(ppb, szBuff, pptl->y); + if (FAILED(hr)) + { + StrCpyNW(pch, L".x", cch2); + return SHPropertyBag_Delete(ppb, szBuff); + } + + return hr; +} + +/************************************************************************** + * SHPropertyBag_WritePOINTS (SHLWAPI.526) + */ +HRESULT WINAPI SHPropertyBag_WritePOINTS(IPropertyBag *ppb, LPCWSTR pszPropName, const POINTS *ppts) +{ + POINTL pt; + + TRACE("%p %s %p\n", ppb, debugstr_w(pszPropName), ppts); + + if (!ppb || !pszPropName || !ppts) + { + ERR("%p %s %p\n", ppb, debugstr_w(pszPropName), ppts); + return E_INVALIDARG; + } + + pt.x = ppts->x; + pt.y = ppts->y; + return SHPropertyBag_WritePOINTL(ppb, pszPropName, &pt); +} + +/************************************************************************** + * SHPropertyBag_WriteRECTL (SHLWAPI.524) + */ +HRESULT WINAPI SHPropertyBag_WriteRECTL(IPropertyBag *ppb, LPCWSTR pszPropName, const RECTL *prcl) +{ + HRESULT hr; + int cch, cch2; + WCHAR *pch, szBuff[MAX_PATH]; + + TRACE("%p %s %p\n", ppb, debugstr_w(pszPropName), prcl); + + if (!ppb || !pszPropName || !prcl) + { + ERR("%p %s %p\n", ppb, debugstr_w(pszPropName), prcl); + return E_INVALIDARG; + } + + StrCpyNW(szBuff, pszPropName, _countof(szBuff)); + + cch = lstrlenW(szBuff); + cch2 = _countof(szBuff) - cch; + if (cch2 < _countof(L".bottom")) + { + ERR("%s is too long\n", debugstr_w(pszPropName)); + return E_FAIL; + } + + pch = &szBuff[cch]; + + StrCpyNW(pch, L".left", cch2); + hr = SHPropertyBag_WriteLONG(ppb, szBuff, prcl->left); + if (SUCCEEDED(hr)) + { + StrCpyNW(pch, L".top", cch2); + hr = SHPropertyBag_WriteLONG(ppb, szBuff, prcl->top); + if (SUCCEEDED(hr)) + { + StrCpyNW(pch, L".right", cch2); + hr = SHPropertyBag_WriteLONG(ppb, szBuff, prcl->right); + if (SUCCEEDED(hr)) + { + StrCpyNW(pch, L".bottom", cch2); + hr = SHPropertyBag_WriteLONG(ppb, szBuff, prcl->bottom); + if (SUCCEEDED(hr)) + return hr; /* All successful */ + + StrCpyNW(pch, L".right", cch2); + hr = SHPropertyBag_Delete(ppb, szBuff); + if (SUCCEEDED(hr)) + return hr; + } + + StrCpyNW(pch, L".top", cch2); + hr = SHPropertyBag_Delete(ppb, szBuff); + if (SUCCEEDED(hr)) + return hr; + } + + StrCpyNW(pch, L".left", cch2); + hr = SHPropertyBag_Delete(ppb, szBuff); + if (SUCCEEDED(hr)) + return hr; + } + + return hr; +} #endif
/* return flags for SHGetObjectCompatFlags, names derived from registry value names */ diff --git a/dll/win32/shlwapi/shlwapi.spec b/dll/win32/shlwapi/shlwapi.spec index 786ed81b005..0833bd8f20a 100644 --- a/dll/win32/shlwapi/shlwapi.spec +++ b/dll/win32/shlwapi/shlwapi.spec @@ -519,20 +519,20 @@ 519 stdcall -noname SKAllocValueW(long wstr wstr ptr ptr ptr) 520 stub -noname SHPropertyBag_ReadBSTR 521 stub -noname SHPropertyBag_ReadPOINTL -522 stub -noname SHPropertyBag_WritePOINTL +522 stdcall -noname SHPropertyBag_WritePOINTL(ptr wstr ptr) 523 stub -noname SHPropertyBag_ReadRECTL -524 stub -noname SHPropertyBag_WriteRECTL +524 stdcall -noname SHPropertyBag_WriteRECTL(ptr wstr ptr) 525 stub -noname SHPropertyBag_ReadPOINTS -526 stub -noname SHPropertyBag_WritePOINTS +526 stdcall -noname SHPropertyBag_WritePOINTS(ptr wstr ptr) 527 stub -noname SHPropertyBag_ReadSHORT 528 stdcall -noname SHPropertyBag_WriteSHORT(ptr wstr long) 529 stub -noname SHPropertyBag_ReadInt -530 stub -noname SHPropertyBag_WriteInt +530 stdcall -noname SHPropertyBag_WriteInt(ptr wstr long) SHPropertyBag_WriteLONG 531 stub -noname SHPropertyBag_ReadStream 532 stdcall -noname SHPropertyBag_WriteStream(ptr wstr ptr) 533 stub -noname SHGetPerScreenResName 534 stub -noname SHPropertyBag_ReadBOOL -535 stub -noname SHPropertyBag_Delete +535 stdcall -noname SHPropertyBag_Delete(ptr wstr) 536 stdcall -stub -noname IUnknown_QueryServicePropertyBag(ptr long ptr ptr) 537 stub -noname SHBoolSystemParametersInfo 538 stdcall -noname IUnknown_QueryServiceForWebBrowserApp(ptr ptr ptr) diff --git a/modules/rostests/apitests/shlwapi/CMakeLists.txt b/modules/rostests/apitests/shlwapi/CMakeLists.txt index 47636a5cae6..34fb46fb71e 100644 --- a/modules/rostests/apitests/shlwapi/CMakeLists.txt +++ b/modules/rostests/apitests/shlwapi/CMakeLists.txt @@ -14,6 +14,7 @@ list(APPEND SOURCE SHAreIconsEqual.c SHLoadIndirectString.c SHLoadRegUIString.c + SHPropertyBag.cpp StrFormatByteSizeW.c testdata.rc testlist.c) diff --git a/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp b/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp new file mode 100644 index 00000000000..6291f25d17e --- /dev/null +++ b/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp @@ -0,0 +1,155 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Tests for SHPropertyBag Read/Write + * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com + */ + +#include <apitest.h> +#include <shlwapi.h> +#include <shlobj.h> +#include <shlwapi_undoc.h> + +#include <pseh/pseh2.h> + +static LPCWSTR s_pszPropNames[4] = { NULL, NULL, NULL, NULL }; +static VARTYPE s_vt; +static INT s_cWrite = 0; + +static void ResetTest(VARTYPE vt, + LPCWSTR pszName0 = NULL, LPCWSTR pszName1 = NULL, + LPCWSTR pszName2 = NULL, LPCWSTR pszName3 = NULL) +{ + s_vt = vt; + s_cWrite = 0; + s_pszPropNames[0] = pszName0; + s_pszPropNames[1] = pszName1; + s_pszPropNames[2] = pszName2; + s_pszPropNames[3] = pszName3; +} + +class CDummyWritePropertyBag : public IPropertyBag +{ +public: + CDummyWritePropertyBag() + { + } + + // IUnknown + STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override + { + ok_int(0, 1); + return S_OK; + } + STDMETHODIMP_(ULONG) AddRef() override + { + ok_int(0, 1); + return S_OK; + } + STDMETHODIMP_(ULONG) Release() override + { + ok_int(0, 1); + return S_OK; + } + + // IPropertyBag + STDMETHODIMP Read(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog *pErrorLog) override + { + ok_int(0, 1); + return S_OK; + } + + STDMETHODIMP Write(LPCWSTR pszPropName, VARIANT *pvari) override + { + ++s_cWrite; + ok_int(s_vt, V_VT(pvari)); + for (size_t i = 0; i < _countof(s_pszPropNames); ++i) + { + if (s_pszPropNames[i]) + { + ok_wstr(pszPropName, s_pszPropNames[i]); + s_pszPropNames[i] = NULL; + if (lstrcmpiW(pszPropName, L"RECTL2.bottom") == 0) + { + s_vt = VT_EMPTY; + ZeroMemory(&s_pszPropNames, sizeof(s_pszPropNames)); + s_pszPropNames[0] = L"RECTL2.right"; + return E_FAIL; + } + break; + } + } + return S_OK; + } +}; + +static void SHPropertyBag_WriteTest(void) +{ + HRESULT hr; + CDummyWritePropertyBag dummy; + + ResetTest(VT_EMPTY, L"EMPTY1"); + hr = SHPropertyBag_Delete(&dummy, s_pszPropNames[0]); + ok_long(hr, S_OK); + ok_int(s_cWrite, 1); + + ResetTest(VT_BOOL, L"BOOL1"); + hr = SHPropertyBag_WriteBOOL(&dummy, s_pszPropNames[0], TRUE); + ok_long(hr, S_OK); + ok_int(s_cWrite, 1); + + ResetTest(VT_UI2, L"SHORT1"); + hr = SHPropertyBag_WriteSHORT(&dummy, s_pszPropNames[0], 1); + ok_long(hr, S_OK); + ok_int(s_cWrite, 1); + + ResetTest(VT_I4, L"LONG1"); + hr = SHPropertyBag_WriteLONG(&dummy, s_pszPropNames[0], 1); + ok_long(hr, S_OK); + ok_int(s_cWrite, 1); + + ResetTest(VT_UI4, L"DWORD1"); + hr = SHPropertyBag_WriteDWORD(&dummy, s_pszPropNames[0], 1); + ok_long(hr, S_OK); + ok_int(s_cWrite, 1); + + ResetTest(VT_BSTR, L"Str1"); + hr = SHPropertyBag_WriteStr(&dummy, s_pszPropNames[0], L"1"); + ok_long(hr, S_OK); + ok_int(s_cWrite, 1); + + ResetTest(VT_I4, L"POINTL1.x", L"POINTL1.y"); + POINTL ptl = { 0xEEEE, 0xDDDD }; + hr = SHPropertyBag_WritePOINTL(&dummy, L"POINTL1", &ptl); + ok_long(hr, S_OK); + ok_int(s_cWrite, 2); + + ResetTest(VT_I4, L"POINTS1.x", L"POINTS1.y"); + POINTS pts = { 0x2222, 0x3333 }; + hr = SHPropertyBag_WritePOINTS(&dummy, L"POINTS1", &pts); + ok_long(hr, S_OK); + ok_int(s_cWrite, 2); + + ResetTest(VT_I4, L"RECTL1.left", L"RECTL1.top", L"RECTL1.right", L"RECTL1.bottom"); + RECTL rcl = { 123, 456, 789, 101112 }; + hr = SHPropertyBag_WriteRECTL(&dummy, L"RECTL1", &rcl); + ok_long(hr, S_OK); + ok_int(s_cWrite, 4); + + ResetTest(VT_I4, L"RECTL2.left", L"RECTL2.top", L"RECTL2.right", L"RECTL2.bottom"); + hr = SHPropertyBag_WriteRECTL(&dummy, L"RECTL2", &rcl); + ok_long(hr, S_OK); + ok_int(s_cWrite, 5); + + GUID guid; + ZeroMemory(&guid, sizeof(guid)); + ResetTest(VT_BSTR, L"GUID1"); + hr = SHPropertyBag_WriteGUID(&dummy, L"GUID1", &guid); + ok_long(hr, S_OK); + ok_int(s_cWrite, 1); +} + +START_TEST(SHPropertyBag) +{ + SHPropertyBag_WriteTest(); +} diff --git a/modules/rostests/apitests/shlwapi/testlist.c b/modules/rostests/apitests/shlwapi/testlist.c index ea30af72bee..08fd3c8e2be 100644 --- a/modules/rostests/apitests/shlwapi/testlist.c +++ b/modules/rostests/apitests/shlwapi/testlist.c @@ -10,6 +10,7 @@ extern void func_PathUnExpandEnvStringsForUser(void); extern void func_SHAreIconsEqual(void); extern void func_SHLoadIndirectString(void); extern void func_SHLoadRegUIString(void); +extern void func_SHPropertyBag(void); extern void func_StrFormatByteSizeW(void);
const struct test winetest_testlist[] = @@ -23,6 +24,7 @@ const struct test winetest_testlist[] = { "SHAreIconsEqual", func_SHAreIconsEqual }, { "SHLoadIndirectString", func_SHLoadIndirectString }, { "SHLoadRegUIString", func_SHLoadRegUIString }, + { "SHPropertyBag", func_SHPropertyBag }, { "StrFormatByteSizeW", func_StrFormatByteSizeW }, { 0, 0 } }; diff --git a/sdk/include/reactos/shlwapi_undoc.h b/sdk/include/reactos/shlwapi_undoc.h index 86ac167b8a5..d584b57df2d 100644 --- a/sdk/include/reactos/shlwapi_undoc.h +++ b/sdk/include/reactos/shlwapi_undoc.h @@ -99,6 +99,7 @@ HRESULT WINAPI SHGetPerScreenResName(OUT LPWSTR lpResName, IN DWORD dwReserved);
HRESULT WINAPI SHPropertyBag_ReadStream(IPropertyBag*,LPCWSTR,IStream**); +HRESULT WINAPI SHPropertyBag_Delete(IPropertyBag *ppb, LPCWSTR pszPropName); HRESULT WINAPI SHPropertyBag_WriteBOOL(IPropertyBag *ppb, LPCWSTR pszPropName, BOOL bValue); HRESULT WINAPI SHPropertyBag_WriteSHORT(IPropertyBag *ppb, LPCWSTR pszPropName, SHORT sValue); HRESULT WINAPI SHPropertyBag_WriteLONG(IPropertyBag *ppb, LPCWSTR pszPropName, LONG lValue); @@ -106,6 +107,9 @@ HRESULT WINAPI SHPropertyBag_WriteDWORD(IPropertyBag *ppb, LPCWSTR pszPropName, HRESULT WINAPI SHPropertyBag_WriteStr(IPropertyBag *ppb, LPCWSTR pszPropName, LPCWSTR pszValue); HRESULT WINAPI SHPropertyBag_WriteGUID(IPropertyBag *ppb, LPCWSTR pszPropName, const GUID *pguid); HRESULT WINAPI SHPropertyBag_WriteStream(IPropertyBag *ppb, LPCWSTR pszPropName, IStream *pStream); +HRESULT WINAPI SHPropertyBag_WritePOINTL(IPropertyBag *ppb, LPCWSTR pszPropName, const POINTL *pptl); +HRESULT WINAPI SHPropertyBag_WritePOINTS(IPropertyBag *ppb, LPCWSTR pszPropName, const POINTS *ppts); +HRESULT WINAPI SHPropertyBag_WriteRECTL(IPropertyBag *ppb, LPCWSTR pszPropName, const RECTL *prcl);
HWND WINAPI SHCreateWorkerWindowA(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra);