[KERNEL32]: Little improvements/fixes for GetCPInfoExW and GetGeoInfoW:
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 26 Apr 2017 17:38:57 +0000 (17:38 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 26 Apr 2017 17:38:57 +0000 (17:38 +0000)
- Rework GetLocalisedText helper such that it looks more like LoadStringW. Also, if the string is not found (either because there is no associated string table, or because its resource length is zero), then return zero.
  Otherwise we return the correct number of characters copied into the user buffer, not counting the NULL terminator.
  This fixes the blank strings showing in the list of codepage user-friendly names in the console properties dialog.
- Simplify the code of NLS_GetGeoFriendlyName: we can directly use the user-provided buffer to retrieve the string.
Addendum to r65157.
CORE-13130 #resolve

svn path=/trunk/; revision=74413

reactos/dll/win32/kernel32/winnls/string/lang.c
reactos/dll/win32/kernel32/winnls/string/nls.c

index f6e6364..b7bdc6a 100644 (file)
@@ -33,7 +33,7 @@ DEBUG_CHANNEL(nls);
 extern int wine_fold_string(int flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen);
 extern int wine_get_sortkey(int flags, const WCHAR *src, int srclen, char *dst, int dstlen);
 extern int wine_compare_string(int flags, const WCHAR *str1, int len1, const WCHAR *str2, int len2);
 extern int wine_fold_string(int flags, const WCHAR *src, int srclen, WCHAR *dst, int dstlen);
 extern int wine_get_sortkey(int flags, const WCHAR *src, int srclen, char *dst, int dstlen);
 extern int wine_compare_string(int flags, const WCHAR *str1, int len1, const WCHAR *str2, int len2);
-extern DWORD GetLocalisedText(DWORD dwResId, WCHAR *lpszDest, DWORD dwDestSize);
+extern UINT GetLocalisedText(IN UINT uID, IN LPWSTR lpszDest, IN UINT cchDest);
 #define NLSRC_OFFSET 5000 /* FIXME */
 
 extern HMODULE kernel32_handle;
 #define NLSRC_OFFSET 5000 /* FIXME */
 
 extern HMODULE kernel32_handle;
@@ -3093,33 +3093,16 @@ BOOL WINAPI EnumUILanguagesW(UILANGUAGE_ENUMPROCW pUILangEnumProc, DWORD dwFlags
 static int
 NLS_GetGeoFriendlyName(GEOID Location, LPWSTR szFriendlyName, int cchData)
 {
 static int
 NLS_GetGeoFriendlyName(GEOID Location, LPWSTR szFriendlyName, int cchData)
 {
-    LPWSTR szBuffer;
-    DWORD dwSize;
-
     /* FIXME: move *.nls resources out of kernel32 into locale.nls */
     Location += NLSRC_OFFSET;
     Location &= 0xFFFF;
 
     /* FIXME: move *.nls resources out of kernel32 into locale.nls */
     Location += NLSRC_OFFSET;
     Location &= 0xFFFF;
 
-    if(cchData == 0)
+    if (cchData == 0)
         return GetLocalisedText(Location, NULL, 0);
 
         return GetLocalisedText(Location, NULL, 0);
 
-    dwSize = cchData * sizeof(WCHAR);
-    szBuffer = HeapAlloc(GetProcessHeap(), 0, dwSize);
-
-    if (!szBuffer)
-    {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return 0;
-    }
-
-    if(GetLocalisedText(Location, szBuffer, dwSize))
-    {
-        memcpy(szFriendlyName, szBuffer, dwSize);
-        HeapFree(GetProcessHeap(), 0, szBuffer);
+    if (GetLocalisedText(Location, szFriendlyName, (UINT)cchData))
         return strlenW(szFriendlyName) + 1;
         return strlenW(szFriendlyName) + 1;
-    }
 
 
-    HeapFree(GetProcessHeap(), 0, szBuffer);
     return 0;
 }
 
     return 0;
 }
 
index 1b1013a..86449e8 100644 (file)
@@ -1714,18 +1714,30 @@ static INT WideCharToUtf7(const WCHAR *src, int srclen, char *dst, int dstlen)
     return dest_index;
 }
 
     return dest_index;
 }
 
