[SHLWAPI][SDK] Rewrite SHGet/SHSetIniStringW in C++ (#5561)

- Follow-up to #5547. Move SHGetIniStringW / SHSetIniStringW into propbag.cpp.
- Rewrite them in C++.
CORE-9283
This commit is contained in:
Katayama Hirofumi MZ
2023-08-16 07:13:14 +09:00
committed by GitHub
parent 2d53e953cd
commit cf55034cdf
3 changed files with 127 additions and 102 deletions

View File

@@ -3272,6 +3272,7 @@ BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
return PlaySoundW(pszSound, hmod, fdwSound);
}
#ifndef __REACTOS__ /* See propbag.cpp */
/*************************************************************************
* @ [SHLWAPI.294]
*
@@ -3291,37 +3292,6 @@ BOOL WINAPI PlaySoundWrapW(LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)
DWORD WINAPI SHGetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPWSTR out,
DWORD outLen, LPCWSTR filename)
{
#ifdef __REACTOS__
WCHAR szSection[MAX_PATH + 2];
WCHAR szWideBuff[MAX_PATH];
CHAR szUtf7Buff[MAX_PATH];
TRACE("(%s,%s,%p,%08x,%s)\n", debugstr_w(appName), debugstr_w(keyName),
out, outLen, debugstr_w(filename));
if (outLen == 0)
return 0;
/* Try ".W"-appended section name. See also SHSetIniStringW. */
lstrcpynW(szSection, appName, _countof(szSection) - 2);
lstrcatW(szSection, L".W");
GetPrivateProfileStringW(szSection, keyName, NULL, szWideBuff, _countof(szWideBuff), filename);
if (szWideBuff[0] == UNICODE_NULL) /* It's empty or not found */
{
/* Try the normal section name */
return GetPrivateProfileStringW(appName, keyName, NULL, out, outLen, filename);
}
/* Okay, now ".W" version is valid. Its value is a UTF-7 string in UTF-16 */
/* szWideBuff --> szUtf7Buff */
SHUnicodeToAnsiCP(CP_ACP, szWideBuff, szUtf7Buff, _countof(szUtf7Buff));
szUtf7Buff[_countof(szUtf7Buff) - 1] = ANSI_NULL;
/* szUtf7Buff --> out */
SHAnsiToUnicodeCP(CP_UTF7, szUtf7Buff, out, outLen);
out[outLen - 1] = UNICODE_NULL;
#else
INT ret;
WCHAR *buf;
@@ -3344,27 +3314,12 @@ DWORD WINAPI SHGetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPWSTR out,
*out = 0;
HeapFree(GetProcessHeap(), 0, buf);
#endif
return strlenW(out);
}
#ifdef __REACTOS__
static BOOL Is7BitClean(LPCWSTR psz)
{
if (!psz)
return TRUE;
while (*psz)
{
if (*psz > 0x7F)
return FALSE;
++psz;
}
return TRUE;
}
#endif
#ifndef __REACTOS__ /* See propbag.cpp */
/*************************************************************************
* @ [SHLWAPI.295]
*
@@ -3384,64 +3339,12 @@ static BOOL Is7BitClean(LPCWSTR psz)
BOOL WINAPI SHSetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPCWSTR str,
LPCWSTR filename)
{
#ifdef __REACTOS__
WCHAR szSection[MAX_PATH + 2];
WCHAR szWideBuff[MAX_PATH];
CHAR szUtf7Buff[MAX_PATH];
TRACE("(%s, %p, %s, %s)\n", debugstr_w(appName), keyName, debugstr_w(str),
debugstr_w(filename));
/* Write a normal profile string. If str was NULL, then key will be deleted */
if (!WritePrivateProfileStringW(appName, keyName, str, filename))
return FALSE;
if (Is7BitClean(str))
{
/* Delete ".A" version */
lstrcpynW(szSection, appName, _countof(szSection) - 2);
lstrcatW(szSection, L".A");
WritePrivateProfileStringW(szSection, keyName, NULL, filename);
/* Delete ".W" version */
lstrcpynW(szSection, appName, _countof(szSection) - 2);
lstrcatW(szSection, L".W");
WritePrivateProfileStringW(szSection, keyName, NULL, filename);
return TRUE;
}
/* Now str is not 7-bit clean. It needs UTF-7 encoding in UTF-16.
We write ".A" and ".W"-appended sections. */
/* str --> szUtf7Buff */
SHUnicodeToAnsiCP(CP_UTF7, str, szUtf7Buff, _countof(szUtf7Buff));
szUtf7Buff[_countof(szUtf7Buff) - 1] = ANSI_NULL;
/* szUtf7Buff --> szWideBuff */
SHAnsiToUnicodeCP(CP_ACP, szUtf7Buff, szWideBuff, _countof(szWideBuff));
szWideBuff[_countof(szWideBuff) - 1] = UNICODE_NULL;
/* Write ".A" version */
lstrcpynW(szSection, appName, _countof(szSection) - 2);
lstrcatW(szSection, L".A");
if (!WritePrivateProfileStringW(szSection, keyName, str, filename))
return FALSE;
/* Write ".W" version */
lstrcpynW(szSection, appName, _countof(szSection) - 2);
lstrcatW(szSection, L".W");
if (!WritePrivateProfileStringW(szSection, keyName, szWideBuff, filename))
return FALSE;
return TRUE;
#else
TRACE("(%s, %p, %s, %s)\n", debugstr_w(appName), keyName, debugstr_w(str),
debugstr_w(filename));
return WritePrivateProfileStringW(appName, keyName, str, filename);
#endif
}
#endif
/*************************************************************************
* @ [SHLWAPI.313]

View File

@@ -12,6 +12,7 @@
#include <atlstr.h> // for CStringW
#include <atlsimpcoll.h> // for CSimpleMap
#include <atlcomcli.h> // for CComVariant
#include <atlconv.h> // for CA2W and CW2A
WINE_DEFAULT_DEBUG_CHANNEL(shell);
@@ -580,3 +581,115 @@ SHCreatePropertyBagOnRegKey(
return pRegBag->QueryInterface(riid, ppvObj);
}
/**************************************************************************
* SHGetIniStringW (SHLWAPI.294)
*
* @see https://source.winehq.org/WineAPI/SHGetIniStringW.html
*/
EXTERN_C DWORD WINAPI
SHGetIniStringW(
_In_z_ LPCWSTR appName,
_In_z_ LPCWSTR keyName,
_Out_writes_to_(outLen, return + 1) LPWSTR out,
_In_ DWORD outLen,
_In_z_ LPCWSTR filename)
{
TRACE("(%s,%s,%p,%08x,%s)\n", debugstr_w(appName), debugstr_w(keyName),
out, outLen, debugstr_w(filename));
if (outLen == 0)
return 0;
// Try ".W"-appended section name. See also SHSetIniStringW
CStringW szSection(appName);
szSection += L".W";
CStringW pszWideBuff;
const INT cchWideMax = 4 * MAX_PATH; // UTF-7 needs 4 times length buffer.
GetPrivateProfileStringW(szSection, keyName, NULL,
pszWideBuff.GetBuffer(cchWideMax), cchWideMax, filename);
pszWideBuff.ReleaseBuffer();
if (pszWideBuff.IsEmpty()) // It's empty or not found
{
// Try the normal section name
return GetPrivateProfileStringW(appName, keyName, NULL, out, outLen, filename);
}
// Okay, now ".W" version is valid. Its value is a UTF-7 string in UTF-16
CW2A wide2utf7(pszWideBuff);
MultiByteToWideChar(CP_UTF7, 0, wide2utf7, -1, out, outLen);
out[outLen - 1] = UNICODE_NULL;
return lstrlenW(out);
}
static BOOL Is7BitClean(LPCWSTR psz)
{
if (!psz)
return TRUE;
while (*psz)
{
if (*psz > 0x7F)
return FALSE;
++psz;
}
return TRUE;
}
/**************************************************************************
* SHSetIniStringW (SHLWAPI.295)
*
* @see https://source.winehq.org/WineAPI/SHSetIniStringW.html
*/
EXTERN_C BOOL WINAPI
SHSetIniStringW(
_In_z_ LPCWSTR appName,
_In_z_ LPCWSTR keyName,
_In_opt_z_ LPCWSTR str,
_In_z_ LPCWSTR filename)
{
TRACE("(%s, %p, %s, %s)\n", debugstr_w(appName), keyName, debugstr_w(str),
debugstr_w(filename));
// Write a normal profile string. If str was NULL, then key will be deleted
if (!WritePrivateProfileStringW(appName, keyName, str, filename))
return FALSE;
if (Is7BitClean(str))
{
// Delete ".A" version
CStringW szSection(appName);
szSection += L".A";
WritePrivateProfileStringW(szSection, keyName, NULL, filename);
// Delete ".W" version
szSection = appName;
szSection += L".W";
WritePrivateProfileStringW(szSection, keyName, NULL, filename);
return TRUE;
}
// Now str is not 7-bit clean. It needs UTF-7 encoding in UTF-16.
// We write ".A" and ".W"-appended sections
CW2A wide2utf7(str, CP_UTF7);
CA2W utf72wide(wide2utf7, CP_ACP);
BOOL ret = TRUE;
// Write ".A" version
CStringW szSection(appName);
szSection += L".A";
if (!WritePrivateProfileStringW(szSection, keyName, str, filename))
ret = FALSE;
// Write ".W" version
szSection = appName;
szSection += L".W";
if (!WritePrivateProfileStringW(szSection, keyName, utf72wide, filename))
ret = FALSE;
return ret;
}

View File

@@ -180,10 +180,19 @@ HRESULT WINAPI SHLoadRegUIStringW(HKEY hkey, LPCWSTR value, LPWSTR buf, DWORD si
#endif
DWORD WINAPI
SHGetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPWSTR out, DWORD outLen, LPCWSTR filename);
SHGetIniStringW(
_In_z_ LPCWSTR appName,
_In_z_ LPCWSTR keyName,
_Out_writes_to_(outLen, return + 1) LPWSTR out,
_In_ DWORD outLen,
_In_z_ LPCWSTR filename);
BOOL WINAPI
SHSetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPCWSTR str, LPCWSTR filename);
SHSetIniStringW(
_In_z_ LPCWSTR appName,
_In_z_ LPCWSTR keyName,
_In_opt_z_ LPCWSTR str,
_In_z_ LPCWSTR filename);
int
WINAPIV