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

commit fe440f7514a6eb59f63e368ee4776164ac797d68
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Wed Jul 26 08:21:47 2023 +0900
Commit:     GitHub <[email protected]>
CommitDate: Wed Jul 26 08:21:47 2023 +0900

    [SHLWAPI][SHLWAPI_APITEST][SDK] Implement SHPropertyBag_ReadDWORD etc. 
(#5479)
    
    - Add VariantChangeTypeForRead helper function.
    - Implement SHPropertyBag_ReadType, SHPropertyBag_ReadBOOL, 
SHPropertyBag_ReadBOOLOld, SHPropertyBag_ReadSHORT,
    SHPropertyBag_ReadLONG, and SHPropertyBag_ReadDWORD functions.
    - SHPropertyBag_ReadInt is an alias to SHPropertyBag_ReadLONG.
    CORE-9283
---
 dll/win32/shlwapi/ordinal.c                        | 187 +++++++++++++++++++++
 dll/win32/shlwapi/shlwapi.spec                     |  12 +-
 .../rostests/apitests/shlwapi/SHPropertyBag.cpp    |  71 +++++++-
 sdk/include/reactos/shlwapi_undoc.h                |   6 +
 4 files changed, 265 insertions(+), 11 deletions(-)

diff --git a/dll/win32/shlwapi/ordinal.c b/dll/win32/shlwapi/ordinal.c
index c7ba39c5cee..d8aaf6a7678 100644
--- a/dll/win32/shlwapi/ordinal.c
+++ b/dll/win32/shlwapi/ordinal.c
@@ -5289,6 +5289,153 @@ HRESULT WINAPI 
IUnknown_QueryServiceForWebBrowserApp(IUnknown* lpUnknown,
     return IUnknown_QueryService(lpUnknown,&IID_IWebBrowserApp,riid,lppOut);
 }
 
+#ifdef __REACTOS__
+HRESULT VariantChangeTypeForRead(_Inout_ VARIANTARG *pvarg, _In_ VARTYPE vt)
+{
+    HRESULT hr;
+    VARIANTARG vargTemp;
+    VARIANT variTemp;
+
+    if (V_VT(pvarg) == vt || vt == VT_EMPTY)
+        return S_OK;
+
+    vargTemp = *pvarg;
+
+    if (V_VT(&vargTemp) != VT_BSTR || vt <= VT_NULL)
+        goto DoDefault;
+
+    if (vt == VT_I1 || vt == VT_I2 || vt == VT_I4)
+    {
+        if (!StrToIntExW(V_BSTR(&vargTemp), STIF_SUPPORT_HEX, 
&V_I4(&variTemp)))
+            goto DoDefault;
+
+        V_VT(&variTemp) = VT_INT;
+        VariantInit(pvarg);
+        hr = VariantChangeType(pvarg, &variTemp, 0, vt);
+        VariantClear(&vargTemp);
+        return hr;
+    }
+
+    if (vt <= VT_DECIMAL)
+        goto DoDefault;
+
+    if (vt == VT_UI1 || vt == VT_UI2 || vt == VT_UI4)
+    {
+        if (!StrToIntExW(V_BSTR(&vargTemp), STIF_SUPPORT_HEX, 
(LPINT)&V_UI4(&variTemp)))
+            goto DoDefault;
+
+        V_VT(&variTemp) = VT_UINT;
+        VariantInit(pvarg);
+        hr = VariantChangeType(pvarg, &variTemp, 0, vt);
+        VariantClear(&vargTemp);
+        return hr;
+    }
+
+    if (vt == VT_INT || vt == VT_UINT)
+    {
+        if (!StrToIntExW(V_BSTR(&vargTemp), STIF_SUPPORT_HEX, 
&V_INT(&variTemp)))
+            goto DoDefault;
+
+        V_VT(&variTemp) = VT_UINT;
+        VariantInit(pvarg);
+        hr = VariantChangeType(pvarg, &variTemp, 0, vt);
+        VariantClear(&vargTemp);
+        return hr;
+    }
+
+DoDefault:
+    VariantInit(pvarg);
+    hr = VariantChangeType(pvarg, &vargTemp, 0, vt);
+    VariantClear(&vargTemp);
+    return hr;
+}
+
+/**************************************************************************
+ *  SHPropertyBag_ReadType (SHLWAPI.493)
+ */
+HRESULT WINAPI
+SHPropertyBag_ReadType(IPropertyBag *ppb, LPCWSTR pszPropName, VARIANTARG 
*pvarg, VARTYPE vt)
+{
+    HRESULT hr;
+
+    VariantInit(pvarg);
+    V_VT(pvarg) = vt;
+
+    hr = IPropertyBag_Read(ppb, pszPropName, pvarg, NULL);
+    if (FAILED(hr))
+    {
+        ERR("%p %s\n", ppb, debugstr_w(pszPropName));
+        VariantInit(pvarg);
+        return hr;
+    }
+
+    return VariantChangeTypeForRead(pvarg, vt);
+}
+
+/**************************************************************************
+ *  SHPropertyBag_ReadBOOL (SHLWAPI.534)
+ */
+HRESULT WINAPI SHPropertyBag_ReadBOOL(IPropertyBag *ppb, LPCWSTR pszPropName, 
BOOL *pbValue)
+{
+    HRESULT hr;
+    VARIANTARG varg;
+
+    TRACE("%p %s %p\n", ppb, debugstr_w(pszPropName), pbValue);
+
+    if (!ppb || !pszPropName || !pbValue)
+    {
+        ERR("%p %s %p\n", ppb, debugstr_w(pszPropName), pbValue);
+        return E_INVALIDARG;
+    }
+
+    hr = SHPropertyBag_ReadType(ppb, pszPropName, &varg, VT_BOOL);
+    if (SUCCEEDED(hr))
+        *pbValue = (V_BOOL(&varg) == VARIANT_TRUE);
+
+    return hr;
+}
+
+/**************************************************************************
+ *  SHPropertyBag_ReadBOOLOld (SHLWAPI.498)
+ */
+BOOL WINAPI SHPropertyBag_ReadBOOLOld(IPropertyBag *ppb, LPCWSTR pszPropName, 
BOOL bDefValue)
+{
+    VARIANTARG varg;
+    HRESULT hr;
+
+    TRACE("%p %s %d\n", ppb, debugstr_w(pszPropName), bDefValue);
+
+    hr = SHPropertyBag_ReadType(ppb, pszPropName, &varg, VT_BOOL);
+    if (FAILED(hr))
+        return bDefValue;
+
+    return V_BOOL(&varg) == VARIANT_TRUE;
+}
+
+/**************************************************************************
+ *  SHPropertyBag_ReadSHORT (SHLWAPI.527)
+ */
+HRESULT WINAPI SHPropertyBag_ReadSHORT(IPropertyBag *ppb, LPCWSTR pszPropName, 
SHORT *psValue)
+{
+    HRESULT hr;
+    VARIANTARG varg;
+
+    TRACE("%p %s %p\n", ppb, debugstr_w(pszPropName), psValue);
+
+    if (!ppb || !pszPropName || !psValue)
+    {
+        ERR("%p %s %p\n", ppb, debugstr_w(pszPropName), psValue);
+        return E_INVALIDARG;
+    }
+
+    hr = SHPropertyBag_ReadType(ppb, pszPropName, &varg, VT_UI2);
+    if (SUCCEEDED(hr))
+        *psValue = V_UI2(&varg);
+
+    return hr;
+}
+#endif
+
 /**************************************************************************
  *  SHPropertyBag_ReadLONG (SHLWAPI.496)
  *
@@ -5304,6 +5451,22 @@ HRESULT WINAPI 
IUnknown_QueryServiceForWebBrowserApp(IUnknown* lpUnknown,
  */
 HRESULT WINAPI SHPropertyBag_ReadLONG(IPropertyBag *ppb, LPCWSTR pszPropName, 
LPLONG pValue)
 {
+#ifdef __REACTOS__
+    HRESULT hr;
+    VARIANTARG varg;
+
+    TRACE("%p %s %p\n", ppb, debugstr_w(pszPropName), pValue);
+
+    if (!ppb || !pszPropName || !pValue)
+    {
+        ERR("%p %s %p\n", ppb, debugstr_w(pszPropName), pValue);
+        return E_INVALIDARG;
+    }
+
+    hr = SHPropertyBag_ReadType(ppb, pszPropName, &varg, VT_I4);
+    if (SUCCEEDED(hr))
+        *pValue = V_I4(&varg);
+#else
     VARIANT var;
     HRESULT hr;
     TRACE("%p %s %p\n", ppb,debugstr_w(pszPropName),pValue);
@@ -5318,10 +5481,34 @@ HRESULT WINAPI SHPropertyBag_ReadLONG(IPropertyBag 
*ppb, LPCWSTR pszPropName, LP
         else
             hr = DISP_E_BADVARTYPE;
     }
+#endif
     return hr;
 }
 
 #ifdef __REACTOS__
+/**************************************************************************
+ *  SHPropertyBag_ReadDWORD (SHLWAPI.507)
+ */
+HRESULT WINAPI SHPropertyBag_ReadDWORD(IPropertyBag *ppb, LPCWSTR pszPropName, 
DWORD *pdwValue)
+{
+    HRESULT hr;
+    VARIANTARG varg;
+
+    TRACE("%p %s %p\n", ppb, debugstr_w(pszPropName), pdwValue);
+
+    if (!ppb || !pszPropName || !pdwValue)
+    {
+        ERR("%p %s %p\n", ppb, debugstr_w(pszPropName), pdwValue);
+        return E_INVALIDARG;
+    }
+
+    hr = SHPropertyBag_ReadType(ppb, pszPropName, &varg, VT_UI4);
+    if (SUCCEEDED(hr))
+        *pdwValue = V_UI4(&varg);
+
+    return hr;
+}
+
 /**************************************************************************
  *  SHPropertyBag_Delete (SHLWAPI.535)
  */
diff --git a/dll/win32/shlwapi/shlwapi.spec b/dll/win32/shlwapi/shlwapi.spec
index 0833bd8f20a..7251262161e 100644
--- a/dll/win32/shlwapi/shlwapi.spec
+++ b/dll/win32/shlwapi/shlwapi.spec
@@ -490,12 +490,12 @@
 490 stdcall -noname GlobalFindAtomWrapW(wstr) kernel32.GlobalFindAtomW
 491 stdcall -noname SHGetShellKey(long long long)
 492 stub -noname PrettifyFileDescriptionW
-493 stub -noname SHPropertyBag_ReadType
+493 stdcall -noname SHPropertyBag_ReadType(ptr wstr ptr long)
 494 stub -noname SHPropertyBag_ReadStr
 495 stdcall -noname SHPropertyBag_WriteStr(ptr wstr wstr)
 496 stdcall -noname SHPropertyBag_ReadLONG(ptr wstr ptr)
 497 stdcall -noname SHPropertyBag_WriteLONG(ptr wstr long)
-498 stub -noname SHPropertyBag_ReadBOOLOld
+498 stdcall -noname SHPropertyBag_ReadBOOLOld(ptr wstr long)
 499 stdcall -noname SHPropertyBag_WriteBOOL(ptr wstr long)
 500 stdcall AssocGetPerceivedType(wstr ptr ptr ptr)
 501 stdcall AssocIsDangerous(wstr)
@@ -504,7 +504,7 @@
 504 stdcall AssocQueryStringA(long long str str ptr ptr)
 505 stub -noname SHPropertyBag_ReadGUID
 506 stdcall -noname SHPropertyBag_WriteGUID(ptr wstr ptr)
-507 stdcall -stub -noname SHPropertyBag_ReadDWORD(ptr ptr ptr)
+507 stdcall -noname SHPropertyBag_ReadDWORD(ptr wstr ptr)
 508 stdcall -noname SHPropertyBag_WriteDWORD(ptr wstr long)
 509 stdcall -noname IUnknown_OnFocusChangeIS(ptr ptr long)
 510 stdcall -noname SHLockSharedEx(ptr long long)
@@ -524,14 +524,14 @@
 524 stdcall -noname SHPropertyBag_WriteRECTL(ptr wstr ptr)
 525 stub -noname SHPropertyBag_ReadPOINTS
 526 stdcall -noname SHPropertyBag_WritePOINTS(ptr wstr ptr)
-527 stub -noname SHPropertyBag_ReadSHORT
+527 stdcall -noname SHPropertyBag_ReadSHORT(ptr wstr ptr)
 528 stdcall -noname SHPropertyBag_WriteSHORT(ptr wstr long)
-529 stub -noname SHPropertyBag_ReadInt
+529 stdcall -noname SHPropertyBag_ReadInt(ptr wstr ptr) SHPropertyBag_ReadLONG
 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
+534 stdcall -noname SHPropertyBag_ReadBOOL(ptr wstr ptr)
 535 stdcall -noname SHPropertyBag_Delete(ptr wstr)
 536 stdcall -stub -noname IUnknown_QueryServicePropertyBag(ptr long ptr ptr)
 537 stub -noname SHBoolSystemParametersInfo
diff --git a/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp 
b/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp
index 6291f25d17e..224d66fb43d 100644
--- a/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp
+++ b/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp
@@ -14,6 +14,7 @@
 
 static LPCWSTR s_pszPropNames[4] = { NULL, NULL, NULL, NULL };
 static VARTYPE s_vt;
+static INT s_cRead = 0;
 static INT s_cWrite = 0;
 
 static void ResetTest(VARTYPE vt,
@@ -21,17 +22,17 @@ static void ResetTest(VARTYPE vt,
                   LPCWSTR pszName2 = NULL, LPCWSTR pszName3 = NULL)
 {
     s_vt = vt;
-    s_cWrite = 0;
+    s_cRead = s_cWrite = 0;
     s_pszPropNames[0] = pszName0;
     s_pszPropNames[1] = pszName1;
     s_pszPropNames[2] = pszName2;
     s_pszPropNames[3] = pszName3;
 }
 
-class CDummyWritePropertyBag : public IPropertyBag
+class CDummyPropertyBag : public IPropertyBag
 {
 public:
-    CDummyWritePropertyBag()
+    CDummyPropertyBag()
     {
     }
 
@@ -55,7 +56,19 @@ public:
     // IPropertyBag
     STDMETHODIMP Read(LPCWSTR pszPropName, VARIANT *pvari, IErrorLog 
*pErrorLog) override
     {
+        ++s_cRead;
+        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;
+                goto Skip1;
+            }
+        }
         ok_int(0, 1);
+Skip1:
         return S_OK;
     }
 
@@ -76,69 +89,115 @@ public:
                     s_pszPropNames[0] = L"RECTL2.right";
                     return E_FAIL;
                 }