-DWORD
-GetLocalisedText(DWORD dwResId, WCHAR *lpszDest, DWORD dwDestSize)
+/*
+ * A function similar to LoadStringW, but adapted for usage by GetCPInfoExW
+ * and GetGeoInfoW. It uses the current user localization, otherwise falls back
+ * to English (US). Contrary to LoadStringW which always saves the loaded string
+ * into the user-given buffer, truncating the string if needed, this function
+ * returns instead an ERROR_INSUFFICIENT_BUFFER error code if the user buffer
+ * is not large enough.
+ */
+UINT
+GetLocalisedText(
+    IN UINT uID,
+    IN LPWSTR lpszDest,
+    IN UINT cchDest)
 {
     HRSRC hrsrc;
 {
     HRSRC hrsrc;
+    HGLOBAL hmem;
     LCID lcid;
     LANGID langId;
     LCID lcid;
     LANGID langId;
-    DWORD dwId;
+    const WCHAR *p;
+    UINT i;
 
 
-    if (dwResId == 37)
-        dwId = dwResId * 100;
-    else
-        dwId = dwResId;
+    /* See HACK in winnls/lang/xx-XX.rc files */
+    if (uID == 37)
+        uID = uID * 100;
 
     lcid = GetUserDefaultLCID();
     lcid = ConvertDefaultLocale(lcid);
 
     lcid = GetUserDefaultLCID();
     lcid = ConvertDefaultLocale(lcid);
@@ -1737,53 +1749,60 @@ GetLocalisedText(DWORD dwResId, WCHAR *lpszDest, DWORD dwDestSize)
 
     hrsrc = FindResourceExW(hCurrentModule,
                             (LPWSTR)RT_STRING,
 
     hrsrc = FindResourceExW(hCurrentModule,
                             (LPWSTR)RT_STRING,
-                            MAKEINTRESOURCEW((dwId >> 4) + 1),
+                            MAKEINTRESOURCEW((uID >> 4) + 1),
                             langId);
 
                             langId);
 
-    /* english fallback */
-    if(!hrsrc)
+    /* English fallback */
+    if (!hrsrc)
     {
         hrsrc = FindResourceExW(hCurrentModule,
     {
         hrsrc = FindResourceExW(hCurrentModule,
-                            (LPWSTR)RT_STRING,
-                            MAKEINTRESOURCEW((dwId >> 4) + 1),
-                            MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
+                                (LPWSTR)RT_STRING,
+                                MAKEINTRESOURCEW((uID >> 4) + 1),
+                                MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
     }
 
     }
 
-    if (hrsrc)
-    {
-        HGLOBAL hmem = LoadResource(hCurrentModule, hrsrc);
+    if (!hrsrc)
+        goto NotFound;
 
 
-        if (hmem)
-        {
-            const WCHAR *p;
-            unsigned int i;
-            unsigned int len;
-
-            p = LockResource(hmem);
-
-            for (i = 0; i < (dwId & 0x0f); i++) p += *p + 1;
+    hmem = LoadResource(hCurrentModule, hrsrc);
+    if (!hmem)
+        goto NotFound;
 
 
-            if(dwDestSize == 0)
-                return *p + 1;
+    p = LockResource(hmem);
 
 
-            len = *p * sizeof(WCHAR);
-
-            if(len + sizeof(WCHAR) > dwDestSize)
-            {
-                SetLastError(ERROR_INSUFFICIENT_BUFFER);
-                return FALSE;
-            }
+    for (i = 0; i < (uID & 0x0F); i++)
+        p += *p + 1;
 
 
-            memcpy(lpszDest, p + 1, len);
-            lpszDest[*p] = '\0';
+    /* Needed for GetGeoInfo(): return the needed string size including the NULL terminator */
+    if (cchDest == 0)
+        return *p + 1;
+    /* Needed for GetGeoInfo(): bail out if the user buffer is not large enough */
+    if (*p + 1 > cchDest)
+    {
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        return 0;
+    }
 
 
-            return TRUE;
-        }
+    i = *p;
+    if (i > 0)
+    {
+        memcpy(lpszDest, p + 1, i * sizeof(WCHAR));
+        lpszDest[i] = L'\0';
+        return i;
+    }
+#if 0
+    else
+    {
+        if (cchDest >= 1)
+            lpszDest[0] = L'\0';
+        /* Fall-back */
     }
     }
+#endif
 
 
-    DPRINT1("Resource not found: dwResId = %lu\n", dwResId);
+NotFound:
+    DPRINT1("Resource not found: uID = %lu\n", uID);
     SetLastError(ERROR_INVALID_PARAMETER);
     SetLastError(ERROR_INVALID_PARAMETER);
-    return FALSE;
+    return 0;
 }
 
 /*
 }
 
 /*
@@ -1849,7 +1868,7 @@ GetCPInfoExW(UINT CodePage,
              DWORD dwFlags,
              LPCPINFOEXW lpCPInfoEx)
 {
              DWORD dwFlags,
              LPCPINFOEXW lpCPInfoEx)
 {
-    if (!GetCPInfo(CodePage, (LPCPINFO) lpCPInfoEx))
+    if (!GetCPInfo(CodePage, (LPCPINFO)lpCPInfoEx))
         return FALSE;
 
     switch(CodePage)
         return FALSE;
 
     switch(CodePage)
@@ -1858,7 +1877,9 @@ GetCPInfoExW(UINT CodePage,
         {
             lpCPInfoEx->CodePage = CP_UTF7;
             lpCPInfoEx->UnicodeDefaultChar = 0x3f;
         {
             lpCPInfoEx->CodePage = CP_UTF7;
             lpCPInfoEx->UnicodeDefaultChar = 0x3f;
-            return GetLocalisedText((DWORD)CodePage, lpCPInfoEx->CodePageName, sizeof(lpCPInfoEx->CodePageName)) != 0;
+            return GetLocalisedText(lpCPInfoEx->CodePage,
+                                    lpCPInfoEx->CodePageName,
+                                    ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
         }
         break;
 
         }
         break;
 
@@ -1866,7 +1887,9 @@ GetCPInfoExW(UINT CodePage,
         {
             lpCPInfoEx->CodePage = CP_UTF8;
             lpCPInfoEx->UnicodeDefaultChar = 0x3f;
         {
             lpCPInfoEx->CodePage = CP_UTF8;
             lpCPInfoEx->UnicodeDefaultChar = 0x3f;
-            return GetLocalisedText((DWORD)CodePage, lpCPInfoEx->CodePageName, sizeof(lpCPInfoEx->CodePageName)) != 0;
+            return GetLocalisedText(lpCPInfoEx->CodePage,
+                                    lpCPInfoEx->CodePageName,
+                                    ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
         }
 
         default:
         }
 
         default:
@@ -1876,14 +1899,16 @@ GetCPInfoExW(UINT CodePage,
             CodePageEntry = IntGetCodePageEntry(CodePage);
             if (CodePageEntry == NULL)
             {
             CodePageEntry = IntGetCodePageEntry(CodePage);
             if (CodePageEntry == NULL)
             {
-                DPRINT1("Could not get CodePage Entry! CodePageEntry = 0\n");
+                DPRINT1("Could not get CodePage Entry! CodePageEntry = NULL\n");
                 SetLastError(ERROR_INVALID_PARAMETER);
                 return FALSE;
             }
 
             lpCPInfoEx->CodePage = CodePageEntry->CodePageTable.CodePage;
             lpCPInfoEx->UnicodeDefaultChar = CodePageEntry->CodePageTable.UniDefaultChar;
                 SetLastError(ERROR_INVALID_PARAMETER);
                 return FALSE;
             }
 
             lpCPInfoEx->CodePage = CodePageEntry->CodePageTable.CodePage;
             lpCPInfoEx->UnicodeDefaultChar = CodePageEntry->CodePageTable.UniDefaultChar;
-            return GetLocalisedText(CodePageEntry->CodePageTable.CodePage, lpCPInfoEx->CodePageName, sizeof(lpCPInfoEx->CodePageName)) != 0;
+            return GetLocalisedText(lpCPInfoEx->CodePage,
+                                    lpCPInfoEx->CodePageName,
+                                    ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
         }
         break;
     }
         }
         break;
     }