https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cf55034cdf3cb3adfb8e2b256ad720b555999522

commit cf55034cdf3cb3adfb8e2b256ad720b555999522
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Wed Aug 16 07:13:14 2023 +0900
Commit:     GitHub <nore...@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

Reply via email to