[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
This commit is contained in:
Katayama Hirofumi MZ 2023-08-02 10:35:25 +09:00 committed by GitHub
parent 53b30e3f3b
commit 6299340c45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 187 additions and 10 deletions

View file

@ -5350,6 +5350,36 @@ DoDefault:
return hr; 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) * SHPropertyBag_ReadType (SHLWAPI.493)
*/ */
@ -5670,6 +5700,74 @@ HRESULT WINAPI SHPropertyBag_ReadRECTL(IPropertyBag *ppb, LPCWSTR pszPropName, R
return SHPropertyBag_ReadLONG(ppb, szBuff, &prcl->bottom); 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) * SHPropertyBag_Delete (SHLWAPI.535)
*/ */

View file

@ -502,7 +502,7 @@
502 stdcall AssocQueryKeyA(long long str str ptr) 502 stdcall AssocQueryKeyA(long long str str ptr)
503 stdcall AssocQueryKeyW(long long wstr wstr ptr) 503 stdcall AssocQueryKeyW(long long wstr wstr ptr)
504 stdcall AssocQueryStringA(long long str str ptr 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) 506 stdcall -noname SHPropertyBag_WriteGUID(ptr wstr ptr)
507 stdcall -noname SHPropertyBag_ReadDWORD(ptr wstr ptr) 507 stdcall -noname SHPropertyBag_ReadDWORD(ptr wstr ptr)
508 stdcall -noname SHPropertyBag_WriteDWORD(ptr wstr long) 508 stdcall -noname SHPropertyBag_WriteDWORD(ptr wstr long)
@ -528,7 +528,7 @@
528 stdcall -noname SHPropertyBag_WriteSHORT(ptr wstr long) 528 stdcall -noname SHPropertyBag_WriteSHORT(ptr wstr long)
529 stdcall -noname SHPropertyBag_ReadInt(ptr wstr ptr) SHPropertyBag_ReadLONG 529 stdcall -noname SHPropertyBag_ReadInt(ptr wstr ptr) SHPropertyBag_ReadLONG
530 stdcall -noname SHPropertyBag_WriteInt(ptr wstr long) SHPropertyBag_WriteLONG 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) 532 stdcall -noname SHPropertyBag_WriteStream(ptr wstr ptr)
533 stub -noname SHGetPerScreenResName 533 stub -noname SHGetPerScreenResName
534 stdcall -noname SHPropertyBag_ReadBOOL(ptr wstr ptr) 534 stdcall -noname SHPropertyBag_ReadBOOL(ptr wstr ptr)

View file

