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);
+#define NLSRC_OFFSET 5000 /* FIXME */
extern HMODULE kernel32_handle;
'L','a','n','g','u','a','g','e',' ','G','r','o','u','p','s',0
};
+#ifndef __REACTOS__
/* Charset to codepage map, sorted by name. */
static const struct charset_entry
{
{ "KOI8U", 21866 },
{ "UTF8", CP_UTF8 }
};
-
+#endif
struct locale_name
{
static LCID lcid_LC_MEASUREMENT;
static LCID lcid_LC_TELEPHONE;
+#ifndef __REACTOS__
/* Copy Ascii string to Unicode without using codepages */
static inline void strcpynAtoW( WCHAR *dst, const char *src, size_t n )
{
}
if (n) *dst = 0;
}
-
+#endif
/***********************************************************************
* get_lcid_codepage
C2_OTHERNEUTRAL /* LRE, LRO, RLE, RLO, PDF */
};
+ if (!src)
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return FALSE;
+ }
+
if (count == -1) count = strlenW(src) + 1;
switch(type)
{
if ((c>=0x30A0)&&(c<=0x30FF)) type3 |= C3_KATAKANA;
if ((c>=0x3040)&&(c<=0x309F)) type3 |= C3_HIRAGANA;
if ((c>=0x4E00)&&(c<=0x9FAF)) type3 |= C3_IDEOGRAPH;
- if ((c>=0x0600)&&(c<=0x06FF)) type3 |= C3_KASHIDA;
+ if (c == 0x0640) type3 |= C3_KASHIDA;
if ((c>=0x3000)&&(c<=0x303F)) type3 |= C3_SYMBOL;
+ if ((c>=0xD800)&&(c<=0xDBFF)) type3 |= C3_HIGHSURROGATE;
+ if ((c>=0xDC00)&&(c<=0xDFFF)) type3 |= C3_LOWSURROGATE;
+
if ((c>=0xFF00)&&(c<=0xFF60)) type3 |= C3_FULLWIDTH;
if ((c>=0xFF00)&&(c<=0xFF20)) type3 |= C3_SYMBOL;
if ((c>=0xFF3B)&&(c<=0xFF40)) type3 |= C3_SYMBOL;
return GetStringTypeA(locale, type, src, count, chartype);
}
-
/*************************************************************************
- * LCMapStringW (KERNEL32.@)
+ * LCMapStringEx (KERNEL32.@)
*
- * See LCMapStringA.
+ * Map characters in a locale sensitive string.
+ *
+ * PARAMS
+ * name [I] Locale name for the conversion.
+ * flags [I] Flags controlling the mapping (LCMAP_ constants from "winnls.h")
+ * src [I] String to map
+ * srclen [I] Length of src in chars, or -1 if src is NUL terminated
+ * dst [O] Destination for mapped string
+ * dstlen [I] Length of dst in characters
+ * version [I] reserved, must be NULL
+ * reserved [I] reserved, must be NULL
+ * lparam [I] reserved, must be 0
+ *
+ * RETURNS
+ * Success: The length of the mapped string in dst, including the NUL terminator.
+ * Failure: 0. Use GetLastError() to determine the cause.
*/
-INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen,
- LPWSTR dst, INT dstlen)
+INT WINAPI LCMapStringEx(LPCWSTR name, DWORD flags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen,
+ LPNLSVERSIONINFO version, LPVOID reserved, LPARAM lparam)
{
LPWSTR dst_ptr;
+ if (version) FIXME("unsupported version structure %p\n", version);
+ if (reserved) FIXME("unsupported reserved pointer %p\n", reserved);
+ if (lparam) FIXME("unsupported lparam %lx\n", lparam);
+
if (!src || !srclen || dstlen < 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
if (!dstlen) dst = NULL;
- lcid = ConvertDefaultLocale(lcid);
-
if (flags & LCMAP_SORTKEY)
{
INT ret;
if (srclen < 0) srclen = strlenW(src);
- TRACE("(0x%04x,0x%08x,%s,%d,%p,%d)\n",
- lcid, flags, debugstr_wn(src, srclen), srclen, dst, dstlen);
+ TRACE("(%s,0x%08x,%s,%d,%p,%d)\n",
+ debugstr_w(name), flags, debugstr_wn(src, srclen), srclen, dst, dstlen);
ret = wine_get_sortkey(flags, src, srclen, (char *)dst, dstlen);
if (ret == 0)
if (srclen < 0) srclen = strlenW(src) + 1;
- TRACE("(0x%04x,0x%08x,%s,%d,%p,%d)\n",
- lcid, flags, debugstr_wn(src, srclen), srclen, dst, dstlen);
+ TRACE("(%s,0x%08x,%s,%d,%p,%d)\n",
+ debugstr_w(name), flags, debugstr_wn(src, srclen), srclen, dst, dstlen);
if (!dst) /* return required string length */
{
return dst_ptr - dst;
}
+/*************************************************************************
+ * LCMapStringW (KERNEL32.@)
+ *
+ * See LCMapStringA.
+ */
+INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen,
+ LPWSTR dst, INT dstlen)
+{
+ TRACE("(0x%04x,0x%08x,%s,%d,%p,%d)\n",
+ lcid, flags, debugstr_wn(src, srclen), srclen, dst, dstlen);
+
+ return LCMapStringEx(NULL, flags, src, srclen, dst, dstlen, NULL, NULL, 0);
+}
+
/*************************************************************************
* LCMapStringA (KERNEL32.@)
*
goto map_string_exit;
}
- dstlenW = LCMapStringW(lcid, flags, srcW, srclenW, NULL, 0);
+ dstlenW = LCMapStringEx(NULL, flags, srcW, srclenW, NULL, 0, NULL, NULL, 0);
if (!dstlenW)
goto map_string_exit;
goto map_string_exit;
}
- LCMapStringW(lcid, flags, srcW, srclenW, dstW, dstlenW);
+ LCMapStringEx(NULL, flags, srcW, srclenW, dstW, dstlenW, NULL, NULL, 0);
ret = WideCharToMultiByte(locale_cp, 0, dstW, dstlenW, dst, dstlen, NULL, NULL);
HeapFree(GetProcessHeap(), 0, dstW);
*
* See CompareStringA.
*/
-INT WINAPI CompareStringW(LCID lcid, DWORD style,
+INT WINAPI CompareStringW(LCID lcid, DWORD flags,
LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
{
+ static const DWORD supported_flags = NORM_IGNORECASE|NORM_IGNORENONSPACE|NORM_IGNORESYMBOLS|SORT_STRINGSORT
+ |NORM_IGNOREKANATYPE|NORM_IGNOREWIDTH|LOCALE_USE_CP_ACP
+ |NORM_LINGUISTIC_CASING|LINGUISTIC_IGNORECASE|0x10000000;
+ static DWORD semistub_flags = NORM_LINGUISTIC_CASING|LINGUISTIC_IGNORECASE|0x10000000;
+ /* 0x10000000 is related to diacritics in Arabic, Japanese, and Hebrew */
INT ret;
+
if (!str1 || !str2)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
- if( style & ~(NORM_IGNORECASE|NORM_IGNORENONSPACE|NORM_IGNORESYMBOLS|
- SORT_STRINGSORT|NORM_IGNOREKANATYPE|NORM_IGNOREWIDTH|LOCALE_USE_CP_ACP|0x10000000) )
+ if (flags & ~supported_flags)
{
SetLastError(ERROR_INVALID_FLAGS);
return 0;
}
- /* this style is related to diacritics in Arabic, Japanese, and Hebrew */
- if (style & 0x10000000)
- WARN("Ignoring unknown style 0x10000000\n");
+ if (flags & semistub_flags)
+ {
+ FIXME("semi-stub behavior for flag(s) 0x%x\n", flags & semistub_flags);
+ semistub_flags &= ~flags;
+ }
if (len1 < 0) len1 = strlenW(str1);
if (len2 < 0) len2 = strlenW(str2);
- ret = wine_compare_string(style, str1, len1, str2, len2);
+ ret = wine_compare_string(flags, str1, len1, str2, len2);
if (ret) /* need to translate result */
return (ret < 0) ? CSTR_LESS_THAN : CSTR_GREATER_THAN;
*
* PARAMS
* lcid [I] LCID for the comparison
- * style [I] Flags for the comparison (NORM_ constants from "winnls.h").
+ * flags [I] Flags for the comparison (NORM_ constants from "winnls.h").
* str1 [I] First string to compare
* len1 [I] Length of str1, or -1 if str1 is NUL terminated
* str2 [I] Second string to compare
return bRet;
}
-/* Registry keys for NLS related information */
-
-static const WCHAR szCountryListName[] = {
- '\\','R','e','g','i','s','t','r','y','\\',
- 'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\',
- 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'T','e','l','e','p','h','o','n','y','\\',
- 'C','o','u','n','t','r','y',' ','L','i','s','t','\0'
-};
-
-
/* Callback function ptrs for EnumSystemLanguageGroupsA/W */
typedef struct
{
static int
NLS_GetGeoFriendlyName(GEOID Location, LPWSTR szFriendlyName, int cchData)
{
- HANDLE hKey;
- WCHAR szPath[MAX_PATH];
- UNICODE_STRING ValueName;
- KEY_VALUE_PARTIAL_INFORMATION *info;
- const int info_size = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
+ LPWSTR szBuffer;
DWORD dwSize;
- NTSTATUS Status;
- int Ret;
- swprintf(szPath, L"\\REGISTRY\\Machine\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Telephony\\Country List\\%lu", Location);
+ /* FIXME: move *.nls resources out of kernel32 into locale.nls */
+ Location += NLSRC_OFFSET;
+ Location &= 0xFFFF;
- hKey = NLS_RegOpenKey(0, szPath);
- if (!hKey)
- {
- WARN("NLS_RegOpenKey() failed\n");
- return 0;
- }
+ if(cchData == 0)
+ return GetLocalisedText(Location, NULL, 0);
- dwSize = info_size + cchData * sizeof(WCHAR);
+ dwSize = cchData * sizeof(WCHAR);
+ szBuffer = HeapAlloc(GetProcessHeap(), 0, dwSize);
- if (!(info = HeapAlloc(GetProcessHeap(), 0, dwSize)))
+ if (!szBuffer)
{
- NtClose(hKey);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
- RtlInitUnicodeString(&ValueName, L"Name");
-
- Status = NtQueryValueKey(hKey, &ValueName, KeyValuePartialInformation,
- (LPBYTE)info, dwSize, &dwSize);
-
- if (!Status)
- {
- Ret = (dwSize - info_size) / sizeof(WCHAR);
-
- if (!Ret || ((WCHAR *)info->Data)[Ret-1])
- {
- if (Ret < cchData || !szFriendlyName) Ret++;
- else
- {
- WARN("ERROR_INSUFFICIENT_BUFFER\n");
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- Ret = 0;
- }
- }
-
- if (Ret && szFriendlyName)
- {
- memcpy(szFriendlyName, info->Data, (Ret-1) * sizeof(WCHAR));
- szFriendlyName[Ret-1] = 0;
- }
- }
- else if (Status == STATUS_BUFFER_OVERFLOW && !szFriendlyName)
- {
- Ret = (dwSize - info_size) / sizeof(WCHAR) + 1;
- }
- else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+ if(GetLocalisedText(Location, szBuffer, dwSize))
{
- Ret = -1;
+ memcpy(szFriendlyName, szBuffer, dwSize);
+ HeapFree(GetProcessHeap(), 0, szBuffer);
+ return strlenW(szFriendlyName) + 1;
}
- else
- {
- SetLastError(RtlNtStatusToDosError(Status));
- Ret = 0;
- }
-
- NtClose(hKey);
- HeapFree(GetProcessHeap(), 0, info);
- return Ret;
+ HeapFree(GetProcessHeap(), 0, szBuffer);
+ return 0;
}
static const struct geoinfo_t *get_geoinfo_dataptr(GEOID geoid)