https://git.reactos.org/?p=reactos.git;a=commitdiff;h=fe440f7514a6eb59f63e3…
commit fe440f7514a6eb59f63e368ee4776164ac797d68
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Wed Jul 26 08:21:47 2023 +0900
Commit: GitHub <noreply(a)github.com>
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,