-                break;
+                goto Skip2;
             }
         }
+        ok_int(0, 1);
+Skip2:
         return S_OK;
     }
 };
 
+static void SHPropertyBag_ReadTest(void)
+{
+    HRESULT hr;
+    CDummyPropertyBag dummy;
+    BOOL bValue = 0xDEADFACE;
+    SHORT sValue = 0xDEAD;
+    LONG lValue = 0xDEADDEAD;
+    DWORD dwValue = 0xFEEDF00D;
+
+    ResetTest(VT_BOOL, L"BOOL1");
+    hr = SHPropertyBag_ReadBOOL(&dummy, s_pszPropNames[0], &bValue);
+    ok_long(hr, S_OK);
+    ok_int(s_cRead, 1);
+    ok_int(s_cWrite, 0);
+
+    ResetTest(VT_UI2, L"SHORT1");
+    hr = SHPropertyBag_ReadSHORT(&dummy, s_pszPropNames[0], &sValue);
+    ok_long(hr, S_OK);
+    ok_int(s_cRead, 1);
+    ok_int(s_cWrite, 0);
+
+    ResetTest(VT_I4, L"LONG1");
+    hr = SHPropertyBag_ReadLONG(&dummy, s_pszPropNames[0], &lValue);
+    ok_long(hr, S_OK);
+    ok_int(s_cRead, 1);
+    ok_int(s_cWrite, 0);
+
+    ResetTest(VT_UI4, L"DWORD1");
+    hr = SHPropertyBag_ReadDWORD(&dummy, s_pszPropNames[0], &dwValue);
+    ok_long(hr, S_OK);
+    ok_int(s_cRead, 1);
+    ok_int(s_cWrite, 0);
+}
+
 static void SHPropertyBag_WriteTest(void)
 {
     HRESULT hr;
-    CDummyWritePropertyBag dummy;
+    CDummyPropertyBag dummy;
 
     ResetTest(VT_EMPTY, L"EMPTY1");
     hr = SHPropertyBag_Delete(&dummy, s_pszPropNames[0]);
     ok_long(hr, S_OK);
+    ok_int(s_cRead, 0);
     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_cRead, 0);
     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_cRead, 0);
     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_cRead, 0);
     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_cRead, 0);
     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_cRead, 0);
     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_cRead, 0);
     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_cRead, 0);
     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_cRead, 0);
     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_cRead, 0);
     ok_int(s_cWrite, 5);
 
     GUID guid;
