[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(&sectionW);
     RtlFreeUnicodeString(&entryW);
     RtlFreeUnicodeString(&stringW);
-- 
2.20.1





More information about the wine-devel mailing list