~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/kernel32/tests/locale.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Unit tests for locale functions
  3  *
  4  * Copyright 2002 YASAR Mehmet
  5  * Copyright 2003 Dmitry Timoshkov
  6  * Copyright 2003 Jon Griffiths
  7  *
  8  * This library is free software; you can redistribute it and/or
  9  * modify it under the terms of the GNU Lesser General Public
 10  * License as published by the Free Software Foundation; either
 11  * version 2.1 of the License, or (at your option) any later version.
 12  *
 13  * This library is distributed in the hope that it will be useful,
 14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16  * Lesser General Public License for more details.
 17  *
 18  * You should have received a copy of the GNU Lesser General Public
 19  * License along with this library; if not, write to the Free Software
 20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 21  *
 22  * NOTES
 23  *  We must pass LOCALE_NOUSEROVERRIDE (NUO) to formatting functions so that
 24  *  even when the user has overridden their default i8n settings (e.g. in
 25  *  the control panel i8n page), we will still get the expected results.
 26  */
 27 
 28 #include <assert.h>
 29 #include <stdlib.h>
 30 #include <stdarg.h>
 31 
 32 #include "wine/test.h"
 33 #include "windef.h"
 34 #include "winbase.h"
 35 #include "winerror.h"
 36 #include "winnls.h"
 37 
 38 static inline unsigned int strlenW( const WCHAR *str )
 39 {
 40     const WCHAR *s = str;
 41     while (*s) s++;
 42     return s - str;
 43 }
 44 
 45 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
 46 {
 47     if (n <= 0) return 0;
 48     while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
 49     return *str1 - *str2;
 50 }
 51 
 52 static inline WCHAR *strchrW( const WCHAR *str, WCHAR ch )
 53 {
 54     do { if (*str == ch) return (WCHAR *)str; } while (*str++);
 55     return NULL;
 56 }
 57 
 58 static inline int isdigitW( WCHAR wc )
 59 {
 60     WORD type;
 61     GetStringTypeW( CT_CTYPE1, &wc, 1, &type );
 62     return type & C1_DIGIT;
 63 }
 64 
 65 /* Some functions are only in later versions of kernel32.dll */
 66 static HMODULE hKernel32;
 67 static WORD enumCount;
 68 
 69 typedef BOOL (WINAPI *EnumSystemLanguageGroupsAFn)(LANGUAGEGROUP_ENUMPROC,
 70                                                    DWORD, LONG_PTR);
 71 static EnumSystemLanguageGroupsAFn pEnumSystemLanguageGroupsA;
 72 typedef BOOL (WINAPI *EnumLanguageGroupLocalesAFn)(LANGGROUPLOCALE_ENUMPROC,
 73                                                    LGRPID, DWORD, LONG_PTR);
 74 static EnumLanguageGroupLocalesAFn pEnumLanguageGroupLocalesA;
 75 typedef BOOL (WINAPI *EnumUILanguagesAFn)(UILANGUAGE_ENUMPROC,
 76                                                    DWORD, LONG_PTR);
 77 static EnumUILanguagesAFn pEnumUILanguagesA;
 78 
 79 typedef INT (WINAPI *FoldStringAFn)(DWORD, LPCSTR, INT, LPSTR, INT);
 80 static FoldStringAFn pFoldStringA;
 81 typedef INT (WINAPI *FoldStringWFn)(DWORD, LPCWSTR, INT, LPWSTR, INT);
 82 static FoldStringWFn pFoldStringW;
 83 
 84 typedef BOOL (WINAPI *IsValidLanguageGroupFn)(LGRPID, DWORD);
 85 static IsValidLanguageGroupFn pIsValidLanguageGroup;
 86 
 87 static void InitFunctionPointers(void)
 88 {
 89   hKernel32 = GetModuleHandleA("kernel32");
 90   pEnumSystemLanguageGroupsA = (void*)GetProcAddress(hKernel32, "EnumSystemLanguageGroupsA");
 91   pEnumLanguageGroupLocalesA = (void*)GetProcAddress(hKernel32, "EnumLanguageGroupLocalesA");
 92   pFoldStringA = (void*)GetProcAddress(hKernel32, "FoldStringA");
 93   pFoldStringW = (void*)GetProcAddress(hKernel32, "FoldStringW");
 94   pIsValidLanguageGroup = (void*)GetProcAddress(hKernel32, "IsValidLanguageGroup");
 95   pEnumUILanguagesA = (void*)GetProcAddress(hKernel32, "EnumUILanguagesA");
 96 }
 97 
 98 #define eq(received, expected, label, type) \
 99         ok((received) == (expected), "%s: got " type " instead of " type "\n", \
100            (label), (received), (expected))
101 
102 #define BUFFER_SIZE    128
103 #define COUNTOF(x) (sizeof(x)/sizeof(x)[0])
104 
105 #define STRINGSA(x,y) strcpy(input, x); strcpy(Expected, y); SetLastError(0xdeadbeef); buffer[0] = '\0'
106 #define EXPECT_LENA ok(ret == lstrlen(Expected)+1, "Expected Len %d, got %d\n", lstrlen(Expected)+1, ret)
107 #define EXPECT_EQA ok(strncmp(buffer, Expected, strlen(Expected)) == 0, \
108   "Expected '%s', got '%s'\n", Expected, buffer)
109 
110 #define STRINGSW(x,y) MultiByteToWideChar(CP_ACP,0,x,-1,input,COUNTOF(input)); \
111    MultiByteToWideChar(CP_ACP,0,y,-1,Expected,COUNTOF(Expected)); \
112    SetLastError(0xdeadbeef); buffer[0] = '\0'
113 #define EXPECT_LENW ok(ret == lstrlenW(Expected)+1, "Expected Len %d, got %d\n", lstrlenW(Expected)+1, ret)
114 #define EXPECT_EQW  ok(strncmpW(buffer, Expected, strlenW(Expected)) == 0, "Bad conversion\n")
115 
116 #define NUO LOCALE_NOUSEROVERRIDE
117 
118 static void test_GetLocaleInfoA(void)
119 {
120   int ret;
121   int len;
122   LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
123   char buffer[BUFFER_SIZE];
124   char expected[BUFFER_SIZE];
125 
126   ok(lcid == 0x409, "wrong LCID calculated - %d\n", lcid);
127 
128   /* en and ar use SUBLANG_NEUTRAL, but GetLocaleInfo assume SUBLANG_DEFAULT
129      Same is true for zh on pre-Vista, but on Vista and higher GetLocaleInfo
130      assumes SUBLANG_NEUTRAL for zh */
131   memset(expected, 0, COUNTOF(expected));
132   len = GetLocaleInfoA(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), LOCALE_SLANGUAGE, expected, COUNTOF(expected));
133   SetLastError(0xdeadbeef);
134   memset(buffer, 0, COUNTOF(buffer));
135   ret = GetLocaleInfoA(LANG_ENGLISH, LOCALE_SLANGUAGE, buffer, COUNTOF(buffer));
136   ok((ret == len) && !lstrcmpA(buffer, expected),
137       "got %d with '%s' (expected %d with '%s')\n",
138       ret, buffer, len, expected);
139 
140   memset(expected, 0, COUNTOF(expected));
141   len = GetLocaleInfoA(MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT), LOCALE_SLANGUAGE, expected, COUNTOF(expected));
142   if (len) {
143       SetLastError(0xdeadbeef);
144       memset(buffer, 0, COUNTOF(buffer));
145       ret = GetLocaleInfoA(LANG_ARABIC, LOCALE_SLANGUAGE, buffer, COUNTOF(buffer));
146       ok((ret == len) && !lstrcmpA(buffer, expected),
147           "got %d with '%s' (expected %d with '%s')\n",
148           ret, buffer, len, expected);
149   }
150   else
151       win_skip("LANG_ARABIC not installed\n");
152 
153   /* SUBLANG_DEFAULT is required for mlang.dll, but optional for GetLocaleInfo */
154   memset(expected, 0, COUNTOF(expected));
155   len = GetLocaleInfoA(MAKELANGID(LANG_GERMAN, SUBLANG_DEFAULT), LOCALE_SLANGUAGE, expected, COUNTOF(expected));
156   SetLastError(0xdeadbeef);
157   memset(buffer, 0, COUNTOF(buffer));
158   ret = GetLocaleInfoA(LANG_GERMAN, LOCALE_SLANGUAGE, buffer, COUNTOF(buffer));
159   ok((ret == len) && !lstrcmpA(buffer, expected),
160       "got %d with '%s' (expected %d with '%s')\n",
161       ret, buffer, len, expected);
162 
163 
164   /* HTMLKit and "Font xplorer lite" expect GetLocaleInfoA to
165    * partially fill the buffer even if it is too short. See bug 637.
166    */
167   SetLastError(0xdeadbeef);
168   memset(buffer, 0, COUNTOF(buffer));
169   ret = GetLocaleInfoA(lcid, NUO|LOCALE_SDAYNAME1, buffer, 0);
170   ok(ret == 7 && !buffer[0], "Expected len=7, got %d\n", ret);
171 
172   SetLastError(0xdeadbeef);
173   memset(buffer, 0, COUNTOF(buffer));
174   ret = GetLocaleInfoA(lcid, NUO|LOCALE_SDAYNAME1, buffer, 3);
175   ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
176       "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
177   ok(!strcmp(buffer, "Mon"), "Expected 'Mon', got '%s'\n", buffer);
178 
179   SetLastError(0xdeadbeef);
180   memset(buffer, 0, COUNTOF(buffer));
181   ret = GetLocaleInfoA(lcid, NUO|LOCALE_SDAYNAME1, buffer, 10);
182   ok(ret == 7, "Expected ret == 7, got %d, error %d\n", ret, GetLastError());
183   ok(!strcmp(buffer, "Monday"), "Expected 'Monday', got '%s'\n", buffer);
184 }
185 
186 static void test_GetLocaleInfoW(void)
187 {
188   LCID lcid_en = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
189   LCID lcid_ru = MAKELCID(MAKELANGID(LANG_RUSSIAN, SUBLANG_NEUTRAL), SORT_DEFAULT);
190   WCHAR bufferW[80], buffer2W[80];
191   CHAR bufferA[80];
192   DWORD ret;
193   INT i;
194 
195   ret = GetLocaleInfoW(lcid_en, LOCALE_SMONTHNAME1, bufferW, COUNTOF(bufferW));
196   if (!ret) {
197       win_skip("GetLocaleInfoW() isn't implemented\n");
198       return;
199   }
200   ret = GetLocaleInfoW(lcid_ru, LOCALE_SMONTHNAME1, bufferW, COUNTOF(bufferW));
201   if (!ret) {
202       win_skip("LANG_RUSSIAN locale data unavailable\n");
203       return;
204   }
205   ret = GetLocaleInfoW(lcid_ru, LOCALE_SMONTHNAME1|LOCALE_RETURN_GENITIVE_NAMES,
206                        bufferW, COUNTOF(bufferW));
207   if (!ret) {
208       win_skip("LOCALE_RETURN_GENITIVE_NAMES isn't supported\n");
209       return;
210   }
211 
212   /* LOCALE_RETURN_GENITIVE_NAMES isn't supported for GetLocaleInfoA */
213   bufferA[0] = 'a';
214   SetLastError(0xdeadbeef);
215   ret = GetLocaleInfoA(lcid_ru, LOCALE_SMONTHNAME1|LOCALE_RETURN_GENITIVE_NAMES,
216                        bufferA, COUNTOF(bufferA));
217   ok(ret == 0, "LOCALE_RETURN_GENITIVE_NAMES should fail with GetLocaleInfoA\n");
218   ok(bufferA[0] == 'a', "Expected buffer to be untouched\n");
219   ok(GetLastError() == ERROR_INVALID_FLAGS,
220      "Expected ERROR_INVALID_FLAGS, got %x\n", GetLastError());
221 
222   bufferW[0] = 'a';
223   SetLastError(0xdeadbeef);
224   ret = GetLocaleInfoW(lcid_ru, LOCALE_RETURN_GENITIVE_NAMES,
225                        bufferW, COUNTOF(bufferW));
226   ok(ret == 0,
227      "LOCALE_RETURN_GENITIVE_NAMES itself doesn't return anything, got %d\n", ret);
228   ok(bufferW[0] == 'a', "Expected buffer to be untouched\n");
229   ok(GetLastError() == ERROR_INVALID_FLAGS,
230      "Expected ERROR_INVALID_FLAGS, got %x\n", GetLastError());
231 
232   /* yes, test empty 13 month entry too */
233   for (i = 0; i < 12; i++) {
234       bufferW[0] = 0;
235       ret = GetLocaleInfoW(lcid_ru, (LOCALE_SMONTHNAME1+i)|LOCALE_RETURN_GENITIVE_NAMES,
236                            bufferW, COUNTOF(bufferW));
237       ok(ret, "Expected non zero result\n");
238       ok(ret == lstrlenW(bufferW)+1, "Expected actual length, got %d, length %d\n",
239                                     ret, lstrlenW(bufferW));
240       buffer2W[0] = 0;
241       ret = GetLocaleInfoW(lcid_ru, LOCALE_SMONTHNAME1+i,
242                            buffer2W, COUNTOF(buffer2W));
243       ok(ret, "Expected non zero result\n");
244       ok(ret == lstrlenW(buffer2W)+1, "Expected actual length, got %d, length %d\n",
245                                     ret, lstrlenW(buffer2W));
246 
247       ok(lstrcmpW(bufferW, buffer2W) != 0,
248            "Expected genitive name to differ, got the same for month %d\n", i+1);
249 
250       /* for locale without genitive names nominative returned in both cases */
251       bufferW[0] = 0;
252       ret = GetLocaleInfoW(lcid_en, (LOCALE_SMONTHNAME1+i)|LOCALE_RETURN_GENITIVE_NAMES,
253                            bufferW, COUNTOF(bufferW));
254       ok(ret, "Expected non zero result\n");
255       ok(ret == lstrlenW(bufferW)+1, "Expected actual length, got %d, length %d\n",
256                                     ret, lstrlenW(bufferW));
257       buffer2W[0] = 0;
258       ret = GetLocaleInfoW(lcid_en, LOCALE_SMONTHNAME1+i,
259                            buffer2W, COUNTOF(buffer2W));
260       ok(ret, "Expected non zero result\n");
261       ok(ret == lstrlenW(buffer2W)+1, "Expected actual length, got %d, length %d\n",
262                                     ret, lstrlenW(buffer2W));
263 
264       ok(lstrcmpW(bufferW, buffer2W) == 0,
265          "Expected same names, got different for month %d\n", i+1);
266   }
267 }
268 
269 static void test_GetTimeFormatA(void)
270 {
271   int ret;
272   SYSTEMTIME  curtime;
273   LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
274   char buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE];
275 
276   memset(&curtime, 2, sizeof(SYSTEMTIME));
277   STRINGSA("tt HH':'mm'@'ss", ""); /* Invalid time */
278   SetLastError(0xdeadbeef);
279   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
280   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
281       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
282 
283   curtime.wHour = 8;
284   curtime.wMinute = 56;
285   curtime.wSecond = 13;
286   curtime.wMilliseconds = 22;
287   STRINGSA("tt HH':'mm'@'ss", "AM 08:56@13"); /* Valid time */
288   SetLastError(0xdeadbeef);
289   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
290   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
291   EXPECT_LENA; EXPECT_EQA;
292 
293   /* MSDN: LOCALE_NOUSEROVERRIDE can't be specified with a format string */
294   SetLastError(0xdeadbeef);
295   ret = GetTimeFormatA(lcid, NUO|TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
296   ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
297      "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
298 
299   STRINGSA("tt HH':'mm'@'ss", "A"); /* Insufficient buffer */
300   SetLastError(0xdeadbeef);
301   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, 2);
302   ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
303       "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
304 
305   STRINGSA("tt HH':'mm'@'ss", "AM 08:56@13"); /* Calculate length only */
306   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, NULL, 0);
307   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
308   EXPECT_LENA;
309 
310   STRINGSA("", "8 AM"); /* TIME_NOMINUTESORSECONDS, default format */
311   ret = GetTimeFormatA(lcid, NUO|TIME_NOMINUTESORSECONDS, &curtime, NULL, buffer, COUNTOF(buffer));
312   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
313   EXPECT_LENA; EXPECT_EQA;
314 
315   STRINGSA("m1s2m3s4", ""); /* TIME_NOMINUTESORSECONDS/complex format */
316   ret = GetTimeFormatA(lcid, TIME_NOMINUTESORSECONDS, &curtime, input, buffer, COUNTOF(buffer));
317   ok(ret == strlen(buffer)+1, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
318   ok( !strcmp( buffer, "" ) || broken( !strcmp( buffer, "4" )), /* win9x */
319       "Expected '', got '%s'\n", buffer );
320 
321   STRINGSA("", "8:56 AM"); /* TIME_NOSECONDS/Default format */
322   ret = GetTimeFormatA(lcid, NUO|TIME_NOSECONDS, &curtime, NULL, buffer, COUNTOF(buffer));
323   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
324   EXPECT_LENA; EXPECT_EQA;
325 
326   STRINGSA("h:m:s tt", "8:56 AM"); /* TIME_NOSECONDS */
327   strcpy(Expected, "8:56 AM");
328   ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
329   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
330   EXPECT_LENA; EXPECT_EQA;
331 
332   STRINGSA("h.@:m.@:s.@:tt", "8.@:56AM"); /* Multiple delimiters */
333   ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
334   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
335   ok( !strcmp( buffer, "8.@:56AM" ) || broken( !strcmp( buffer, "8.@:56.@:AM" )) /* win9x */,
336       "Expected '8.@:56AM', got '%s'\n", buffer );
337 
338   STRINGSA("s1s2s3", ""); /* Duplicate tokens */
339   ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
340   ok(ret == strlen(buffer)+1, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
341   ok( !strcmp( buffer, "" ) || broken( !strcmp( buffer, "3" )), /* win9x */
342       "Expected '', got '%s'\n", buffer );
343 
344   STRINGSA("t/tt", "A/AM"); /* AM time marker */
345   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
346   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
347   EXPECT_LENA; EXPECT_EQA;
348 
349   curtime.wHour = 13;
350   STRINGSA("t/tt", "P/PM"); /* PM time marker */
351   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
352   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
353   EXPECT_LENA; EXPECT_EQA;
354 
355   STRINGSA("h1t2tt3m", "156"); /* TIME_NOTIMEMARKER: removes text around time marker token */
356   ret = GetTimeFormatA(lcid, TIME_NOTIMEMARKER, &curtime, input, buffer, COUNTOF(buffer));
357   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
358   EXPECT_LENA; EXPECT_EQA;
359 
360   STRINGSA("h:m:s tt", "13:56:13 PM"); /* TIME_FORCE24HOURFORMAT */
361   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
362   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
363   EXPECT_LENA; EXPECT_EQA;
364 
365   STRINGSA("h:m:s", "13:56:13"); /* TIME_FORCE24HOURFORMAT doesn't add time marker */
366   ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
367   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
368   EXPECT_LENA; EXPECT_EQA;
369 
370   curtime.wHour = 14; /* change this to 14 or 2pm */
371   curtime.wMinute = 5;
372   curtime.wSecond = 3;
373   STRINGSA("h hh H HH m mm s ss t tt", "2 02 14 14 5 05 3 03 P PM"); /* 24 hrs, leading 0 */
374   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
375   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
376   EXPECT_LENA; EXPECT_EQA;
377 
378   curtime.wHour = 0;
379   STRINGSA("h/H/hh/HH", "12/0/12/00"); /* "hh" and "HH" */
380   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
381   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
382   EXPECT_LENA; EXPECT_EQA;
383 
384   STRINGSA("h:m:s tt", "12:5:3 AM"); /* non-zero flags should fail with format, doesn't */
385   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
386   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
387   EXPECT_LENA; EXPECT_EQA;
388 
389   /* try to convert formatting strings with more than two letters
390    * "h:hh:hhh:H:HH:HHH:m:mm:mmm:M:MM:MMM:s:ss:sss:S:SS:SSS"
391    * NOTE: We expect any letter for which there is an upper case value
392    *       we should see a replacement.  For letters that DO NOT have
393    *       upper case values we should see NO REPLACEMENT.
394    */
395   curtime.wHour = 8;
396   curtime.wMinute = 56;
397   curtime.wSecond = 13;
398   curtime.wMilliseconds = 22;
399   STRINGSA("h:hh:hhh H:HH:HHH m:mm:mmm M:MM:MMM s:ss:sss S:SS:SSS",
400            "8:08:08 8:08:08 56:56:56 M:MM:MMM 13:13:13 S:SS:SSS");
401   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
402   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
403   EXPECT_LENA; EXPECT_EQA;
404 
405   STRINGSA("h", "text"); /* Don't write to buffer if len is 0 */
406   strcpy(buffer, "text");
407   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, 0);
408   ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError());
409   EXPECT_EQA;
410 
411   STRINGSA("h 'h' H 'H' HH 'HH' m 'm' s 's' t 't' tt 'tt'",
412            "8 h 8 H 08 HH 56 m 13 s A t AM tt"); /* "'" preserves tokens */
413   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
414   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
415   EXPECT_LENA; EXPECT_EQA;
416 
417   STRINGSA("'''", "'"); /* invalid quoted string */
418   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
419   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
420   EXPECT_LENA; EXPECT_EQA;
421 
422   /* test that msdn suggested single quotation usage works as expected */
423   STRINGSA("''''", "'"); /* single quote mark */
424   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
425   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
426   EXPECT_LENA; EXPECT_EQA;
427 
428   STRINGSA("''HHHHHH", "08"); /* Normal use */
429   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
430   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
431   EXPECT_LENA; EXPECT_EQA;
432 
433   /* and test for normal use of the single quotation mark */
434   STRINGSA("'''HHHHHH'", "'HHHHHH"); /* Normal use */
435   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
436   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
437   EXPECT_LENA; EXPECT_EQA;
438 
439   STRINGSA("'''HHHHHH", "'HHHHHH"); /* Odd use */
440   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
441   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
442   EXPECT_LENA; EXPECT_EQA;
443 
444   STRINGSA("'123'tt", ""); /* TIME_NOTIMEMARKER drops literals too */
445   ret = GetTimeFormatA(lcid, TIME_NOTIMEMARKER, &curtime, input, buffer, COUNTOF(buffer));
446   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
447   EXPECT_LENA; EXPECT_EQA;
448 
449   curtime.wHour = 25;
450   STRINGSA("'123'tt", ""); /* Invalid time */
451   SetLastError(0xdeadbeef);
452   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
453   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
454       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
455 
456   curtime.wHour = 12;
457   curtime.wMonth = 60; /* Invalid */
458   STRINGSA("h:m:s", "12:56:13"); /* Invalid date */
459   ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
460   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
461   EXPECT_LENA; EXPECT_EQA;
462 }
463 
464 static void test_GetDateFormatA(void)
465 {
466   int ret;
467   SYSTEMTIME  curtime;
468   LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
469   char buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE];
470 
471   memset(&curtime, 2, sizeof(SYSTEMTIME)); /* Invalid time */
472   STRINGSA("ddd',' MMM dd yy","");
473   SetLastError(0xdeadbeef);
474   ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
475   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
476       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
477 
478   curtime.wYear = 2002;
479   curtime.wMonth = 5;
480   curtime.wDay = 4;
481   curtime.wDayOfWeek = 3;
482   STRINGSA("ddd',' MMM dd yy","Sat, May 04 02"); /* Simple case */
483   ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
484   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
485   EXPECT_LENA; EXPECT_EQA;
486 
487   /* Same as above but with LOCALE_NOUSEROVERRIDE */
488   STRINGSA("ddd',' MMM dd yy",""); /* Simple case */
489   SetLastError(0xdeadbeef);
490   ret = GetDateFormatA(lcid, NUO, &curtime, input, buffer, COUNTOF(buffer));
491   ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
492      "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
493   EXPECT_EQA;
494 
495   STRINGSA("ddd',' MMM dd yy","Sat, May 04 02"); /* Format containing "'" */
496   ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
497   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
498   EXPECT_LENA; EXPECT_EQA;
499 
500   curtime.wHour = 36; /* Invalid */
501   STRINGSA("ddd',' MMM dd ''''yy","Sat, May 04 '02"); /* Invalid time */
502   ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
503   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
504   EXPECT_LENA; EXPECT_EQA;
505 
506   STRINGSA("ddd',' MMM dd ''''yy",""); /* Get size only */
507   ret = GetDateFormatA(lcid, 0, &curtime, input, NULL, 0);
508   ok(ret == 16, "Expected ret == 16, got %d, error %d\n", ret, GetLastError());
509   EXPECT_EQA;
510 
511   STRINGSA("ddd',' MMM dd ''''yy",""); /* Buffer too small */
512   SetLastError(0xdeadbeef);
513   ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, 2);
514   ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
515       "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
516 
517   STRINGSA("ddd',' MMM dd ''''yy","5/4/2002"); /* Default to DATE_SHORTDATE */
518   ret = GetDateFormat(lcid, NUO, &curtime, NULL, buffer, COUNTOF(buffer));
519   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
520   if (strncmp(buffer, Expected, strlen(Expected)) && strncmp(buffer, "5/4/02", strlen(Expected)) != 0)
521           ok (0, "Expected '%s' or '5/4/02', got '%s'\n", Expected, buffer);
522 
523   STRINGSA("ddd',' MMM dd ''''yy", "Saturday, May 04, 2002"); /* DATE_LONGDATE */
524   ret = GetDateFormat(lcid, NUO|DATE_LONGDATE, &curtime, NULL, buffer, COUNTOF(buffer));
525   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
526   EXPECT_LENA; EXPECT_EQA;
527 
528   /* test for expected DATE_YEARMONTH behavior with null format */
529   /* NT4 returns ERROR_INVALID_FLAGS for DATE_YEARMONTH */
530   STRINGSA("ddd',' MMM dd ''''yy", ""); /* DATE_YEARMONTH */
531   SetLastError(0xdeadbeef);
532   ret = GetDateFormat(lcid, NUO|DATE_YEARMONTH, &curtime, input, buffer, COUNTOF(buffer));
533   ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
534      "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
535   EXPECT_EQA;
536 
537   /* Test that using invalid DATE_* flags results in the correct error */
538   /* and return values */
539   STRINGSA("m/d/y", ""); /* Invalid flags */
540   SetLastError(0xdeadbeef);
541   ret = GetDateFormat(lcid, DATE_YEARMONTH|DATE_SHORTDATE|DATE_LONGDATE,
542                       &curtime, input, buffer, COUNTOF(buffer));
543   ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
544      "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
545   EXPECT_EQA;
546 }
547 
548 static void test_GetDateFormatW(void)
549 {
550   int ret;
551   SYSTEMTIME  curtime;
552   WCHAR buffer[BUFFER_SIZE], input[BUFFER_SIZE], Expected[BUFFER_SIZE];
553   LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
554 
555   STRINGSW("",""); /* If flags is not zero then format must be NULL */
556   ret = GetDateFormatW(LOCALE_SYSTEM_DEFAULT, DATE_LONGDATE, NULL,
557                        input, buffer, COUNTOF(buffer));
558   if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
559   {
560     win_skip("GetDateFormatW is not implemented\n");
561     return;
562   }
563   ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
564      "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
565   EXPECT_EQW;
566 
567   STRINGSW("",""); /* NULL buffer, len > 0 */
568   SetLastError(0xdeadbeef);
569   ret = GetDateFormatW (lcid, 0, NULL, input, NULL, COUNTOF(buffer));
570   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
571       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
572 
573   STRINGSW("",""); /* NULL buffer, len == 0 */
574   ret = GetDateFormatW (lcid, 0, NULL, input, NULL, 0);
575   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
576   EXPECT_LENW; EXPECT_EQW;
577 
578   curtime.wYear = 2002;
579   curtime.wMonth = 10;
580   curtime.wDay = 23;
581   curtime.wDayOfWeek = 45612; /* Should be 3 - Wednesday */
582   curtime.wHour = 65432; /* Invalid */
583   curtime.wMinute = 34512; /* Invalid */
584   curtime.wSecond = 65535; /* Invalid */
585   curtime.wMilliseconds = 12345;
586   STRINGSW("dddd d MMMM yyyy","Wednesday 23 October 2002"); /* Incorrect DOW and time */
587   ret = GetDateFormatW (lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
588   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
589   EXPECT_LENW; EXPECT_EQW;
590 
591   /* Limit tests */
592 
593   curtime.wYear = 1601;
594   curtime.wMonth = 1;
595   curtime.wDay = 1;
596   curtime.wDayOfWeek = 0; /* Irrelevant */
597   curtime.wHour = 0;
598   curtime.wMinute = 0;
599   curtime.wSecond = 0;
600   curtime.wMilliseconds = 0;
601   STRINGSW("dddd d MMMM yyyy","Monday 1 January 1601");
602   SetLastError(0xdeadbeef);
603   ret = GetDateFormatW (lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
604   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
605   EXPECT_LENW; EXPECT_EQW;
606 
607   curtime.wYear = 1600;
608   curtime.wMonth = 12;
609   curtime.wDay = 31;
610   curtime.wDayOfWeek = 0; /* Irrelevant */
611   curtime.wHour = 23;
612   curtime.wMinute = 59;
613   curtime.wSecond = 59;
614   curtime.wMilliseconds = 999;
615   STRINGSW("dddd d MMMM yyyy","Friday 31 December 1600");
616   SetLastError(0xdeadbeef);
617   ret = GetDateFormatW (lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
618   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
619       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
620 }
621 
622 
623 #define CY_POS_LEFT  0
624 #define CY_POS_RIGHT 1
625 #define CY_POS_LEFT_SPACE  2
626 #define CY_POS_RIGHT_SPACE 3
627 
628 static void test_GetCurrencyFormatA(void)
629 {
630   static char szDot[] = { '.', '\0' };
631   static char szComma[] = { ',', '\0' };
632   static char szDollar[] = { '$', '\0' };
633   int ret;
634   LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
635   char buffer[BUFFER_SIZE], Expected[BUFFER_SIZE], input[BUFFER_SIZE];
636   CURRENCYFMTA format;
637 
638   memset(&format, 0, sizeof(format));
639 
640   STRINGSA("23",""); /* NULL output, length > 0 --> Error */
641   SetLastError(0xdeadbeef);
642   ret = GetCurrencyFormatA(lcid, 0, input, NULL, NULL, COUNTOF(buffer));
643   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
644       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
645 
646   STRINGSA("23,53",""); /* Invalid character --> Error */
647   SetLastError(0xdeadbeef);
648   ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
649   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
650       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
651 
652   STRINGSA("--",""); /* Double '-' --> Error */
653   SetLastError(0xdeadbeef);
654   ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
655   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
656       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
657 
658   STRINGSA("0-",""); /* Trailing '-' --> Error */
659   SetLastError(0xdeadbeef);
660   ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
661   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
662       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
663 
664   STRINGSA("0..",""); /* Double '.' --> Error */
665   SetLastError(0xdeadbeef);
666   ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
667   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
668       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
669 
670   STRINGSA(" 0.1",""); /* Leading space --> Error */
671   SetLastError(0xdeadbeef);
672   ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
673   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
674       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
675 
676   STRINGSA("1234","$"); /* Length too small --> Write up to length chars */
677   SetLastError(0xdeadbeef);
678   ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, 2);
679   ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
680       "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
681 
682   STRINGSA("2353",""); /* Format and flags given --> Error */
683   SetLastError(0xdeadbeef);
684   ret = GetCurrencyFormatA(lcid, NUO, input, &format, buffer, COUNTOF(buffer));
685   ok( !ret, "Expected ret == 0, got %d\n", ret);
686   ok( GetLastError() == ERROR_INVALID_FLAGS || GetLastError() == ERROR_INVALID_PARAMETER,
687       "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
688 
689   STRINGSA("2353",""); /* Invalid format --> Error */
690   SetLastError(0xdeadbeef);
691   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
692   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
693       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
694 
695   STRINGSA("2353","$2,353.00"); /* Valid number */
696   ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
697   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
698   EXPECT_LENA; EXPECT_EQA;
699 
700   STRINGSA("-2353","($2,353.00)"); /* Valid negative number */
701   ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
702   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
703   EXPECT_LENA; EXPECT_EQA;
704 
705   STRINGSA("2353.1","$2,353.10"); /* Valid real number */
706   ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
707   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
708   EXPECT_LENA; EXPECT_EQA;
709 
710   STRINGSA("2353.111","$2,353.11"); /* Too many DP --> Truncated */
711   ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
712   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
713   EXPECT_LENA; EXPECT_EQA;
714 
715   STRINGSA("2353.119","$2,353.12");  /* Too many DP --> Rounded */
716   ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
717   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
718   EXPECT_LENA; EXPECT_EQA;
719 
720   format.NumDigits = 0; /* No decimal separator */
721   format.LeadingZero = 0;
722   format.Grouping = 0;  /* No grouping char */
723   format.NegativeOrder = 0;
724   format.PositiveOrder = CY_POS_LEFT;
725   format.lpDecimalSep = szDot;
726   format.lpThousandSep = szComma;
727   format.lpCurrencySymbol = szDollar;
728 
729   STRINGSA("2353","$2353"); /* No decimal or grouping chars expected */
730   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
731   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
732   EXPECT_LENA; EXPECT_EQA;
733 
734   format.NumDigits = 1; /* 1 DP --> Expect decimal separator */
735   STRINGSA("2353","$2353.0");
736   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
737   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
738   EXPECT_LENA; EXPECT_EQA;
739 
740   format.Grouping = 2; /* Group by 100's */
741   STRINGSA("2353","$23,53.0");
742   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
743   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
744   EXPECT_LENA; EXPECT_EQA;
745 
746   STRINGSA("235","$235.0"); /* Grouping of a positive number */
747   format.Grouping = 3;
748   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
749   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
750   EXPECT_LENA; EXPECT_EQA;
751 
752   STRINGSA("-235","$-235.0"); /* Grouping of a negative number */
753   format.NegativeOrder = 2;
754   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
755   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
756   EXPECT_LENA; EXPECT_EQA;
757 
758   format.LeadingZero = 1; /* Always provide leading zero */
759   STRINGSA(".5","$0.5");
760   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
761   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
762   EXPECT_LENA; EXPECT_EQA;
763 
764   format.PositiveOrder = CY_POS_RIGHT;
765   STRINGSA("1","1.0$");
766   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
767   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
768   EXPECT_LENA; EXPECT_EQA;
769 
770   format.PositiveOrder = CY_POS_LEFT_SPACE;
771   STRINGSA("1","$ 1.0");
772   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
773   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
774   EXPECT_LENA; EXPECT_EQA;
775 
776   format.PositiveOrder = CY_POS_RIGHT_SPACE;
777   STRINGSA("1","1.0 $");
778   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
779   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
780   EXPECT_LENA; EXPECT_EQA;
781 
782   format.NegativeOrder = 0;
783   STRINGSA("-1","($1.0)");
784   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
785   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
786   EXPECT_LENA; EXPECT_EQA;
787 
788   format.NegativeOrder = 1;
789   STRINGSA("-1","-$1.0");
790   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
791   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
792   EXPECT_LENA; EXPECT_EQA;
793 
794   format.NegativeOrder = 2;
795   STRINGSA("-1","$-1.0");
796   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
797   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
798   EXPECT_LENA; EXPECT_EQA;
799 
800   format.NegativeOrder = 3;
801   STRINGSA("-1","$1.0-");
802   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
803   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
804   EXPECT_LENA; EXPECT_EQA;
805 
806   format.NegativeOrder = 4;
807   STRINGSA("-1","(1.0$)");
808   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
809   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
810   EXPECT_LENA; EXPECT_EQA;
811 
812   format.NegativeOrder = 5;
813   STRINGSA("-1","-1.0$");
814   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
815   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
816   EXPECT_LENA; EXPECT_EQA;
817 
818   format.NegativeOrder = 6;
819   STRINGSA("-1","1.0-$");
820   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
821   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
822   EXPECT_LENA; EXPECT_EQA;
823 
824   format.NegativeOrder = 7;
825   STRINGSA("-1","1.0$-");
826   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
827   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
828   EXPECT_LENA; EXPECT_EQA;
829 
830   format.NegativeOrder = 8;
831   STRINGSA("-1","-1.0 $");
832   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
833   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
834   EXPECT_LENA; EXPECT_EQA;
835 
836   format.NegativeOrder = 9;
837   STRINGSA("-1","-$ 1.0");
838   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
839   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
840   EXPECT_LENA; EXPECT_EQA;
841 
842   format.NegativeOrder = 10;
843   STRINGSA("-1","1.0 $-");
844   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
845   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
846   EXPECT_LENA; EXPECT_EQA;
847 
848   format.NegativeOrder = 11;
849   STRINGSA("-1","$ 1.0-");
850   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
851   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
852   EXPECT_LENA; EXPECT_EQA;
853 
854   format.NegativeOrder = 12;
855   STRINGSA("-1","$ -1.0");
856   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
857   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
858   EXPECT_LENA; EXPECT_EQA;
859 
860   format.NegativeOrder = 13;
861   STRINGSA("-1","1.0- $");
862   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
863   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
864   EXPECT_LENA; EXPECT_EQA;
865 
866   format.NegativeOrder = 14;
867   STRINGSA("-1","($ 1.0)");
868   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
869   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
870   EXPECT_LENA; EXPECT_EQA;
871 
872   format.NegativeOrder = 15;
873   STRINGSA("-1","(1.0 $)");
874   ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
875   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
876   EXPECT_LENA; EXPECT_EQA;
877 }
878 
879 #define NEG_PARENS      0 /* "(1.1)" */
880 #define NEG_LEFT        1 /* "-1.1"  */
881 #define NEG_LEFT_SPACE  2 /* "- 1.1" */
882 #define NEG_RIGHT       3 /* "1.1-"  */
883 #define NEG_RIGHT_SPACE 4 /* "1.1 -" */
884 
885 static void test_GetNumberFormatA(void)
886 {
887   static char szDot[] = { '.', '\0' };
888   static char szComma[] = { ',', '\0' };
889   int ret;
890   LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
891   char buffer[BUFFER_SIZE], Expected[BUFFER_SIZE], input[BUFFER_SIZE];
892   NUMBERFMTA format;
893 
894   memset(&format, 0, sizeof(format));
895 
896   STRINGSA("23",""); /* NULL output, length > 0 --> Error */
897   SetLastError(0xdeadbeef);
898   ret = GetNumberFormatA(lcid, 0, input, NULL, NULL, COUNTOF(buffer));
899   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
900       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
901 
902   STRINGSA("23,53",""); /* Invalid character --> Error */
903   SetLastError(0xdeadbeef);
904   ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
905   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
906       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
907 
908   STRINGSA("--",""); /* Double '-' --> Error */
909   SetLastError(0xdeadbeef);
910   ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
911   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
912       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
913 
914   STRINGSA("0-",""); /* Trailing '-' --> Error */
915   SetLastError(0xdeadbeef);
916   ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
917   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
918       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
919 
920   STRINGSA("0..",""); /* Double '.' --> Error */
921   SetLastError(0xdeadbeef);
922   ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
923   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
924       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
925 
926   STRINGSA(" 0.1",""); /* Leading space --> Error */
927   SetLastError(0xdeadbeef);
928   ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
929   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
930       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
931 
932   STRINGSA("1234","1"); /* Length too small --> Write up to length chars */
933   SetLastError(0xdeadbeef);
934   ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, 2);
935   ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
936       "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
937 
938   STRINGSA("2353",""); /* Format and flags given --> Error */
939   SetLastError(0xdeadbeef);
940   ret = GetNumberFormatA(lcid, NUO, input, &format, buffer, COUNTOF(buffer));
941   ok( !ret, "Expected ret == 0, got %d\n", ret);
942   ok( GetLastError() == ERROR_INVALID_FLAGS || GetLastError() == ERROR_INVALID_PARAMETER,
943       "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
944 
945   STRINGSA("2353",""); /* Invalid format --> Error */
946   SetLastError(0xdeadbeef);
947   ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
948   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
949       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
950 
951   STRINGSA("2353","2,353.00"); /* Valid number */
952   ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
953   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
954   EXPECT_LENA; EXPECT_EQA;
955 
956   STRINGSA("-2353","-2,353.00"); /* Valid negative number */
957   ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
958   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
959   EXPECT_LENA; EXPECT_EQA;
960 
961   STRINGSA("-353","-353.00"); /* test for off by one error in grouping */
962   ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
963   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
964   EXPECT_LENA; EXPECT_EQA;
965 
966   STRINGSA("2353.1","2,353.10"); /* Valid real number */
967   ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
968   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
969   EXPECT_LENA; EXPECT_EQA;
970 
971   STRINGSA("2353.111","2,353.11"); /* Too many DP --> Truncated */
972   ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
973   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
974   EXPECT_LENA; EXPECT_EQA;
975 
976   STRINGSA("2353.119","2,353.12");  /* Too many DP --> Rounded */
977   ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
978   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
979   EXPECT_LENA; EXPECT_EQA;
980 
981   format.NumDigits = 0; /* No decimal separator */
982   format.LeadingZero = 0;
983   format.Grouping = 0;  /* No grouping char */
984   format.NegativeOrder = 0;
985   format.lpDecimalSep = szDot;
986   format.lpThousandSep = szComma;
987 
988   STRINGSA("2353","2353"); /* No decimal or grouping chars expected */
989   ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
990   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
991   EXPECT_LENA; EXPECT_EQA;
992 
993   format.NumDigits = 1; /* 1 DP --> Expect decimal separator */
994   STRINGSA("2353","2353.0");
995   ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
996   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
997   EXPECT_LENA; EXPECT_EQA;
998 
999   format.Grouping = 2; /* Group by 100's */
1000   STRINGSA("2353","23,53.0");
1001   ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
1002   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
1003   EXPECT_LENA; EXPECT_EQA;
1004 
1005   STRINGSA("235","235.0"); /* Grouping of a positive number */
1006   format.Grouping = 3;
1007   ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
1008   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
1009   EXPECT_LENA; EXPECT_EQA;
1010 
1011   STRINGSA("-235","-235.0"); /* Grouping of a negative number */
1012   format.NegativeOrder = NEG_LEFT;
1013   ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
1014   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
1015   EXPECT_LENA; EXPECT_EQA;
1016 
1017   format.LeadingZero = 1; /* Always provide leading zero */
1018   STRINGSA(".5","0.5");
1019   ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
1020   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
1021   EXPECT_LENA; EXPECT_EQA;
1022 
1023   format.NegativeOrder = NEG_PARENS;
1024   STRINGSA("-1","(1.0)");
1025   ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
1026   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
1027   EXPECT_LENA; EXPECT_EQA;
1028 
1029   format.NegativeOrder = NEG_LEFT;
1030   STRINGSA("-1","-1.0");
1031   ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
1032   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
1033   EXPECT_LENA; EXPECT_EQA;
1034 
1035   format.NegativeOrder = NEG_LEFT_SPACE;
1036   STRINGSA("-1","- 1.0");
1037   ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
1038   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
1039   EXPECT_LENA; EXPECT_EQA;
1040 
1041   format.NegativeOrder = NEG_RIGHT;
1042   STRINGSA("-1","1.0-");
1043   ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
1044   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
1045   EXPECT_LENA; EXPECT_EQA;
1046 
1047   format.NegativeOrder = NEG_RIGHT_SPACE;
1048   STRINGSA("-1","1.0 -");
1049   ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
1050   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
1051   EXPECT_LENA; EXPECT_EQA;
1052 
1053   lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
1054 
1055   if (IsValidLocale(lcid, 0))
1056   {
1057     STRINGSA("-12345","-12 345,00"); /* Try French formatting */
1058     Expected[3] = 160; /* Non breaking space */
1059     ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
1060     ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
1061     EXPECT_LENA; EXPECT_EQA;
1062   }
1063 }
1064 
1065 
1066 static void test_CompareStringA(void)
1067 {
1068   int ret;
1069   LCID lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
1070 
1071   ret = CompareStringA(lcid, NORM_IGNORECASE, "Salut", -1, "Salute", -1);
1072   ok (ret== 1, "(Salut/Salute) Expected 1, got %d\n", ret);
1073 
1074   ret = CompareStringA(lcid, NORM_IGNORECASE, "Salut", -1, "SaLuT", -1);
1075   ok (ret== 2, "(Salut/SaLuT) Expected 2, got %d\n", ret);
1076 
1077   ret = CompareStringA(lcid, NORM_IGNORECASE, "Salut", -1, "hola", -1);
1078   ok (ret== 3, "(Salut/hola) Expected 3, got %d\n", ret);
1079 
1080   ret = CompareStringA(lcid, NORM_IGNORECASE, "haha", -1, "hoho", -1);
1081   ok (ret== 1, "(haha/hoho) Expected 1, got %d\n", ret);
1082 
1083   lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
1084 
1085   ret = CompareStringA(lcid, NORM_IGNORECASE, "haha", -1, "hoho", -1);
1086   ok (ret== 1, "(haha/hoho) Expected 1, got %d\n", ret);
1087 
1088   ret = CompareStringA(lcid, NORM_IGNORECASE, "haha", -1, "hoho", 0);
1089   ok (ret== 3, "(haha/hoho) Expected 3, got %d\n", ret);
1090 
1091     ret = CompareStringA(lcid, NORM_IGNORECASE, "Salut", 5, "saLuT", -1);
1092     ok (ret == 2, "(Salut/saLuT) Expected 2, got %d\n", ret);
1093 
1094     /* test for CompareStringA flags */
1095     SetLastError(0xdeadbeef);
1096     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0x8, "NULL", -1, "NULL", -1);
1097     ok(GetLastError() == ERROR_INVALID_FLAGS,
1098         "unexpected error code %d\n", GetLastError());
1099     ok(!ret, "CompareStringA must fail with invalid flag\n");
1100 
1101     SetLastError(0xdeadbeef);
1102     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, LOCALE_USE_CP_ACP, "NULL", -1, "NULL", -1);
1103     ok(GetLastError() == 0xdeadbeef, "unexpected error code %d\n", GetLastError());
1104     ok(ret == CSTR_EQUAL, "CompareStringA error: %d != CSTR_EQUAL\n", ret);
1105     /* end of test for CompareStringA flags */
1106 
1107     ret = lstrcmpA("", "");
1108     ok (ret == 0, "lstrcmpA(\"\", \"\") should return 0, got %d\n", ret);
1109 
1110     ret = lstrcmpA(NULL, NULL);
1111     ok (ret == 0 || broken(ret == -2) /* win9x */, "lstrcmpA(NULL, NULL) should return 0, got %d\n", ret);
1112 
1113     ret = lstrcmpA("", NULL);
1114     ok (ret == 1 || broken(ret == -2) /* win9x */, "lstrcmpA(\"\", NULL) should return 1, got %d\n", ret);
1115 
1116     ret = lstrcmpA(NULL, "");
1117     ok (ret == -1 || broken(ret == -2) /* win9x */, "lstrcmpA(NULL, \"\") should return -1, got %d\n", ret);
1118  
1119     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"EndDialog",-1,"_Property",-1);
1120     ok( ret == 3, "EndDialog vs _Property ... expected 3, got %d\n", ret);
1121 
1122     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"osp_vba.sreg0070",-1,"_IEWWBrowserComp",-1);
1123     ok( ret == 3, "osp_vba.sreg0070 vs _IEWWBrowserComp ... expected 3, got %d\n", ret);
1124 
1125     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"r",-1,"\\",-1); 
1126     ok( ret == 3, "r vs \\ ... expected 3, got %d\n", ret);
1127 
1128     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT,0,"osp_vba.sreg0031", -1, "OriginalDatabase", -1 );
1129     ok( ret == 3, "osp_vba.sreg0031 vs OriginalDatabase ... expected 3, got %d\n", ret);
1130 
1131     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "AAA", -1, "aaa", -1 );
1132     ok( ret == 3, "AAA vs aaa expected 3, got %d\n", ret);
1133 
1134     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "AAA", -1, "aab", -1 );
1135     ok( ret == 1, "AAA vs aab expected 1, got %d\n", ret);
1136 
1137     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "AAA", -1, "Aab", -1 );
1138     ok( ret == 1, "AAA vs Aab expected 1, got %d\n", ret);
1139 
1140     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, ".AAA", -1, "Aab", -1 );
1141     ok( ret == 1, ".AAA vs Aab expected 1, got %d\n", ret);
1142 
1143     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, ".AAA", -1, "A.ab", -1 );
1144     ok( ret == 1, ".AAA vs A.ab expected 1, got %d\n", ret);
1145 
1146     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "aa", -1, "AB", -1 );
1147     ok( ret == 1, "aa vs AB expected 1, got %d\n", ret);
1148 
1149     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "aa", -1, "Aab", -1 );
1150     ok( ret == 1, "aa vs Aab expected 1, got %d\n", ret);
1151 
1152     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "aB", -1, "Aab", -1 );
1153     ok( ret == 3, "aB vs Aab expected 3, got %d\n", ret);
1154 
1155     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "Ba", -1, "bab", -1 );
1156     ok( ret == 1, "Ba vs bab expected 1, got %d\n", ret);
1157 
1158     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "{100}{83}{71}{71}{71}", -1, "Global_DataAccess_JRO", -1 );
1159     ok( ret == 1, "{100}{83}{71}{71}{71} vs Global_DataAccess_JRO expected 1, got %d\n", ret);
1160 
1161     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "a", -1, "{", -1 );
1162     ok( ret == 3, "a vs { expected 3, got %d\n", ret);
1163 
1164     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "A", -1, "{", -1 );
1165     ok( ret == 3, "A vs { expected 3, got %d\n", ret);
1166 
1167     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "3.5", 0, "4.0", -1 );
1168     ok(ret == 1, "3.5/0 vs 4.0/-1 expected 1, got %d\n", ret);
1169 
1170     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "3.5", -1, "4.0", -1 );
1171     ok(ret == 1, "3.5 vs 4.0 expected 1, got %d\n", ret);
1172 
1173     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "3.520.4403.2", -1, "4.0.2927.10", -1 );
1174     ok(ret == 1, "3.520.4403.2 vs 4.0.2927.10 expected 1, got %d\n", ret);
1175 
1176    /* hyphen and apostrophe are treated differently depending on
1177     * whether SORT_STRINGSORT specified or not
1178     */
1179     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "-o", -1, "/m", -1 );
1180     ok(ret == 3, "-o vs /m expected 3, got %d\n", ret);
1181 
1182     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "/m", -1, "-o", -1 );
1183     ok(ret == 1, "/m vs -o expected 1, got %d\n", ret);
1184 
1185     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "-o", -1, "/m", -1 );
1186     ok(ret == 1, "-o vs /m expected 1, got %d\n", ret);
1187 
1188     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "/m", -1, "-o", -1 );
1189     ok(ret == 3, "/m vs -o expected 3, got %d\n", ret);
1190 
1191     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "'o", -1, "/m", -1 );
1192     ok(ret == 3, "'o vs /m expected 3, got %d\n", ret);
1193 
1194     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "/m", -1, "'o", -1 );
1195     ok(ret == 1, "/m vs 'o expected 1, got %d\n", ret);
1196 
1197     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "'o", -1, "/m", -1 );
1198     ok(ret == 1, "'o vs /m expected 1, got %d\n", ret);
1199 
1200     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "/m", -1, "'o", -1 );
1201     ok(ret == 3, "/m vs 'o expected 3, got %d\n", ret);
1202 
1203     if (0) { /* this requires collation table patch to make it MS compatible */
1204     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "'o", -1, "-o", -1 );
1205     ok(ret == 1, "'o vs -o expected 1, got %d\n", ret);
1206 
1207     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "'o", -1, "-o", -1 );
1208     ok(ret == 1, "'o vs -o expected 1, got %d\n", ret);
1209 
1210     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "'", -1, "-", -1 );
1211     ok(ret == 1, "' vs - expected 1, got %d\n", ret);
1212 
1213     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "'", -1, "-", -1 );
1214     ok(ret == 1, "' vs - expected 1, got %d\n", ret);
1215 
1216     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "`o", -1, "/m", -1 );
1217     ok(ret == 3, "`o vs /m expected 3, got %d\n", ret);
1218 
1219     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "/m", -1, "`o", -1 );
1220     ok(ret == 1, "/m vs `o expected 1, got %d\n", ret);
1221 
1222     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "`o", -1, "/m", -1 );
1223     ok(ret == 3, "`o vs /m expected 3, got %d\n", ret);
1224 
1225     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "/m", -1, "`o", -1 );
1226     ok(ret == 1, "/m vs `o expected 1, got %d\n", ret);
1227 
1228     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "`o", -1, "-m", -1 );
1229     ok(ret == 1, "`o vs -m expected 1, got %d\n", ret);
1230 
1231     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "-m", -1, "`o", -1 );
1232     ok(ret == 3, "-m vs `o expected 3, got %d\n", ret);
1233 
1234     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "`o", -1, "-m", -1 );
1235     ok(ret == 3, "`o vs -m expected 3, got %d\n", ret);
1236 
1237     ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "-m", -1, "`o", -1 );
1238     ok(ret == 1, "-m vs `o expected 1, got %d\n", ret);
1239     }
1240 
1241     ret = CompareStringA(LOCALE_USER_DEFAULT, 0, "aLuZkUtZ", 8, "aLuZkUtZ", 9);
1242     ok(ret == 2, "aLuZkUtZ vs aLuZkUtZ\\0 expected 2, got %d\n", ret);
1243 
1244     ret = CompareStringA(LOCALE_USER_DEFAULT, 0, "aLuZkUtZ", 7, "aLuZkUtZ\0A", 10);
1245     ok(ret == 1, "aLuZkUtZ vs aLuZkUtZ\\0A expected 1, got %d\n", ret);
1246 
1247     /* WinXP handles embedded NULLs differently than earlier versions */
1248     ret = CompareStringA(LOCALE_USER_DEFAULT, 0, "aLuZkUtZ", 8, "aLuZkUtZ\0A", 10);
1249     ok(ret == 1 || ret == 2, "aLuZkUtZ vs aLuZkUtZ\\0A expected 1 or 2, got %d\n", ret);
1250 
1251     ret = CompareStringA(LOCALE_USER_DEFAULT, 0, "aLu\0ZkUtZ", 8, "aLu\0ZkUtZ\0A", 10);
1252     ok(ret == 1 || ret == 2, "aLu\\0ZkUtZ vs aLu\\0ZkUtZ\\0A expected 1 or 2, got %d\n", ret);
1253 
1254     ret = CompareStringA(lcid, 0, "a\0b", -1, "a", -1);
1255     ok(ret == 2, "a vs a expected 2, got %d\n", ret);
1256 
1257     ret = CompareStringA(lcid, 0, "a\0b", 4, "a", 2);
1258     ok(ret == CSTR_EQUAL || /* win2k */
1259        ret == CSTR_GREATER_THAN,
1260        "a\\0b vs a expected CSTR_EQUAL or CSTR_GREATER_THAN, got %d\n", ret);
1261 
1262     ret = CompareStringA(lcid, 0, "\2", 2, "\1", 2);
1263     todo_wine ok(ret != 2, "\\2 vs \\1 expected unequal\n");
1264 
1265     ret = CompareStringA(lcid, NORM_IGNORECASE | LOCALE_USE_CP_ACP, "#", -1, ".", -1);
1266     todo_wine ok(ret == CSTR_LESS_THAN, "\"#\" vs \".\" expected CSTR_LESS_THAN, got %d\n", ret);
1267 
1268     ret = lstrcmpi("#", ".");
1269     todo_wine ok(ret == -1, "\"#\" vs \".\" expected -1, got %d\n", ret);
1270 }
1271 
1272 static void test_LCMapStringA(void)
1273 {
1274     int ret, ret2;
1275     char buf[256], buf2[256];
1276     static const char upper_case[] = "\tJUST! A, TEST; STRING 1/*+-.\r\n";
1277     static const char lower_case[] = "\tjust! a, test; string 1/*+-.\r\n";
1278     static const char symbols_stripped[] = "justateststring1";
1279 
1280     SetLastError(0xdeadbeef);
1281     ret = LCMapStringA(LOCALE_USER_DEFAULT, LOCALE_USE_CP_ACP | LCMAP_LOWERCASE,
1282                        lower_case, -1, buf, sizeof(buf));
1283     ok(ret == lstrlenA(lower_case) + 1,
1284        "ret %d, error %d, expected value %d\n",
1285        ret, GetLastError(), lstrlenA(lower_case) + 1);
1286     ok(!memcmp(buf, lower_case, ret), "LCMapStringA should return %s, but not %s\n", lower_case, buf);
1287 
1288     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE | LCMAP_UPPERCASE,
1289                        upper_case, -1, buf, sizeof(buf));
1290     ok(!ret, "LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive\n");
1291     ok(GetLastError() == ERROR_INVALID_FLAGS,
1292        "unexpected error code %d\n", GetLastError());
1293 
1294     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_HIRAGANA | LCMAP_KATAKANA,
1295                        upper_case, -1, buf, sizeof(buf));
1296     ok(!ret, "LCMAP_HIRAGANA and LCMAP_KATAKANA are mutually exclusive\n");
1297     ok(GetLastError() == ERROR_INVALID_FLAGS,
1298        "unexpected error code %d\n", GetLastError());
1299 
1300     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_HALFWIDTH | LCMAP_FULLWIDTH,
1301                        upper_case, -1, buf, sizeof(buf));
1302     ok(!ret, "LCMAP_HALFWIDTH | LCMAP_FULLWIDTH are mutually exclusive\n");
1303     ok(GetLastError() == ERROR_INVALID_FLAGS,
1304        "unexpected error code %d\n", GetLastError());
1305 
1306     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_TRADITIONAL_CHINESE | LCMAP_SIMPLIFIED_CHINESE,
1307                        upper_case, -1, buf, sizeof(buf));
1308     ok(!ret, "LCMAP_TRADITIONAL_CHINESE and LCMAP_SIMPLIFIED_CHINESE are mutually exclusive\n");
1309     ok(GetLastError() == ERROR_INVALID_FLAGS,
1310        "unexpected error code %d\n", GetLastError());
1311 
1312     /* SORT_STRINGSORT must be used exclusively with LCMAP_SORTKEY */
1313     SetLastError(0xdeadbeef);
1314     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE | SORT_STRINGSORT,
1315                        upper_case, -1, buf, sizeof(buf));
1316     ok(GetLastError() == ERROR_INVALID_FLAGS, "expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
1317     ok(!ret, "SORT_STRINGSORT without LCMAP_SORTKEY must fail\n");
1318 
1319     /* test LCMAP_LOWERCASE */
1320     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE,
1321                        upper_case, -1, buf, sizeof(buf));
1322     ok(ret == lstrlenA(upper_case) + 1,
1323        "ret %d, error %d, expected value %d\n",
1324        ret, GetLastError(), lstrlenA(upper_case) + 1);
1325     ok(!lstrcmpA(buf, lower_case), "LCMapStringA should return %s, but not %s\n", lower_case, buf);
1326 
1327     /* test LCMAP_UPPERCASE */
1328     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE,
1329                        lower_case, -1, buf, sizeof(buf));
1330     ok(ret == lstrlenA(lower_case) + 1,
1331        "ret %d, error %d, expected value %d\n",
1332        ret, GetLastError(), lstrlenA(lower_case) + 1);
1333     ok(!lstrcmpA(buf, upper_case), "LCMapStringA should return %s, but not %s\n", upper_case, buf);
1334 
1335     /* test buffer overflow */
1336     SetLastError(0xdeadbeef);
1337     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE,
1338                        lower_case, -1, buf, 4);
1339     ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1340        "should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d\n", ret);
1341 
1342     /* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
1343     lstrcpyA(buf, lower_case);
1344     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE,
1345                        buf, -1, buf, sizeof(buf));
1346     if (!ret) /* Win9x */
1347         trace("Ignoring LCMapStringA(LCMAP_UPPERCASE, buf, buf) error on Win9x\n");
1348     else
1349     {
1350         ok(ret == lstrlenA(lower_case) + 1,
1351            "ret %d, error %d, expected value %d\n",
1352            ret, GetLastError(), lstrlenA(lower_case) + 1);
1353         ok(!lstrcmpA(buf, upper_case), "LCMapStringA should return %s, but not %s\n", upper_case, buf);
1354     }
1355     lstrcpyA(buf, upper_case);
1356     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE,
1357                        buf, -1, buf, sizeof(buf));
1358     if (!ret) /* Win9x */
1359         trace("Ignoring LCMapStringA(LCMAP_LOWERCASE, buf, buf) error on Win9x\n");
1360     else
1361     {
1362         ok(ret == lstrlenA(upper_case) + 1,
1363            "ret %d, error %d, expected value %d\n",
1364            ret, GetLastError(), lstrlenA(lower_case) + 1);
1365         ok(!lstrcmpA(buf, lower_case), "LCMapStringA should return %s, but not %s\n", lower_case, buf);
1366     }
1367 
1368     /* otherwise src == dst should fail */
1369     SetLastError(0xdeadbeef);
1370     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | LCMAP_UPPERCASE,
1371                        buf, 10, buf, sizeof(buf));
1372     ok(GetLastError() == ERROR_INVALID_FLAGS /* NT */ ||
1373        GetLastError() == ERROR_INVALID_PARAMETER /* Win9x */,
1374        "unexpected error code %d\n", GetLastError());
1375     ok(!ret, "src == dst without LCMAP_UPPERCASE or LCMAP_LOWERCASE must fail\n");
1376 
1377     /* test whether '\0' is always appended */
1378     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1379                        upper_case, -1, buf, sizeof(buf));
1380     ok(ret, "LCMapStringA must succeed\n");
1381     ok(buf[ret-1] == 0, "LCMapStringA not null-terminated\n");
1382     ret2 = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1383                        upper_case, lstrlenA(upper_case), buf2, sizeof(buf2));
1384     ok(ret2, "LCMapStringA must succeed\n");
1385     ok(buf2[ret2-1] == 0, "LCMapStringA not null-terminated\n" );
1386     ok(ret == ret2, "lengths of sort keys must be equal\n");
1387     ok(!lstrcmpA(buf, buf2), "sort keys must be equal\n");
1388 
1389     /* test LCMAP_SORTKEY | NORM_IGNORECASE */
1390     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | NORM_IGNORECASE,
1391                        upper_case, -1, buf, sizeof(buf));
1392     ok(ret, "LCMapStringA must succeed\n");
1393     ret2 = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1394                        lower_case, -1, buf2, sizeof(buf2));
1395     ok(ret2, "LCMapStringA must succeed\n");
1396     ok(ret == ret2, "lengths of sort keys must be equal\n");
1397     ok(!lstrcmpA(buf, buf2), "sort keys must be equal\n");
1398 
1399     /* Don't test LCMAP_SORTKEY | NORM_IGNORENONSPACE, produces different
1400        results from plain LCMAP_SORTKEY on Vista */
1401 
1402     /* test LCMAP_SORTKEY | NORM_IGNORESYMBOLS */
1403     ret = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | NORM_IGNORESYMBOLS,
1404                        lower_case, -1, buf, sizeof(buf));
1405     ok(ret, "LCMapStringA must succeed\n");
1406     ret2 = LCMapStringA(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1407                        symbols_stripped, -1, buf2, sizeof(buf2));
1408     ok(ret2, "LCMapStringA must succeed\n");
1409     ok(ret == ret2, "lengths of sort keys must be equal\n");
1410     ok(!lstrcmpA(buf, buf2), "sort keys must be equal\n");
1411 
1412     /* test NORM_IGNORENONSPACE */
1413     lstrcpyA(buf, "foo");
1414     ret = LCMapStringA(LOCALE_USER_DEFAULT, NORM_IGNORENONSPACE,
1415                        lower_case, -1, buf, sizeof(buf));
1416     ok(ret == lstrlenA(lower_case) + 1, "LCMapStringA should return %d, ret = %d\n",
1417         lstrlenA(lower_case) + 1, ret);
1418     ok(!lstrcmpA(buf, lower_case), "LCMapStringA should return %s, but not %s\n", lower_case, buf);
1419 
1420     /* test NORM_IGNORESYMBOLS */
1421     lstrcpyA(buf, "foo");
1422     ret = LCMapStringA(LOCALE_USER_DEFAULT, NORM_IGNORESYMBOLS,
1423                        lower_case, -1, buf, sizeof(buf));
1424     ok(ret == lstrlenA(symbols_stripped) + 1, "LCMapStringA should return %d, ret = %d\n",
1425         lstrlenA(symbols_stripped) + 1, ret);
1426     ok(!lstrcmpA(buf, symbols_stripped), "LCMapStringA should return %s, but not %s\n", lower_case, buf);
1427 
1428     /* test srclen = 0 */
1429     SetLastError(0xdeadbeef);
1430     ret = LCMapStringA(LOCALE_USER_DEFAULT, 0, upper_case, 0, buf, sizeof(buf));
1431     ok(!ret, "LCMapStringA should fail with srclen = 0\n");
1432     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1433        "unexpected error code %d\n", GetLastError());
1434 }
1435 
1436 static void test_LCMapStringW(void)
1437 {
1438     int ret, ret2;
1439     WCHAR buf[256], buf2[256];
1440     char *p_buf = (char *)buf, *p_buf2 = (char *)buf2;
1441     static const WCHAR upper_case[] = {'\t','J','U','S','T','!',' ','A',',',' ','T','E','S','T',';',' ','S','T','R','I','N','G',' ','1','/','*','+','-','.','\r','\n',0};
1442     static const WCHAR lower_case[] = {'\t','j','u','s','t','!',' ','a',',',' ','t','e','s','t',';',' ','s','t','r','i','n','g',' ','1','/','*','+','-','.','\r','\n',0};
1443     static const WCHAR symbols_stripped[] = {'j','u','s','t','a','t','e','s','t','s','t','r','i','n','g','1',0};
1444     static const WCHAR fooW[] = {'f','o','o',0};
1445 
1446     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE | LCMAP_UPPERCASE,
1447                        upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1448     if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1449     {
1450         win_skip("LCMapStringW is not implemented\n");
1451         return;
1452     }
1453     if (broken(ret))
1454         ok(lstrcmpW(buf, upper_case) == 0, "Expected upper case string\n");
1455     else
1456     {
1457         ok(!ret, "LCMAP_LOWERCASE and LCMAP_UPPERCASE are mutually exclusive\n");
1458         ok(GetLastError() == ERROR_INVALID_FLAGS,
1459            "unexpected error code %d\n", GetLastError());
1460     }
1461 
1462     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_HIRAGANA | LCMAP_KATAKANA,
1463                        upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1464     ok(!ret, "LCMAP_HIRAGANA and LCMAP_KATAKANA are mutually exclusive\n");
1465     ok(GetLastError() == ERROR_INVALID_FLAGS,
1466        "unexpected error code %d\n", GetLastError());
1467 
1468     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_HALFWIDTH | LCMAP_FULLWIDTH,
1469                        upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1470     ok(!ret, "LCMAP_HALFWIDTH | LCMAP_FULLWIDTH are mutually exclusive\n");
1471     ok(GetLastError() == ERROR_INVALID_FLAGS,
1472        "unexpected error code %d\n", GetLastError());
1473 
1474     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_TRADITIONAL_CHINESE | LCMAP_SIMPLIFIED_CHINESE,
1475                        upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1476     ok(!ret, "LCMAP_TRADITIONAL_CHINESE and LCMAP_SIMPLIFIED_CHINESE are mutually exclusive\n");
1477     ok(GetLastError() == ERROR_INVALID_FLAGS,
1478        "unexpected error code %d\n", GetLastError());
1479 
1480     /* SORT_STRINGSORT must be used exclusively with LCMAP_SORTKEY */
1481     SetLastError(0xdeadbeef);
1482     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE | SORT_STRINGSORT,
1483                        upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1484     ok(GetLastError() == ERROR_INVALID_FLAGS, "expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
1485     ok(!ret, "SORT_STRINGSORT without LCMAP_SORTKEY must fail\n");
1486 
1487     /* test LCMAP_LOWERCASE */
1488     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE,
1489                        upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1490     ok(ret == lstrlenW(upper_case) + 1,
1491        "ret %d, error %d, expected value %d\n",
1492        ret, GetLastError(), lstrlenW(upper_case) + 1);
1493     ok(!lstrcmpW(buf, lower_case), "string compare mismatch\n");
1494 
1495     /* test LCMAP_UPPERCASE */
1496     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE,
1497                        lower_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1498     ok(ret == lstrlenW(lower_case) + 1,
1499        "ret %d, error %d, expected value %d\n",
1500        ret, GetLastError(), lstrlenW(lower_case) + 1);
1501     ok(!lstrcmpW(buf, upper_case), "string compare mismatch\n");
1502 
1503     /* test buffer overflow */
1504     SetLastError(0xdeadbeef);
1505     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE,
1506                        lower_case, -1, buf, 4);
1507     ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
1508        "should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d\n", ret);
1509 
1510     /* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
1511     lstrcpyW(buf, lower_case);
1512     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_UPPERCASE,
1513                        buf, -1, buf, sizeof(buf)/sizeof(WCHAR));
1514     ok(ret == lstrlenW(lower_case) + 1,
1515        "ret %d, error %d, expected value %d\n",
1516        ret, GetLastError(), lstrlenW(lower_case) + 1);
1517     ok(!lstrcmpW(buf, upper_case), "string compare mismatch\n");
1518 
1519     lstrcpyW(buf, upper_case);
1520     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_LOWERCASE,
1521                        buf, -1, buf, sizeof(buf)/sizeof(WCHAR));
1522     ok(ret == lstrlenW(upper_case) + 1,
1523        "ret %d, error %d, expected value %d\n",
1524        ret, GetLastError(), lstrlenW(lower_case) + 1);
1525     ok(!lstrcmpW(buf, lower_case), "string compare mismatch\n");
1526 
1527     /* otherwise src == dst should fail */
1528     SetLastError(0xdeadbeef);
1529     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | LCMAP_UPPERCASE,
1530                        buf, 10, buf, sizeof(buf));
1531     ok(GetLastError() == ERROR_INVALID_FLAGS /* NT */ ||
1532        GetLastError() == ERROR_INVALID_PARAMETER /* Win9x */,
1533        "unexpected error code %d\n", GetLastError());
1534     ok(!ret, "src == dst without LCMAP_UPPERCASE or LCMAP_LOWERCASE must fail\n");
1535 
1536     /* test whether '\0' is always appended */
1537     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1538                        upper_case, -1, buf, sizeof(buf));
1539     ok(ret, "LCMapStringW must succeed\n");
1540     ret2 = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1541                        upper_case, lstrlenW(upper_case), buf2, sizeof(buf2));
1542     ok(ret, "LCMapStringW must succeed\n");
1543     ok(ret == ret2, "lengths of sort keys must be equal\n");
1544     ok(!lstrcmpA(p_buf, p_buf2), "sort keys must be equal\n");
1545 
1546     /* test LCMAP_SORTKEY | NORM_IGNORECASE */
1547     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | NORM_IGNORECASE,
1548                        upper_case, -1, buf, sizeof(buf));
1549     ok(ret, "LCMapStringW must succeed\n");
1550     ret2 = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1551                        lower_case, -1, buf2, sizeof(buf2));
1552     ok(ret2, "LCMapStringW must succeed\n");
1553     ok(ret == ret2, "lengths of sort keys must be equal\n");
1554     ok(!lstrcmpA(p_buf, p_buf2), "sort keys must be equal\n");
1555 
1556     /* Don't test LCMAP_SORTKEY | NORM_IGNORENONSPACE, produces different
1557        results from plain LCMAP_SORTKEY on Vista */
1558 
1559     /* test LCMAP_SORTKEY | NORM_IGNORESYMBOLS */
1560     ret = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY | NORM_IGNORESYMBOLS,
1561                        lower_case, -1, buf, sizeof(buf));
1562     ok(ret, "LCMapStringW must succeed\n");
1563     ret2 = LCMapStringW(LOCALE_USER_DEFAULT, LCMAP_SORTKEY,
1564                        symbols_stripped, -1, buf2, sizeof(buf2));
1565     ok(ret2, "LCMapStringW must succeed\n");
1566     ok(ret == ret2, "lengths of sort keys must be equal\n");
1567     ok(!lstrcmpA(p_buf, p_buf2), "sort keys must be equal\n");
1568 
1569     /* test NORM_IGNORENONSPACE */
1570     lstrcpyW(buf, fooW);
1571     ret = LCMapStringW(LOCALE_USER_DEFAULT, NORM_IGNORENONSPACE,
1572                        lower_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1573     ok(ret == lstrlenW(lower_case) + 1, "LCMapStringW should return %d, ret = %d\n",
1574         lstrlenW(lower_case) + 1, ret);
1575     ok(!lstrcmpW(buf, lower_case), "string comparison mismatch\n");
1576 
1577     /* test NORM_IGNORESYMBOLS */
1578     lstrcpyW(buf, fooW);
1579     ret = LCMapStringW(LOCALE_USER_DEFAULT, NORM_IGNORESYMBOLS,
1580                        lower_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
1581     ok(ret == lstrlenW(symbols_stripped) + 1, "LCMapStringW should return %d, ret = %d\n",
1582         lstrlenW(symbols_stripped) + 1, ret);
1583     ok(!lstrcmpW(buf, symbols_stripped), "string comparison mismatch\n");
1584 
1585     /* test srclen = 0 */
1586     SetLastError(0xdeadbeef);
1587     ret = LCMapStringW(LOCALE_USER_DEFAULT, 0, upper_case, 0, buf, sizeof(buf)/sizeof(WCHAR));
1588     ok(!ret, "LCMapStringW should fail with srclen = 0\n");
1589     ok(GetLastError() == ERROR_INVALID_PARAMETER,
1590        "unexpected error code %d\n", GetLastError());
1591 }
1592 
1593 /* this requires collation table patch to make it MS compatible */
1594 static const char * const strings_sorted[] =
1595 {
1596 "'",
1597 "-",
1598 "!",
1599 "\"",
1600 ".",
1601 ":",
1602 "\\",
1603 "_",
1604 "`",
1605 "{",
1606 "}",
1607 "+",
1608 "",
1609 "1",
1610 "2",
1611 "3",
1612 "4",
1613 "5",
1614 "6",
1615 "7",
1616 "8",
1617 "9",
1618 "a",
1619 "A",
1620 "b",
1621 "B",
1622 "c",
1623 "C"
1624 };
1625 
1626 static const char * const strings[] =
1627 {
1628 "C",
1629 "\"",
1630 "9",
1631 "'",
1632 "}",
1633 "-",
1634 "7",
1635 "+",
1636 "`",
1637 "1",
1638 "a",
1639 "5",
1640 "\\",
1641 "8",
1642 "B",
1643 "3",
1644 "_",
1645 "6",
1646 "{",
1647 "2",
1648 "c",
1649 "4",
1650 "!",
1651 "",
1652 "A",
1653 ":",
1654 "b",
1655 "."
1656 };
1657 
1658 static int compare_string1(const void *e1, const void *e2)
1659 {
1660     const char *s1 = *(const char *const *)e1;
1661     const char *s2 = *(const char *const *)e2;
1662 
1663     return lstrcmpA(s1, s2);
1664 }
1665 
1666 static int compare_string2(const void *e1, const void *e2)
1667 {
1668     const char *s1 = *(const char *const *)e1;
1669     const char *s2 = *(const char *const *)e2;
1670 
1671     return CompareStringA(0, 0, s1, -1, s2, -1) - 2;
1672 }
1673 
1674 static int compare_string3(const void *e1, const void *e2)
1675 {
1676     const char *s1 = *(const char *const *)e1;
1677     const char *s2 = *(const char *const *)e2;
1678     char key1[256], key2[256];
1679 
1680     LCMapStringA(0, LCMAP_SORTKEY, s1, -1, key1, sizeof(key1));
1681     LCMapStringA(0, LCMAP_SORTKEY, s2, -1, key2, sizeof(key2));
1682     return strcmp(key1, key2);
1683 }
1684 
1685 static void test_sorting(void)
1686 {
1687     char buf[256];
1688     char **str_buf = (char **)buf;
1689     int i;
1690 
1691     assert(sizeof(buf) >= sizeof(strings));
1692 
1693     /* 1. sort using lstrcmpA */
1694     memcpy(buf, strings, sizeof(strings));
1695     qsort(buf, sizeof(strings)/sizeof(strings[0]), sizeof(strings[0]), compare_string1);
1696     for (i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
1697     {
1698         ok(!strcmp(strings_sorted[i], str_buf[i]),
1699            "qsort using lstrcmpA failed for element %d\n", i);
1700     }
1701     /* 2. sort using CompareStringA */
1702     memcpy(buf, strings, sizeof(strings));
1703     qsort(buf, sizeof(strings)/sizeof(strings[0]), sizeof(strings[0]), compare_string2);
1704     for (i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
1705     {
1706         ok(!strcmp(strings_sorted[i], str_buf[i]),
1707            "qsort using CompareStringA failed for element %d\n", i);
1708     }
1709     /* 3. sort using sort keys */
1710     memcpy(buf, strings, sizeof(strings));
1711     qsort(buf, sizeof(strings)/sizeof(strings[0]), sizeof(strings[0]), compare_string3);
1712     for (i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
1713     {
1714         ok(!strcmp(strings_sorted[i], str_buf[i]),
1715            "qsort using sort keys failed for element %d\n", i);
1716     }
1717 }
1718 
1719 static void test_FoldStringA(void)
1720 {
1721   int ret, i, j;
1722   BOOL is_special;
1723   char src[256], dst[256];
1724   static const char digits_src[] = { 0xB9,0xB2,0xB3,'\0'  };
1725   static const char digits_dst[] = { '1','2','3','\0'  };
1726   static const char composite_src[] =
1727   {
1728     0x8a,0x8e,0x9a,0x9e,0x9f,0xc0,0xc1,0xc2,
1729     0xc3,0xc4,0xc5,0xc7,0xc8,0xc9,0xca,0xcb,
1730     0xcc,0xcd,0xce,0xcf,0xd1,0xd2,0xd3,0xd4,
1731     0xd5,0xd6,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,
1732     0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe7,0xe8,
1733     0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf1,
1734     0xf2,0xf3,0xf4,0xf5,0xf6,0xf8,0xf9,0xfa,
1735     0xfb,0xfc,0xfd,0xff,'\0'
1736   };
1737   static const char composite_dst[] =
1738   {
1739     0x53,0x3f,0x5a,0x3f,0x73,0x3f,0x7a,0x3f,
1740     0x59,0xa8,0x41,0x60,0x41,0xb4,0x41,0x5e,
1741     0x41,0x7e,0x41,0xa8,0x41,0xb0,0x43,0xb8,
1742     0x45,0x60,0x45,0xb4,0x45,0x5e,0x45,0xa8,
1743     0x49,0x60,0x49,0xb4,0x49,0x5e,0x49,0xa8,
1744     0x4e,0x7e,0x4f,0x60,0x4f,0xb4,0x4f,0x5e,
1745     0x4f,0x7e,0x4f,0xa8,0x4f,0x3f,0x55,0x60,
1746     0x55,0xb4,0x55,0x5e,0x55,0xa8,0x59,0xb4,
1747     0x61,0x60,0x61,0xb4,0x61,0x5e,0x61,0x7e,
1748     0x61,0xa8,0x61,0xb0,0x63,0xb8,0x65,0x60,
1749     0x65,0xb4,0x65,0x5e,0x65,0xa8,0x69,0x60,
1750     0x69,0xb4,0x69,0x5e,0x69,0xa8,0x6e,0x7e,
1751     0x6f,0x60,0x6f,0xb4,0x6f,0x5e,0x6f,0x7e,
1752     0x6f,0xa8,0x6f,0x3f,0x75,0x60,0x75,0xb4,
1753     0x75,0x5e,0x75,0xa8,0x79,0xb4,0x79,0xa8,'\0'
1754   };
1755   static const char composite_dst_alt[] =
1756   {
1757     0x53,0x3f,0x5a,0x3f,0x73,0x3f,0x7a,0x3f,
1758     0x59,0xa8,0x41,0x60,0x41,0xb4,0x41,0x5e,
1759     0x41,0x7e,0x41,0xa8,0x41,0xb0,0x43,0xb8,
1760     0x45,0x60,0x45,0xb4,0x45,0x5e,0x45,0xa8,
1761     0x49,0x60,0x49,0xb4,0x49,0x5e,0x49,0xa8,
1762     0x4e,0x7e,0x4f,0x60,0x4f,0xb4,0x4f,0x5e,
1763     0x4f,0x7e,0x4f,0xa8,0xd8,0x55,0x60,0x55,
1764     0xb4,0x55,0x5e,0x55,0xa8,0x59,0xb4,0x61,
1765     0x60,0x61,0xb4,0x61,0x5e,0x61,0x7e,0x61,
1766     0xa8,0x61,0xb0,0x63,0xb8,0x65,0x60,0x65,
1767     0xb4,0x65,0x5e,0x65,0xa8,0x69,0x60,0x69,
1768     0xb4,0x69,0x5e,0x69,0xa8,0x6e,0x7e,0x6f,
1769     0x60,0x6f,0xb4,0x6f,0x5e,0x6f,0x7e,0x6f,
1770     0xa8,0xf8,0x75,0x60,0x75,0xb4,0x75,0x5e,
1771     0x75,0xa8,0x79,0xb4,0x79,0xa8,'\0'
1772   };
1773   static const char ligatures_src[] =
1774   {
1775     0x8C,0x9C,0xC6,0xDE,0xDF,0xE6,0xFE,'\0'
1776   };
1777   static const char ligatures_dst[] =
1778   {
1779     'O','E','o','e','A','E','T','H','s','s','a','e','t','h','\0'
1780   };
1781   static const struct special
1782   {
1783     char src;
1784     char dst[4];
1785   }  foldczone_special[] =
1786   {
1787     /* src   dst                   */
1788     { 0x85, { 0x2e, 0x2e, 0x2e, 0x00 } },
1789     { 0x98, { 0x20, 0x7e, 0x00 } },
1790     { 0x99, { 0x54, 0x4d, 0x00 } },
1791     { 0xa0, { 0x20, 0x00 } },
1792     { 0xa8, { 0x20, 0xa8, 0x00 } },
1793     { 0xaa, { 0x61, 0x00 } },
1794     { 0xaf, { 0x20, 0xaf, 0x00 } },
1795     { 0xb2, { 0x32, 0x00 } },
1796     { 0xb3, { 0x33, 0x00 } },
1797     { 0xb4, { 0x20, 0xb4, 0x00 } },
1798     { 0xb8, { 0x20, 0xb8, 0x00 } },
1799     { 0xb9, { 0x31, 0x00 } },
1800     { 0xba, { 0x6f, 0x00 } },
1801     { 0xbc, { 0x31, 0x2f, 0x34, 0x00 } },
1802     { 0xbd, { 0x31, 0x2f, 0x32, 0x00 } },
1803     { 0xbe, { 0x33, 0x2f, 0x34, 0x00 } },
1804     { 0x00 }
1805   };
1806 
1807   if (!pFoldStringA)
1808     return; /* FoldString is present in NT v3.1+, but not 95/98/Me */
1809 
1810   /* these tests are locale specific */
1811   if (GetACP() != 1252)
1812   {
1813       trace("Skipping FoldStringA tests for a not Latin 1 locale\n");
1814       return;
1815   }
1816 
1817   /* MAP_FOLDDIGITS */
1818   SetLastError(0);
1819   ret = pFoldStringA(MAP_FOLDDIGITS, digits_src, -1, dst, 256);
1820   if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
1821   {
1822     win_skip("FoldStringA is not implemented\n");
1823     return;
1824   }
1825   ok(ret == 4, "Expected ret == 4, got %d, error %d\n", ret, GetLastError());
1826   ok(strcmp(dst, digits_dst) == 0,
1827      "MAP_FOLDDIGITS: Expected '%s', got '%s'\n", digits_dst, dst);
1828   for (i = 1; i < 256; i++)
1829   {
1830     if (!strchr(digits_src, i))
1831     {
1832       src[0] = i;
1833       src[1] = '\0';
1834       SetLastError(0);
1835       ret = pFoldStringA(MAP_FOLDDIGITS, src, -1, dst, 256);
1836       ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError());
1837       ok(dst[0] == src[0],
1838          "MAP_FOLDDIGITS: Expected '%s', got '%s'\n", src, dst);
1839     }
1840   }
1841 
1842   /* MAP_EXPAND_LIGATURES */
1843   SetLastError(0);
1844   ret = pFoldStringA(MAP_EXPAND_LIGATURES, ligatures_src, -1, dst, 256);
1845   /* NT 4.0 doesn't support MAP_EXPAND_LIGATURES */
1846   if (!(ret == 0 && GetLastError() == ERROR_INVALID_FLAGS)) {
1847     ok(ret == sizeof(ligatures_dst), "Got %d, error %d\n", ret, GetLastError());
1848     ok(strcmp(dst, ligatures_dst) == 0,
1849        "MAP_EXPAND_LIGATURES: Expected '%s', got '%s'\n", ligatures_dst, dst);
1850     for (i = 1; i < 256; i++)
1851     {
1852       if (!strchr(ligatures_src, i))
1853       {
1854         src[0] = i;
1855         src[1] = '\0';
1856         SetLastError(0);
1857         ret = pFoldStringA(MAP_EXPAND_LIGATURES, src, -1, dst, 256);
1858         if (ret == 3)
1859         {
1860           /* Vista */
1861           ok((i == 0xDC && lstrcmpA(dst, "UE") == 0) ||
1862              (i == 0xFC && lstrcmpA(dst, "ue") == 0),
1863              "Got %s for %d\n", dst, i);
1864         }
1865         else
1866         {
1867           ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError());
1868           ok(dst[0] == src[0],
1869              "MAP_EXPAND_LIGATURES: Expected '%s', got '%s'\n", src, dst);
1870         }
1871       }
1872     }
1873   }
1874 
1875   /* MAP_COMPOSITE */
1876   SetLastError(0);
1877   ret = pFoldStringA(MAP_COMPOSITE, composite_src, -1, dst, 256);
1878   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
1879   ok(ret == 121 || ret == 119, "Expected 121 or 119, got %d\n", ret);
1880   ok(strcmp(dst, composite_dst) == 0 || strcmp(dst, composite_dst_alt) == 0,
1881      "MAP_COMPOSITE: Mismatch, got '%s'\n", dst);
1882 
1883   for (i = 1; i < 256; i++)
1884   {
1885     if (!strchr(composite_src, i))
1886     {
1887       src[0] = i;
1888       src[1] = '\0';
1889       SetLastError(0);
1890       ret = pFoldStringA(MAP_COMPOSITE, src, -1, dst, 256);
1891       ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError());
1892       ok(dst[0] == src[0],
1893          "0x%02x, 0x%02x,0x%02x,0x%02x,\n", (unsigned char)src[0],
1894          (unsigned char)dst[0],(unsigned char)dst[1],(unsigned char)dst[2]);
1895     }
1896   }
1897 
1898   /* MAP_FOLDCZONE */
1899   for (i = 1; i < 256; i++)
1900   {
1901     src[0] = i;
1902     src[1] = '\0';
1903     SetLastError(0);
1904     ret = pFoldStringA(MAP_FOLDCZONE, src, -1, dst, 256);
1905     is_special = FALSE;
1906     for (j = 0; foldczone_special[j].src != 0 && ! is_special; j++)
1907     {
1908       if (foldczone_special[j].src == src[0])
1909       {
1910         ok(ret == 2 || ret == lstrlenA(foldczone_special[j].dst) + 1,
1911            "Expected ret == 2 or %d, got %d, error %d\n",
1912            lstrlenA(foldczone_special[j].dst) + 1, ret, GetLastError());
1913         ok(src[0] == dst[0] || lstrcmpA(foldczone_special[j].dst, dst) == 0,
1914            "MAP_FOLDCZONE: string mismatch for 0x%02x\n",
1915            (unsigned char)src[0]);
1916         is_special = TRUE;
1917       }
1918     }
1919     if (! is_special)
1920     {
1921       ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError());
1922       ok(src[0] == dst[0],
1923          "MAP_FOLDCZONE: Expected 0x%02x, got 0x%02x\n",
1924          (unsigned char)src[0], (unsigned char)dst[0]);
1925     }
1926   }
1927 
1928   /* MAP_PRECOMPOSED */
1929   for (i = 1; i < 256; i++)
1930   {
1931     src[0] = i;
1932     src[1] = '\0';
1933     SetLastError(0);
1934     ret = pFoldStringA(MAP_PRECOMPOSED, src, -1, dst, 256);
1935     ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError());
1936     ok(src[0] == dst[0],
1937        "MAP_PRECOMPOSED: Expected 0x%02x, got 0x%02x\n",
1938        (unsigned char)src[0], (unsigned char)dst[0]);
1939   }
1940 }
1941 
1942 static void test_FoldStringW(void)
1943 {
1944   int ret;
1945   unsigned int i, j;
1946   WCHAR src[256], dst[256], ch, prev_ch = 1;
1947   static const DWORD badFlags[] =
1948   {
1949     0,
1950     MAP_PRECOMPOSED|MAP_COMPOSITE,
1951     MAP_PRECOMPOSED|MAP_EXPAND_LIGATURES,
1952     MAP_COMPOSITE|MAP_EXPAND_LIGATURES
1953   };
1954   /* Ranges of digits 0-9 : Must be sorted! */
1955   static const WCHAR digitRanges[] =
1956   {
1957     0x0030, /* ''-'9' */
1958     0x0660, /* Eastern Arabic */
1959     0x06F0, /* Arabic - Hindu */
1960     0x0966, /* Devengari */
1961     0x09E6, /* Bengalii */
1962     0x0A66, /* Gurmukhi */
1963     0x0AE6, /* Gujarati */
1964     0x0B66, /* Oriya */
1965     0x0BE6, /* Tamil - No 0 */
1966     0x0C66, /* Telugu */
1967     0x0CE6, /* Kannada */
1968     0x0D66, /* Maylayalam */
1969     0x0E50, /* Thai */
1970     0x0ED0, /* Laos */
1971     0x0F29, /* Tibet - 0 is out of sequence */
1972     0x2070, /* Superscript - 1, 2, 3 are out of sequence */
1973     0x2080, /* Subscript */
1974     0x245F, /* Circled - 0 is out of sequence */
1975     0x2473, /* Bracketed */
1976     0x2487, /* Full stop */
1977     0x2775, /* Inverted circled - No 0 */
1978     0x277F, /* Patterned circled - No 0 */
1979     0x2789, /* Inverted Patterned circled - No 0 */
1980     0x3020, /* Hangzhou */
1981     0xff10, /* Pliene chasse (?) */
1982     0xffff  /* Terminator */
1983   };
1984   /* Digits which are represented, but out of sequence */
1985   static const WCHAR outOfSequenceDigits[] =
1986   {
1987       0xB9,   /* Superscript 1 */
1988       0xB2,   /* Superscript 2 */
1989       0xB3,   /* Superscript 3 */
1990       0x0F33, /* Tibetan half zero */
1991       0x24EA, /* Circled 0 */
1992       0x3007, /* Ideographic number zero */
1993       '\0'    /* Terminator */
1994   };
1995   /* Digits in digitRanges for which no representation is available */
1996   static const WCHAR noDigitAvailable[] =
1997   {
1998       0x0BE6, /* No Tamil 0 */
1999       0x0F29, /* No Tibetan half zero (out of sequence) */
2000       0x2473, /* No Bracketed 0 */
2001       0x2487, /* No 0 Full stop */
2002       0x2775, /* No inverted circled 0 */
2003       0x277F, /* No patterned circled */
2004       0x2789, /* No inverted Patterned circled */
2005       0x3020, /* No Hangzhou 0 */
2006       '\0'    /* Terminator */
2007   };
2008   static const WCHAR foldczone_src[] =
2009   {
2010     'W',    'i',    'n',    'e',    0x0348, 0x0551, 0x1323, 0x280d,
2011     0xff37, 0xff49, 0xff4e, 0xff45, '\0'
2012   };
2013   static const WCHAR foldczone_dst[] =
2014   {
2015     'W','i','n','e',0x0348,0x0551,0x1323,0x280d,'W','i','n','e','\0'
2016   };
2017   static const WCHAR ligatures_src[] =
2018   {
2019     'W',    'i',    'n',    'e',    0x03a6, 0x03b9, 0x03bd, 0x03b5,
2020     0x00c6, 0x00de, 0x00df, 0x00e6, 0x00fe, 0x0132, 0x0133, 0x0152,
2021     0x0153, 0x01c4, 0x01c5, 0x01c6, 0x01c7, 0x01c8, 0x01c9, 0x01ca,
2022     0x01cb, 0x01cc, 0x01e2, 0x01e3, 0x01f1, 0x01f2, 0x01f3, 0x01fc,
2023     0x01fd, 0x05f0, 0x05f1, 0x05f2, 0xfb00, 0xfb01, 0xfb02, 0xfb03,
2024     0xfb04, 0xfb05, 0xfb06, '\0'
2025   };
2026   static const WCHAR ligatures_dst[] =
2027   {
2028     'W','i','n','e',0x03a6,0x03b9,0x03bd,0x03b5,
2029     'A','E','T','H','s','s','a','e','t','h','I','J','i','j','O','E','o','e',
2030     'D',0x017d,'D',0x017e,'d',0x017e,'L','J','L','j','l','j','N','J','N','j',
2031     'n','j',0x0100,0x0112,0x0101,0x0113,'D','Z','D','z','d','z',0x00c1,0x00c9,
2032     0x00e1,0x00e9,0x05d5,0x05d5,0x05d5,0x05d9,0x05d9,0x05d9,'f','f','f','i',
2033     'f','l','f','f','i','f','f','l',0x017f,'t','s','t','\0'
2034   };
2035 
2036   if (!pFoldStringW)
2037   {
2038     win_skip("FoldStringW is not available\n");
2039     return; /* FoldString is present in NT v3.1+, but not 95/98/Me */
2040   }
2041 
2042   /* Invalid flag combinations */
2043   for (i = 0; i < sizeof(badFlags)/sizeof(badFlags[0]); i++)
2044   {
2045     src[0] = dst[0] = '\0';
2046     SetLastError(0);
2047     ret = pFoldStringW(badFlags[i], src, 256, dst, 256);
2048     if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
2049     {
2050       win_skip("FoldStringW is not implemented\n");
2051       return;
2052     }
2053     ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
2054        "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
2055   }
2056 
2057   /* src & dst cannot be the same */
2058   SetLastError(0);
2059   ret = pFoldStringW(MAP_FOLDCZONE, src, -1, src, 256);
2060   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
2061       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2062 
2063   /* src can't be NULL */
2064   SetLastError(0);
2065   ret = pFoldStringW(MAP_FOLDCZONE, NULL, -1, dst, 256);
2066   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
2067       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2068 
2069   /* srclen can't be 0 */
2070   SetLastError(0);
2071   ret = pFoldStringW(MAP_FOLDCZONE, src, 0, dst, 256);
2072   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
2073       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2074 
2075   /* dstlen can't be < 0 */
2076   SetLastError(0);
2077   ret = pFoldStringW(MAP_FOLDCZONE, src, -1, dst, -1);
2078   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
2079       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2080 
2081   /* Ret includes terminating NUL which is appended if srclen = -1 */
2082   SetLastError(0);
2083   src[0] = 'A';
2084   src[1] = '\0';
2085   dst[0] = '\0';
2086   ret = pFoldStringW(MAP_FOLDCZONE, src, -1, dst, 256);
2087   ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError());
2088   ok(dst[0] == 'A' && dst[1] == '\0',
2089      "srclen=-1: Expected ret=2 [%d,%d], got ret=%d [%d,%d], err=%d\n",
2090      'A', '\0', ret, dst[0], dst[1], GetLastError());
2091 
2092   /* If size is given, result is not NUL terminated */
2093   SetLastError(0);
2094   src[0] = 'A';
2095   src[1] = 'A';
2096   dst[0] = 'X';
2097   dst[1] = 'X';
2098   ret = pFoldStringW(MAP_FOLDCZONE, src, 1, dst, 256);
2099   ok(ret == 1, "Expected ret == 1, got %d, error %d\n", ret, GetLastError());
2100   ok(dst[0] == 'A' && dst[1] == 'X',
2101      "srclen=1: Expected ret=1, [%d,%d], got ret=%d,[%d,%d], err=%d\n",
2102      'A','X', ret, dst[0], dst[1], GetLastError());
2103 
2104   /* MAP_FOLDDIGITS */
2105   for (j = 0; j < sizeof(digitRanges)/sizeof(digitRanges[0]); j++)
2106   {
2107     /* Check everything before this range */
2108     for (ch = prev_ch; ch < digitRanges[j]; ch++)
2109     {
2110       SetLastError(0);
2111       src[0] = ch;
2112       src[1] = dst[0] = '\0';
2113       ret = pFoldStringW(MAP_FOLDDIGITS, src, -1, dst, 256);
2114       ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError());
2115 
2116       ok(dst[0] == ch || strchrW(outOfSequenceDigits, ch) ||
2117          /* Wine (correctly) maps all Unicode 4.0+ digits */
2118          isdigitW(ch) || (ch >= 0x24F5 && ch <= 0x24FD) || ch == 0x24FF ||
2119          (ch >= 0x1369 && ch <= 0x1371),
2120          "MAP_FOLDDIGITS: ch %d 0x%04x Expected unchanged got %d\n", ch, ch, dst[0]);
2121     }
2122 
2123     if (digitRanges[j] == 0xffff)
2124       break; /* Finished the whole code point space */
2125 
2126     for (ch = digitRanges[j]; ch < digitRanges[j] + 10; ch++)
2127     {
2128       WCHAR c;
2129 
2130       /* Map out of sequence characters */
2131       if      (ch == 0x2071) c = 0x00B9; /* Superscript 1 */
2132       else if (ch == 0x2072) c = 0x00B2; /* Superscript 2 */
2133       else if (ch == 0x2073) c = 0x00B3; /* Superscript 3 */
2134       else if (ch == 0x245F) c = 0x24EA; /* Circled 0     */
2135       else                   c = ch;
2136       SetLastError(0);
2137       src[0] = c;
2138       src[1] = dst[0] = '\0';
2139       ret = pFoldStringW(MAP_FOLDDIGITS, src, -1, dst, 256);
2140       ok(ret == 2, "Expected ret == 2, got %d, error %d\n", ret, GetLastError());
2141 
2142       ok((dst[0] == '' + ch - digitRanges[j] && dst[1] == '\0') ||
2143          broken( dst[0] == ch ) ||  /* old Windows versions don't have all mappings */
2144          (digitRanges[j] == 0x3020 && dst[0] == ch) || /* Hangzhou not present in all Windows versions */
2145          (digitRanges[j] == 0x0F29 && dst[0] == ch) || /* Tibetan not present in all Windows versions */
2146          strchrW(noDigitAvailable, c),
2147          "MAP_FOLDDIGITS: ch %d Expected %d got %d\n",
2148          ch, '' + digitRanges[j] - ch, dst[0]);
2149     }
2150     prev_ch = ch;
2151   }
2152 
2153   /* MAP_FOLDCZONE */
2154   SetLastError(0);
2155   ret = pFoldStringW(MAP_FOLDCZONE, foldczone_src, -1, dst, 256);
2156   ok(ret == sizeof(foldczone_dst)/sizeof(foldczone_dst[0]),
2157      "Got %d, error %d\n", ret, GetLastError());
2158   ok(!memcmp(dst, foldczone_dst, sizeof(foldczone_dst)),
2159      "MAP_FOLDCZONE: Expanded incorrectly\n");
2160 
2161   /* MAP_EXPAND_LIGATURES */
2162   SetLastError(0);
2163   ret = pFoldStringW(MAP_EXPAND_LIGATURES, ligatures_src, -1, dst, 256);
2164   /* NT 4.0 doesn't support MAP_EXPAND_LIGATURES */
2165   if (!(ret == 0 && GetLastError() == ERROR_INVALID_FLAGS)) {
2166     ok(ret == sizeof(ligatures_dst)/sizeof(ligatures_dst[0]),
2167        "Got %d, error %d\n", ret, GetLastError());
2168     ok(!memcmp(dst, ligatures_dst, sizeof(ligatures_dst)),
2169        "MAP_EXPAND_LIGATURES: Expanded incorrectly\n");
2170   }
2171 
2172   /* FIXME: MAP_PRECOMPOSED : MAP_COMPOSITE */
2173 }
2174 
2175 
2176 
2177 #define LCID_OK(l) \
2178   ok(lcid == l, "Expected lcid = %08x, got %08x\n", l, lcid)
2179 #define MKLCID(x,y,z) MAKELCID(MAKELANGID(x, y), z)
2180 #define LCID_RES(src, res) lcid = ConvertDefaultLocale(src); LCID_OK(res)
2181 #define TEST_LCIDLANG(a,b) LCID_RES(MAKELCID(a,b), MAKELCID(a,b))
2182 #define TEST_LCID(a,b,c) LCID_RES(MKLCID(a,b,c), MKLCID(a,b,c))
2183 
2184 static void test_ConvertDefaultLocale(void)
2185 {
2186   LCID lcid;
2187 
2188   /* Doesn't change lcid, even if non default sublang/sort used */
2189   TEST_LCID(LANG_ENGLISH,  SUBLANG_ENGLISH_US, SORT_DEFAULT);
2190   TEST_LCID(LANG_ENGLISH,  SUBLANG_ENGLISH_UK, SORT_DEFAULT);
2191   TEST_LCID(LANG_JAPANESE, SUBLANG_DEFAULT,    SORT_DEFAULT);
2192   TEST_LCID(LANG_JAPANESE, SUBLANG_DEFAULT,    SORT_JAPANESE_UNICODE);
2193 
2194   /* SUBLANG_NEUTRAL -> SUBLANG_DEFAULT */
2195   LCID_RES(MKLCID(LANG_ENGLISH,  SUBLANG_NEUTRAL, SORT_DEFAULT),
2196            MKLCID(LANG_ENGLISH,  SUBLANG_DEFAULT, SORT_DEFAULT));
2197   LCID_RES(MKLCID(LANG_JAPANESE, SUBLANG_NEUTRAL, SORT_DEFAULT),
2198            MKLCID(LANG_JAPANESE, SUBLANG_DEFAULT, SORT_DEFAULT));
2199 
2200   /* Invariant language is not treated specially */
2201   TEST_LCID(LANG_INVARIANT, SUBLANG_DEFAULT, SORT_DEFAULT);
2202 
2203   /* User/system default languages alone are not mapped */
2204   TEST_LCIDLANG(LANG_SYSTEM_DEFAULT, SORT_JAPANESE_UNICODE);
2205   TEST_LCIDLANG(LANG_USER_DEFAULT,   SORT_JAPANESE_UNICODE);
2206 
2207   /* Default lcids */
2208   LCID_RES(LOCALE_SYSTEM_DEFAULT, GetSystemDefaultLCID());
2209   LCID_RES(LOCALE_USER_DEFAULT,   GetUserDefaultLCID());
2210   LCID_RES(LOCALE_NEUTRAL,        GetUserDefaultLCID());
2211 }
2212 
2213 static BOOL CALLBACK langgrp_procA(LGRPID lgrpid, LPSTR lpszNum, LPSTR lpszName,
2214                                     DWORD dwFlags, LONG_PTR lParam)
2215 {
2216   trace("%08x, %s, %s, %08x, %08lx\n",
2217         lgrpid, lpszNum, lpszName, dwFlags, lParam);
2218 
2219   ok(pIsValidLanguageGroup(lgrpid, dwFlags) == TRUE,
2220      "Enumerated grp %d not valid (flags %d)\n", lgrpid, dwFlags);
2221 
2222   /* If lParam is one, we are calling with flags defaulted from 0 */
2223   ok(!lParam || (dwFlags == LGRPID_INSTALLED || dwFlags == LGRPID_SUPPORTED),
2224          "Expected dwFlags == LGRPID_INSTALLED || dwFlags == LGRPID_SUPPORTED, got %d\n", dwFlags);
2225 
2226   return TRUE;
2227 }
2228 
2229 static void test_EnumSystemLanguageGroupsA(void)
2230 {
2231   BOOL ret;
2232 
2233   if (!pEnumSystemLanguageGroupsA || !pIsValidLanguageGroup)
2234   {
2235     win_skip("EnumSystemLanguageGroupsA and/or IsValidLanguageGroup are not available\n");
2236     return;
2237   }
2238 
2239   /* No enumeration proc */
2240   SetLastError(0);
2241   ret = pEnumSystemLanguageGroupsA(0, LGRPID_INSTALLED, 0);
2242   if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2243   {
2244     win_skip("EnumSystemLanguageGroupsA is not implemented\n");
2245     return;
2246   }
2247   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
2248       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2249 
2250   /* Invalid flags */
2251   SetLastError(0);
2252   pEnumSystemLanguageGroupsA(langgrp_procA, LGRPID_INSTALLED|LGRPID_SUPPORTED, 0);
2253   ok(GetLastError() == ERROR_INVALID_FLAGS, "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
2254 
2255   /* No flags - defaults to LGRPID_INSTALLED */
2256   SetLastError(0xdeadbeef);
2257   pEnumSystemLanguageGroupsA(langgrp_procA, 0, 1);
2258   ok(GetLastError() == 0xdeadbeef, "got error %d\n", GetLastError());
2259 
2260   pEnumSystemLanguageGroupsA(langgrp_procA, LGRPID_INSTALLED, 0);
2261   pEnumSystemLanguageGroupsA(langgrp_procA, LGRPID_SUPPORTED, 0);
2262 }
2263 
2264 
2265 static BOOL CALLBACK lgrplocale_procA(LGRPID lgrpid, LCID lcid, LPSTR lpszNum,
2266                                       LONG_PTR lParam)
2267 {
2268   trace("%08x, %08x, %s, %08lx\n", lgrpid, lcid, lpszNum, lParam);
2269 
2270   /* invalid locale enumerated on some platforms */
2271   if (lcid == 0)
2272       return TRUE;
2273 
2274   ok(pIsValidLanguageGroup(lgrpid, LGRPID_SUPPORTED) == TRUE,
2275      "Enumerated grp %d not valid\n", lgrpid);
2276   ok(IsValidLocale(lcid, LCID_SUPPORTED) == TRUE,
2277      "Enumerated grp locale %d not valid\n", lcid);
2278   return TRUE;
2279 }
2280 
2281 static void test_EnumLanguageGroupLocalesA(void)
2282 {
2283   BOOL ret;
2284 
2285   if (!pEnumLanguageGroupLocalesA || !pIsValidLanguageGroup)
2286   {
2287     win_skip("EnumLanguageGroupLocalesA and/or IsValidLanguageGroup are not available\n");
2288     return;
2289   }
2290 
2291   /* No enumeration proc */
2292   SetLastError(0);
2293   ret = pEnumLanguageGroupLocalesA(0, LGRPID_WESTERN_EUROPE, 0, 0);
2294   if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2295   {
2296     win_skip("EnumLanguageGroupLocalesA is not implemented\n");
2297     return;
2298   }
2299   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
2300       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2301 
2302   /* lgrpid too small */
2303   SetLastError(0);
2304   ret = pEnumLanguageGroupLocalesA(lgrplocale_procA, 0, 0, 0);
2305   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
2306       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2307 
2308   /* lgrpid too big */
2309   SetLastError(0);
2310   ret = pEnumLanguageGroupLocalesA(lgrplocale_procA, LGRPID_ARMENIAN + 1, 0, 0);
2311   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
2312       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2313 
2314   /* dwFlags is reserved */
2315   SetLastError(0);
2316   ret = pEnumLanguageGroupLocalesA(0, LGRPID_WESTERN_EUROPE, 0x1, 0);
2317   ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
2318       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2319 
2320   pEnumLanguageGroupLocalesA(lgrplocale_procA, LGRPID_WESTERN_EUROPE, 0, 0);
2321 }
2322 
2323 static void test_SetLocaleInfoA(void)
2324 {
2325   BOOL bRet;
2326   LCID lcid = GetUserDefaultLCID();
2327 
2328   /* Null data */
2329   SetLastError(0);
2330   bRet = SetLocaleInfoA(lcid, LOCALE_SDATE, 0);
2331   ok( !bRet && GetLastError() == ERROR_INVALID_PARAMETER,
2332       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2333 
2334   /* IDATE */
2335   SetLastError(0);
2336   bRet = SetLocaleInfoA(lcid, LOCALE_IDATE, (LPSTR)test_SetLocaleInfoA);
2337   ok(!bRet && GetLastError() == ERROR_INVALID_FLAGS,
2338      "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
2339 
2340   /* ILDATE */
2341   SetLastError(0);
2342   bRet = SetLocaleInfoA(lcid, LOCALE_ILDATE, (LPSTR)test_SetLocaleInfoA);
2343   ok(!bRet && GetLastError() == ERROR_INVALID_FLAGS,
2344      "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
2345 }
2346 
2347 static BOOL CALLBACK luilocale_proc1A(LPSTR value, LONG_PTR lParam)
2348 {
2349   trace("%s %08lx\n", value, lParam);
2350   return(TRUE);
2351 }
2352 
2353 static BOOL CALLBACK luilocale_proc2A(LPSTR value, LONG_PTR lParam)
2354 {
2355   ok(!enumCount, "callback called again unexpected\n");
2356   enumCount++;
2357   return(FALSE);
2358 }
2359 
2360 static BOOL CALLBACK luilocale_proc3A(LPSTR value, LONG_PTR lParam)
2361 {
2362   ok(0,"callback called unexpected\n");
2363   return(FALSE);
2364 }
2365 
2366 static void test_EnumUILanguageA(void)
2367 {
2368   BOOL ret;
2369   if (!pEnumUILanguagesA) {
2370     win_skip("EnumUILanguagesA is not available on Win9x or NT4\n");
2371     return;
2372   }
2373 
2374   SetLastError(ERROR_SUCCESS);
2375   ret = pEnumUILanguagesA(luilocale_proc1A, 0, 0);
2376   if (ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
2377   {
2378     win_skip("EnumUILanguagesA is not implemented\n");
2379     return;
2380   }
2381   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
2382 
2383   enumCount = 0;
2384   SetLastError(ERROR_SUCCESS);
2385   ret = pEnumUILanguagesA(luilocale_proc2A, 0, 0);
2386   ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
2387 
2388   SetLastError(ERROR_SUCCESS);
2389   ret = pEnumUILanguagesA(NULL, 0, 0);
2390   ok(!ret, "Expected return value FALSE, got %u\n", ret);
2391   ok(GetLastError() == ERROR_INVALID_PARAMETER,
2392       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2393 
2394   SetLastError(ERROR_SUCCESS);
2395   ret = pEnumUILanguagesA(luilocale_proc3A, 0x5a5a5a5a, 0);
2396   ok(!ret, "Expected return value FALSE, got %u\n", ret);
2397   ok(GetLastError() == ERROR_INVALID_FLAGS, "Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
2398 
2399   SetLastError(ERROR_SUCCESS);
2400   ret = pEnumUILanguagesA(NULL, 0x5a5a5a5a, 0);
2401   ok(!ret, "Expected return value FALSE, got %u\n", ret);
2402   ok(GetLastError() == ERROR_INVALID_PARAMETER,
2403       "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
2404 }
2405 
2406 static char date_fmt_buf[1024];
2407 
2408 static BOOL CALLBACK enum_datetime_procA(LPSTR fmt)
2409 {
2410     lstrcatA(date_fmt_buf, fmt);
2411     lstrcatA(date_fmt_buf, "\n");
2412     return TRUE;
2413 }
2414 
2415 static void test_EnumDateFormatsA(void)
2416 {
2417     char *p, buf[256];
2418     BOOL ret;
2419     LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
2420 
2421     trace("EnumDateFormatsA 0\n");
2422     date_fmt_buf[0] = 0;
2423     SetLastError(0xdeadbeef);
2424     ret = EnumDateFormatsA(enum_datetime_procA, lcid, 0);
2425     if (!ret && (GetLastError() == ERROR_INVALID_FLAGS))
2426     {
2427         win_skip("0 for dwFlags is not supported\n");
2428     }
2429     else
2430     {
2431         ok(ret, "EnumDateFormatsA(0) error %d\n", GetLastError());
2432         trace("%s\n", date_fmt_buf);
2433         /* test the 1st enumerated format */
2434         if ((p = strchr(date_fmt_buf, '\n'))) *p = 0;
2435         ret = GetLocaleInfoA(lcid, LOCALE_SSHORTDATE, buf, sizeof(buf));
2436         ok(ret, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
2437         ok(!lstrcmpA(date_fmt_buf, buf), "expected \"%s\" got \"%s\"\n", date_fmt_buf, buf);
2438     }
2439 
2440     trace("EnumDateFormatsA LOCALE_USE_CP_ACP\n");
2441     date_fmt_buf[0] = 0;
2442     SetLastError(0xdeadbeef);
2443     ret = EnumDateFormatsA(enum_datetime_procA, lcid, LOCALE_USE_CP_ACP);
2444     if (!ret && (GetLastError() == ERROR_INVALID_FLAGS))
2445     {
2446         win_skip("LOCALE_USE_CP_ACP is not supported\n");
2447     }
2448     else
2449     {
2450         ok(ret, "EnumDateFormatsA(LOCALE_USE_CP_ACP) error %d\n", GetLastError());
2451         trace("%s\n", date_fmt_buf);
2452         /* test the 1st enumerated format */
2453         if ((p = strchr(date_fmt_buf, '\n'))) *p = 0;
2454         ret = GetLocaleInfoA(lcid, LOCALE_SSHORTDATE, buf, sizeof(buf));
2455         ok(ret, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
2456         ok(!lstrcmpA(date_fmt_buf, buf), "expected \"%s\" got \"%s\"\n", date_fmt_buf, buf);
2457     }
2458 
2459     trace("EnumDateFormatsA DATE_SHORTDATE\n");
2460     date_fmt_buf[0] = 0;
2461     ret = EnumDateFormatsA(enum_datetime_procA, lcid, DATE_SHORTDATE);
2462     ok(ret, "EnumDateFormatsA(DATE_SHORTDATE) error %d\n", GetLastError());
2463     trace("%s\n", date_fmt_buf);
2464     /* test the 1st enumerated format */
2465     if ((p = strchr(date_fmt_buf, '\n'))) *p = 0;
2466     ret = GetLocaleInfoA(lcid, LOCALE_SSHORTDATE, buf, sizeof(buf));
2467     ok(ret, "GetLocaleInfoA(LOCALE_SSHORTDATE) error %d\n", GetLastError());
2468     ok(!lstrcmpA(date_fmt_buf, buf), "expected \"%s\" got \"%s\"\n", date_fmt_buf, buf);
2469 
2470     trace("EnumDateFormatsA DATE_LONGDATE\n");
2471     date_fmt_buf[0] = 0;
2472     ret = EnumDateFormatsA(enum_datetime_procA, lcid, DATE_LONGDATE);
2473     ok(ret, "EnumDateFormatsA(DATE_LONGDATE) error %d\n", GetLastError());
2474     trace("%s\n", date_fmt_buf);
2475     /* test the 1st enumerated format */
2476     if ((p = strchr(date_fmt_buf, '\n'))) *p = 0;
2477     ret = GetLocaleInfoA(lcid, LOCALE_SLONGDATE, buf, sizeof(buf));
2478     ok(ret, "GetLocaleInfoA(LOCALE_SLONGDATE) error %d\n", GetLastError());
2479     ok(!lstrcmpA(date_fmt_buf, buf), "expected \"%s\" got \"%s\"\n", date_fmt_buf, buf);
2480 
2481     trace("EnumDateFormatsA DATE_YEARMONTH\n");
2482     date_fmt_buf[0] = 0;
2483     SetLastError(0xdeadbeef);
2484     ret = EnumDateFormatsA(enum_datetime_procA, lcid, DATE_YEARMONTH);
2485     if (!ret && (GetLastError() == ERROR_INVALID_FLAGS))
2486     {
2487         skip("DATE_YEARMONTH is only present on W2K and later\n");
2488         return;
2489     }
2490     ok(ret, "EnumDateFormatsA(DATE_YEARMONTH) error %d\n", GetLastError());
2491     trace("%s\n", date_fmt_buf);
2492     /* test the 1st enumerated format */
2493     if ((p = strchr(date_fmt_buf, '\n'))) *p = 0;
2494     ret = GetLocaleInfoA(lcid, LOCALE_SYEARMONTH, buf, sizeof(buf));
2495     ok(ret, "GetLocaleInfoA(LOCALE_SYEARMONTH) error %d\n", GetLastError());
2496     ok(!lstrcmpA(date_fmt_buf, buf) || broken(!buf[0]) /* win9x */,
2497        "expected \"%s\" got \"%s\"\n", date_fmt_buf, buf);
2498 }
2499 
2500 static void test_EnumTimeFormatsA(void)
2501 {
2502     char *p, buf[256];
2503     BOOL ret;
2504     LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
2505 
2506     trace("EnumTimeFormatsA 0\n");
2507     date_fmt_buf[0] = 0;
2508     ret = EnumTimeFormatsA(enum_datetime_procA, lcid, 0);
2509     ok(ret, "EnumTimeFormatsA(0) error %d\n", GetLastError());
2510     trace("%s\n", date_fmt_buf);
2511     /* test the 1st enumerated format */
2512     if ((p = strchr(date_fmt_buf, '\n'))) *p = 0;
2513     ret = GetLocaleInfoA(lcid, LOCALE_STIMEFORMAT, buf, sizeof(buf));
2514     ok(ret, "GetLocaleInfoA(LOCALE_STIMEFORMAT) error %d\n", GetLastError());
2515     ok(!lstrcmpA(date_fmt_buf, buf), "expected \"%s\" got \"%s\"\n", date_fmt_buf, buf);
2516 
2517     trace("EnumTimeFormatsA LOCALE_USE_CP_ACP\n");
2518     date_fmt_buf[0] = 0;
2519     ret = EnumTimeFormatsA(enum_datetime_procA, lcid, LOCALE_USE_CP_ACP);
2520     ok(ret, "EnumTimeFormatsA(LOCALE_USE_CP_ACP) error %d\n", GetLastError());
2521     trace("%s\n", date_fmt_buf);
2522     /* test the 1st enumerated format */
2523     if ((p = strchr(date_fmt_buf, '\n'))) *p = 0;
2524     ret = GetLocaleInfoA(lcid, LOCALE_STIMEFORMAT, buf, sizeof(buf));
2525     ok(ret, "GetLocaleInfoA(LOCALE_STIMEFORMAT) error %d\n", GetLastError());
2526     ok(!lstrcmpA(date_fmt_buf, buf), "expected \"%s\" got \"%s\"\n", date_fmt_buf, buf);
2527 }
2528 
2529 static void test_GetCPInfo(void)
2530 {
2531     BOOL ret;
2532     CPINFO cpinfo;
2533 
2534     SetLastError(0xdeadbeef);
2535     ret = GetCPInfo(CP_SYMBOL, &cpinfo);
2536     ok(!ret, "GetCPInfo(CP_SYMBOL) should fail\n");
2537     ok(GetLastError() == ERROR_INVALID_PARAMETER,
2538        "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
2539 
2540     SetLastError(0xdeadbeef);
2541     ret = GetCPInfo(CP_UTF7, &cpinfo);
2542     if (!ret && GetLastError() == ERROR_INVALID_PARAMETER)
2543     {
2544         skip("Codepage CP_UTF7 is not installed/available\n");
2545     }
2546     else
2547     {
2548         ok(ret, "GetCPInfo(CP_UTF7) error %u\n", GetLastError());
2549         ok(cpinfo.DefaultChar[0] == 0x3f, "expected 0x3f, got 0x%x\n", cpinfo.DefaultChar[0]);
2550         ok(cpinfo.DefaultChar[1] == 0, "expected 0, got 0x%x\n", cpinfo.DefaultChar[1]);
2551         ok(cpinfo.LeadByte[0] == 0, "expected 0, got 0x%x\n", cpinfo.LeadByte[0]);
2552         ok(cpinfo.LeadByte[1] == 0, "expected 0, got 0x%x\n", cpinfo.LeadByte[1]);
2553         ok(cpinfo.MaxCharSize == 5, "expected 5, got 0x%x\n", cpinfo.MaxCharSize);
2554     }
2555 
2556     SetLastError(0xdeadbeef);
2557     ret = GetCPInfo(CP_UTF8, &cpinfo);
2558     if (!ret && GetLastError() == ERROR_INVALID_PARAMETER)
2559     {
2560         skip("Codepage CP_UTF8 is not installed/available\n");
2561     }
2562     else
2563     {
2564         ok(ret, "GetCPInfo(CP_UTF8) error %u\n", GetLastError());
2565         ok(cpinfo.DefaultChar[0] == 0x3f, "expected 0x3f, got 0x%x\n", cpinfo.DefaultChar[0]);
2566         ok(cpinfo.DefaultChar[1] == 0, "expected 0, got 0x%x\n", cpinfo.DefaultChar[1]);
2567         ok(cpinfo.LeadByte[0] == 0, "expected 0, got 0x%x\n", cpinfo.LeadByte[0]);
2568         ok(cpinfo.LeadByte[1] == 0, "expected 0, got 0x%x\n", cpinfo.LeadByte[1]);
2569         ok(cpinfo.MaxCharSize == 4 || broken(cpinfo.MaxCharSize == 3) /* win9x */,
2570            "expected 4, got %u\n", cpinfo.MaxCharSize);
2571     }
2572 }
2573 
2574 START_TEST(locale)
2575 {
2576   InitFunctionPointers();
2577 
2578   test_EnumTimeFormatsA();
2579   test_EnumDateFormatsA();
2580   test_GetLocaleInfoA();
2581   test_GetLocaleInfoW();
2582   test_GetTimeFormatA();
2583   test_GetDateFormatA();
2584   test_GetDateFormatW();
2585   test_GetCurrencyFormatA(); /* Also tests the W version */
2586   test_GetNumberFormatA();   /* Also tests the W version */
2587   test_CompareStringA();
2588   test_LCMapStringA();
2589   test_LCMapStringW();
2590   test_FoldStringA();
2591   test_FoldStringW();
2592   test_ConvertDefaultLocale();
2593   test_EnumSystemLanguageGroupsA();
2594   test_EnumLanguageGroupLocalesA();
2595   test_SetLocaleInfoA();
2596   test_EnumUILanguageA();
2597   test_GetCPInfo();
2598   /* this requires collation table patch to make it MS compatible */
2599   if (0) test_sorting();
2600 }
2601 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.