https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cf55034cdf3cb3adfb8e2…
commit cf55034cdf3cb3adfb8e2b256ad720b555999522
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Wed Aug 16 07:13:14 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Wed Aug 16 07:13:14 2023 +0900
[SHLWAPI][SDK] Rewrite SHGet/SHSetIniStringW in C++ (#5561)
- Follow-up to #5547. Move SHGetIniStringW / SHSetIniStringW into propbag.cpp.
- Rewrite them in C++.
CORE-9283
---
dll/win32/shlwapi/ordinal.c | 103 +-------------------------------
dll/win32/shlwapi/propbag.cpp | 113 ++++++++++++++++++++++++++++++++++++
sdk/include/reactos/shlwapi_undoc.h | 13 ++++-
3 files changed, 127 insertions(+), 102 deletions(-)
diff --git a/dll/win32/shlwapi/ordinal.c b/dll/win32/shlwapi/ordinal.c
index a151d4dce00..6f8855fd10a 100644
--- a/dll/win32/shlwapi/ordinal.c
+++ b/dll/win32/shlwapi/ordinal.c
@@ -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]
diff --git a/dll/win32/shlwapi/propbag.cpp b/dll/win32/shlwapi/propbag.cpp
index f9951324d0c..28e22736d5d 100644
--- a/dll/win32/shlwapi/propbag.cpp
+++ b/dll/win32/shlwapi/propbag.cpp
@@ -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;
+}
diff --git a/sdk/include/reactos/shlwapi_undoc.h b/sdk/include/reactos/shlwapi_undoc.h
index a2677a639ce..4e01e7c633f 100644
--- a/sdk/include/reactos/shlwapi_undoc.h
+++ b/sdk/include/reactos/shlwapi_undoc.h
@@ -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