[RFC PATCH 1/2] kernel32: Move implementation of {Get,Write}PrivateProfileStringW() to helper.
Jactry Zeng
jzeng at codeweavers.com
Tue Apr 23 02:50:29 CDT 2019
Hi folks,
This series is trying to fix GetPrivateProfileStringA() to let it can deal with section\key\value with multibyte characters.
The related real application is DISTRAINT: Deluxe Edition[1]. It saved localization information in some .ini files and used GetPrivateProfileStringA() for accessing them. The problem is MultiByteToWideChar(CP_ACP) in PROFILE_Load() will return decomposed string with '0x003f' for some multibyte characters when LC_CTYPE is zh_CN.UTF-8 or ja_JP.UTF-8. Then PROFILE_Load() will cache an wrong string and return a wrong result for GetPrivateProfileStringA().
But I'm not very sure if this is a good way to fix this issue since it hard coding codepage to 1252 for MultiByteToWideChar()/WideCharToMultiByte().
Any comments would be appreciated!
[1] https://store.steampowered.com/app/395170/DISTRAINT_Deluxe_Edition/
Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
---
dlls/kernel32/profile.c | 97 ++++++++++++++++++++++++-----------------
1 file changed, 58 insertions(+), 39 deletions(-)
diff --git a/dlls/kernel32/profile.c b/dlls/kernel32/profile.c
index 027693e5da..462d64e5f0 100644
--- a/dlls/kernel32/profile.c
+++ b/dlls/kernel32/profile.c
@@ -1082,17 +1082,13 @@ UINT WINAPI GetProfileIntW( LPCWSTR section, LPCWSTR entry, INT def_val )
return GetPrivateProfileIntW( section, entry, def_val, wininiW );
}
-/***********************************************************************
- * GetPrivateProfileStringW (KERNEL32.@)
- */
-INT WINAPI GetPrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
- LPCWSTR def_val, LPWSTR buffer,
- UINT len, LPCWSTR filename )
+static int get_private_profile_string(LPCWSTR section, LPCWSTR entry, LPCWSTR def_val,
+ LPWSTR buffer, UINT len, LPCWSTR filename)
{
- int ret;
- LPWSTR defval_tmp = NULL;
+ int ret;
+ LPWSTR defval_tmp = NULL;
- TRACE("%s,%s,%s,%p,%u,%s\n", debugstr_w(section), debugstr_w(entry),
+ TRACE("(%s, %s, %s, %p, %u, %s)\n", debugstr_w(section), debugstr_w(entry),
debugstr_w(def_val), buffer, len, debugstr_w(filename));
/* strip any trailing ' ' of def_val. */
@@ -1114,22 +1110,25 @@ INT WINAPI GetPrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
}
}
- RtlEnterCriticalSection( &PROFILE_CritSect );
+ RtlEnterCriticalSection(&PROFILE_CritSect);
- if (PROFILE_Open( filename, FALSE )) {
- if (section == NULL)
+ if (PROFILE_Open(filename, FALSE))
+ {
+ if (section == NULL)
ret = PROFILE_GetSectionNames(buffer, len);
- else
- /* PROFILE_GetString can handle the 'entry == NULL' case */
- ret = PROFILE_GetString( section, entry, def_val, buffer, len );
- } else if (buffer && def_val) {
- lstrcpynW( buffer, def_val, len );
- ret = strlenW( buffer );
+ else
+ /* PROFILE_GetString can handle the 'entry == NULL' case */
+ ret = PROFILE_GetString(section, entry, def_val, buffer, len);
+ }
+ else if (buffer && def_val)
+ {
+ lstrcpynW(buffer, def_val, len);
+ ret = strlenW(buffer);
}
else
- ret = 0;
+ ret = 0;
- RtlLeaveCriticalSection( &PROFILE_CritSect );
+ RtlLeaveCriticalSection(&PROFILE_CritSect);
HeapFree(GetProcessHeap(), 0, defval_tmp);
@@ -1138,12 +1137,23 @@ INT WINAPI GetPrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
return ret;
}
+/***********************************************************************
+ * GetPrivateProfileStringW (KERNEL32.@)
+ */
+INT WINAPI GetPrivateProfileStringW(LPCWSTR section, LPCWSTR entry,
+ LPCWSTR def_val, LPWSTR buffer,
+ UINT len, LPCWSTR filename)
+{
+ return get_private_profile_string(section, entry, def_val, buffer,
+ len, filename);
+}
+
/***********************************************************************
* GetPrivateProfileStringA (KERNEL32.@)
*/
-INT WINAPI GetPrivateProfileStringA( LPCSTR section, LPCSTR entry,
- LPCSTR def_val, LPSTR buffer,
- UINT len, LPCSTR filename )
+INT WINAPI GetPrivateProfileStringA(LPCSTR section, LPCSTR entry,
+ LPCSTR def_val, LPSTR buffer,
+ UINT len, LPCSTR filename)
{
UNICODE_STRING sectionW, entryW, def_valW, filenameW;
LPWSTR bufferW;
@@ -1159,9 +1169,9 @@ INT WINAPI GetPrivateProfileStringA( LPCSTR section, LPCSTR entry,
if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else filenameW.Buffer = NULL;
- retW = GetPrivateProfileStringW( sectionW.Buffer, entryW.Buffer,
- def_valW.Buffer, bufferW, len,
- filenameW.Buffer);
+ retW = get_private_profile_string(sectionW.Buffer, entryW.Buffer,
+ def_valW.Buffer, bufferW, len,
+ filenameW.Buffer);
if (len && buffer)
{
if (retW)
@@ -1358,38 +1368,47 @@ INT WINAPI GetProfileSectionW( LPCWSTR section, LPWSTR buffer, DWORD len )
return GetPrivateProfileSectionW( section, buffer, len, wininiW );
}
-
-/***********************************************************************
- * WritePrivateProfileStringW (KERNEL32.@)
- */
-BOOL WINAPI WritePrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
- LPCWSTR string, LPCWSTR filename )
+static BOOL write_private_profile_string(LPCWSTR section, LPCWSTR entry, LPCWSTR string,
+ LPCWSTR filename)
{
BOOL ret = FALSE;
- RtlEnterCriticalSection( &PROFILE_CritSect );
+ TRACE("(%s, %s, %s, %s)\n", debugstr_w(section), debugstr_w(entry),
+ debugstr_w(string), debugstr_w(filename));
+
+ RtlEnterCriticalSection(&PROFILE_CritSect);
if (!section && !entry && !string) /* documented "file flush" case */
{
- if (!filename || PROFILE_Open( filename, TRUE ))
+ if (!filename || PROFILE_Open(filename, TRUE))
{
if (CurProfile) PROFILE_ReleaseFile(); /* always return FALSE in this case */
}
}
- else if (PROFILE_Open( filename, TRUE ))
+ else if (PROFILE_Open(filename, TRUE))
{
if (!section) {
SetLastError(ERROR_FILE_NOT_FOUND);
} else {
- ret = PROFILE_SetString( section, entry, string, FALSE);
+ ret = PROFILE_SetString(section, entry, string, FALSE);
if (ret) ret = PROFILE_FlushFile();
}
}
- RtlLeaveCriticalSection( &PROFILE_CritSect );
+ RtlLeaveCriticalSection(&PROFILE_CritSect);
return ret;
}
+/***********************************************************************
+ * WritePrivateProfileStringW (KERNEL32.@)
+ */
+BOOL WINAPI WritePrivateProfileStringW(LPCWSTR section, LPCWSTR entry,
+ LPCWSTR string, LPCWSTR filename)
+{
+ return write_private_profile_string(section, entry, string,
+ filename);
+}
+
/***********************************************************************
* WritePrivateProfileStringA (KERNEL32.@)
*/
@@ -1408,8 +1427,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH WritePrivateProfileStringA( LPCSTR section, LPCSTR
if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
else filenameW.Buffer = NULL;
- ret = WritePrivateProfileStringW(sectionW.Buffer, entryW.Buffer,
- stringW.Buffer, filenameW.Buffer);
+ ret = write_private_profile_string(sectionW.Buffer, entryW.Buffer,
+ stringW.Buffer, filenameW.Buffer);
RtlFreeUnicodeString(§ionW);
RtlFreeUnicodeString(&entryW);
RtlFreeUnicodeString(&stringW);
--
2.20.1
More information about the wine-devel
mailing list