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

commit 6299340c453afd140f6fc7d96795d90c0852458c
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Wed Aug 2 10:35:25 2023 +0900
Commit:     GitHub <[email protected]>
CommitDate: Wed Aug 2 10:35:25 2023 +0900

    [SHLWAPI][SHLWAPI_APITEST][SDK] Implement SHPropertyBag_ReadGUID etc. 
(#5491)
    
    - Implement SHPropertyBag_ReadGUID and SHPropertyBag_ReadStream functions.
    - Modify shlwapi.spec and shlwapi_undoc.h.
     CORE-9283
---
 dll/win32/shlwapi/ordinal.c                        | 98 ++++++++++++++++++++++
 dll/win32/shlwapi/shlwapi.spec                     |  4 +-
 modules/rostests/apitests/shlwapi/CMakeLists.txt   |  4 +-
 .../rostests/apitests/shlwapi/SHPropertyBag.cpp    | 88 +++++++++++++++++--
 sdk/include/reactos/shlwapi_undoc.h                |  3 +-
 5 files changed, 187 insertions(+), 10 deletions(-)

diff --git a/dll/win32/shlwapi/ordinal.c b/dll/win32/shlwapi/ordinal.c
index 1162e8b720f..3599e723011 100644
--- a/dll/win32/shlwapi/ordinal.c
+++ b/dll/win32/shlwapi/ordinal.c
@@ -5350,6 +5350,36 @@ DoDefault:
     return hr;
 }
 
+BOOL
+VariantArrayToBuffer(
+    _In_ const VARIANT *pvarIn,
+    _Out_writes_(cbSize) LPVOID pvDest,
+    _In_ SIZE_T cbSize)
+{
+    LPVOID pvData;
+    LONG LowerBound, UpperBound;
+    LPSAFEARRAY pArray;
+
+    /* Only supports byte array */
+    if (!pvarIn || V_VT(pvarIn) != (VT_UI1 | VT_ARRAY))
+        return FALSE;
+
+    /* Boundary check and access */
+    pArray = V_ARRAY(pvarIn);
+    if (SafeArrayGetDim(pArray) == 1 &&
+        SUCCEEDED(SafeArrayGetLBound(pArray, 1, &LowerBound)) &&
+        SUCCEEDED(SafeArrayGetUBound(pArray, 1, &UpperBound)) &&
+        ((LONG)cbSize <= UpperBound - LowerBound + 1) &&
+        SUCCEEDED(SafeArrayAccessData(pArray, &pvData)))
+    {
+        CopyMemory(pvDest, pvData, cbSize);
+        SafeArrayUnaccessData(pArray);
+        return TRUE; /* Success */
+    }
+
+    return FALSE; /* Failure */
+}
+
 /**************************************************************************
  *  SHPropertyBag_ReadType (SHLWAPI.493)
  */
@@ -5670,6 +5700,74 @@ HRESULT WINAPI SHPropertyBag_ReadRECTL(IPropertyBag 
*ppb, LPCWSTR pszPropName, R
     return SHPropertyBag_ReadLONG(ppb, szBuff, &prcl->bottom);
 }
 