@ -24,7 +24,7 @@ add_rc_deps(testdata.rc ${CMAKE_CURRENT_BINARY_DIR}/shlwapi_resource_dll/shlwapi
add_executable(shlwapi_apitest ${SOURCE}) add_executable(shlwapi_apitest ${SOURCE})
set_module_type(shlwapi_apitest win32cui) set_module_type(shlwapi_apitest win32cui)
target_link_libraries(shlwapi_apitest ${PSEH_LIB}) target_link_libraries(shlwapi_apitest ${PSEH_LIB} uuid)
add_importlibs(shlwapi_apitest shlwapi oleaut32 user32 advapi32 msvcrt kernel32) add_importlibs(shlwapi_apitest shlwapi oleaut32 ole32 user32 advapi32 msvcrt kernel32)
add_dependencies(shlwapi_apitest shlwapi_resource_dll) add_dependencies(shlwapi_apitest shlwapi_resource_dll)
add_rostests_file(TARGET shlwapi_apitest) add_rostests_file(TARGET shlwapi_apitest)

View file

@ -9,6 +9,7 @@
#include <shlwapi.h> #include <shlwapi.h>
#include <shlobj.h> #include <shlobj.h>
#include <shlwapi_undoc.h> #include <shlwapi_undoc.h>
#include <versionhelpers.h>
#include <pseh/pseh2.h> #include <pseh/pseh2.h>
@ -29,6 +30,30 @@ static void ResetTest(VARTYPE vt,
s_pszPropNames[3] = pszName3; 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 class CDummyPropertyBag : public IPropertyBag
{ {
public: public:
@ -39,17 +64,17 @@ public:
// IUnknown // IUnknown
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override
{ {
ok_int(0, 1); ok(FALSE, "Unexpected call\n");
return S_OK; return S_OK;
} }
STDMETHODIMP_(ULONG) AddRef() override STDMETHODIMP_(ULONG) AddRef() override
{ {
ok_int(0, 1); ok(FALSE, "Unexpected call\n");
return S_OK; return S_OK;
} }
STDMETHODIMP_(ULONG) Release() override STDMETHODIMP_(ULONG) Release() override
{ {
ok_int(0, 1); ok(FALSE, "Unexpected call\n");
return S_OK; return S_OK;
} }
@ -64,13 +89,38 @@ public:
{ {
ok_wstr(pszPropName, s_pszPropNames[i]); ok_wstr(pszPropName, s_pszPropNames[i]);
s_pszPropNames[i] = NULL; s_pszPropNames[i] = NULL;
if (lstrcmpiW(pszPropName, L"RECTL2.top") == 0) if (lstrcmpiW(pszPropName, L"RECTL2.top") == 0)
return E_FAIL; 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; goto Skip1;
} }
} }
ok_int(0, 1); ok(FALSE, "Unexpected call\n");
Skip1: Skip1:
return S_OK; return S_OK;
} }
@ -95,7 +145,7 @@ Skip1:
goto Skip2; goto Skip2;
} }
} }
ok_int(0, 1); ok(FALSE, "Unexpected call\n");
Skip2: Skip2:
return S_OK; return S_OK;
} }
@ -113,6 +163,7 @@ static void SHPropertyBag_ReadTest(void)
POINTL ptl = { 0xEEEE, 0xDDDD }; POINTL ptl = { 0xEEEE, 0xDDDD };
POINTS pts = { 0x2222, 0x3333 }; POINTS pts = { 0x2222, 0x3333 };
RECTL rcl = { 123, 456, 789, 101112 }; RECTL rcl = { 123, 456, 789, 101112 };
GUID guid = { 0 };
ResetTest(VT_BOOL, L"BOOL1"); ResetTest(VT_BOOL, L"BOOL1");
hr = SHPropertyBag_ReadBOOL(&dummy, s_pszPropNames[0], &bValue); hr = SHPropertyBag_ReadBOOL(&dummy, s_pszPropNames[0], &bValue);
@ -168,6 +219,33 @@ static void SHPropertyBag_ReadTest(void)
ok_long(hr, E_FAIL); ok_long(hr, E_FAIL);
ok_int(s_cRead, 2); ok_int(s_cRead, 2);
ok_int(s_cWrite, 0); 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) static void SHPropertyBag_WriteTest(void)

View file

@ -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_ReadPOINTL(IPropertyBag *ppb, LPCWSTR pszPropName, POINTL *pptl);
HRESULT WINAPI SHPropertyBag_ReadPOINTS(IPropertyBag *ppb, LPCWSTR pszPropName, POINTS *ppts); HRESULT WINAPI SHPropertyBag_ReadPOINTS(IPropertyBag *ppb, LPCWSTR pszPropName, POINTS *ppts);
HRESULT WINAPI SHPropertyBag_ReadRECTL(IPropertyBag *ppb, LPCWSTR pszPropName, RECTL *prcl); 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, HRESULT WINAPI SHGetPerScreenResName(OUT LPWSTR lpResName,
IN INT cchResName, IN INT cchResName,
IN DWORD dwReserved); IN DWORD dwReserved);
HRESULT WINAPI SHPropertyBag_ReadStream(IPropertyBag*,LPCWSTR,IStream**);
HRESULT WINAPI SHPropertyBag_Delete(IPropertyBag *ppb, LPCWSTR pszPropName); HRESULT WINAPI SHPropertyBag_Delete(IPropertyBag *ppb, LPCWSTR pszPropName);
HRESULT WINAPI SHPropertyBag_WriteBOOL(IPropertyBag *ppb, LPCWSTR pszPropName, BOOL bValue); HRESULT WINAPI SHPropertyBag_WriteBOOL(IPropertyBag *ppb, LPCWSTR pszPropName, BOOL bValue);
HRESULT WINAPI SHPropertyBag_WriteSHORT(IPropertyBag *ppb, LPCWSTR pszPropName, SHORT sValue); HRESULT WINAPI SHPropertyBag_WriteSHORT(IPropertyBag *ppb, LPCWSTR pszPropName, SHORT sValue);