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

commit a83fedcbfa981f17ab1fbd99045f2bdc7d71812e
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Wed Aug 9 08:23:33 2023 +0900
Commit:     GitHub <[email protected]>
CommitDate: Wed Aug 9 08:23:33 2023 +0900

    [SHLWAPI][SHLWAPI_APITEST][SDK] SHGetIniStringW/SHSetIniStringW (#5547)
    
    Follow-up to #5531. These two functions are necessary for INI file property 
bag support.
    - Implement SHGetIniStringW and SHSetIniStringW.
    - Strengthen SHPropertyBag testcase of shlwapi_apitest.
    CORE-9283
---
 dll/win32/shlwapi/ordinal.c                        | 104 +++++++++++++++++++++
 .../rostests/apitests/shlwapi/SHPropertyBag.cpp    |  50 ++++++++++
 sdk/include/reactos/shlwapi_undoc.h                |   6 ++
 3 files changed, 160 insertions(+)

diff --git a/dll/win32/shlwapi/ordinal.c b/dll/win32/shlwapi/ordinal.c
index f43408d9479..a151d4dce00 100644
--- a/dll/win32/shlwapi/ordinal.c
+++ b/dll/win32/shlwapi/ordinal.c
@@ -47,6 +47,9 @@
 #include "commdlg.h"
 #include "mlang.h"
 #include "mshtmhst.h"
+#ifdef __REACTOS__
+    #include <shlwapi_undoc.h>
+#endif
 #include "wine/unicode.h"
 #include "wine/debug.h"
 
@@ -3288,6 +3291,37 @@ 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;
 
@@ -3310,10 +3344,27 @@ 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
+
 /*************************************************************************
  *      @      [SHLWAPI.295]
  *
@@ -3333,10 +3384,63 @@ DWORD WINAPI SHGetIniStringW(LPCWSTR appName, LPCWSTR 
keyName, LPWSTR out,
 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
 }
 
 /*************************************************************************
diff --git a/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp 
b/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp
index 365c4478f19..2593cf66c6d 100644
--- a/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp
+++ b/modules/rostests/apitests/shlwapi/SHPropertyBag.cpp
@@ -638,10 +638,60 @@ static void SHPropertyBag_OnRegKey(void)
     RegCloseKey(hKey);
 }
 
+static void SHPropertyBag_SHSetIniStringW(void)
+{
+    WCHAR szIniFile[MAX_PATH];
+    WCHAR szValue[MAX_PATH];
+    BOOL bRet;
+    DWORD dwRet;
+
+    ExpandEnvironmentStringsW(L"%TEMP%\\SHSetIniString.ini", szIniFile, 
_countof(szIniFile));
+
+    DeleteFileW(szIniFile);
+
+    trace("%ls\n", szIniFile);
+
+    bRet = SHSetIniStringW(L"TestSection", L"Key", L"Value", szIniFile);
+    ok_int(bRet, TRUE);
+
+    WritePrivateProfileStringW(NULL, NULL, NULL, szIniFile);
+
+    dwRet = SHGetIniStringW(L"TestSection", L"Key", szValue, 
_countof(szValue), szIniFile);
+    ok_long(dwRet, 5);
+    ok_wstr(szValue, L"Value");
+
+    bRet = SHSetIniStringW(L"TestSection", L"Key", NULL, szIniFile);
+    ok_int(bRet, TRUE);
+
+    WritePrivateProfileStringW(NULL, NULL, NULL, szIniFile);
+
+    dwRet = SHGetIniStringW(L"TestSection", L"Key", szValue, 
_countof(szValue), szIniFile);
+    ok_long(dwRet, 0);
+    ok_wstr(szValue, L"");
+
+    bRet = SHSetIniStringW(L"TestSection", L"Key", 
L"ABC\x3042\x3044\x3046\x2665", szIniFile);
+    ok_int(bRet, TRUE);
+
+    WritePrivateProfileStringW(NULL, NULL, NULL, szIniFile);
+
+    dwRet = SHGetIniStringW(L"TestSection", L"Key", szValue, 
_countof(szValue), szIniFile);
+    ok_long(dwRet, 7);
+    ok_wstr(szValue, L"ABC\x3042\x3044\x3046\x2665");
+
+    szValue[0] = 0x3000;
+    szValue[1] = UNICODE_NULL;
+    dwRet = SHGetIniStringW(L"TestSection", L"NotExistentKey", szValue, 
_countof(szValue), szIniFile);
+    ok_long(dwRet, 0);
+    ok_wstr(szValue, L"");
+
+    DeleteFileW(szIniFile);
+}
+
 START_TEST(SHPropertyBag)
 {
     SHPropertyBag_ReadTest();
     SHPropertyBag_WriteTest();
     SHPropertyBag_OnMemory();
     SHPropertyBag_OnRegKey();
+    SHPropertyBag_SHSetIniStringW();
 }
diff --git a/sdk/include/reactos/shlwapi_undoc.h 
b/sdk/include/reactos/shlwapi_undoc.h
index 29aae083047..a2677a639ce 100644
--- a/sdk/include/reactos/shlwapi_undoc.h
+++ b/sdk/include/reactos/shlwapi_undoc.h
@@ -179,6 +179,12 @@ HRESULT WINAPI SHLoadRegUIStringW(HKEY hkey, LPCWSTR 
value, LPWSTR buf, DWORD si
 #define SHLoadRegUIString  SHLoadRegUIStringA
 #endif
 
+DWORD WINAPI
+SHGetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPWSTR out, DWORD outLen, 
LPCWSTR filename);
+
+BOOL WINAPI
+SHSetIniStringW(LPCWSTR appName, LPCWSTR keyName, LPCWSTR str, LPCWSTR 
filename);
+
 int
 WINAPIV
 ShellMessageBoxWrapW(

Reply via email to