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