+/**************************************************************************
+ *  SHPropertyBag_ReadGUID (SHLWAPI.505)
+ */
+HRESULT WINAPI SHPropertyBag_ReadGUID(IPropertyBag *ppb, LPCWSTR pszPropName, 
GUID *pguid)
+{
+    HRESULT hr;
+    BOOL bRet;
+    VARIANT vari;
+
+    TRACE("%p %s %p\n", ppb, debugstr_w(pszPropName), pguid);
+
+    if (!ppb || !pszPropName || !pguid)
+    {
+        ERR("%p %s %p\n", ppb, debugstr_w(pszPropName), pguid);
+        return E_INVALIDARG;
+    }
+
+    hr = SHPropertyBag_ReadType(ppb, pszPropName, &vari, VT_EMPTY);
+    if (FAILED(hr))
+    {
+        ERR("%p %s %p\n", ppb, debugstr_w(pszPropName), pguid);
+        return hr;
+    }
+
+    if (V_VT(&vari) == (VT_UI1 | VT_ARRAY)) /* Byte Array */
+        bRet = VariantArrayToBuffer(&vari, pguid, sizeof(*pguid));
+    else if (V_VT(&vari) == VT_BSTR)
+        bRet = GUIDFromStringW(V_BSTR(&vari), pguid);
+    else
+#if (_WIN32_WINNT >= _WIN32_WINNT_VISTA)
+        bRet = FALSE;
+#else
+        bRet = TRUE; /* This is by design in WinXP/Win2k3. */
+#endif
+
+    if (!bRet)
+        ERR("%p %s %p\n", ppb, debugstr_w(pszPropName), pguid);
+
+    VariantClear(&vari);
+    return (bRet ? S_OK : E_FAIL);
+}
+
+/**************************************************************************
+ *  SHPropertyBag_ReadStream (SHLWAPI.531)
+ */
+HRESULT WINAPI SHPropertyBag_ReadStream(IPropertyBag *ppb, LPCWSTR 
pszPropName, IStream **ppStream)
+{
+    HRESULT hr;
+    VARIANT vari;
+
+    TRACE("%p %s %p\n", ppb, debugstr_w(pszPropName), ppStream);
+
+    if (!ppb || !pszPropName || !ppStream)
+    {
+        ERR("%p %s %p\n", ppb, debugstr_w(pszPropName), ppStream);
+        return E_INVALIDARG;
+    }
+
+    hr = SHPropertyBag_ReadType(ppb, pszPropName, &vari, VT_UNKNOWN);
+    if (FAILED(hr))
+        return hr;
+
+    hr = IUnknown_QueryInterface(V_UNKNOWN(&vari), &IID_IStream, (void 
**)ppStream);
+    IUnknown_Release(V_UNKNOWN(&vari));
+
+    return hr;
+}
+
 /**************************************************************************
  *  SHPropertyBag_Delete (SHLWAPI.535)
  */
diff --git a/dll/win32/shlwapi/shlwapi.spec b/dll/win32/shlwapi/shlwapi.spec
index 001d7b9ab17..8dc01d454dc 100644
--- a/dll/win32/shlwapi/shlwapi.spec
+++ b/dll/win32/shlwapi/shlwapi.spec
@@ -502,7 +502,7 @@
 502 stdcall AssocQueryKeyA(long long str str ptr)
 503 stdcall AssocQueryKeyW(long long wstr wstr ptr)
 504 stdcall AssocQueryStringA(long long str str ptr ptr)
-505 stub -noname SHPropertyBag_ReadGUID
+505 stdcall -noname SHPropertyBag_ReadGUID(ptr wstr ptr)
 506 stdcall -noname SHPropertyBag_WriteGUID(ptr wstr ptr)
 507 stdcall -noname SHPropertyBag_ReadDWORD(ptr wstr ptr)
 508 stdcall -noname SHPropertyBag_WriteDWORD(ptr wstr long)
@@ -528,7 +528,7 @@
 528 stdcall -noname SHPropertyBag_WriteSHORT(ptr wstr long)
 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
+531 stdcall -noname SHPropertyBag_ReadStream(ptr wstr ptr)
 532 stdcall -noname SHPropertyBag_WriteStream(ptr wstr ptr)
 533 stub -noname SHGetPerScreenResName
 534 stdcall -noname SHPropertyBag_ReadBOOL(ptr wstr ptr)
