winex11.drv: Map coordinates before calling send_mouse_input.
[wine/zf.git] / dlls / shlwapi / tests / string.c
blob77c108e38bfb118edbfdb593e914a161f02752f2
1 /* Unit test suite for SHLWAPI string functions
3 * Copyright 2003 Jon Griffiths
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdio.h>
22 #include "wine/test.h"
23 #include "winbase.h"
24 #include "winerror.h"
25 #include "winnls.h"
26 #define NO_SHLWAPI_REG
27 #define NO_SHLWAPI_PATH
28 #define NO_SHLWAPI_GDI
29 #define NO_SHLWAPI_STREAM
30 #include "shlwapi.h"
31 #include "shtypes.h"
33 #define expect_eq(expr, val, type, fmt) do { \
34 type ret = expr; \
35 ok(ret == val, "Unexpected value of '" #expr "': " #fmt " instead of " #val "\n", ret); \
36 } while (0);
38 #define expect_eq2(expr, val1, val2, type, fmt) do { \
39 type ret = expr; \
40 ok(ret == val1 || ret == val2, "Unexpected value of '" #expr "': " #fmt " instead of " #val1 " or " #val2 "\n", ret); \
41 } while (0);
43 static BOOL (WINAPI *pChrCmpIA)(CHAR, CHAR);
44 static BOOL (WINAPI *pChrCmpIW)(WCHAR, WCHAR);
45 static BOOL (WINAPI *pIntlStrEqWorkerA)(BOOL,LPCSTR,LPCSTR,int);
46 static BOOL (WINAPI *pIntlStrEqWorkerW)(BOOL,LPCWSTR,LPCWSTR,int);
47 static DWORD (WINAPI *pSHAnsiToAnsi)(LPCSTR,LPSTR,int);
48 static DWORD (WINAPI *pSHUnicodeToUnicode)(LPCWSTR,LPWSTR,int);
49 static LPSTR (WINAPI *pStrCatBuffA)(LPSTR,LPCSTR,INT);
50 static LPWSTR (WINAPI *pStrCatBuffW)(LPWSTR,LPCWSTR,INT);
51 static DWORD (WINAPI *pStrCatChainW)(LPWSTR,DWORD,DWORD,LPCWSTR);
52 static LPSTR (WINAPI *pStrCpyNXA)(LPSTR,LPCSTR,int);
53 static LPWSTR (WINAPI *pStrCpyNXW)(LPWSTR,LPCWSTR,int);
54 static LPSTR (WINAPI *pStrFormatByteSize64A)(LONGLONG,LPSTR,UINT);
55 static LPSTR (WINAPI *pStrFormatKBSizeA)(LONGLONG,LPSTR,UINT);
56 static LPWSTR (WINAPI *pStrFormatKBSizeW)(LONGLONG,LPWSTR,UINT);
57 static BOOL (WINAPI *pStrIsIntlEqualA)(BOOL,LPCSTR,LPCSTR,int);
58 static BOOL (WINAPI *pStrIsIntlEqualW)(BOOL,LPCWSTR,LPCWSTR,int);
59 static LPWSTR (WINAPI *pStrPBrkW)(LPCWSTR,LPCWSTR);
60 static LPSTR (WINAPI *pStrRChrA)(LPCSTR,LPCSTR,WORD);
61 static HRESULT (WINAPI *pStrRetToBSTR)(STRRET*,LPCITEMIDLIST,BSTR*);
62 static HRESULT (WINAPI *pStrRetToBufA)(STRRET*,LPCITEMIDLIST,LPSTR,UINT);
63 static HRESULT (WINAPI *pStrRetToBufW)(STRRET*,LPCITEMIDLIST,LPWSTR,UINT);
64 static LPWSTR (WINAPI *pStrStrNW)(LPCWSTR,LPCWSTR,UINT);
65 static LPWSTR (WINAPI *pStrStrNIW)(LPCWSTR,LPCWSTR,UINT);
66 static INT (WINAPIV *pwnsprintfA)(LPSTR,INT,LPCSTR, ...);
67 static INT (WINAPIV *pwnsprintfW)(LPWSTR,INT,LPCWSTR, ...);
68 static LPWSTR (WINAPI *pStrChrNW)(LPCWSTR,WCHAR,UINT);
69 static BOOL (WINAPI *pStrToInt64ExA)(LPCSTR,DWORD,LONGLONG*);
70 static BOOL (WINAPI *pStrToInt64ExW)(LPCWSTR,DWORD,LONGLONG*);
72 /* StrToInt/StrToIntEx results */
73 typedef struct tagStrToIntResult
75 const char* string;
76 int str_to_int;
77 LONGLONG str_to_int64_ex;
78 LONGLONG str_to_int64_hex;
79 BOOL failure;
80 } StrToIntResult;
82 static const StrToIntResult StrToInt_results[] = {
83 { "1099", 1099, 1099, 1099 },
84 { "4294967319", 23, ((LONGLONG)1 << 32) | 23, ((LONGLONG)1 << 32) | 23 },
85 { "+88987", 0, 88987, 88987 },
86 { "012", 12, 12, 12 },
87 { "-55", -55, -55, -55 },
88 { "-0", 0, 0, 0 },
89 { "0x44ff", 0, 0, 0x44ff },
90 { "0x2bdc546291f4b1", 0, 0, ((LONGLONG)0x2bdc54 << 32) | 0x6291f4b1 },
91 { "+0x44f4", 0, 0, 0x44f4 },
92 { "-0x44fd", 0, 0, 0x44fd },
93 { "+ 88987", 0, 0, 0, TRUE },
95 { "- 55", 0, 0, 0, TRUE },
96 { "- 0", 0, 0, 0, TRUE },
97 { "+ 0x44f4", 0, 0, 0, TRUE },
98 { "--0x44fd", 0, 0, 0, TRUE },
99 { " 1999", 0, 1999, 1999 },
100 { " +88987", 0, 88987, 88987 },
101 { " 012", 0, 12, 12 },
102 { " -55", 0, -55, -55 },
103 { " 0x44ff", 0, 0, 0x44ff },
104 { " +0x44f4", 0, 0, 0x44f4 },
105 { " -0x44fd", 0, 0, 0x44fd },
106 { "\t\n +3", 0, 3, 3 },
107 { "\v+4", 0, 0, 0, TRUE },
108 { "\f+5", 0, 0, 0, TRUE },
109 { "\r+6", 0, 0, 0, TRUE },
110 { NULL, 0, 0, 0 }
113 /* pStrFormatByteSize64/StrFormatKBSize results */
114 typedef struct tagStrFormatSizeResult
116 LONGLONG value;
117 const char* byte_size_64;
118 const char* kb_size;
119 int kb_size_broken;
120 const char* kb_size2;
121 } StrFormatSizeResult;
124 static const StrFormatSizeResult StrFormatSize_results[] = {
125 { -1023, "-1023 bytes", "0 KB"},
126 { -24, "-24 bytes", "0 KB"},
127 { 309, "309 bytes", "1 KB"},
128 { 10191, "9.95 KB", "10 KB"},
129 { 100353, "98.0 KB", "99 KB"},
130 { 1022286, "998 KB", "999 KB"},
131 { 1046862, "0.99 MB", "1,023 KB", 1, "1023 KB"},
132 { 1048574619, "999 MB", "1,023,999 KB", 1, "1023999 KB"},
133 { 1073741775, "0.99 GB", "1,048,576 KB", 1, "1048576 KB"},
134 { ((LONGLONG)0x000000f9 << 32) | 0xfffff94e, "999 GB", "1,048,575,999 KB", 1, "1048575999 KB"},
135 { ((LONGLONG)0x000000ff << 32) | 0xfffffa9b, "0.99 TB", "1,073,741,823 KB", 1, "1073741823 KB"},
136 { ((LONGLONG)0x0003e7ff << 32) | 0xfffffa9b, "999 TB", "1,073,741,823,999 KB", 1, "4294967295 KB"},
137 { ((LONGLONG)0x0003ffff << 32) | 0xfffffbe8, "0.99 PB", "1,099,511,627,775 KB", 1, "4294967295 KB"},
138 { ((LONGLONG)0x0f9fffff << 32) | 0xfffffd35, "999 PB", "1,099,511,627,776,000 KB", 1, "0 KB"},
139 { ((LONGLONG)0x0fffffff << 32) | 0xfffffa9b, "0.99 EB", "1,125,899,906,842,623 KB", 1, "4294967295 KB"},
140 { 0, NULL, NULL }
143 /* StrFromTimeIntervalA/StrFromTimeIntervalW results */
144 typedef struct tagStrFromTimeIntervalResult
146 DWORD ms;
147 int digits;
148 const char* time_interval;
149 } StrFromTimeIntervalResult;
152 static const StrFromTimeIntervalResult StrFromTimeInterval_results[] = {
153 { 1, 1, " 0 sec" },
154 { 1, 2, " 0 sec" },
155 { 1, 3, " 0 sec" },
156 { 1, 4, " 0 sec" },
157 { 1, 5, " 0 sec" },
158 { 1, 6, " 0 sec" },
159 { 1, 7, " 0 sec" },
161 { 1000000, 1, " 10 min" },
162 { 1000000, 2, " 16 min" },
163 { 1000000, 3, " 16 min 40 sec" },
164 { 1000000, 4, " 16 min 40 sec" },
165 { 1000000, 5, " 16 min 40 sec" },
166 { 1000000, 6, " 16 min 40 sec" },
167 { 1000000, 7, " 16 min 40 sec" },
169 { 1999999, 1, " 30 min" },
170 { 1999999, 2, " 33 min" },
171 { 1999999, 3, " 33 min 20 sec" },
172 { 1999999, 4, " 33 min 20 sec" },
173 { 1999999, 5, " 33 min 20 sec" },
174 { 1999999, 6, " 33 min 20 sec" },
175 { 1999999, 7, " 33 min 20 sec" },
177 { 3999997, 1, " 1 hr" },
178 { 3999997, 2, " 1 hr 6 min" },
179 { 3999997, 3, " 1 hr 6 min 40 sec" },
180 { 3999997, 4, " 1 hr 6 min 40 sec" },
181 { 3999997, 5, " 1 hr 6 min 40 sec" },
182 { 3999997, 6, " 1 hr 6 min 40 sec" },
183 { 3999997, 7, " 1 hr 6 min 40 sec" },
185 { 149999851, 7, " 41 hr 40 min 0 sec" },
186 { 150999850, 1, " 40 hr" },
187 { 150999850, 2, " 41 hr" },
188 { 150999850, 3, " 41 hr 50 min" },
189 { 150999850, 4, " 41 hr 56 min" },
190 { 150999850, 5, " 41 hr 56 min 40 sec" },
191 { 150999850, 6, " 41 hr 56 min 40 sec" },
192 { 150999850, 7, " 41 hr 56 min 40 sec" },
194 { 493999507, 1, " 100 hr" },
195 { 493999507, 2, " 130 hr" },
196 { 493999507, 3, " 137 hr" },
197 { 493999507, 4, " 137 hr 10 min" },
198 { 493999507, 5, " 137 hr 13 min" },
199 { 493999507, 6, " 137 hr 13 min 20 sec" },
200 { 493999507, 7, " 137 hr 13 min 20 sec" },
202 { 0, 0, NULL }
206 /* Returns true if the user interface is in English. Note that this does not
207 * presume of the formatting of dates, numbers, etc.
209 static BOOL is_lang_english(void)
211 static HMODULE hkernel32 = NULL;
212 static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
213 static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
215 if (!hkernel32)
217 hkernel32 = GetModuleHandleA("kernel32.dll");
218 pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
219 pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
221 if (pGetThreadUILanguage)
222 return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH;
223 if (pGetUserDefaultUILanguage)
224 return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH;
226 return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
229 /* Returns true if the dates, numbers, etc. are formatted using English
230 * conventions.
232 static BOOL is_locale_english(void)
234 /* Surprisingly GetThreadLocale() is irrelevant here */
235 return PRIMARYLANGID(GetUserDefaultLangID()) == LANG_ENGLISH;
238 static void test_StrChrA(void)
240 char string[129];
241 WORD count;
243 /* this test crashes on win2k SP4 */
244 /*ok(!StrChrA(NULL,'\0'), "found a character in a NULL string!\n");*/
246 for (count = 32; count < 128; count++)
247 string[count] = (char)count;
248 string[128] = '\0';
250 for (count = 32; count < 128; count++)
252 LPSTR result = StrChrA(string+32, count);
253 INT pos = result - string;
254 ok(pos == count, "found char '%c' in wrong place: got %d, expected %d\n", count, pos, count);
257 for (count = 32; count < 128; count++)
259 LPSTR result = StrChrA(string+count+1, count);
260 ok(!result, "found char '%c' not in the string\n", count);
264 static void test_StrChrW(void)
266 WCHAR string[16385];
267 WORD count;
269 /* this test crashes on win2k SP4 */
270 /*ok(!StrChrW(NULL,'\0'), "found a character in a NULL string!\n");*/
272 for (count = 32; count < 16384; count++)
273 string[count] = count;
274 string[16384] = '\0';
276 for (count = 32; count < 16384; count++)
278 LPWSTR result = StrChrW(string+32, count);
279 ok((result - string) == count, "found char %d in wrong place\n", count);
282 for (count = 32; count < 16384; count++)
284 LPWSTR result = StrChrW(string+count+1, count);
285 ok(!result, "found char not in the string\n");
289 static void test_StrChrIA(void)
291 char string[129];
292 WORD count;
294 /* this test crashes on win2k SP4 */
295 /*ok(!StrChrIA(NULL,'\0'), "found a character in a NULL string!\n");*/
297 for (count = 32; count < 128; count++)
298 string[count] = (char)count;
299 string[128] = '\0';
301 for (count = 'A'; count <= 'X'; count++)
303 LPSTR result = StrChrIA(string+32, count);
305 ok(result - string == count, "found char '%c' in wrong place\n", count);
306 ok(StrChrIA(result, count)!=NULL, "didn't find lowercase '%c'\n", count);
309 for (count = 'a'; count < 'z'; count++)
311 LPSTR result = StrChrIA(string+count+1, count);
312 ok(!result, "found char not in the string\n");
316 static void test_StrChrIW(void)
318 WCHAR string[129];
319 WORD count;
321 /* this test crashes on win2k SP4 */
322 /*ok(!StrChrIA(NULL,'\0'), "found a character in a NULL string!\n");*/
324 for (count = 32; count < 128; count++)
325 string[count] = count;
326 string[128] = '\0';
328 for (count = 'A'; count <= 'X'; count++)
330 LPWSTR result = StrChrIW(string+32, count);
332 ok(result - string == count, "found char '%c' in wrong place\n", count);
333 ok(StrChrIW(result, count)!=NULL, "didn't find lowercase '%c'\n", count);
336 for (count = 'a'; count < 'z'; count++)
338 LPWSTR result = StrChrIW(string+count+1, count);
339 ok(!result, "found char not in the string\n");
343 static void test_StrRChrA(void)
345 char string[129];
346 WORD count;
348 /* this test crashes on win2k SP4 */
349 /*ok(!StrRChrA(NULL, NULL,'\0'), "found a character in a NULL string!\n");*/
351 for (count = 32; count < 128; count++)
352 string[count] = (char)count;
353 string[128] = '\0';
355 for (count = 32; count < 128; count++)
357 LPSTR result = StrRChrA(string+32, NULL, count);
358 ok(result - string == count, "found char %d in wrong place\n", count);
361 for (count = 32; count < 128; count++)
363 LPSTR result = StrRChrA(string+count+1, NULL, count);
364 ok(!result, "found char not in the string\n");
367 for (count = 32; count < 128; count++)
369 LPSTR result = StrRChrA(string+count+1, string + 127, count);
370 ok(!result, "found char not in the string\n");
374 static void test_StrRChrW(void)
376 WCHAR string[129];
377 WORD count;
379 /* this test crashes on win2k SP4 */
380 /*ok(!StrRChrW(NULL, NULL,'\0'), "found a character in a NULL string!\n");*/
382 for (count = 32; count < 128; count++)
383 string[count] = count;
384 string[128] = '\0';
386 for (count = 32; count < 128; count++)
388 LPWSTR result = StrRChrW(string+32, NULL, count);
389 INT pos = result - string;
390 ok(pos == count, "found char %d in wrong place: got %d, expected %d\n", count, pos, count);
393 for (count = 32; count < 128; count++)
395 LPWSTR result = StrRChrW(string+count+1, NULL, count);
396 ok(!result, "found char %d not in the string\n", count);
399 for (count = 32; count < 128; count++)
401 LPWSTR result = StrRChrW(string+count+1, string + 127, count);
402 ok(!result, "found char %d not in the string\n", count);
406 static void test_StrCpyW(void)
408 WCHAR szSrc[256];
409 WCHAR szBuff[256];
410 const StrFormatSizeResult* result = StrFormatSize_results;
411 LPWSTR lpRes;
413 while(result->value)
415 MultiByteToWideChar(CP_ACP, 0, result->byte_size_64, -1, szSrc, ARRAY_SIZE(szSrc));
417 lpRes = StrCpyW(szBuff, szSrc);
418 ok(!StrCmpW(szSrc, szBuff) && lpRes == szBuff, "Copied string %s wrong\n", result->byte_size_64);
419 result++;
422 /* this test crashes on win2k SP4 */
423 /*lpRes = StrCpyW(szBuff, NULL);*/
424 /*ok(lpRes == szBuff, "Wrong return value: got %p expected %p\n", lpRes, szBuff);*/
426 /* this test crashes on win2k SP4 */
427 /*lpRes = StrCpyW(NULL, szSrc);*/
428 /*ok(lpRes == NULL, "Wrong return value: got %p expected NULL\n", lpRes);*/
430 /* this test crashes on win2k SP4 */
431 /*lpRes = StrCpyW(NULL, NULL);*/
432 /*ok(lpRes == NULL, "Wrong return value: got %p expected NULL\n", lpRes);*/
435 static void test_StrChrNW(void)
437 static const WCHAR string[] = {'T','e','s','t','i','n','g',' ','S','t','r','i','n','g',0};
438 LPWSTR p;
440 if (!pStrChrNW)
442 win_skip("StrChrNW not available\n");
443 return;
446 p = pStrChrNW(string,'t',10);
447 ok(*p=='t',"Found wrong 't'\n");
448 ok(*(p+1)=='i',"next should be 'i'\n");
450 p = pStrChrNW(string,'S',10);
451 ok(*p=='S',"Found wrong 'S'\n");
453 p = pStrChrNW(string,'r',10);
454 ok(p==NULL,"Should not have found 'r'\n");
457 static void test_StrToIntA(void)
459 const StrToIntResult *result = StrToInt_results;
460 int return_val;
462 while (result->string)
464 return_val = StrToIntA(result->string);
465 ok(return_val == result->str_to_int, "converted '%s' wrong (%d)\n",
466 result->string, return_val);
467 result++;
471 static void test_StrToIntW(void)
473 WCHAR szBuff[256];
474 const StrToIntResult *result = StrToInt_results;
475 int return_val;
477 while (result->string)
479 MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
480 return_val = StrToIntW(szBuff);
481 ok(return_val == result->str_to_int, "converted '%s' wrong (%d)\n",
482 result->string, return_val);
483 result++;
487 static void test_StrToIntExA(void)
489 const StrToIntResult *result = StrToInt_results;
490 int return_val;
491 BOOL bRet;
493 while (result->string)
495 return_val = -1;
496 bRet = StrToIntExA(result->string,0,&return_val);
497 if (result->failure)
498 ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string);
499 else
500 ok(bRet, "Failed for '%s'\n", result->string);
501 if (bRet)
502 ok(return_val == (int)result->str_to_int64_ex, "converted '%s' wrong (%d)\n",
503 result->string, return_val);
504 result++;
507 result = StrToInt_results;
508 while (result->string)
510 return_val = -1;
511 bRet = StrToIntExA(result->string,STIF_SUPPORT_HEX,&return_val);
512 if (result->failure)
513 ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string);
514 else
515 ok(bRet, "Failed for '%s'\n", result->string);
516 if (bRet)
517 ok(return_val == (int)result->str_to_int64_hex, "converted '%s' wrong (%d)\n",
518 result->string, return_val);
519 result++;
523 static void test_StrToIntExW(void)
525 WCHAR szBuff[256];
526 const StrToIntResult *result = StrToInt_results;
527 int return_val;
528 BOOL bRet;
530 while (result->string)
532 return_val = -1;
533 MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
534 bRet = StrToIntExW(szBuff, 0, &return_val);
535 if (result->failure)
536 ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string);
537 else
538 ok(bRet, "Failed for '%s'\n", result->string);
539 if (bRet)
540 ok(return_val == (int)result->str_to_int64_ex, "converted '%s' wrong (%d)\n",
541 result->string, return_val);
542 result++;
545 result = StrToInt_results;
546 while (result->string)
548 return_val = -1;
549 MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
550 bRet = StrToIntExW(szBuff, STIF_SUPPORT_HEX, &return_val);
551 if (result->failure)
552 ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string);
553 else
554 ok(bRet, "Failed for '%s'\n", result->string);
555 if (bRet)
556 ok(return_val == (int)result->str_to_int64_hex, "converted '%s' wrong (%d)\n",
557 result->string, return_val);
558 result++;
561 return_val = -1;
562 bRet = StrToIntExW(L"\x0661\x0662", 0, &return_val);
563 ok( !bRet, "Returned %d for Unicode digits\n", return_val );
564 bRet = StrToIntExW(L"\x07c3\x07c4", 0, &return_val);
565 ok( !bRet, "Returned %d for Unicode digits\n", return_val );
566 bRet = StrToIntExW(L"\xa0-2", 0, &return_val);
567 ok( !bRet, "Returned %d for Unicode space\n", return_val );
570 static void test_StrToInt64ExA(void)
572 const StrToIntResult *result = StrToInt_results;
573 LONGLONG return_val;
574 BOOL bRet;
576 if (!pStrToInt64ExA)
578 win_skip("StrToInt64ExA() is not available\n");
579 return;
582 while (result->string)
584 return_val = -1;
585 bRet = pStrToInt64ExA(result->string,0,&return_val);
586 if (result->failure)
587 ok(!bRet, "Got %s instead of failure for '%s'\n",
588 wine_dbgstr_longlong(return_val), result->string);
589 else
590 ok(bRet, "Failed for '%s'\n", result->string);
591 if (bRet)
592 ok(return_val == result->str_to_int64_ex, "converted '%s' wrong (%s)\n",
593 result->string, wine_dbgstr_longlong(return_val));
594 result++;
597 result = StrToInt_results;
598 while (result->string)
600 return_val = -1;
601 bRet = pStrToInt64ExA(result->string,STIF_SUPPORT_HEX,&return_val);
602 if (result->failure)
603 ok(!bRet, "Got %s instead of failure for '%s'\n",
604 wine_dbgstr_longlong(return_val), result->string);
605 else
606 ok(bRet, "Failed for '%s'\n", result->string);
607 if (bRet)
608 ok(return_val == result->str_to_int64_hex, "converted '%s' wrong (%s)\n",
609 result->string, wine_dbgstr_longlong(return_val));
610 result++;
614 static void test_StrToInt64ExW(void)
616 WCHAR szBuff[256];
617 const StrToIntResult *result = StrToInt_results;
618 LONGLONG return_val;
619 BOOL bRet;
621 if (!pStrToInt64ExW)
623 win_skip("StrToInt64ExW() is not available\n");
624 return;
627 while (result->string)
629 return_val = -1;
630 MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
631 bRet = pStrToInt64ExW(szBuff, 0, &return_val);
632 if (result->failure)
633 ok(!bRet, "Got %s instead of failure for '%s'\n",
634 wine_dbgstr_longlong(return_val), result->string);
635 else
636 ok(bRet, "Failed for '%s'\n", result->string);
637 if (bRet)
638 ok(return_val == result->str_to_int64_ex, "converted '%s' wrong (%s)\n",
639 result->string, wine_dbgstr_longlong(return_val));
640 result++;
643 result = StrToInt_results;
644 while (result->string)
646 return_val = -1;
647 MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
648 bRet = pStrToInt64ExW(szBuff, STIF_SUPPORT_HEX, &return_val);
649 if (result->failure)
650 ok(!bRet, "Got %s instead of failure for '%s'\n",
651 wine_dbgstr_longlong(return_val), result->string);
652 else
653 ok(bRet, "Failed for '%s'\n", result->string);
654 if (bRet)
655 ok(return_val == result->str_to_int64_hex, "converted '%s' wrong (%s)\n",
656 result->string, wine_dbgstr_longlong(return_val));
657 result++;
660 return_val = -1;
661 bRet = pStrToInt64ExW(L"\x0661\x0662", 0, &return_val);
662 ok( !bRet, "Returned %s for Unicode digits\n", wine_dbgstr_longlong(return_val) );
663 bRet = pStrToInt64ExW(L"\x07c3\x07c4", 0, &return_val);
664 ok( !bRet, "Returned %s for Unicode digits\n", wine_dbgstr_longlong(return_val) );
665 bRet = pStrToInt64ExW(L"\xa0-2", 0, &return_val);
666 ok( !bRet, "Returned %s for Unicode space\n", wine_dbgstr_longlong(return_val) );
669 static void test_StrDupA(void)
671 LPSTR lpszStr;
672 const StrFormatSizeResult* result = StrFormatSize_results;
674 while(result->value)
676 lpszStr = StrDupA(result->byte_size_64);
678 ok(lpszStr != NULL, "Dup failed\n");
679 if (lpszStr)
681 ok(!strcmp(result->byte_size_64, lpszStr), "Copied string wrong\n");
682 LocalFree(lpszStr);
684 result++;
687 /* Later versions of shlwapi return NULL for this, but earlier versions
688 * returned an empty string (as Wine does).
690 lpszStr = StrDupA(NULL);
691 ok(lpszStr == NULL || *lpszStr == '\0', "NULL string returned %p\n", lpszStr);
692 LocalFree(lpszStr);
695 static void test_StrFormatByteSize64A(void)
697 char szBuff[256];
698 const StrFormatSizeResult* result = StrFormatSize_results;
700 if (!pStrFormatByteSize64A)
702 win_skip("StrFormatByteSize64A() is not available\n");
703 return;
706 while(result->value)
708 pStrFormatByteSize64A(result->value, szBuff, 256);
710 ok(!strcmp(result->byte_size_64, szBuff),
711 "Formatted %s wrong: got %s, expected %s\n",
712 wine_dbgstr_longlong(result->value), szBuff, result->byte_size_64);
714 result++;
718 static void test_StrFormatKBSizeW(void)
720 WCHAR szBuffW[256];
721 char szBuff[256];
722 const StrFormatSizeResult* result = StrFormatSize_results;
724 if (!pStrFormatKBSizeW)
726 win_skip("StrFormatKBSizeW() is not available\n");
727 return;
730 while(result->value)
732 pStrFormatKBSizeW(result->value, szBuffW, 256);
733 WideCharToMultiByte(CP_ACP, 0, szBuffW, -1, szBuff, ARRAY_SIZE(szBuff), NULL, NULL);
735 ok(!strcmp(result->kb_size, szBuff), "Formatted %s wrong: got %s, expected %s\n",
736 wine_dbgstr_longlong(result->value), szBuff, result->kb_size);
737 result++;
741 static void test_StrFormatKBSizeA(void)
743 char szBuff[256];
744 const StrFormatSizeResult* result = StrFormatSize_results;
746 if (!pStrFormatKBSizeA)
748 win_skip("StrFormatKBSizeA() is not available\n");
749 return;
752 while(result->value)
754 pStrFormatKBSizeA(result->value, szBuff, 256);
756 /* shlwapi on Win98 SE does not appear to apply delimiters to the output
757 * and does not correctly handle extremely large values. */
758 ok(!strcmp(result->kb_size, szBuff) ||
759 (result->kb_size_broken && !strcmp(result->kb_size2, szBuff)),
760 "Formatted %s wrong: got %s, expected %s\n",
761 wine_dbgstr_longlong(result->value), szBuff, result->kb_size);
762 result++;
766 static void test_StrFromTimeIntervalA(void)
768 char szBuff[256];
769 const StrFromTimeIntervalResult* result = StrFromTimeInterval_results;
771 while(result->ms)
773 StrFromTimeIntervalA(szBuff, 256, result->ms, result->digits);
775 ok(!strcmp(result->time_interval, szBuff), "Formatted %d %d wrong: %s\n",
776 result->ms, result->digits, szBuff);
777 result++;
781 static void test_StrCmpA(void)
783 static const char str1[] = {'a','b','c','d','e','f'};
784 static const char str2[] = {'a','B','c','d','e','f'};
785 ok(0 != StrCmpNA(str1, str2, 6), "StrCmpNA is case-insensitive\n");
786 ok(0 == StrCmpNIA(str1, str2, 6), "StrCmpNIA is case-sensitive\n");
787 if (pChrCmpIA) {
788 ok(!pChrCmpIA('a', 'a'), "ChrCmpIA doesn't work at all!\n");
789 ok(!pChrCmpIA('b', 'B'), "ChrCmpIA is not case-insensitive\n");
790 ok(pChrCmpIA('a', 'z'), "ChrCmpIA believes that a == z!\n");
792 else
793 win_skip("ChrCmpIA() is not available\n");
795 if (pStrIsIntlEqualA)
797 ok(pStrIsIntlEqualA(FALSE, str1, str2, 5), "StrIsIntlEqualA(FALSE,...) isn't case-insensitive\n");
798 ok(!pStrIsIntlEqualA(TRUE, str1, str2, 5), "StrIsIntlEqualA(TRUE,...) isn't case-sensitive\n");
800 else
801 win_skip("StrIsIntlEqualA() is not available\n");
803 if (pIntlStrEqWorkerA)
805 ok(pIntlStrEqWorkerA(FALSE, str1, str2, 5), "IntlStrEqWorkerA(FALSE,...) isn't case-insensitive\n");
806 ok(!pIntlStrEqWorkerA(TRUE, str1, str2, 5), "pIntlStrEqWorkerA(TRUE,...) isn't case-sensitive\n");
808 else
809 win_skip("IntlStrEqWorkerA() is not available\n");
812 static void test_StrCmpW(void)
814 static const WCHAR str1[] = {'a','b','c','d','e','f'};
815 static const WCHAR str2[] = {'a','B','c','d','e','f'};
816 ok(0 != StrCmpNW(str1, str2, 5), "StrCmpNW is case-insensitive\n");
817 ok(0 == StrCmpNIW(str1, str2, 5), "StrCmpNIW is case-sensitive\n");
818 if (pChrCmpIW) {
819 ok(!pChrCmpIW('a', 'a'), "ChrCmpIW doesn't work at all!\n");
820 ok(!pChrCmpIW('b', 'B'), "ChrCmpIW is not case-insensitive\n");
821 ok(pChrCmpIW('a', 'z'), "ChrCmpIW believes that a == z!\n");
823 else
824 win_skip("ChrCmpIW() is not available\n");
826 if (pStrIsIntlEqualW)
828 ok(pStrIsIntlEqualW(FALSE, str1, str2, 5), "StrIsIntlEqualW(FALSE,...) isn't case-insensitive\n");
829 ok(!pStrIsIntlEqualW(TRUE, str1, str2, 5), "StrIsIntlEqualW(TRUE,...) isn't case-sensitive\n");
831 else
832 win_skip("StrIsIntlEqualW() is not available\n");
834 if (pIntlStrEqWorkerW)
836 ok(pIntlStrEqWorkerW(FALSE, str1, str2, 5), "IntlStrEqWorkerW(FALSE,...) isn't case-insensitive\n");
837 ok(!pIntlStrEqWorkerW(TRUE, str1, str2, 5), "IntlStrEqWorkerW(TRUE,...) isn't case-sensitive\n");
839 else
840 win_skip("IntlStrEqWorkerW() is not available\n");
843 static WCHAR *CoDupStrW(const char* src)
845 INT len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
846 WCHAR* szTemp = CoTaskMemAlloc(len * sizeof(WCHAR));
847 MultiByteToWideChar(CP_ACP, 0, src, -1, szTemp, len);
848 return szTemp;
851 static void test_StrRetToBSTR(void)
853 static const WCHAR szTestW[] = { 'T','e','s','t','\0' };
854 ITEMIDLIST iidl[10];
855 BSTR bstr;
856 STRRET strret;
857 HRESULT ret;
859 if (!pStrRetToBSTR)
861 win_skip("StrRetToBSTR() is not available\n");
862 return;
865 strret.uType = STRRET_WSTR;
866 U(strret).pOleStr = CoDupStrW("Test");
867 bstr = 0;
868 ret = pStrRetToBSTR(&strret, NULL, &bstr);
869 ok(ret == S_OK && bstr && !wcscmp(bstr, szTestW),
870 "STRRET_WSTR: dup failed, ret=0x%08x, bstr %p\n", ret, bstr);
871 SysFreeString(bstr);
873 strret.uType = STRRET_CSTR;
874 lstrcpyA(U(strret).cStr, "Test");
875 ret = pStrRetToBSTR(&strret, NULL, &bstr);
876 ok(ret == S_OK && bstr && !wcscmp(bstr, szTestW),
877 "STRRET_CSTR: dup failed, ret=0x%08x, bstr %p\n", ret, bstr);
878 SysFreeString(bstr);
880 strret.uType = STRRET_OFFSET;
881 U(strret).uOffset = 1;
882 strcpy((char*)&iidl, " Test");
883 ret = pStrRetToBSTR(&strret, iidl, &bstr);
884 ok(ret == S_OK && bstr && !wcscmp(bstr, szTestW),
885 "STRRET_OFFSET: dup failed, ret=0x%08x, bstr %p\n", ret, bstr);
886 SysFreeString(bstr);
888 /* Native crashes if str is NULL */
891 static void test_StrCpyNXA(void)
893 LPCSTR lpSrc = "hello";
894 LPSTR lpszRes;
895 char dest[8];
897 if (!pStrCpyNXA)
899 win_skip("StrCpyNXA() is not available\n");
900 return;
903 memset(dest, '\n', sizeof(dest));
904 lpszRes = pStrCpyNXA(dest, lpSrc, ARRAY_SIZE(dest));
905 ok(lpszRes == dest + 5 && !memcmp(dest, "hello\0\n\n", sizeof(dest)),
906 "StrCpyNXA: expected %p, \"hello\\0\\n\\n\", got %p, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
907 dest + 5, lpszRes, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
910 static void test_StrCpyNXW(void)
912 static const WCHAR lpInit[] = { '\n','\n','\n','\n','\n','\n','\n','\n' };
913 static const WCHAR lpSrc[] = { 'h','e','l','l','o','\0' };
914 static const WCHAR lpRes[] = { 'h','e','l','l','o','\0','\n','\n' };
915 LPWSTR lpszRes;
916 WCHAR dest[8];
918 if (!pStrCpyNXW)
920 win_skip("StrCpyNXW() is not available\n");
921 return;
924 memcpy(dest, lpInit, sizeof(lpInit));
925 lpszRes = pStrCpyNXW(dest, lpSrc, ARRAY_SIZE(dest));
926 ok(lpszRes == dest + 5 && !memcmp(dest, lpRes, sizeof(dest)),
927 "StrCpyNXW: expected %p, \"hello\\0\\n\\n\", got %p, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
928 dest + 5, lpszRes, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
931 #define check_strrstri(type, str, pos, needle, exp) \
932 ret##type = StrRStrI##type(str, str+pos, needle); \
933 ok(ret##type == (exp), "Type " #type ", expected %p but got %p (string base %p)\n", \
934 (exp), ret##type, str);
936 static void test_StrRStrI(void)
938 static const CHAR szTest[] = "yAxxxxAy";
939 static const CHAR szTest2[] = "ABABABAB";
940 static const WCHAR wszTest[] = {'y','A','x','x','x','x','A','y',0};
941 static const WCHAR wszTest2[] = {'A','B','A','B','A','B','A','B',0};
943 static const WCHAR wszPattern1[] = {'A',0};
944 static const WCHAR wszPattern2[] = {'a','X',0};
945 static const WCHAR wszPattern3[] = {'A','y',0};
946 static const WCHAR wszPattern4[] = {'a','b',0};
947 LPWSTR retW;
948 LPSTR retA;
950 check_strrstri(A, szTest, 4, "A", szTest+1);
951 check_strrstri(A, szTest, 4, "aX", szTest+1);
952 check_strrstri(A, szTest, 4, "Ay", NULL);
953 check_strrstri(W, wszTest, 4, wszPattern1, wszTest+1);
954 check_strrstri(W, wszTest, 4, wszPattern2, wszTest+1);
955 check_strrstri(W, wszTest, 4, wszPattern3, NULL);
957 check_strrstri(A, szTest2, 4, "ab", szTest2+2);
958 check_strrstri(A, szTest2, 3, "ab", szTest2+2);
959 check_strrstri(A, szTest2, 2, "ab", szTest2);
960 check_strrstri(A, szTest2, 1, "ab", szTest2);
961 check_strrstri(A, szTest2, 0, "ab", NULL);
962 check_strrstri(W, wszTest2, 4, wszPattern4, wszTest2+2);
963 check_strrstri(W, wszTest2, 3, wszPattern4, wszTest2+2);
964 check_strrstri(W, wszTest2, 2, wszPattern4, wszTest2);
965 check_strrstri(W, wszTest2, 1, wszPattern4, wszTest2);
966 check_strrstri(W, wszTest2, 0, wszPattern4, NULL);
970 static void test_SHAnsiToAnsi(void)
972 char dest[8];
973 DWORD dwRet;
975 if (!pSHAnsiToAnsi)
977 win_skip("SHAnsiToAnsi() is not available\n");
978 return;
981 if (pSHAnsiToAnsi == (void *)pStrPBrkW)
983 win_skip("Ordinal 345 corresponds to StrPBrkW, skipping SHAnsiToAnsi tests\n");
984 return;
987 memset(dest, '\n', sizeof(dest));
988 dwRet = pSHAnsiToAnsi("hello", dest, ARRAY_SIZE(dest));
989 ok(dwRet == 6 && !memcmp(dest, "hello\0\n\n", sizeof(dest)),
990 "SHAnsiToAnsi: expected 6, \"hello\\0\\n\\n\", got %d, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
991 dwRet, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
994 static void test_SHUnicodeToUnicode(void)
996 static const WCHAR lpInit[] = { '\n','\n','\n','\n','\n','\n','\n','\n' };
997 static const WCHAR lpSrc[] = { 'h','e','l','l','o','\0' };
998 static const WCHAR lpRes[] = { 'h','e','l','l','o','\0','\n','\n' };
999 WCHAR dest[8];
1000 DWORD dwRet;
1002 if (!pSHUnicodeToUnicode)
1004 win_skip("SHUnicodeToUnicode() is not available\n");
1005 return;
1008 if (pSHUnicodeToUnicode == (void *)pStrRChrA)
1010 win_skip("Ordinal 346 corresponds to StrRChrA, skipping SHUnicodeToUnicode tests\n");
1011 return;
1014 memcpy(dest, lpInit, sizeof(lpInit));
1015 dwRet = pSHUnicodeToUnicode(lpSrc, dest, ARRAY_SIZE(dest));
1016 ok(dwRet == 6 && !memcmp(dest, lpRes, sizeof(dest)),
1017 "SHUnicodeToUnicode: expected 6, \"hello\\0\\n\\n\", got %d, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
1018 dwRet, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
1021 static void test_StrXXX_overflows(void)
1023 CHAR str1[2*MAX_PATH+1], buf[2*MAX_PATH];
1024 WCHAR wstr1[2*MAX_PATH+1], wbuf[2*MAX_PATH];
1025 const WCHAR fmt[] = {'%','s',0};
1026 STRRET strret;
1027 HRESULT hres;
1028 int ret;
1029 int i;
1031 for (i=0; i<2*MAX_PATH; i++)
1033 str1[i] = '0'+(i%10);
1034 wstr1[i] = '0'+(i%10);
1036 str1[2*MAX_PATH] = 0;
1037 wstr1[2*MAX_PATH] = 0;
1039 memset(buf, 0xbf, sizeof(buf));
1040 expect_eq(StrCpyNA(buf, str1, 10), buf, PCHAR, "%p");
1041 expect_eq(buf[9], 0, CHAR, "%x");
1042 expect_eq(buf[10], '\xbf', CHAR, "%x");
1044 if (pStrCatBuffA)
1046 expect_eq(pStrCatBuffA(buf, str1, 100), buf, PCHAR, "%p");
1047 expect_eq(buf[99], 0, CHAR, "%x");
1048 expect_eq(buf[100], '\xbf', CHAR, "%x");
1050 else
1051 win_skip("StrCatBuffA() is not available\n");
1053 if (0)
1055 /* crashes on XP */
1056 StrCpyNW(wbuf, (LPCWSTR)0x1, 10);
1057 StrCpyNW((LPWSTR)0x1, wstr1, 10);
1060 memset(wbuf, 0xbf, sizeof(wbuf));
1061 expect_eq(StrCpyNW(wbuf, (LPCWSTR)0x1, 1), wbuf, PWCHAR, "%p");
1062 expect_eq(wbuf[0], 0, WCHAR, "%x");
1063 expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x");
1065 memset(wbuf, 0xbf, sizeof(wbuf));
1066 expect_eq(StrCpyNW(wbuf, 0, 10), wbuf, PWCHAR, "%p");
1067 expect_eq(wbuf[0], 0, WCHAR, "%x");
1068 expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x");
1070 memset(wbuf, 0xbf, sizeof(wbuf));
1071 expect_eq(StrCpyNW(wbuf, 0, 0), wbuf, PWCHAR, "%p");
1072 expect_eq(wbuf[0], (WCHAR)0xbfbf, WCHAR, "%x");
1073 expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x");
1075 memset(wbuf, 0xbf, sizeof(wbuf));
1076 expect_eq(StrCpyNW(wbuf, wstr1, 0), wbuf, PWCHAR, "%p");
1077 expect_eq(wbuf[0], (WCHAR)0xbfbf, WCHAR, "%x");
1078 expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x");
1080 memset(wbuf, 0xbf, sizeof(wbuf));
1081 expect_eq(StrCpyNW(wbuf, wstr1, 10), wbuf, PWCHAR, "%p");
1082 expect_eq(wbuf[9], 0, WCHAR, "%x");
1083 expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
1085 if (pStrCatBuffW)
1087 expect_eq(pStrCatBuffW(wbuf, wstr1, 100), wbuf, PWCHAR, "%p");
1088 expect_eq(wbuf[99], 0, WCHAR, "%x");
1089 expect_eq(wbuf[100], (WCHAR)0xbfbf, WCHAR, "%x");
1091 else
1092 win_skip("StrCatBuffW() is not available\n");
1094 if (pStrRetToBufW)
1096 memset(wbuf, 0xbf, sizeof(wbuf));
1097 strret.uType = STRRET_WSTR;
1098 U(strret).pOleStr = StrDupW(wstr1);
1099 hres = pStrRetToBufW(&strret, NULL, wbuf, 10);
1100 ok(hres == E_NOT_SUFFICIENT_BUFFER || broken(hres == S_OK) /* winxp */,
1101 "StrRetToBufW returned %08x\n", hres);
1102 if (hres == E_NOT_SUFFICIENT_BUFFER)
1103 expect_eq(wbuf[0], 0, WCHAR, "%x");
1104 expect_eq(wbuf[9], 0, WCHAR, "%x");
1105 expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
1107 memset(wbuf, 0xbf, sizeof(wbuf));
1108 strret.uType = STRRET_CSTR;
1109 StrCpyNA(U(strret).cStr, str1, MAX_PATH);
1110 hres = pStrRetToBufW(&strret, NULL, wbuf, 10);
1111 ok(hres == S_OK, "StrRetToBufW returned %08x\n", hres);
1112 ok(!memcmp(wbuf, wstr1, 9*sizeof(WCHAR)) && !wbuf[9], "StrRetToBuf returned %s\n", wine_dbgstr_w(wbuf));
1114 memset(wbuf, 0xbf, sizeof(wbuf));
1115 strret.uType = STRRET_WSTR;
1116 U(strret).pOleStr = NULL;
1117 hres = pStrRetToBufW(&strret, NULL, wbuf, 10);
1118 ok(hres == E_FAIL, "StrRetToBufW returned %08x\n", hres);
1119 ok(!wbuf[0], "StrRetToBuf returned %s\n", wine_dbgstr_w(wbuf));
1121 else
1122 win_skip("StrRetToBufW() is not available\n");
1124 if (pStrRetToBufA)
1126 memset(buf, 0xbf, sizeof(buf));
1127 strret.uType = STRRET_CSTR;
1128 StrCpyNA(U(strret).cStr, str1, MAX_PATH);
1129 expect_eq2(pStrRetToBufA(&strret, NULL, buf, 10), S_OK, E_NOT_SUFFICIENT_BUFFER /* Vista */, HRESULT, "%x");
1130 expect_eq(buf[9], 0, CHAR, "%x");
1131 expect_eq(buf[10], (CHAR)0xbf, CHAR, "%x");
1133 else
1134 win_skip("StrRetToBufA() is not available\n");
1136 if (pwnsprintfA)
1138 memset(buf, 0xbf, sizeof(buf));
1139 ret = pwnsprintfA(buf, 10, "%s", str1);
1140 ok(broken(ret == 9) || ret == -1 /* Vista */, "Unexpected wnsprintfA return %d, expected 9 or -1\n", ret);
1141 expect_eq(buf[9], 0, CHAR, "%x");
1142 expect_eq(buf[10], (CHAR)0xbf, CHAR, "%x");
1144 else
1145 win_skip("wnsprintfA() is not available\n");
1147 if (pwnsprintfW)
1149 memset(wbuf, 0xbf, sizeof(wbuf));
1150 ret = pwnsprintfW(wbuf, 10, fmt, wstr1);
1151 ok(broken(ret == 9) || ret == -1 /* Vista */, "Unexpected wnsprintfW return %d, expected 9 or -1\n", ret);
1152 expect_eq(wbuf[9], 0, WCHAR, "%x");
1153 expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
1155 else
1156 win_skip("wnsprintfW() is not available\n");
1159 static void test_StrStrA(void)
1161 static const char *deadbeefA = "DeAdBeEf";
1163 const struct
1165 const char *search;
1166 const char *expect;
1167 } StrStrA_cases[] =
1169 {"", NULL},
1170 {"DeAd", deadbeefA},
1171 {"dead", NULL},
1172 {"AdBe", deadbeefA + 2},
1173 {"adbe", NULL},
1174 {"BeEf", deadbeefA + 4},
1175 {"beef", NULL},
1178 LPSTR ret;
1179 int i;
1181 /* Tests crash on Win2k */
1182 if (0)
1184 ret = StrStrA(NULL, NULL);
1185 ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
1187 ret = StrStrA(NULL, "");
1188 ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
1190 ret = StrStrA("", NULL);
1191 ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
1194 ret = StrStrA("", "");
1195 ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
1197 for (i = 0; i < ARRAY_SIZE(StrStrA_cases); i++)
1199 ret = StrStrA(deadbeefA, StrStrA_cases[i].search);
1200 ok(ret == StrStrA_cases[i].expect,
1201 "[%d] Expected StrStrA to return %p, got %p\n",
1202 i, StrStrA_cases[i].expect, ret);
1206 static void test_StrStrW(void)
1208 static const WCHAR emptyW[] = {0};
1209 static const WCHAR deadbeefW[] = {'D','e','A','d','B','e','E','f',0};
1210 static const WCHAR deadW[] = {'D','e','A','d',0};
1211 static const WCHAR dead_lowerW[] = {'d','e','a','d',0};
1212 static const WCHAR adbeW[] = {'A','d','B','e',0};
1213 static const WCHAR adbe_lowerW[] = {'a','d','b','e',0};
1214 static const WCHAR beefW[] = {'B','e','E','f',0};
1215 static const WCHAR beef_lowerW[] = {'b','e','e','f',0};
1217 const struct
1219 const WCHAR *search;
1220 const WCHAR *expect;
1221 } StrStrW_cases[] =
1223 {emptyW, NULL},
1224 {deadW, deadbeefW},
1225 {dead_lowerW, NULL},
1226 {adbeW, deadbeefW + 2},
1227 {adbe_lowerW, NULL},
1228 {beefW, deadbeefW + 4},
1229 {beef_lowerW, NULL},
1232 LPWSTR ret;
1233 int i;
1235 /* Tests crash on Win2k */
1236 if (0)
1238 ret = StrStrW(NULL, NULL);
1239 ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
1241 ret = StrStrW(NULL, emptyW);
1242 ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
1244 ret = StrStrW(emptyW, NULL);
1245 ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
1248 ret = StrStrW(emptyW, emptyW);
1249 ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
1251 for (i = 0; i < ARRAY_SIZE(StrStrW_cases); i++)
1253 ret = StrStrW(deadbeefW, StrStrW_cases[i].search);
1254 ok(ret == StrStrW_cases[i].expect,
1255 "[%d] Expected StrStrW to return %p, got %p\n",
1256 i, StrStrW_cases[i].expect, ret);
1260 static void test_StrStrIA(void)
1262 static const char *deadbeefA = "DeAdBeEf";
1264 const struct
1266 const char *search;
1267 const char *expect;
1268 } StrStrIA_cases[] =
1270 {"", NULL},
1271 {"DeAd", deadbeefA},
1272 {"dead", deadbeefA},
1273 {"AdBe", deadbeefA + 2},
1274 {"adbe", deadbeefA + 2},
1275 {"BeEf", deadbeefA + 4},
1276 {"beef", deadbeefA + 4},
1277 {"cafe", NULL},
1280 LPSTR ret;
1281 int i;
1283 /* Tests crash on Win2k */
1284 if (0)
1286 ret = StrStrIA(NULL, NULL);
1287 ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
1289 ret = StrStrIA(NULL, "");
1290 ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
1292 ret = StrStrIA("", NULL);
1293 ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
1296 ret = StrStrIA("", "");
1297 ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
1299 for (i = 0; i < ARRAY_SIZE(StrStrIA_cases); i++)
1301 ret = StrStrIA(deadbeefA, StrStrIA_cases[i].search);
1302 ok(ret == StrStrIA_cases[i].expect,
1303 "[%d] Expected StrStrIA to return %p, got %p\n",
1304 i, StrStrIA_cases[i].expect, ret);
1308 static void test_StrStrIW(void)
1310 static const WCHAR emptyW[] = {0};
1311 static const WCHAR deadbeefW[] = {'D','e','A','d','B','e','E','f',0};
1312 static const WCHAR deadW[] = {'D','e','A','d',0};
1313 static const WCHAR dead_lowerW[] = {'d','e','a','d',0};
1314 static const WCHAR adbeW[] = {'A','d','B','e',0};
1315 static const WCHAR adbe_lowerW[] = {'a','d','b','e',0};
1316 static const WCHAR beefW[] = {'B','e','E','f',0};
1317 static const WCHAR beef_lowerW[] = {'b','e','e','f',0};
1318 static const WCHAR cafeW[] = {'c','a','f','e',0};
1320 const struct
1322 const WCHAR *search;
1323 const WCHAR *expect;
1324 } StrStrIW_cases[] =
1326 {emptyW, NULL},
1327 {deadW, deadbeefW},
1328 {dead_lowerW, deadbeefW},
1329 {adbeW, deadbeefW + 2},
1330 {adbe_lowerW, deadbeefW + 2},
1331 {beefW, deadbeefW + 4},
1332 {beef_lowerW, deadbeefW + 4},
1333 {cafeW, NULL},
1336 LPWSTR ret;
1337 int i;
1339 /* Tests crash on Win2k */
1340 if (0)
1342 ret = StrStrIW(NULL, NULL);
1343 ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
1345 ret = StrStrIW(NULL, emptyW);
1346 ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
1348 ret = StrStrIW(emptyW, NULL);
1349 ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
1352 ret = StrStrIW(emptyW, emptyW);
1353 ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
1355 for (i = 0; i < ARRAY_SIZE(StrStrIW_cases); i++)
1357 ret = StrStrIW(deadbeefW, StrStrIW_cases[i].search);
1358 ok(ret == StrStrIW_cases[i].expect,
1359 "[%d] Expected StrStrIW to return %p, got %p\n",
1360 i, StrStrIW_cases[i].expect, ret);
1364 static void test_StrStrNW(void)
1366 static const WCHAR emptyW[] = {0};
1367 static const WCHAR deadbeefW[] = {'D','e','A','d','B','e','E','f',0};
1368 static const WCHAR deadW[] = {'D','e','A','d',0};
1369 static const WCHAR dead_lowerW[] = {'d','e','a','d',0};
1370 static const WCHAR adbeW[] = {'A','d','B','e',0};
1371 static const WCHAR adbe_lowerW[] = {'a','d','b','e',0};
1372 static const WCHAR beefW[] = {'B','e','E','f',0};
1373 static const WCHAR beef_lowerW[] = {'b','e','e','f',0};
1375 const struct
1377 const WCHAR *search;
1378 const UINT count;
1379 const WCHAR *expect;
1380 } StrStrNW_cases[] =
1382 {emptyW, ARRAY_SIZE(deadbeefW), NULL},
1383 {deadW, ARRAY_SIZE(deadbeefW), deadbeefW},
1384 {dead_lowerW, ARRAY_SIZE(deadbeefW), NULL},
1385 {adbeW, ARRAY_SIZE(deadbeefW), deadbeefW + 2},
1386 {adbe_lowerW, ARRAY_SIZE(deadbeefW), NULL},
1387 {beefW, ARRAY_SIZE(deadbeefW), deadbeefW + 4},
1388 {beef_lowerW, ARRAY_SIZE(deadbeefW), NULL},
1389 {beefW, 0, NULL},
1390 {beefW, 1, NULL},
1391 {beefW, 2, NULL},
1392 {beefW, 3, NULL},
1393 {beefW, 4, NULL},
1394 {beefW, 5, deadbeefW + 4},
1395 {beefW, 6, deadbeefW + 4},
1396 {beefW, 7, deadbeefW + 4},
1397 {beefW, 8, deadbeefW + 4},
1398 {beefW, 9, deadbeefW + 4},
1401 LPWSTR ret;
1402 UINT i;
1404 if (!pStrStrNW)
1406 win_skip("StrStrNW() is not available\n");
1407 return;
1410 ret = pStrStrNW(NULL, NULL, 0);
1411 ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
1413 ret = pStrStrNW(NULL, NULL, 10);
1414 ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
1416 ret = pStrStrNW(NULL, emptyW, 10);
1417 ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
1419 ret = pStrStrNW(emptyW, NULL, 10);
1420 ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
1422 ret = pStrStrNW(emptyW, emptyW, 10);
1423 ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
1425 for (i = 0; i < ARRAY_SIZE(StrStrNW_cases); i++)
1427 ret = pStrStrNW(deadbeefW, StrStrNW_cases[i].search, StrStrNW_cases[i].count);
1428 ok(ret == StrStrNW_cases[i].expect,
1429 "[%d] Expected StrStrNW to return %p, got %p\n",
1430 i, StrStrNW_cases[i].expect, ret);
1433 /* StrStrNW accepts counts larger than the search string length but rejects
1434 * counts larger than around 2G. The limit seems to change based on the
1435 * caller executable itself. */
1436 ret = pStrStrNW(deadbeefW, beefW, 100);
1437 ok(ret == deadbeefW + 4, "Expected StrStrNW to return deadbeefW + 4, got %p\n", ret);
1439 if (0)
1441 ret = pStrStrNW(deadbeefW, beefW, ~0U);
1442 ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
1446 static void test_StrStrNIW(void)
1448 static const WCHAR emptyW[] = {0};
1449 static const WCHAR deadbeefW[] = {'D','e','A','d','B','e','E','f',0};
1450 static const WCHAR deadW[] = {'D','e','A','d',0};
1451 static const WCHAR dead_lowerW[] = {'d','e','a','d',0};
1452 static const WCHAR adbeW[] = {'A','d','B','e',0};
1453 static const WCHAR adbe_lowerW[] = {'a','d','b','e',0};
1454 static const WCHAR beefW[] = {'B','e','E','f',0};
1455 static const WCHAR beef_lowerW[] = {'b','e','e','f',0};
1456 static const WCHAR cafeW[] = {'c','a','f','e',0};
1458 const struct
1460 const WCHAR *search;
1461 const UINT count;
1462 const WCHAR *expect;
1463 } StrStrNIW_cases[] =
1465 {emptyW, ARRAY_SIZE(deadbeefW), NULL},
1466 {deadW, ARRAY_SIZE(deadbeefW), deadbeefW},
1467 {dead_lowerW, ARRAY_SIZE(deadbeefW), deadbeefW},
1468 {adbeW, ARRAY_SIZE(deadbeefW), deadbeefW + 2},
1469 {adbe_lowerW, ARRAY_SIZE(deadbeefW), deadbeefW + 2},
1470 {beefW, ARRAY_SIZE(deadbeefW), deadbeefW + 4},
1471 {beef_lowerW, ARRAY_SIZE(deadbeefW), deadbeefW + 4},
1472 {cafeW, ARRAY_SIZE(deadbeefW), NULL},
1473 {beefW, 0, NULL},
1474 {beefW, 1, NULL},
1475 {beefW, 2, NULL},
1476 {beefW, 3, NULL},
1477 {beefW, 4, NULL},
1478 {beefW, 5, deadbeefW + 4},
1479 {beefW, 6, deadbeefW + 4},
1480 {beefW, 7, deadbeefW + 4},
1481 {beefW, 8, deadbeefW + 4},
1482 {beefW, 9, deadbeefW + 4},
1483 {beef_lowerW, 0, NULL},
1484 {beef_lowerW, 1, NULL},
1485 {beef_lowerW, 2, NULL},
1486 {beef_lowerW, 3, NULL},
1487 {beef_lowerW, 4, NULL},
1488 {beef_lowerW, 5, deadbeefW + 4},
1489 {beef_lowerW, 6, deadbeefW + 4},
1490 {beef_lowerW, 7, deadbeefW + 4},
1491 {beef_lowerW, 8, deadbeefW + 4},
1492 {beef_lowerW, 9, deadbeefW + 4},
1495 LPWSTR ret;
1496 UINT i;
1498 if (!pStrStrNIW)
1500 win_skip("StrStrNIW() is not available\n");
1501 return;
1504 ret = pStrStrNIW(NULL, NULL, 0);
1505 ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
1507 ret = pStrStrNIW(NULL, NULL, 10);
1508 ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
1510 ret = pStrStrNIW(NULL, emptyW, 10);
1511 ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
1513 ret = pStrStrNIW(emptyW, NULL, 10);
1514 ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
1516 ret = pStrStrNIW(emptyW, emptyW, 10);
1517 ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
1519 for (i = 0; i < ARRAY_SIZE(StrStrNIW_cases); i++)
1521 ret = pStrStrNIW(deadbeefW, StrStrNIW_cases[i].search, StrStrNIW_cases[i].count);
1522 ok(ret == StrStrNIW_cases[i].expect,
1523 "[%d] Expected StrStrNIW to return %p, got %p\n",
1524 i, StrStrNIW_cases[i].expect, ret);
1527 /* StrStrNIW accepts counts larger than the search string length but rejects
1528 * counts larger than around 2G. The limit seems to change based on the
1529 * caller executable itself. */
1530 ret = pStrStrNIW(deadbeefW, beefW, 100);
1531 ok(ret == deadbeefW + 4, "Expected StrStrNIW to return deadbeefW + 4, got %p\n", ret);
1533 if (0)
1535 ret = pStrStrNIW(deadbeefW, beefW, ~0U);
1536 ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
1540 static void test_StrCatChainW(void)
1542 static const WCHAR deadbeefW[] = {'D','e','A','d','B','e','E','f',0};
1543 static const WCHAR deadW[] = {'D','e','A','d',0};
1544 static const WCHAR beefW[] = {'B','e','E','f',0};
1546 WCHAR buf[32 + 1];
1547 DWORD ret;
1549 if (!pStrCatChainW)
1551 win_skip("StrCatChainW is not available\n");
1552 return;
1555 /* Test with NULL buffer */
1556 ret = pStrCatChainW(NULL, 0, 0, beefW);
1557 ok(ret == 0, "Expected StrCatChainW to return 0, got %u\n", ret);
1559 /* Test with empty buffer */
1560 memset(buf, 0x11, sizeof(buf));
1561 ret = pStrCatChainW(buf, 0, 0, beefW);
1562 ok(ret == 0, "Expected StrCatChainW to return 0, got %u\n", ret);
1563 ok(buf[0] == 0x1111, "Expected buf[0] = 0x1111, got %x\n", buf[0]);
1565 memcpy(buf, deadbeefW, sizeof(deadbeefW));
1566 ret = pStrCatChainW(buf, 0, -1, beefW);
1567 ok(ret == 8, "Expected StrCatChainW to return 8, got %u\n", ret);
1568 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1570 /* Append data to existing string with offset = -1 */
1571 memset(buf, 0x11, sizeof(buf));
1572 ret = pStrCatChainW(buf, 32, 0, deadW);
1573 ok(ret == 4, "Expected StrCatChainW to return 4, got %u\n", ret);
1574 ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1576 ret = pStrCatChainW(buf, 32, -1, beefW);
1577 ok(ret == 8, "Expected StrCatChainW to return 8, got %u\n", ret);
1578 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1580 /* Append data at a fixed offset */
1581 memset(buf, 0x11, sizeof(buf));
1582 ret = pStrCatChainW(buf, 32, 0, deadW);
1583 ok(ret == 4, "Expected StrCatChainW to return 4, got %u\n", ret);
1584 ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1586 ret = pStrCatChainW(buf, 32, 4, beefW);
1587 ok(ret == 8, "Expected StrCatChainW to return 8, got %u\n", ret);
1588 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1590 /* Buffer exactly sufficient for string + terminating null */
1591 memset(buf, 0x11, sizeof(buf));
1592 ret = pStrCatChainW(buf, 5, 0, deadW);
1593 ok(ret == 4, "Expected StrCatChainW to return 4, got %u\n", ret);
1594 ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1596 /* Buffer too small, string will be truncated */
1597 memset(buf, 0x11, sizeof(buf));
1598 ret = pStrCatChainW(buf, 4, 0, deadW);
1599 if (ret == 4)
1601 /* Windows 2000 and XP uses a slightly different implementation
1602 * for StrCatChainW, which doesn't ensure that strings are null-
1603 * terminated. Skip test if we detect such an implementation. */
1604 win_skip("Windows2000/XP behaviour detected for StrCatChainW, skipping tests\n");
1605 return;
1607 ok(ret == 3, "Expected StrCatChainW to return 3, got %u\n", ret);
1608 ok(!memcmp(buf, deadW, 3 * sizeof(WCHAR)), "Buffer contains wrong data\n");
1609 ok(!buf[3], "String is not nullterminated\n");
1610 ok(buf[4] == 0x1111, "Expected buf[4] = 0x1111, got %x\n", buf[4]);
1612 /* Overwrite part of an existing string */
1613 ret = pStrCatChainW(buf, 4, 1, beefW);
1614 ok(ret == 3, "Expected StrCatChainW to return 3, got %u\n", ret);
1615 ok(buf[0] == 'D', "Expected buf[0] = 'D', got %x\n", buf[0]);
1616 ok(buf[1] == 'B', "Expected buf[1] = 'B', got %x\n", buf[1]);
1617 ok(buf[2] == 'e', "Expected buf[2] = 'e', got %x\n", buf[2]);
1618 ok(!buf[3], "String is not nullterminated\n");
1619 ok(buf[4] == 0x1111, "Expected buf[4] = 0x1111, got %x\n", buf[4]);
1621 /* Test appending to full buffer */
1622 memset(buf, 0x11, sizeof(buf));
1623 memcpy(buf, deadbeefW, sizeof(deadbeefW));
1624 memcpy(buf + 9, deadW, sizeof(deadW));
1625 ret = pStrCatChainW(buf, 9, 8, beefW);
1626 ok(ret == 8, "Expected StrCatChainW to return 8, got %u\n", ret);
1627 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1628 ok(!memcmp(buf + 9, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1630 /* Offset points at the end of the buffer */
1631 ret = pStrCatChainW(buf, 9, 9, beefW);
1632 ok(ret == 8, "Expected StrCatChainW to return 8, got %u\n", ret);
1633 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1634 ok(!memcmp(buf + 9, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1636 /* Offset points outside of the buffer */
1637 ret = pStrCatChainW(buf, 9, 10, beefW);
1638 ok(ret == 10, "Expected StrCatChainW to return 10, got %u\n", ret);
1639 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1640 ok(!memcmp(buf + 9, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1642 /* The same but without nullterminated string */
1643 memcpy(buf, deadbeefW, sizeof(deadbeefW));
1644 ret = pStrCatChainW(buf, 5, -1, deadW);
1645 ok(ret == 8, "Expected StrCatChainW to return 8, got %u\n", ret);
1646 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1648 ret = pStrCatChainW(buf, 5, 5, deadW);
1649 ok(ret == 4, "Expected StrCatChainW to return 4, got %u\n", ret);
1650 ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1651 ok(buf[5] == 'e', "Expected buf[5] = 'e', got %x\n", buf[5]);
1653 ret = pStrCatChainW(buf, 5, 6, deadW);
1654 ok(ret == 6, "Expected StrCatChainW to return 6, got %u\n", ret);
1655 ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1656 ok(buf[5] == 'e', "Expected buf[5] = 'e', got %x\n", buf[5]);
1659 START_TEST(string)
1661 HMODULE hShlwapi;
1662 CHAR thousandDelim[8];
1663 CHAR decimalDelim[8];
1664 CoInitialize(0);
1666 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, thousandDelim, 8);
1667 GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, decimalDelim, 8);
1669 hShlwapi = GetModuleHandleA("shlwapi");
1670 pChrCmpIA = (void *)GetProcAddress(hShlwapi, "ChrCmpIA");
1671 pChrCmpIW = (void *)GetProcAddress(hShlwapi, "ChrCmpIW");
1672 pIntlStrEqWorkerA = (void *)GetProcAddress(hShlwapi, "IntlStrEqWorkerA");
1673 pIntlStrEqWorkerW = (void *)GetProcAddress(hShlwapi, "IntlStrEqWorkerW");
1674 pSHAnsiToAnsi = (void *)GetProcAddress(hShlwapi, (LPSTR)345);
1675 pSHUnicodeToUnicode = (void *)GetProcAddress(hShlwapi, (LPSTR)346);
1676 pStrCatBuffA = (void *)GetProcAddress(hShlwapi, "StrCatBuffA");
1677 pStrCatBuffW = (void *)GetProcAddress(hShlwapi, "StrCatBuffW");
1678 pStrCatChainW = (void *)GetProcAddress(hShlwapi, "StrCatChainW");
1679 pStrCpyNXA = (void *)GetProcAddress(hShlwapi, (LPSTR)399);
1680 pStrCpyNXW = (void *)GetProcAddress(hShlwapi, (LPSTR)400);
1681 pStrChrNW = (void *)GetProcAddress(hShlwapi, "StrChrNW");
1682 pStrFormatByteSize64A = (void *)GetProcAddress(hShlwapi, "StrFormatByteSize64A");
1683 pStrFormatKBSizeA = (void *)GetProcAddress(hShlwapi, "StrFormatKBSizeA");
1684 pStrFormatKBSizeW = (void *)GetProcAddress(hShlwapi, "StrFormatKBSizeW");
1685 pStrIsIntlEqualA = (void *)GetProcAddress(hShlwapi, "StrIsIntlEqualA");
1686 pStrIsIntlEqualW = (void *)GetProcAddress(hShlwapi, "StrIsIntlEqualW");
1687 pStrPBrkW = (void *)GetProcAddress(hShlwapi, "StrPBrkW");
1688 pStrRChrA = (void *)GetProcAddress(hShlwapi, "StrRChrA");
1689 pStrRetToBSTR = (void *)GetProcAddress(hShlwapi, "StrRetToBSTR");
1690 pStrRetToBufA = (void *)GetProcAddress(hShlwapi, "StrRetToBufA");
1691 pStrRetToBufW = (void *)GetProcAddress(hShlwapi, "StrRetToBufW");
1692 pStrStrNW = (void *)GetProcAddress(hShlwapi, "StrStrNW");
1693 pStrStrNIW = (void *)GetProcAddress(hShlwapi, "StrStrNIW");
1694 pwnsprintfA = (void *)GetProcAddress(hShlwapi, "wnsprintfA");
1695 pwnsprintfW = (void *)GetProcAddress(hShlwapi, "wnsprintfW");
1696 pStrToInt64ExA = (void *)GetProcAddress(hShlwapi, "StrToInt64ExA");
1697 pStrToInt64ExW = (void *)GetProcAddress(hShlwapi, "StrToInt64ExW");
1699 test_StrChrA();
1700 test_StrChrW();
1701 test_StrChrIA();
1702 test_StrChrIW();
1703 test_StrRChrA();
1704 test_StrRChrW();
1705 test_StrCpyW();
1706 test_StrChrNW();
1707 test_StrToIntA();
1708 test_StrToIntW();
1709 test_StrToIntExA();
1710 test_StrToIntExW();
1711 test_StrToInt64ExA();
1712 test_StrToInt64ExW();
1713 test_StrDupA();
1715 /* language-dependent test */
1716 if (is_lang_english() && is_locale_english())
1718 test_StrFormatByteSize64A();
1719 test_StrFormatKBSizeA();
1720 test_StrFormatKBSizeW();
1722 else
1723 skip("An English UI and locale is required for the StrFormat*Size tests\n");
1724 if (is_lang_english())
1725 test_StrFromTimeIntervalA();
1726 else
1727 skip("An English UI is required for the StrFromTimeInterval tests\n");
1729 test_StrCmpA();
1730 test_StrCmpW();
1731 test_StrRetToBSTR();
1732 test_StrCpyNXA();
1733 test_StrCpyNXW();
1734 test_StrRStrI();
1735 test_SHAnsiToAnsi();
1736 test_SHUnicodeToUnicode();
1737 test_StrXXX_overflows();
1738 test_StrStrA();
1739 test_StrStrW();
1740 test_StrStrIA();
1741 test_StrStrIW();
1742 test_StrStrNW();
1743 test_StrStrNIW();
1744 test_StrCatChainW();
1746 CoUninitialize();