From: Jactry Zeng Subject: [RFC PATCH 2/2] kernel32: Split A/W implementation of {Get,Write}PrivateProfileString(). Message-Id: Date: Tue, 23 Apr 2019 15:51:11 +0800 Signed-off-by: Jactry Zeng --- 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;ifilename && !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(§ionW, 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(§ionW); - 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(§ionW, 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(§ionW); - 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