[RFC PATCH 2/2] kernel32: Split A/W implementation of {Get,Write}PrivateProfileString().

Jactry Zeng jzeng at codeweavers.com
Tue Apr 23 02:51:11 CDT 2019


Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
---
 dlls/kernel32/profile.c       | 126 +++++++++++++++++++---------------
 dlls/kernel32/tests/profile.c |  91 +++++++++++++++++++++---
 2 files changed, 151 insertions(+), 66 deletions(-)

diff --git a/dlls/kernel32/profile.c b/dlls/kernel32/profile.c
index 462d64e5f0..3defaf6bef 100644
--- a/dlls/kernel32/profile.c
+++ b/dlls/kernel32/profile.c
@@ -68,6 +68,7 @@ typedef struct
     WCHAR           *filename;
     FILETIME LastWriteTime;
     ENCODING encoding;
+    BOOL is_unicode;
 } PROFILE;
 
 
@@ -149,7 +150,7 @@ static inline void PROFILE_WriteMarker(HANDLE hFile, ENCODING encoding)
     }
 }
 
-static void PROFILE_WriteLine( HANDLE hFile, WCHAR * szLine, int len, ENCODING encoding)
+static void PROFILE_WriteLine(HANDLE hFile, WCHAR *szLine, int len, ENCODING encoding, BOOL is_unicode)
 {
     char * write_buffer;
     int write_buffer_len;
@@ -160,10 +161,10 @@ static void PROFILE_WriteLine( HANDLE hFile, WCHAR * szLine, int len, ENCODING e
     switch (encoding)
     {
     case ENCODING_ANSI:
-        write_buffer_len = WideCharToMultiByte(CP_ACP, 0, szLine, len, NULL, 0, NULL, NULL);
+        write_buffer_len = WideCharToMultiByte(is_unicode ? CP_ACP : 1252, 0, szLine, len, NULL, 0, NULL, NULL);
         write_buffer = HeapAlloc(GetProcessHeap(), 0, write_buffer_len);
         if (!write_buffer) return;
-        len = WideCharToMultiByte(CP_ACP, 0, szLine, len, write_buffer, write_buffer_len, NULL, NULL);
+        len = WideCharToMultiByte(is_unicode ? CP_ACP : 1252, 0, szLine, len, write_buffer, write_buffer_len, NULL, NULL);
         WriteFile(hFile, write_buffer, len, &dwBytesWritten, NULL);
         HeapFree(GetProcessHeap(), 0, write_buffer);
         break;
@@ -192,7 +193,7 @@ static void PROFILE_WriteLine( HANDLE hFile, WCHAR * szLine, int len, ENCODING e
  *
  * Save a profile tree to a file.
  */
-static void PROFILE_Save( HANDLE hFile, const PROFILESECTION *section, ENCODING encoding )
+static void PROFILE_Save(HANDLE hFile, const PROFILESECTION *section, ENCODING encoding, BOOL is_unicode)
 {
     PROFILEKEY *key;
     WCHAR *buffer, *p;
@@ -238,7 +239,7 @@ static void PROFILE_Save( HANDLE hFile, const PROFILESECTION *section, ENCODING
             *p++ = '\r';
             *p++ = '\n';
         }
-        PROFILE_WriteLine( hFile, buffer, len, encoding );
+        PROFILE_WriteLine(hFile, buffer, len, encoding, is_unicode);
         HeapFree(GetProcessHeap(), 0, buffer);
     }
 }
@@ -305,7 +306,7 @@ static inline ENCODING PROFILE_DetectTextEncoding(const void * buffer, int * len
  *
  * Load a profile tree from a file.
  */
-static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding)
+static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING *pEncoding, BOOL is_unicode)
 {
     void *buffer_base, *pBuffer;
     WCHAR * szFile;
@@ -343,14 +344,14 @@ static PROFILESECTION *PROFILE_Load(HANDLE hFile, ENCODING * pEncoding)
     case ENCODING_ANSI:
         TRACE("ANSI encoding\n");
 
-        len = MultiByteToWideChar(CP_ACP, 0, pBuffer, dwFileSize, NULL, 0);
+        len = MultiByteToWideChar(is_unicode ? CP_ACP : 1252, 0, pBuffer, dwFileSize, NULL, 0);
         szFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
         if (!szFile)
         {
             HeapFree(GetProcessHeap(), 0, buffer_base);
             return NULL;
         }
-        MultiByteToWideChar(CP_ACP, 0, pBuffer, dwFileSize, szFile, len);
+        MultiByteToWideChar(is_unicode ? CP_ACP : 1252, 0, pBuffer, dwFileSize, szFile, len);
         szEnd = szFile + len;
         break;
     case ENCODING_UTF8:
@@ -678,7 +679,7 @@ static BOOL PROFILE_FlushFile(void)
     }
 
     TRACE("Saving %s\n", debugstr_w(CurProfile->filename));
-    PROFILE_Save( hFile, CurProfile->section, CurProfile->encoding );
+    PROFILE_Save(hFile, CurProfile->section, CurProfile->encoding, CurProfile->is_unicode);
     if(GetFileTime(hFile, NULL, NULL, &LastWriteTime))
        CurProfile->LastWriteTime=LastWriteTime;
     CloseHandle( hFile );
@@ -729,7 +730,7 @@ static BOOL is_not_current(FILETIME * ft)
  *
  * Open a profile file, checking the cached file first.
  */
-static BOOL PROFILE_Open( LPCWSTR filename, BOOL write_access )
+static BOOL PROFILE_Open(LPCWSTR filename, BOOL write_access, BOOL is_unicode)
 {
     WCHAR buffer[MAX_PATH];
     HANDLE hFile = INVALID_HANDLE_VALUE;
@@ -750,6 +751,7 @@ static BOOL PROFILE_Open( LPCWSTR filename, BOOL write_access )
           MRUProfile[i]->section=NULL;
           MRUProfile[i]->filename=NULL;
           MRUProfile[i]->encoding=ENCODING_ANSI;
+          MRUProfile[i]->is_unicode = is_unicode;
           ZeroMemory(&MRUProfile[i]->LastWriteTime, sizeof(FILETIME));
        }
 
@@ -786,7 +788,8 @@ static BOOL PROFILE_Open( LPCWSTR filename, BOOL write_access )
 
     for(i=0;i<N_CACHED_PROFILES;i++)
     {
-        if ((MRUProfile[i]->filename && !strcmpiW( buffer, MRUProfile[i]->filename )))
+        if ((MRUProfile[i]->filename && !strcmpiW(buffer, MRUProfile[i]->filename) &&
+             (MRUProfile[i]->is_unicode == is_unicode)))
         {
             TRACE("MRU Filename: %s, new filename: %s\n", debugstr_w(MRUProfile[i]->filename), debugstr_w(buffer));
             if(i)
@@ -810,7 +813,7 @@ static BOOL PROFILE_Open( LPCWSTR filename, BOOL write_access )
                     TRACE("(%s): already opened, needs refreshing (mru=%d)\n",
                           debugstr_w(buffer), i);
                     PROFILE_Free(CurProfile->section);
-                    CurProfile->section = PROFILE_Load(hFile, &CurProfile->encoding);
+                    CurProfile->section = PROFILE_Load(hFile, &CurProfile->encoding, CurProfile->is_unicode);
                     CurProfile->LastWriteTime = LastWriteTime;
                 }
                 CloseHandle(hFile);
@@ -840,7 +843,8 @@ static BOOL PROFILE_Open( LPCWSTR filename, BOOL write_access )
 
     if (hFile != INVALID_HANDLE_VALUE)
     {
-        CurProfile->section = PROFILE_Load(hFile, &CurProfile->encoding);
+        CurProfile->is_unicode = is_unicode;
+        CurProfile->section = PROFILE_Load(hFile, &CurProfile->encoding, CurProfile->is_unicode);
         GetFileTime(hFile, NULL, NULL, &CurProfile->LastWriteTime);
         CloseHandle(hFile);
     }
@@ -1062,6 +1066,19 @@ static BOOL PROFILE_SetString( LPCWSTR section_name, LPCWSTR key_name,
     return TRUE;
 }
 
+static LPWSTR c2w(LPCSTR string)
+{
+    INT lenW;
+    LPWSTR stringW = NULL;
+
+    if (!string)
+        return stringW;
+
+    lenW = MultiByteToWideChar(1252, 0, string, -1, NULL, 0);
+    if ((stringW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR))))
+        MultiByteToWideChar(1252, 0, string, -1, stringW, lenW);
+    return stringW;
+}
 
 /********************* API functions **********************************/
 
@@ -1083,13 +1100,13 @@ UINT WINAPI GetProfileIntW( LPCWSTR section, LPCWSTR entry, INT def_val )
 }
 
 static int get_private_profile_string(LPCWSTR section, LPCWSTR entry, LPCWSTR def_val,
-                                      LPWSTR buffer, UINT len, LPCWSTR filename)
+                                      LPWSTR buffer, UINT len, LPCWSTR filename, BOOL is_unicode)
 {
     int ret;
     LPWSTR defval_tmp = NULL;
 
-    TRACE("(%s, %s, %s, %p, %u, %s)\n", debugstr_w(section), debugstr_w(entry),
-          debugstr_w(def_val), buffer, len, debugstr_w(filename));
+    TRACE("(%s, %s, %s, %p, %u, %s, %d)\n", debugstr_w(section), debugstr_w(entry),
+          debugstr_w(def_val), buffer, len, debugstr_w(filename), is_unicode);
 
     /* strip any trailing ' ' of def_val. */
     if (def_val)
@@ -1112,7 +1129,7 @@ static int get_private_profile_string(LPCWSTR section, LPCWSTR entry, LPCWSTR de
 
     RtlEnterCriticalSection(&PROFILE_CritSect);
 
-    if (PROFILE_Open(filename, FALSE))
+    if (PROFILE_Open(filename, FALSE, is_unicode))
     {
         if (section == NULL)
             ret = PROFILE_GetSectionNames(buffer, len);
@@ -1145,7 +1162,7 @@ INT WINAPI GetPrivateProfileStringW(LPCWSTR section, LPCWSTR entry,
                                     UINT len, LPCWSTR filename)
 {
     return get_private_profile_string(section, entry, def_val, buffer,
-                                      len, filename);
+                                      len, filename, TRUE);
 }
 
 /***********************************************************************
@@ -1155,39 +1172,35 @@ 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;
+    UNICODE_STRING filenameW;
+    LPWSTR bufferW, sectionW, entryW, def_valW;
     INT retW, ret = 0;
 
     bufferW = buffer ? HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)) : NULL;
-    if (section) RtlCreateUnicodeStringFromAsciiz(&sectionW, section);
-    else sectionW.Buffer = NULL;
-    if (entry) RtlCreateUnicodeStringFromAsciiz(&entryW, entry);
-    else entryW.Buffer = NULL;
-    if (def_val) RtlCreateUnicodeStringFromAsciiz(&def_valW, def_val);
-    else def_valW.Buffer = NULL;
+    sectionW = c2w(section);
+    entryW = c2w(entry);
+    def_valW = c2w(def_val);
     if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
     else filenameW.Buffer = NULL;
 
-    retW = get_private_profile_string(sectionW.Buffer, entryW.Buffer,
-                                      def_valW.Buffer, bufferW, len,
-                                      filenameW.Buffer);
+    retW = get_private_profile_string(sectionW, entryW, def_valW, bufferW, len,
+                                      filenameW.Buffer, FALSE);
     if (len && buffer)
     {
         if (retW)
         {
-            ret = WideCharToMultiByte(CP_ACP, 0, bufferW, retW, buffer, len - 1, NULL, NULL);
+            ret = WideCharToMultiByte(1252, 0, bufferW, retW, buffer, len - 1, NULL, NULL);
             if (!ret)
                 ret = len - 1;
         }
         buffer[ret] = 0;
     }
 
-    RtlFreeUnicodeString(&sectionW);
-    RtlFreeUnicodeString(&entryW);
-    RtlFreeUnicodeString(&def_valW);
     RtlFreeUnicodeString(&filenameW);
     HeapFree(GetProcessHeap(), 0, bufferW);
+    HeapFree(GetProcessHeap(), 0, sectionW);
+    HeapFree(GetProcessHeap(), 0, entryW);
+    HeapFree(GetProcessHeap(), 0, def_valW);
     return ret;
 }
 
@@ -1298,7 +1311,7 @@ INT WINAPI GetPrivateProfileSectionW( LPCWSTR section, LPWSTR buffer,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename, FALSE ))
+    if (PROFILE_Open(filename, FALSE, TRUE))
         ret = PROFILE_GetSection(CurProfile->section, section, buffer, len, TRUE);
 
     RtlLeaveCriticalSection( &PROFILE_CritSect );
@@ -1369,23 +1382,23 @@ INT WINAPI GetProfileSectionW( LPCWSTR section, LPWSTR buffer, DWORD len )
 }
 
 static BOOL write_private_profile_string(LPCWSTR section, LPCWSTR entry, LPCWSTR string,
-                                         LPCWSTR filename)
+                                         LPCWSTR filename, BOOL is_unicode)
 {
     BOOL ret = FALSE;
 
-    TRACE("(%s, %s, %s, %s)\n", debugstr_w(section), debugstr_w(entry),
-          debugstr_w(string), debugstr_w(filename));
+    TRACE("(%s, %s, %s, %s, %d)\n", debugstr_w(section), debugstr_w(entry),
+          debugstr_w(string), debugstr_w(filename), is_unicode);
 
     RtlEnterCriticalSection(&PROFILE_CritSect);
 
     if (!section && !entry && !string) /* documented "file flush" case */
     {
-        if (!filename || PROFILE_Open(filename, TRUE))
+        if (!filename || PROFILE_Open(filename, TRUE, is_unicode))
         {
             if (CurProfile) PROFILE_ReleaseFile();  /* always return FALSE in this case */
         }
     }
-    else if (PROFILE_Open(filename, TRUE))
+    else if (PROFILE_Open(filename, TRUE, is_unicode))
     {
         if (!section) {
             SetLastError(ERROR_FILE_NOT_FOUND);
@@ -1406,7 +1419,7 @@ BOOL WINAPI WritePrivateProfileStringW(LPCWSTR section, LPCWSTR entry,
                                        LPCWSTR string, LPCWSTR filename)
 {
     return write_private_profile_string(section, entry, string,
-                                        filename);
+                                        filename, TRUE);
 }
 
 /***********************************************************************
@@ -1415,23 +1428,22 @@ BOOL WINAPI WritePrivateProfileStringW(LPCWSTR section, LPCWSTR entry,
 BOOL WINAPI DECLSPEC_HOTPATCH WritePrivateProfileStringA( LPCSTR section, LPCSTR entry,
                                                           LPCSTR string, LPCSTR filename )
 {
-    UNICODE_STRING sectionW, entryW, stringW, filenameW;
+    UNICODE_STRING filenameW;
+    LPWSTR sectionW, entryW, stringW;
     BOOL ret;
 
-    if (section) RtlCreateUnicodeStringFromAsciiz(&sectionW, section);
-    else sectionW.Buffer = NULL;
-    if (entry) RtlCreateUnicodeStringFromAsciiz(&entryW, entry);
-    else entryW.Buffer = NULL;
-    if (string) RtlCreateUnicodeStringFromAsciiz(&stringW, string);
-    else stringW.Buffer = NULL;
+    sectionW = c2w(section);
+    entryW = c2w(entry);
+    stringW = c2w(string);
     if (filename) RtlCreateUnicodeStringFromAsciiz(&filenameW, filename);
     else filenameW.Buffer = NULL;
 
-    ret = write_private_profile_string(sectionW.Buffer, entryW.Buffer,
-                                       stringW.Buffer, filenameW.Buffer);
-    RtlFreeUnicodeString(&sectionW);
-    RtlFreeUnicodeString(&entryW);
-    RtlFreeUnicodeString(&stringW);
+    ret = write_private_profile_string(sectionW, entryW, stringW,
+                                       filenameW.Buffer, FALSE);
+
+    HeapFree(GetProcessHeap(), 0, sectionW);
+    HeapFree(GetProcessHeap(), 0, entryW);
+    HeapFree(GetProcessHeap(), 0, stringW);
     RtlFreeUnicodeString(&filenameW);
     return ret;
 }
@@ -1449,12 +1461,12 @@ BOOL WINAPI WritePrivateProfileSectionW( LPCWSTR section,
 
     if (!section && !string)
     {
-        if (!filename || PROFILE_Open( filename, TRUE ))
+        if (!filename || PROFILE_Open(filename, TRUE, TRUE))
         {
             if (CurProfile) PROFILE_ReleaseFile();  /* always return FALSE in this case */
         }
     }
-    else if (PROFILE_Open( filename, TRUE )) {
+    else if (PROFILE_Open(filename, TRUE, TRUE)) {
         if (!string) {/* delete the named section*/
 	    ret = PROFILE_SetString(section,NULL,NULL, FALSE);
         } else {
@@ -1576,7 +1588,7 @@ DWORD WINAPI GetPrivateProfileSectionNamesW( LPWSTR buffer, DWORD size,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename, FALSE ))
+    if (PROFILE_Open(filename, FALSE, TRUE))
         ret = PROFILE_GetSectionNames(buffer, size);
 
     RtlLeaveCriticalSection( &PROFILE_CritSect );
@@ -1631,7 +1643,7 @@ BOOL WINAPI GetPrivateProfileStructW (LPCWSTR section, LPCWSTR key,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename, FALSE )) {
+    if (PROFILE_Open(filename, FALSE, TRUE)) {
         PROFILEKEY *k = PROFILE_Find ( &CurProfile->section, section, key, FALSE, FALSE);
 	if (k) {
 	    TRACE("value (at %p): %s\n", k->value, debugstr_w(k->value));
@@ -1751,7 +1763,7 @@ BOOL WINAPI WritePrivateProfileStructW (LPCWSTR section, LPCWSTR key,
 
     RtlEnterCriticalSection( &PROFILE_CritSect );
 
-    if (PROFILE_Open( filename, TRUE )) {
+    if (PROFILE_Open(filename, TRUE, TRUE)) {
         ret = PROFILE_SetString( section, key, outstring, FALSE);
         if (ret) ret = PROFILE_FlushFile();
     }
diff --git a/dlls/kernel32/tests/profile.c b/dlls/kernel32/tests/profile.c
index 8a0089bb1b..293d009eb8 100644
--- a/dlls/kernel32/tests/profile.c
+++ b/dlls/kernel32/tests/profile.c
@@ -592,7 +592,11 @@ static void test_GetPrivateProfileString(const char *content, const char *descri
        empty string and check for modification */
     CHAR emptystr[MAX_PATH] = "";
     LPSTR tempfile;
-
+    CHAR expected_val[MAX_PATH];
+    WCHAR bufW[MAX_PATH], expected_valW[MAX_PATH];
+    static const WCHAR section_schineseW[] = {0xe6,0xae,0xb5,0x31,0};
+    static const WCHAR name5W[] = {'n','a','m','e','5',0};
+    static const WCHAR filenameW[] = {'.','\\','w','i','n','e','t','e','s','t','.','i','n','i',0};
     static const char filename[] = ".\\winetest.ini";
 
     trace("test_GetPrivateProfileStringA: %s\n", descript);
@@ -620,12 +624,12 @@ static void test_GetPrivateProfileString(const char *content, const char *descri
     lstrcpyA(buf, "kumquat");
     ret = GetPrivateProfileStringA(NULL, "name1", "default",
                                    buf, MAX_PATH, filename);
-    ok(ret == 18 ||
-       broken(ret == 19), /* Win9x and WinME */
-       "Expected 18, got %d\n", ret);
-    len = lstrlenA("section1") + sizeof(CHAR) + lstrlenA("section2") + 2 * sizeof(CHAR);
-    ok(!memcmp(buf, "section1\0section2\0\0", len),
-       "Expected \"section1\\0section2\\0\\0\", got \"%s\"\n", buf);
+    ok(ret == 23 ||
+       broken(ret == 24), /* Win9x and WinME */
+       "Expected 23, got %d\n", ret);
+    len = lstrlenA("section1") + lstrlenA("section2") + lstrlenA("\xe6\xae\xb5\x31") + 4 * sizeof(CHAR);
+    ok(!memcmp(buf, "section1\0section2\0\xe6\xae\xb5\x31\0\0", len),
+       "Expected \"section1\\0section2\\0\xe6\xae\xb5\x31\\0\\0\", got \"%s\"\n", buf);
 
     /* lpAppName is empty */
     memset(buf, 0xc, sizeof(buf));
@@ -827,6 +831,42 @@ static void test_GetPrivateProfileString(const char *content, const char *descri
     ok(ret == 0, "Expected 0, got %d\n", ret);
     ok(!lstrcmpA(buf, ""), "Expected \"\", got \"%s\"\n", buf);
 
+    memset(buf, 0xc, sizeof(buf));
+    lstrcpyA(buf, "kumquat");
+    ret = GetPrivateProfileStringA("\xe6\xae\xb5\x31", "name5", "default",
+                                   buf, MAX_PATH, filename);
+    ok(ret == 4, "Expected 4, got %d\n", ret);
+    ok(!lstrcmpA(buf, "\xe9\x85\x92\x2e"),
+       "Expected \"\xe9\x85\x92\x2e\", got \"%s\"\n", buf);
+
+    memset(buf, 0xc,sizeof(buf));
+    lstrcpyA(buf, "kumquat");
+    ret = GetPrivateProfileStringA("\xe6\xae\xb5\x31", "\xe5\xa7\x93", "default",
+                                   buf, MAX_PATH, filename);
+    ok(ret == 4, "Expected 4, got %d\n", ret);
+    ok(!lstrcmpA(buf, "\xe6\x9b\xbe\x2e"),
+       "Expected \"\xe6\x9b\xbe\x2e\", got \"%s\"\n", buf);
+
+    memset(buf, 0xc, sizeof(buf));
+    lstrcpyA(buf, "kumquat");
+    ret = GetPrivateProfileStringA("\xe6\xae\xb5\x31", "name6", "default",
+                                   buf, MAX_PATH, filename);
+    ok(ret == 7, "Expected 7, got %d\n", ret);
+    ok(!lstrcmpA(buf, "\xd7\x99\xd7\x99\xd7\x9f\x2e"),
+       "Expected \"\xd7\x99\xd7\x99\xd7\x9f\x2e\", got \"%s\"\n", buf);
+
+
+    memset(bufW, 0xc, sizeof(bufW));
+    lstrcpyA(expected_val, "\xe9\x85\x92\x2e");
+    len = MultiByteToWideChar(CP_ACP, 0, expected_val, -1, expected_valW, MAX_PATH) - 1;
+    ret = GetPrivateProfileStringW(section_schineseW, name5W, NULL,
+                                   bufW, MAX_PATH, filenameW);
+    ok(ret == len ||
+       (ret == 0 && bufW[0] == '\0') /* non-English */, "Expected %d, got %d\n", len, ret);
+    if (ret)
+        ok(!lstrcmpW(bufW, expected_valW), "Expected \"%s\", got \"%s\"\n",
+           wine_dbgstr_w(expected_valW), wine_dbgstr_w(bufW));
+
     /* lpAppName is NULL, not enough room for final section name */
     memset(buf, 0xc,sizeof(buf));
     lstrcpyA(buf, "kumquat");
@@ -1171,6 +1211,31 @@ static void test_WritePrivateProfileString(void)
             "key1=string1"                          /* 14 bytes */
             , 59)), "File doesn't match\n");
     DeleteFileA(path);
+
+    data = "[section1]\r\n"
+           "name=\xe9\x85\x92\x2e\r\n";
+    GetTempFileNameA(temp, "wine", 0, path);
+    ret = WritePrivateProfileStringA("section1", "name", "\xe9\x85\x92\x2e", path);
+    ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
+    ok(check_file_data(path, data), "File doesn't match\n");
+
+    data = "[section1]\r\n"
+           "name=\xe9\x85\x92\x2e\r\n"
+           "\xe5\xa7\x93=\xe6\x9b\xbe\x2e\r\n";
+    ret = WritePrivateProfileStringA("section1", "\xe5\xa7\x93", "\xe6\x9b\xbe\x2e", path);
+    ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
+    ok(check_file_data(path, data), "File doesn't match\n");
+
+    data = "[section1]\r\n"
+           "name=\xe9\x85\x92\x2e\r\n"
+           "\xe5\xa7\x93=\xe6\x9b\xbe\x2e\r\n"
+           "[\xe6\xae\xb5\x31]\r\n"
+           "name2=\xe6\x9b\xbe\x2e\r\n";
+    ret = WritePrivateProfileStringA("\xe6\xae\xb5\x31", "name2", "\xe6\x9b\xbe\x2e", path);
+    ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
+    ok(check_file_data(path, data), "File doesn't match\n");
+
+    DeleteFileA(path);
 }
 
 START_TEST(profile)
@@ -1189,7 +1254,11 @@ START_TEST(profile)
         "name2=\"val2\"\r\n"
         "name3\r\n"
         "name4=a\r\n"
-        "[section2]\r\n",
+        "[section2]\r\n"
+        "[\xe6\xae\xb5\x31]\r\n"  /* Simplified Chinese in UTF-8 */
+        "name5=\xe9\x85\x92\x2e\r\n"  /* Simplified Chinese in UTF-8 */
+        "\xe5\xa7\x93=\xe6\x9b\xbe\x2e\r\n"  /* Simplified Chinese in UTF-8 */
+        "name6=\xd7\x99\xd7\x99\xd7\x9f\x2e\r\n", /* Hebrew in UTF-8 */
         "CR+LF");
     test_GetPrivateProfileString(
         "[section1]\r"
@@ -1197,7 +1266,11 @@ START_TEST(profile)
         "name2=\"val2\"\r"
         "name3\r"
         "name4=a\r"
-        "[section2]\r",
+        "[section2]\r"
+        "[\xe6\xae\xb5\x31]\r"  /* Simplified Chinese in UTF-8 */
+        "name5=\xe9\x85\x92\x2e\r"  /* Simplified Chinese in UTF-8 */
+        "\xe5\xa7\x93=\xe6\x9b\xbe\x2e\r" /* Simplified Chinese in UTF-8 */
+        "name6=\xd7\x99\xd7\x99\xd7\x9f\x2e\r", /* Hebrew in UTF-8 */
         "CR only");
     test_WritePrivateProfileString();
 }
-- 
2.20.1




More information about the wine-devel mailing list