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;
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;
}
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;
+ 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);
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));
+ (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);
- return FALSE;
+ return 0;
}
/*
DWORD dwFlags,
LPCPINFOEXW lpCPInfoEx)
{
- if (!GetCPInfo(CodePage, (LPCPINFO) lpCPInfoEx))
+ if (!GetCPInfo(CodePage, (LPCPINFO)lpCPInfoEx))
return FALSE;
switch(CodePage)
{
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;
{
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:
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;
}