@@ -146,10 +205,12 @@ static void SHPropertyBag_WriteTest(void)
     ResetTest(VT_BSTR, L"GUID1");
     hr = SHPropertyBag_WriteGUID(&dummy, L"GUID1", &guid);
     ok_long(hr, S_OK);
+    ok_int(s_cRead, 0);
     ok_int(s_cWrite, 1);
 }
 
 START_TEST(SHPropertyBag)
 {
+    SHPropertyBag_ReadTest();
     SHPropertyBag_WriteTest();
 }
diff --git a/sdk/include/reactos/shlwapi_undoc.h 
b/sdk/include/reactos/shlwapi_undoc.h
index d584b57df2d..87f7d62d289 100644
--- a/sdk/include/reactos/shlwapi_undoc.h
+++ b/sdk/include/reactos/shlwapi_undoc.h
@@ -92,6 +92,12 @@ BOOL WINAPI SHExpandEnvironmentStringsForUserW(HANDLE, 
LPCWSTR, LPWSTR, DWORD);
 
 BOOL WINAPI SHIsEmptyStream(IStream*);
 HRESULT WINAPI SHInvokeDefaultCommand(HWND,IShellFolder*,LPCITEMIDLIST);
+HRESULT WINAPI SHPropertyBag_ReadType(IPropertyBag *ppb, LPCWSTR pszPropName, 
VARIANTARG *pvarg, VARTYPE vt);
+HRESULT WINAPI SHPropertyBag_ReadBOOL(IPropertyBag *ppb, LPCWSTR pszPropName, 
BOOL *pbValue);
+BOOL WINAPI SHPropertyBag_ReadBOOLOld(IPropertyBag *ppb, LPCWSTR pszPropName, 
BOOL bDefValue);
+HRESULT WINAPI SHPropertyBag_ReadSHORT(IPropertyBag *ppb, LPCWSTR pszPropName, 
SHORT *psValue);
+HRESULT WINAPI SHPropertyBag_ReadLONG(IPropertyBag *ppb, LPCWSTR pszPropName, 
LPLONG pValue);
+HRESULT WINAPI SHPropertyBag_ReadDWORD(IPropertyBag *ppb, LPCWSTR pszPropName, 
DWORD *pdwValue);
 HRESULT WINAPI SHPropertyBag_ReadPOINTL(IPropertyBag*,LPCWSTR,POINTL*);
 
 HRESULT WINAPI SHGetPerScreenResName(OUT LPWSTR lpResName,

Reply via email to