https://git.reactos.org/?p=reactos.git;a=commitdiff;h=57ce30b85fadf28888fdf97b094fd2ab94940673

commit 57ce30b85fadf28888fdf97b094fd2ab94940673
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Tue Jul 25 18:19:22 2023 +0900
Commit:     GitHub <[email protected]>
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 
<[email protected]>
+ */
+
+#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);

Reply via email to