diff --git a/modules/rostests/apitests/shlwapi/CMakeLists.txt 
b/modules/rostests/apitests/shlwapi/CMakeLists.txt
index ef141efc92f..d5c4d32562e 100644
--- a/modules/rostests/apitests/shlwapi/CMakeLists.txt
+++ b/modules/rostests/apitests/shlwapi/CMakeLists.txt
@@ -24,7 +24,7 @@ add_rc_deps(testdata.rc 
${CMAKE_CURRENT_BINARY_DIR}/shlwapi_resource_dll/shlwapi
 
 add_executable(shlwapi_apitest ${SOURCE})
 set_module_type(shlwapi_apitest win32cui)
-target_link_libraries(shlwapi_apitest ${PSEH_LIB})
-add_importlibs(shlwapi_apitest shlwapi oleaut32 user32 advapi32 msvcrt 
kernel32)
+target_link_libraries(shlwapi_apitest ${PSEH_LIB} uuid)
+add_importlibs(shlwapi_apitest shlwapi oleaut32 ole32 user32 advapi32 msvcrt 
kernel32)
 add_dependencies(shlwapi_apitest shlwapi_resource_dll)
 add_rostests_file(TARGET shlwapi_apitest)
diff --git a/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp 
b/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp
index bdf3e6f02e1..1aca2d256c0 100644
--- a/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp
+++ b/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp
@@ -9,6 +9,7 @@
 #include <shlwapi.h>
 #include <shlobj.h>
 #include <shlwapi_undoc.h>
+#include <versionhelpers.h>
 
 #include <pseh/pseh2.h>
 
@@ -29,6 +30,30 @@ static void ResetTest(VARTYPE vt,
     s_pszPropNames[3] = pszName3;
 }
 
+static SAFEARRAY* CreateByteArray(LPCVOID pvSrc, DWORD cbSize)
+{
+    SAFEARRAYBOUND Bound;
+    Bound.lLbound = 0;
+    Bound.cElements = cbSize;
+
+    SAFEARRAY* pArray = SafeArrayCreate(VT_UI1, 1, &Bound);
+    if (!pArray)
+        return NULL;
+
+    void HUGEP *pvData;
+    HRESULT hr = SafeArrayAccessData(pArray, &pvData);
+    if (FAILED(hr))
+    {
+        SafeArrayDestroy(pArray);
+        return NULL;
+    }
+
+    CopyMemory(pvData, pvSrc, cbSize);
+    SafeArrayUnaccessData(pArray);
+
+    return pArray;
+}
+
 class CDummyPropertyBag : public IPropertyBag
 {
 public:
@@ -39,17 +64,17 @@ public:
     // IUnknown
     STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override
     {
-        ok_int(0, 1);
+        ok(FALSE, "Unexpected call\n");
         return S_OK;
     }
     STDMETHODIMP_(ULONG) AddRef() override
     {
-        ok_int(0, 1);
+        ok(FALSE, "Unexpected call\n");
         return S_OK;
     }
     STDMETHODIMP_(ULONG) Release() override
     {
-        ok_int(0, 1);
+        ok(FALSE, "Unexpected call\n");
         return S_OK;
     }
 
@@ -64,13 +89,38 @@ public:
             {
                 ok_wstr(pszPropName, s_pszPropNames[i]);
                 s_pszPropNames[i] = NULL;
+
                 if (lstrcmpiW(pszPropName, L"RECTL2.top") == 0)
                     return E_FAIL;
 
+                if (lstrcmpiW(pszPropName, L"GUID1") == 0)
+                {
+                    V_VT(pvari) = (VT_UI1 | VT_ARRAY);
+                    V_ARRAY(pvari) = CreateByteArray(&IID_IShellLink, 
sizeof(IID));
+                    return S_OK;
+                }
+
+                if (lstrcmpiW(pszPropName, L"GUID2") == 0)
+                {
+                    WCHAR szText[50];
+                    StringFromGUID2(IID_IUnknown, szText, _countof(szText));
+
+                    V_VT(pvari) = VT_BSTR;
+                    V_BSTR(pvari) = SysAllocString(szText);
+                    return S_OK;
+                }
+
+                if (lstrcmpiW(pszPropName, L"GUID3") == 0)
+                {
+                    V_VT(pvari) = VT_EMPTY;
+                    V_UI4(pvari) = 0xDEADFACE;
+                    return S_OK;
+                }
+
                 goto Skip1;
             }
         }
-        ok_int(0, 1);
+        ok(FALSE, "Unexpected call\n");
 Skip1:
         return S_OK;
     }
