mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 00:50:23 +00:00
[SHLWAPI][SHLWAPI_APITEST][SDK] INI file property bag (#5546)
- Add SHGetIniStringUTF7W and SHSetIniStringUTF7W functions. - Add CIniPropertyBag class. - Implement SHCreatePropertyBagOnProfileSection function. CORE-9283
This commit is contained in:
parent
c0e443058e
commit
56d95154ee
4 changed files with 465 additions and 3 deletions
|
@ -693,3 +693,305 @@ SHSetIniStringW(
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* SHGetIniStringUTF7W (SHLWAPI.473)
|
||||||
|
*
|
||||||
|
* Retrieves a string value from an INI file.
|
||||||
|
*
|
||||||
|
* @param lpAppName The section name.
|
||||||
|
* @param lpKeyName The key name.
|
||||||
|
* If this string begins from '@', the value will be interpreted as UTF-7.
|
||||||
|
* @param lpReturnedString Receives a wide string value.
|
||||||
|
* @param nSize The number of characters in lpReturnedString.
|
||||||
|
* @param lpFileName The INI file.
|
||||||
|
* @return The number of characters copied to the buffer if succeeded.
|
||||||
|
*/
|
||||||
|
EXTERN_C DWORD WINAPI
|
||||||
|
SHGetIniStringUTF7W(
|
||||||
|
_In_opt_z_ LPCWSTR lpAppName,
|
||||||
|
_In_z_ LPCWSTR lpKeyName,
|
||||||
|
_Out_writes_to_(nSize, return + 1) _Post_z_ LPWSTR lpReturnedString,
|
||||||
|
_In_ DWORD nSize,
|
||||||
|
_In_z_ LPCWSTR lpFileName)
|
||||||
|
{
|
||||||
|
if (*lpKeyName == L'@') // UTF-7
|
||||||
|
return SHGetIniStringW(lpAppName, lpKeyName + 1, lpReturnedString, nSize, lpFileName);
|
||||||
|
|
||||||
|
return GetPrivateProfileStringW(lpAppName, lpKeyName, L"", lpReturnedString, nSize, lpFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* SHSetIniStringUTF7W (SHLWAPI.474)
|
||||||
|
*
|
||||||
|
* Sets a string value on an INI file.
|
||||||
|
*
|
||||||
|
* @param lpAppName The section name.
|
||||||
|
* @param lpKeyName The key name.
|
||||||
|
* If this begins from '@', the value will be stored as UTF-7.
|
||||||
|
* @param lpString The wide string value to be set.
|
||||||
|
* @param lpFileName The INI file.
|
||||||
|
* @return TRUE if successful. FALSE if failed.
|
||||||
|
*/
|
||||||
|
EXTERN_C BOOL WINAPI
|
||||||
|
SHSetIniStringUTF7W(
|
||||||
|
_In_z_ LPCWSTR lpAppName,
|
||||||
|
_In_z_ LPCWSTR lpKeyName,
|
||||||
|
_In_opt_z_ LPCWSTR lpString,
|
||||||
|
_In_z_ LPCWSTR lpFileName)
|
||||||
|
{
|
||||||
|
if (*lpKeyName == L'@') // UTF-7
|
||||||
|
return SHSetIniStringW(lpAppName, lpKeyName + 1, lpString, lpFileName);
|
||||||
|
|
||||||
|
return WritePrivateProfileStringW(lpAppName, lpKeyName, lpString, lpFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
class CIniPropertyBag : public CBasePropertyBag
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
LPWSTR m_pszFileName;
|
||||||
|
LPWSTR m_pszSection;
|
||||||
|
BOOL m_bAlternateStream; // ADS (Alternate Data Stream)
|
||||||
|
|
||||||
|
static BOOL LooksLikeAnAlternateStream(LPCWSTR pszStart)
|
||||||
|
{
|
||||||
|
LPCWSTR pch = StrRChrW(pszStart, NULL, L'\\');
|
||||||
|
if (!pch)
|
||||||
|
pch = pszStart;
|
||||||
|
return StrChrW(pch, L':') != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
_GetSectionAndName(
|
||||||
|
LPCWSTR pszStart,
|
||||||
|
LPWSTR pszSection,
|
||||||
|
UINT cchSectionMax,
|
||||||
|
LPWSTR pszName,
|
||||||
|
UINT cchNameMax);
|
||||||
|
|
||||||
|
public:
|
||||||
|
CIniPropertyBag(DWORD dwMode)
|
||||||
|
: CBasePropertyBag(dwMode)
|
||||||
|
, m_pszFileName(NULL)
|
||||||
|
, m_pszSection(NULL)
|
||||||
|
, m_bAlternateStream(FALSE)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~CIniPropertyBag() override
|
||||||
|
{
|
||||||
|
::LocalFree(m_pszFileName);
|
||||||
|
::LocalFree(m_pszSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT Init(LPCWSTR pszIniFile, LPCWSTR pszSection);
|
||||||
|
|
||||||
|
STDMETHODIMP Read(
|
||||||
|
_In_z_ LPCWSTR pszPropName,
|
||||||
|
_Inout_ VARIANT *pvari,
|
||||||
|
_Inout_opt_ IErrorLog *pErrorLog) override;
|
||||||
|
|
||||||
|
STDMETHODIMP Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT CIniPropertyBag::Init(LPCWSTR pszIniFile, LPCWSTR pszSection)
|
||||||
|
{
|
||||||
|
m_pszFileName = StrDupW(pszIniFile);
|
||||||
|
if (!m_pszFileName)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
// Is it an ADS (Alternate Data Stream) pathname?
|
||||||
|
m_bAlternateStream = LooksLikeAnAlternateStream(m_pszFileName);
|
||||||
|
|
||||||
|
if (pszSection)
|
||||||
|
{
|
||||||
|
m_pszSection = StrDupW(pszSection);
|
||||||
|
if (!m_pszSection)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
CIniPropertyBag::_GetSectionAndName(
|
||||||
|
LPCWSTR pszStart,
|
||||||
|
LPWSTR pszSection,
|
||||||
|
UINT cchSectionMax,
|
||||||
|
LPWSTR pszName,
|
||||||
|
UINT cchNameMax)
|
||||||
|
{
|
||||||
|
LPCWSTR pchSep = StrChrW(pszStart, L'\\');
|
||||||
|
if (pchSep)
|
||||||
|
{
|
||||||
|
UINT cchSep = (UINT)(pchSep - pszStart + 1);
|
||||||
|
StrCpyNW(pszSection, pszStart, min(cchSep, cchSectionMax));
|
||||||
|
StrCpyNW(pszName, pchSep + 1, cchNameMax);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_pszSection)
|
||||||
|
{
|
||||||
|
StrCpyNW(pszSection, m_pszSection, cchSectionMax);
|
||||||
|
StrCpyNW(pszName, pszStart, cchNameMax);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ERR("%p: %s\n", this, debugstr_w(pszStart));
|
||||||
|
return E_INVALIDARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP
|
||||||
|
CIniPropertyBag::Read(
|
||||||
|
_In_z_ LPCWSTR pszPropName,
|
||||||
|
_Inout_ VARIANT *pvari,
|
||||||
|
_Inout_opt_ IErrorLog *pErrorLog)
|
||||||
|
{
|
||||||
|
UNREFERENCED_PARAMETER(pErrorLog);
|
||||||
|
|
||||||
|
TRACE("%p: %s %p %p\n", this, debugstr_w(pszPropName), pvari, pErrorLog);
|
||||||
|
|
||||||
|
VARTYPE vt = V_VT(pvari);
|
||||||
|
|
||||||
|
::VariantInit(pvari);
|
||||||
|
|
||||||
|
if ((m_dwMode & (STGM_READ | STGM_WRITE | STGM_READWRITE)) == STGM_WRITE)
|
||||||
|
{
|
||||||
|
ERR("%p: 0x%X\n", this, m_dwMode);
|
||||||
|
return E_ACCESSDENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
WCHAR szSection[64], szName[64];
|
||||||
|
HRESULT hr =
|
||||||
|
_GetSectionAndName(pszPropName, szSection, _countof(szSection), szName, _countof(szName));
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
const INT cchBuffMax = 4 * MAX_PATH; // UTF-7 needs 4 times length buffer.
|
||||||
|
CComHeapPtr<WCHAR> pszBuff;
|
||||||
|
if (!pszBuff.Allocate(cchBuffMax * sizeof(WCHAR)))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
if (!SHGetIniStringUTF7W(szSection, szName, pszBuff, cchBuffMax, m_pszFileName))
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
BSTR bstr = ::SysAllocString(pszBuff);
|
||||||
|
V_BSTR(pvari) = bstr;
|
||||||
|
if (!bstr)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
V_VT(pvari) = VT_BSTR;
|
||||||
|
return ::VariantChangeTypeForRead(pvari, vt);
|
||||||
|
}
|
||||||
|
|
||||||
|
STDMETHODIMP
|
||||||
|
CIniPropertyBag::Write(_In_z_ LPCWSTR pszPropName, _In_ VARIANT *pvari)
|
||||||
|
{
|
||||||
|
TRACE("%p: %s %p\n", this, debugstr_w(pszPropName), pvari);
|
||||||
|
|
||||||
|
if ((m_dwMode & (STGM_READ | STGM_WRITE | STGM_READWRITE)) == STGM_READ)
|
||||||
|
{
|
||||||
|
ERR("%p: 0x%X\n", this, m_dwMode);
|
||||||
|
return E_ACCESSDENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
BSTR bstr;
|
||||||
|
VARIANTARG vargTemp = { 0 };
|
||||||
|
switch (V_VT(pvari))
|
||||||
|
{
|
||||||
|
case VT_EMPTY:
|
||||||
|
bstr = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VT_BSTR:
|
||||||
|
bstr = V_BSTR(pvari);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
hr = ::VariantChangeType(&vargTemp, pvari, 0, VT_BSTR);
|
||||||
|
if (FAILED(hr))
|
||||||
|
goto Quit;
|
||||||
|
|
||||||
|
bstr = V_BSTR(&vargTemp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
WCHAR szSection[64], szName[64];
|
||||||
|
hr = _GetSectionAndName(pszPropName, szSection, _countof(szSection), szName, _countof(szName));
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
if (SHSetIniStringUTF7W(szSection, szName, bstr, m_pszFileName))
|
||||||
|
{
|
||||||
|
if (!m_bAlternateStream)
|
||||||
|
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_PATHW, m_pszFileName, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
::VariantClear(&vargTemp);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* SHCreatePropertyBagOnProfileSection (SHLWAPI.472)
|
||||||
|
*
|
||||||
|
* Creates a property bag object on INI file.
|
||||||
|
*
|
||||||
|
* @param lpFileName The INI filename.
|
||||||
|
* @param pszSection The optional section name.
|
||||||
|
* @param dwMode The combination of STGM_READ, STGM_WRITE, STGM_READWRITE, and STGM_CREATE.
|
||||||
|
* @param riid Specifies either IID_IUnknown, IID_IPropertyBag or IID_IPropertyBag2.
|
||||||
|
* @param ppvObj Receives an IPropertyBag pointer.
|
||||||
|
* @return An HRESULT value. S_OK on success, non-zero on failure.
|
||||||
|
* @see https://www.geoffchappell.com/studies/windows/shell/shlwapi/api/propbag/createonprofilesection.htm
|
||||||
|
*/
|
||||||
|
EXTERN_C HRESULT WINAPI
|
||||||
|
SHCreatePropertyBagOnProfileSection(
|
||||||
|
_In_z_ LPCWSTR lpFileName,
|
||||||
|
_In_opt_z_ LPCWSTR pszSection,
|
||||||
|
_In_ DWORD dwMode,
|
||||||
|
_In_ REFIID riid,
|
||||||
|
_Out_ void **ppvObj)
|
||||||
|
{
|
||||||
|
HANDLE hFile;
|
||||||
|
PWCHAR pchFileTitle;
|
||||||
|
WCHAR szBuff[MAX_PATH];
|
||||||
|
|
||||||
|
if (dwMode & STGM_CREATE)
|
||||||
|
{
|
||||||
|
hFile = ::CreateFileW(lpFileName, 0, FILE_SHARE_DELETE, 0, CREATE_NEW,
|
||||||
|
FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM, NULL);
|
||||||
|
if (hFile != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
pchFileTitle = PathFindFileNameW(lpFileName);
|
||||||
|
if (lstrcmpiW(pchFileTitle, L"desktop.ini") == 0)
|
||||||
|
{
|
||||||
|
StrCpyNW(szBuff, lpFileName, _countof(szBuff));
|
||||||
|
if (PathRemoveFileSpecW(szBuff))
|
||||||
|
PathMakeSystemFolderW(szBuff);
|
||||||
|
}
|
||||||
|
::CloseHandle(hFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppvObj = NULL;
|
||||||
|
|
||||||
|
if (!PathFileExistsW(lpFileName))
|
||||||
|
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||||
|
|
||||||
|
CComPtr<CIniPropertyBag> pIniPB(new CIniPropertyBag(dwMode));
|
||||||
|
|
||||||
|
HRESULT hr = pIniPB->Init(lpFileName, pszSection);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
ERR("0x%08X\n", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pIniPB->QueryInterface(riid, ppvObj);
|
||||||
|
}
|
||||||
|
|
|
@ -469,9 +469,9 @@
|
||||||
469 stub -noname RunRegCommand
|
469 stub -noname RunRegCommand
|
||||||
470 stub -noname IUnknown_ProfferServiceOld
|
470 stub -noname IUnknown_ProfferServiceOld
|
||||||
471 stdcall -noname SHCreatePropertyBagOnRegKey(ptr wstr long ptr ptr)
|
471 stdcall -noname SHCreatePropertyBagOnRegKey(ptr wstr long ptr ptr)
|
||||||
472 stub -noname SHCreatePropertyBagOnProfileSelection
|
472 stdcall -noname SHCreatePropertyBagOnProfileSection(wstr wstr long ptr ptr)
|
||||||
473 stub -noname SHGetIniStringUTF7W
|
473 stdcall -noname SHGetIniStringUTF7W(wstr wstr ptr long wstr)
|
||||||
474 stub -noname SHSetIniStringUTF7W
|
474 stdcall -noname SHSetIniStringUTF7W(wstr wstr wstr wstr)
|
||||||
475 stdcall -noname GetShellSecurityDescriptor(ptr long)
|
475 stdcall -noname GetShellSecurityDescriptor(ptr long)
|
||||||
476 stdcall -noname SHGetObjectCompatFlags(ptr ptr)
|
476 stdcall -noname SHGetObjectCompatFlags(ptr ptr)
|
||||||
477 stdcall -noname SHCreatePropertyBagOnMemory(long ptr ptr)
|
477 stdcall -noname SHCreatePropertyBagOnMemory(long ptr ptr)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <apitest.h>
|
#include <apitest.h>
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <shlwapi_undoc.h>
|
#include <shlwapi_undoc.h>
|
||||||
#include <versionhelpers.h>
|
#include <versionhelpers.h>
|
||||||
|
|
||||||
|
@ -687,6 +688,141 @@ static void SHPropertyBag_SHSetIniStringW(void)
|
||||||
DeleteFileW(szIniFile);
|
DeleteFileW(szIniFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHPropertyBag_OnIniFile(void)
|
||||||
|
{
|
||||||
|
WCHAR szIniFile[MAX_PATH], szValue[MAX_PATH];
|
||||||
|
HRESULT hr;
|
||||||
|
IPropertyBag *pPropBag;
|
||||||
|
VARIANT vari;
|
||||||
|
DWORD dwRet;
|
||||||
|
|
||||||
|
ExpandEnvironmentStringsW(L"%TEMP%\\SHPropertyBag.ini", szIniFile, _countof(szIniFile));
|
||||||
|
|
||||||
|
DeleteFileW(szIniFile);
|
||||||
|
fclose(_wfopen(szIniFile, L"w"));
|
||||||
|
|
||||||
|
trace("%ls\n", szIniFile);
|
||||||
|
|
||||||
|
// read-write
|
||||||
|
hr = SHCreatePropertyBagOnProfileSection(
|
||||||
|
szIniFile,
|
||||||
|
L"TestSection",
|
||||||
|
STGM_READWRITE,
|
||||||
|
IID_IPropertyBag,
|
||||||
|
(void**)&pPropBag);
|
||||||
|
ok_long(hr, S_OK);
|
||||||
|
ok_int(PathFileExistsW(szIniFile), TRUE);
|
||||||
|
|
||||||
|
// Write UI4
|
||||||
|
VariantInit(&vari);
|
||||||
|
V_VT(&vari) = VT_UI4;
|
||||||
|
V_UI4(&vari) = 0xDEADFACE;
|
||||||
|
hr = pPropBag->Write(L"Name1", &vari);
|
||||||
|
ok_long(hr, S_OK);
|
||||||
|
VariantClear(&vari);
|
||||||
|
|
||||||
|
// Write BSTR
|
||||||
|
VariantInit(&vari);
|
||||||
|
V_VT(&vari) = VT_BSTR;
|
||||||
|
V_BSTR(&vari) = SysAllocString(L"StrValue");
|
||||||
|
hr = pPropBag->Write(L"Name2", &vari);
|
||||||
|
ok_long(hr, S_OK);
|
||||||
|
VariantClear(&vari);
|
||||||
|
|
||||||
|
// Write BSTR (dirty UTF-7)
|
||||||
|
VariantInit(&vari);
|
||||||
|
V_VT(&vari) = VT_BSTR;
|
||||||
|
V_BSTR(&vari) = SysAllocString(L"ABC\x3042\x3044\x3046\x2665");
|
||||||
|
hr = pPropBag->Write(L"@Name3", &vari);
|
||||||
|
ok_long(hr, S_OK);
|
||||||
|
VariantClear(&vari);
|
||||||
|
|
||||||
|
// Write BSTR (clean UTF-7)
|
||||||
|
VariantInit(&vari);
|
||||||
|
V_VT(&vari) = VT_BSTR;
|
||||||
|
V_BSTR(&vari) = SysAllocString(L"1234abc");
|
||||||
|
hr = pPropBag->Write(L"@Name4", &vari);
|
||||||
|
ok_long(hr, S_OK);
|
||||||
|
VariantClear(&vari);
|
||||||
|
|
||||||
|
pPropBag->Release();
|
||||||
|
|
||||||
|
// Flush
|
||||||
|
WritePrivateProfileStringW(NULL, NULL, NULL, szIniFile);
|
||||||
|
|
||||||
|
// Check INI file
|
||||||
|
dwRet = GetPrivateProfileStringW(L"TestSection", L"Name1", L"BAD", szValue, _countof(szValue), szIniFile);
|
||||||
|
ok_long(dwRet, 10);
|
||||||
|
ok_wstr(szValue, L"3735943886");
|
||||||
|
|
||||||
|
dwRet = GetPrivateProfileStringW(L"TestSection", L"Name2", L"BAD", szValue, _countof(szValue), szIniFile);
|
||||||
|
ok_long(dwRet, 8);
|
||||||
|
ok_wstr(szValue, L"StrValue");
|
||||||
|
|
||||||
|
GetPrivateProfileStringW(L"TestSection", L"Name3", L"NotFound", szValue, _countof(szValue), szIniFile);
|
||||||
|
ok_int(memcmp(szValue, L"ABC", 3 * sizeof(WCHAR)), 0);
|
||||||
|
|
||||||
|
GetPrivateProfileStringW(L"TestSection.A", L"Name3", L"NotFound", szValue, _countof(szValue), szIniFile);
|
||||||
|
ok_int(memcmp(szValue, L"ABC", 3 * sizeof(WCHAR)), 0);
|
||||||
|
|
||||||
|
GetPrivateProfileStringW(L"TestSection.W", L"Name3", L"NotFound", szValue, _countof(szValue), szIniFile);
|
||||||
|
ok_wstr(szValue, L"ABC+MEIwRDBGJmU-"); // UTF-7
|
||||||
|
|
||||||
|
GetPrivateProfileStringW(L"TestSection", L"Name4", L"NotFound", szValue, _countof(szValue), szIniFile);
|
||||||
|
ok_wstr(szValue, L"1234abc");
|
||||||
|
|
||||||
|
GetPrivateProfileStringW(L"TestSection.A", L"Name4", L"NotFound", szValue, _countof(szValue), szIniFile);
|
||||||
|
ok_wstr(szValue, L"NotFound");
|
||||||
|
|
||||||
|
GetPrivateProfileStringW(L"TestSection.W", L"Name4", L"NotFound", szValue, _countof(szValue), szIniFile);
|
||||||
|
ok_wstr(szValue, L"NotFound");
|
||||||
|
|
||||||
|
// read-only
|
||||||
|
hr = SHCreatePropertyBagOnProfileSection(
|
||||||
|
szIniFile,
|
||||||
|
NULL,
|
||||||
|
STGM_READ,
|
||||||
|
IID_IPropertyBag,
|
||||||
|
(void**)&pPropBag);
|
||||||
|
ok_long(hr, S_OK);
|
||||||
|
|
||||||
|
// Read UI4
|
||||||
|
VariantInit(&vari);
|
||||||
|
V_VT(&vari) = VT_UI4;
|
||||||
|
hr = pPropBag->Read(L"TestSection\\Name1", &vari, NULL);
|
||||||
|
ok_long(hr, S_OK);
|
||||||
|
ok_long(V_UI4(&vari), 0xDEADFACE);
|
||||||
|
VariantClear(&vari);
|
||||||
|
|
||||||
|
// Read BSTR
|
||||||
|
VariantInit(&vari);
|
||||||
|
V_VT(&vari) = VT_BSTR;
|
||||||
|
hr = pPropBag->Read(L"TestSection\\Name2", &vari, NULL);
|
||||||
|
ok_long(hr, S_OK);
|
||||||
|
ok_wstr(V_BSTR(&vari), L"StrValue");
|
||||||
|
VariantClear(&vari);
|
||||||
|
|
||||||
|
// Read BSTR (dirty UTF-7)
|
||||||
|
VariantInit(&vari);
|
||||||
|
V_VT(&vari) = VT_BSTR;
|
||||||
|
hr = pPropBag->Read(L"TestSection\\@Name3", &vari, NULL);
|
||||||
|
ok_long(hr, S_OK);
|
||||||
|
ok_wstr(V_BSTR(&vari), L"ABC\x3042\x3044\x3046\x2665");
|
||||||
|
VariantClear(&vari);
|
||||||
|
|
||||||
|
// Read BSTR (clean UTF-7)
|
||||||
|
VariantInit(&vari);
|
||||||
|
V_VT(&vari) = VT_BSTR;
|
||||||
|
hr = pPropBag->Read(L"TestSection\\@Name4", &vari, NULL);
|
||||||
|
ok_long(hr, S_OK);
|
||||||
|
ok_wstr(V_BSTR(&vari), L"1234abc");
|
||||||
|
VariantClear(&vari);
|
||||||
|
|
||||||
|
pPropBag->Release();
|
||||||
|
|
||||||
|
DeleteFileW(szIniFile);
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(SHPropertyBag)
|
START_TEST(SHPropertyBag)
|
||||||
{
|
{
|
||||||
SHPropertyBag_ReadTest();
|
SHPropertyBag_ReadTest();
|
||||||
|
@ -694,4 +830,5 @@ START_TEST(SHPropertyBag)
|
||||||
SHPropertyBag_OnMemory();
|
SHPropertyBag_OnMemory();
|
||||||
SHPropertyBag_OnRegKey();
|
SHPropertyBag_OnRegKey();
|
||||||
SHPropertyBag_SHSetIniStringW();
|
SHPropertyBag_SHSetIniStringW();
|
||||||
|
SHPropertyBag_OnIniFile();
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,14 @@ SHCreatePropertyBagOnRegKey(
|
||||||
_In_ REFIID riid,
|
_In_ REFIID riid,
|
||||||
_Out_ void **ppvObj);
|
_Out_ void **ppvObj);
|
||||||
|
|
||||||
|
HRESULT WINAPI
|
||||||
|
SHCreatePropertyBagOnProfileSection(
|
||||||
|
_In_z_ LPCWSTR lpFileName,
|
||||||
|
_In_opt_z_ LPCWSTR pszSection,
|
||||||
|
_In_ DWORD dwMode,
|
||||||
|
_In_ REFIID riid,
|
||||||
|
_Out_ void **ppvObj);
|
||||||
|
|
||||||
HWND WINAPI SHCreateWorkerWindowA(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle,
|
HWND WINAPI SHCreateWorkerWindowA(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle,
|
||||||
DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra);
|
DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra);
|
||||||
|
|
||||||
|
@ -194,6 +202,21 @@ SHSetIniStringW(
|
||||||
_In_opt_z_ LPCWSTR str,
|
_In_opt_z_ LPCWSTR str,
|
||||||
_In_z_ LPCWSTR filename);
|
_In_z_ LPCWSTR filename);
|
||||||
|
|
||||||
|
DWORD WINAPI
|
||||||
|
SHGetIniStringUTF7W(
|
||||||
|
_In_opt_z_ LPCWSTR lpAppName,
|
||||||
|
_In_z_ LPCWSTR lpKeyName,
|
||||||
|
_Out_writes_to_(nSize, return + 1) _Post_z_ LPWSTR lpReturnedString,
|
||||||
|
_In_ DWORD nSize,
|
||||||
|
_In_z_ LPCWSTR lpFileName);
|
||||||
|
|
||||||
|
BOOL WINAPI
|
||||||
|
SHSetIniStringUTF7W(
|
||||||
|
_In_z_ LPCWSTR lpAppName,
|
||||||
|
_In_z_ LPCWSTR lpKeyName,
|
||||||
|
_In_opt_z_ LPCWSTR lpString,
|
||||||
|
_In_z_ LPCWSTR lpFileName);
|
||||||
|
|
||||||
int
|
int
|
||||||
WINAPIV
|
WINAPIV
|
||||||
ShellMessageBoxWrapW(
|
ShellMessageBoxWrapW(
|
||||||
|
|
Loading…
Reference in a new issue