Author: hbelusca
Date: Wed Apr 26 17:38:57 2017
New Revision: 74413
URL:
http://svn.reactos.org/svn/reactos?rev=74413&view=rev
Log:
[KERNEL32]: Little improvements/fixes for GetCPInfoExW and GetGeoInfoW:
- 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
Modified:
trunk/reactos/dll/win32/kernel32/winnls/string/lang.c
trunk/reactos/dll/win32/kernel32/winnls/string/nls.c
Modified: trunk/reactos/dll/win32/kernel32/winnls/string/lang.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/winnls/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/winnls/string/lang.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/winnls/string/lang.c [iso-8859-1] Wed Apr 26 17:38:57
2017
@@ -33,7 +33,7 @@
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;
@@ -3093,33 +3093,16 @@
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;
- if(cchData == 0)
+ if (cchData == 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;
- }
-
- HeapFree(GetProcessHeap(), 0, szBuffer);
+
return 0;
}
Modified: trunk/reactos/dll/win32/kernel32/winnls/string/nls.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/winnls/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/winnls/string/nls.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/winnls/string/nls.c [iso-8859-1] Wed Apr 26 17:38:57
2017
@@ -1714,18 +1714,30 @@
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;
+ HGLOBAL hmem;
LCID lcid;
LANGID langId;
- DWORD dwId;
-
- if (dwResId == 37)
- dwId = dwResId * 100;
- else
- dwId = dwResId;
+ const WCHAR *p;
+ UINT i;
+
+ /* See HACK in winnls/lang/xx-XX.rc files */
+ if (uID == 37)
+ uID = uID * 100;
lcid = GetUserDefaultLCID();
lcid = ConvertDefaultLocale(lcid);
@@ -1737,53 +1749,60 @@
hrsrc = FindResourceExW(hCurrentModule,
(LPWSTR)RT_STRING,
- MAKEINTRESOURCEW((dwId >> 4) + 1),
+ MAKEINTRESOURCEW((uID >> 4) + 1),
langId);
- /* english fallback */
- if(!hrsrc)
+ /* English fallback */
+ if (!hrsrc)
{
hrsrc = FindResourceExW(hCurrentModule,
- (LPWSTR)RT_STRING,
- MAKEINTRESOURCEW((dwId >> 4) + 1),
- MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
- }
-
- if (hrsrc)
- {
- HGLOBAL hmem = LoadResource(hCurrentModule, hrsrc);
-
- if (hmem)
- {
- const WCHAR *p;
- unsigned int i;
- unsigned int len;
-
- p = LockResource(hmem);
-
- for (i = 0; i < (dwId & 0x0f); i++) p += *p + 1;
-
- if(dwDestSize == 0)
- return *p + 1;
-
- len = *p * sizeof(WCHAR);
-
- if(len + sizeof(WCHAR) > dwDestSize)
- {
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- }
-
- memcpy(lpszDest, p + 1, len);
- lpszDest[*p] = '\0';
-
- return TRUE;
- }
- }
-
- DPRINT1("Resource not found: dwResId = %lu\n", dwResId);
+ (LPWSTR)RT_STRING,
+ MAKEINTRESOURCEW((uID >> 4) + 1),
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
+ }
+
+ if (!hrsrc)
+ goto NotFound;
+
+ hmem = LoadResource(hCurrentModule, hrsrc);
+ if (!hmem)
+ goto NotFound;
+
+ p = LockResource(hmem);
+
+ for (i = 0; i < (uID & 0x0F); i++)
+ p += *p + 1;
+
+ /* 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;
+ }
+
+ 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
+
+NotFound:
+ DPRINT1("Resource not found: uID = %lu\n", uID);
SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ return 0;
}
/*
@@ -1849,7 +1868,7 @@
DWORD dwFlags,
LPCPINFOEXW lpCPInfoEx)
{
- if (!GetCPInfo(CodePage, (LPCPINFO) lpCPInfoEx))
+ if (!GetCPInfo(CodePage, (LPCPINFO)lpCPInfoEx))
return FALSE;
switch(CodePage)
@@ -1858,7 +1877,9 @@
{
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;
@@ -1866,7 +1887,9 @@
{
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:
@@ -1876,14 +1899,16 @@
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;
- return GetLocalisedText(CodePageEntry->CodePageTable.CodePage,
lpCPInfoEx->CodePageName, sizeof(lpCPInfoEx->CodePageName)) != 0;
+ return GetLocalisedText(lpCPInfoEx->CodePage,
+ lpCPInfoEx->CodePageName,
+ ARRAYSIZE(lpCPInfoEx->CodePageName)) != 0;
}
break;
}