@@ -95,7 +145,7 @@ Skip1:
                 goto Skip2;
             }
         }
-        ok_int(0, 1);
+        ok(FALSE, "Unexpected call\n");
 Skip2:
         return S_OK;
     }
@@ -113,6 +163,7 @@ static void SHPropertyBag_ReadTest(void)
     POINTL ptl = { 0xEEEE, 0xDDDD };
     POINTS pts = { 0x2222, 0x3333 };
     RECTL rcl = { 123, 456, 789, 101112 };
+    GUID guid = { 0 };
 
     ResetTest(VT_BOOL, L"BOOL1");
     hr = SHPropertyBag_ReadBOOL(&dummy, s_pszPropNames[0], &bValue);
@@ -168,6 +219,33 @@ static void SHPropertyBag_ReadTest(void)
     ok_long(hr, E_FAIL);
     ok_int(s_cRead, 2);
     ok_int(s_cWrite, 0);
+
+    ResetTest(VT_EMPTY, L"GUID1");
+    hr = SHPropertyBag_ReadGUID(&dummy, L"GUID1", &guid);
+    ok_long(hr, S_OK);
+    ok_int(s_cRead, 1);
+    ok_int(s_cWrite, 0);
+    ok_int(IsEqualGUID(guid, IID_IShellLink), TRUE);
+
+    ResetTest(VT_EMPTY, L"GUID2");
+    hr = SHPropertyBag_ReadGUID(&dummy, L"GUID2", &guid);
+    ok_long(hr, S_OK);
+    ok_int(s_cRead, 1);
+    ok_int(s_cWrite, 0);
+    ok_int(IsEqualGUID(guid, IID_IUnknown), TRUE);
+
+    ResetTest(VT_EMPTY, L"GUID3");
+    guid = IID_IExtractIcon;
+    hr = SHPropertyBag_ReadGUID(&dummy, L"GUID3", &guid);
+
+    if (IsWindowsVistaOrGreater())
+        ok_long(hr, E_INVALIDARG);
+    else
+        ok_long(hr, S_OK);
+
+    ok_int(s_cRead, 1);
+    ok_int(s_cWrite, 0);
+    ok_int(IsEqualGUID(guid, IID_IExtractIcon), TRUE);
 }
 
 static void SHPropertyBag_WriteTest(void)
diff --git a/sdk/include/reactos/shlwapi_undoc.h 
b/sdk/include/reactos/shlwapi_undoc.h
index 564a105f5e9..a2cec2e047c 100644
--- a/sdk/include/reactos/shlwapi_undoc.h
+++ b/sdk/include/reactos/shlwapi_undoc.h
@@ -103,12 +103,13 @@ HRESULT WINAPI SHPropertyBag_ReadStr(IPropertyBag *ppb, 
LPCWSTR pszPropName, LPW
 HRESULT WINAPI SHPropertyBag_ReadPOINTL(IPropertyBag *ppb, LPCWSTR 
pszPropName, POINTL *pptl);
 HRESULT WINAPI SHPropertyBag_ReadPOINTS(IPropertyBag *ppb, LPCWSTR 
pszPropName, POINTS *ppts);
 HRESULT WINAPI SHPropertyBag_ReadRECTL(IPropertyBag *ppb, LPCWSTR pszPropName, 
RECTL *prcl);
+HRESULT WINAPI SHPropertyBag_ReadGUID(IPropertyBag *ppb, LPCWSTR pszPropName, 
GUID *pguid);
+HRESULT WINAPI SHPropertyBag_ReadStream(IPropertyBag *ppb, LPCWSTR 
pszPropName, IStream **ppStream);
 
 HRESULT WINAPI SHGetPerScreenResName(OUT LPWSTR lpResName,
                                      IN INT cchResName,
                                      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);

Reply via email to