ReactOS 0.4.16-dev-1946-g52006dd
string.c
Go to the documentation of this file.
1/* Unit test suite for SHLWAPI string functions
2 *
3 * Copyright 2003 Jon Griffiths
4 *
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.
9 *
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.
14 *
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
18 */
19
20#include <stdio.h>
21
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"
32
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);
37
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);
42
43static BOOL (WINAPI *pChrCmpIA)(CHAR, CHAR);
44static BOOL (WINAPI *pChrCmpIW)(WCHAR, WCHAR);
45static BOOL (WINAPI *pIntlStrEqWorkerA)(BOOL,LPCSTR,LPCSTR,int);
46static BOOL (WINAPI *pIntlStrEqWorkerW)(BOOL,LPCWSTR,LPCWSTR,int);
47static DWORD (WINAPI *pSHAnsiToAnsi)(LPCSTR,LPSTR,int);
48static DWORD (WINAPI *pSHUnicodeToUnicode)(LPCWSTR,LPWSTR,int);
49static LPSTR (WINAPI *pStrCatBuffA)(LPSTR,LPCSTR,INT);
50static LPWSTR (WINAPI *pStrCatBuffW)(LPWSTR,LPCWSTR,INT);
51static DWORD (WINAPI *pStrCatChainW)(LPWSTR,DWORD,DWORD,LPCWSTR);
52static LPSTR (WINAPI *pStrCpyNXA)(LPSTR,LPCSTR,int);
53static LPWSTR (WINAPI *pStrCpyNXW)(LPWSTR,LPCWSTR,int);
54static LPSTR (WINAPI *pStrFormatByteSize64A)(LONGLONG,LPSTR,UINT);
55static HRESULT (WINAPI *pStrFormatByteSizeEx)(LONGLONG,SFBS_FLAGS,LPWSTR,UINT);
56static LPSTR (WINAPI *pStrFormatKBSizeA)(LONGLONG,LPSTR,UINT);
57static LPWSTR (WINAPI *pStrFormatKBSizeW)(LONGLONG,LPWSTR,UINT);
58static BOOL (WINAPI *pStrIsIntlEqualA)(BOOL,LPCSTR,LPCSTR,int);
59static BOOL (WINAPI *pStrIsIntlEqualW)(BOOL,LPCWSTR,LPCWSTR,int);
60static LPWSTR (WINAPI *pStrPBrkW)(LPCWSTR,LPCWSTR);
61static LPSTR (WINAPI *pStrRChrA)(LPCSTR,LPCSTR,WORD);
62static HRESULT (WINAPI *pStrRetToBSTR)(STRRET*,LPCITEMIDLIST,BSTR*);
63static HRESULT (WINAPI *pStrRetToBufA)(STRRET*,LPCITEMIDLIST,LPSTR,UINT);
64static HRESULT (WINAPI *pStrRetToBufW)(STRRET*,LPCITEMIDLIST,LPWSTR,UINT);
65static LPWSTR (WINAPI *pStrStrNW)(LPCWSTR,LPCWSTR,UINT);
66static LPWSTR (WINAPI *pStrStrNIW)(LPCWSTR,LPCWSTR,UINT);
67static INT (WINAPIV *pwnsprintfA)(LPSTR,INT,LPCSTR, ...);
68static INT (WINAPIV *pwnsprintfW)(LPWSTR,INT,LPCWSTR, ...);
69static LPWSTR (WINAPI *pStrChrNW)(LPCWSTR,WCHAR,UINT);
70static BOOL (WINAPI *pStrToInt64ExA)(LPCSTR,DWORD,LONGLONG*);
71static BOOL (WINAPI *pStrToInt64ExW)(LPCWSTR,DWORD,LONGLONG*);
72
73/* StrToInt/StrToIntEx results */
74typedef struct tagStrToIntResult
75{
76 const char* string;
82
84 { "1099", 1099, 1099, 1099 },
85 { "4294967319", 23, ((LONGLONG)1 << 32) | 23, ((LONGLONG)1 << 32) | 23 },
86 { "+88987", 0, 88987, 88987 },
87 { "012", 12, 12, 12 },
88 { "-55", -55, -55, -55 },
89 { "-0", 0, 0, 0 },
90 { "0x44ff", 0, 0, 0x44ff },
91 { "0x2bdc546291f4b1", 0, 0, ((LONGLONG)0x2bdc54 << 32) | 0x6291f4b1 },
92 { "+0x44f4", 0, 0, 0x44f4 },
93 { "-0x44fd", 0, 0, 0x44fd },
94 { "+ 88987", 0, 0, 0, TRUE },
95
96 { "- 55", 0, 0, 0, TRUE },
97 { "- 0", 0, 0, 0, TRUE },
98 { "+ 0x44f4", 0, 0, 0, TRUE },
99 { "--0x44fd", 0, 0, 0, TRUE },
100 { " 1999", 0, 1999, 1999 },
101 { " +88987", 0, 88987, 88987 },
102 { " 012", 0, 12, 12 },
103 { " -55", 0, -55, -55 },
104 { " 0x44ff", 0, 0, 0x44ff },
105 { " +0x44f4", 0, 0, 0x44f4 },
106 { " -0x44fd", 0, 0, 0x44fd },
107 { "\t\n +3", 0, 3, 3 },
108 { "\v+4", 0, 0, 0, TRUE },
109 { "\f+5", 0, 0, 0, TRUE },
110 { "\r+6", 0, 0, 0, TRUE },
111 { NULL, 0, 0, 0 }
112};
113
114/* pStrFormatByteSize64/StrFormatKBSize results */
116{
118 const char* byte_size_64;
119 const char* kb_size;
121 const char* kb_size2;
123
124
126 { -1023, "-1023 bytes", "0 KB"},
127 { -24, "-24 bytes", "0 KB"},
128 { 309, "309 bytes", "1 KB"},
129 { 10191, "9.95 KB", "10 KB"},
130 { 100353, "98.0 KB", "99 KB"},
131 { 1022286, "998 KB", "999 KB"},
132 { 1046862, "0.99 MB", "1,023 KB", 1, "1023 KB"},
133 { 1048574619, "999 MB", "1,023,999 KB", 1, "1023999 KB"},
134 { 1073741775, "0.99 GB", "1,048,576 KB", 1, "1048576 KB"},
135 { ((LONGLONG)0x000000f9 << 32) | 0xfffff94e, "999 GB", "1,048,575,999 KB", 1, "1048575999 KB"},
136 { ((LONGLONG)0x000000ff << 32) | 0xfffffa9b, "0.99 TB", "1,073,741,823 KB", 1, "1073741823 KB"},
137 { ((LONGLONG)0x0003e7ff << 32) | 0xfffffa9b, "999 TB", "1,073,741,823,999 KB", 1, "4294967295 KB"},
138 { ((LONGLONG)0x0003ffff << 32) | 0xfffffbe8, "0.99 PB", "1,099,511,627,775 KB", 1, "4294967295 KB"},
139 { ((LONGLONG)0x0f9fffff << 32) | 0xfffffd35, "999 PB", "1,099,511,627,776,000 KB", 1, "0 KB"},
140 { ((LONGLONG)0x0fffffff << 32) | 0xfffffa9b, "0.99 EB", "1,125,899,906,842,623 KB", 1, "4294967295 KB"},
141 { 0, NULL, NULL }
142};
143
144/* StrFromTimeIntervalA/StrFromTimeIntervalW results */
146{
149 const char* time_interval;
151
152
154 { 1, 1, " 0 sec" },
155 { 1, 2, " 0 sec" },
156 { 1, 3, " 0 sec" },
157 { 1, 4, " 0 sec" },
158 { 1, 5, " 0 sec" },
159 { 1, 6, " 0 sec" },
160 { 1, 7, " 0 sec" },
161
162 { 1000000, 1, " 10 min" },
163 { 1000000, 2, " 16 min" },
164 { 1000000, 3, " 16 min 40 sec" },
165 { 1000000, 4, " 16 min 40 sec" },
166 { 1000000, 5, " 16 min 40 sec" },
167 { 1000000, 6, " 16 min 40 sec" },
168 { 1000000, 7, " 16 min 40 sec" },
169
170 { 1999999, 1, " 30 min" },
171 { 1999999, 2, " 33 min" },
172 { 1999999, 3, " 33 min 20 sec" },
173 { 1999999, 4, " 33 min 20 sec" },
174 { 1999999, 5, " 33 min 20 sec" },
175 { 1999999, 6, " 33 min 20 sec" },
176 { 1999999, 7, " 33 min 20 sec" },
177
178 { 3999997, 1, " 1 hr" },
179 { 3999997, 2, " 1 hr 6 min" },
180 { 3999997, 3, " 1 hr 6 min 40 sec" },
181 { 3999997, 4, " 1 hr 6 min 40 sec" },
182 { 3999997, 5, " 1 hr 6 min 40 sec" },
183 { 3999997, 6, " 1 hr 6 min 40 sec" },
184 { 3999997, 7, " 1 hr 6 min 40 sec" },
185
186 { 149999851, 7, " 41 hr 40 min 0 sec" },
187 { 150999850, 1, " 40 hr" },
188 { 150999850, 2, " 41 hr" },
189 { 150999850, 3, " 41 hr 50 min" },
190 { 150999850, 4, " 41 hr 56 min" },
191 { 150999850, 5, " 41 hr 56 min 40 sec" },
192 { 150999850, 6, " 41 hr 56 min 40 sec" },
193 { 150999850, 7, " 41 hr 56 min 40 sec" },
194
195 { 493999507, 1, " 100 hr" },
196 { 493999507, 2, " 130 hr" },
197 { 493999507, 3, " 137 hr" },
198 { 493999507, 4, " 137 hr 10 min" },
199 { 493999507, 5, " 137 hr 13 min" },
200 { 493999507, 6, " 137 hr 13 min 20 sec" },
201 { 493999507, 7, " 137 hr 13 min 20 sec" },
202
203 { 0, 0, NULL }
204};
205
206
207/* Returns true if the user interface is in English. Note that this does not
208 * presume of the formatting of dates, numbers, etc.
209 */
211{
212 static HMODULE hkernel32 = NULL;
213 static LANGID (WINAPI *pGetThreadUILanguage)(void) = NULL;
214 static LANGID (WINAPI *pGetUserDefaultUILanguage)(void) = NULL;
215
216 if (!hkernel32)
217 {
218 hkernel32 = GetModuleHandleA("kernel32.dll");
219 pGetThreadUILanguage = (void*)GetProcAddress(hkernel32, "GetThreadUILanguage");
220 pGetUserDefaultUILanguage = (void*)GetProcAddress(hkernel32, "GetUserDefaultUILanguage");
221 }
222 if (pGetThreadUILanguage)
223 return PRIMARYLANGID(pGetThreadUILanguage()) == LANG_ENGLISH;
224 if (pGetUserDefaultUILanguage)
225 return PRIMARYLANGID(pGetUserDefaultUILanguage()) == LANG_ENGLISH;
226
228}
229
230/* Returns true if the dates, numbers, etc. are formatted using English
231 * conventions.
232 */
234{
235 /* Surprisingly GetThreadLocale() is irrelevant here */
237}
238
239static void test_StrChrA(void)
240{
241 char string[129];
242 WORD count;
243
244 /* this test crashes on win2k SP4 */
245 /*ok(!StrChrA(NULL,'\0'), "found a character in a NULL string!\n");*/
246
247 for (count = 32; count < 128; count++)
248 string[count] = (char)count;
249 string[128] = '\0';
250
251 for (count = 32; count < 128; count++)
252 {
253 LPSTR result = StrChrA(string+32, count);
254 INT pos = result - string;
255 ok(pos == count, "found char '%c' in wrong place: got %d, expected %d\n", count, pos, count);
256 }
257
258 for (count = 32; count < 128; count++)
259 {
260 LPSTR result = StrChrA(string+count+1, count);
261 ok(!result, "found char '%c' not in the string\n", count);
262 }
263}
264
265static void test_StrChrW(void)
266{
267 WCHAR string[16385];
268 WORD count;
269
270 /* this test crashes on win2k SP4 */
271 /*ok(!StrChrW(NULL,'\0'), "found a character in a NULL string!\n");*/
272
273 for (count = 32; count < 16384; count++)
274 string[count] = count;
275 string[16384] = '\0';
276
277 for (count = 32; count < 16384; count++)
278 {
279 LPWSTR result = StrChrW(string+32, count);
280 ok((result - string) == count, "found char %d in wrong place\n", count);
281 }
282
283 for (count = 32; count < 16384; count++)
284 {
285 LPWSTR result = StrChrW(string+count+1, count);
286 ok(!result, "found char not in the string\n");
287 }
288}
289
290static void test_StrChrIA(void)
291{
292 char string[129];
293 WORD count;
294
295 /* this test crashes on win2k SP4 */
296 /*ok(!StrChrIA(NULL,'\0'), "found a character in a NULL string!\n");*/
297
298 for (count = 32; count < 128; count++)
299 string[count] = (char)count;
300 string[128] = '\0';
301
302 for (count = 'A'; count <= 'X'; count++)
303 {
304 LPSTR result = StrChrIA(string+32, count);
305
306 ok(result - string == count, "found char '%c' in wrong place\n", count);
307 ok(StrChrIA(result, count)!=NULL, "didn't find lowercase '%c'\n", count);
308 }
309
310 for (count = 'a'; count < 'z'; count++)
311 {
312 LPSTR result = StrChrIA(string+count+1, count);
313 ok(!result, "found char not in the string\n");
314 }
315}
316
317static void test_StrChrIW(void)
318{
319 WCHAR string[129];
320 WORD count;
321
322 /* this test crashes on win2k SP4 */
323 /*ok(!StrChrIA(NULL,'\0'), "found a character in a NULL string!\n");*/
324
325 for (count = 32; count < 128; count++)
326 string[count] = count;
327 string[128] = '\0';
328
329 for (count = 'A'; count <= 'X'; count++)
330 {
331 LPWSTR result = StrChrIW(string+32, count);
332
333 ok(result - string == count, "found char '%c' in wrong place\n", count);
334 ok(StrChrIW(result, count)!=NULL, "didn't find lowercase '%c'\n", count);
335 }
336
337 for (count = 'a'; count < 'z'; count++)
338 {
339 LPWSTR result = StrChrIW(string+count+1, count);
340 ok(!result, "found char not in the string\n");
341 }
342}
343
344static void test_StrRChrA(void)
345{
346 char string[129];
347 WORD count;
348
349 /* this test crashes on win2k SP4 */
350 /*ok(!StrRChrA(NULL, NULL,'\0'), "found a character in a NULL string!\n");*/
351
352 for (count = 32; count < 128; count++)
353 string[count] = (char)count;
354 string[128] = '\0';
355
356 for (count = 32; count < 128; count++)
357 {
358 LPSTR result = StrRChrA(string+32, NULL, count);
359 ok(result - string == count, "found char %d in wrong place\n", count);
360 }
361
362 for (count = 32; count < 128; count++)
363 {
364 LPSTR result = StrRChrA(string+count+1, NULL, count);
365 ok(!result, "found char not in the string\n");
366 }
367
368 for (count = 32; count < 128; count++)
369 {
370 LPSTR result = StrRChrA(string+count+1, string + 127, count);
371 ok(!result, "found char not in the string\n");
372 }
373}
374
375static void test_StrRChrW(void)
376{
377 WCHAR string[129];
378 WORD count;
379
380 /* this test crashes on win2k SP4 */
381 /*ok(!StrRChrW(NULL, NULL,'\0'), "found a character in a NULL string!\n");*/
382
383 for (count = 32; count < 128; count++)
384 string[count] = count;
385 string[128] = '\0';
386
387 for (count = 32; count < 128; count++)
388 {
389 LPWSTR result = StrRChrW(string+32, NULL, count);
390 INT pos = result - string;
391 ok(pos == count, "found char %d in wrong place: got %d, expected %d\n", count, pos, count);
392 }
393
394 for (count = 32; count < 128; count++)
395 {
396 LPWSTR result = StrRChrW(string+count+1, NULL, count);
397 ok(!result, "found char %d not in the string\n", count);
398 }
399
400 for (count = 32; count < 128; count++)
401 {
402 LPWSTR result = StrRChrW(string+count+1, string + 127, count);
403 ok(!result, "found char %d not in the string\n", count);
404 }
405}
406
407static void test_StrCpyW(void)
408{
409 WCHAR szSrc[256];
410 WCHAR szBuff[256];
412 LPWSTR lpRes;
413
414 while(result->value)
415 {
416 MultiByteToWideChar(CP_ACP, 0, result->byte_size_64, -1, szSrc, ARRAY_SIZE(szSrc));
417
418 lpRes = StrCpyW(szBuff, szSrc);
419 ok(!StrCmpW(szSrc, szBuff) && lpRes == szBuff, "Copied string %s wrong\n", result->byte_size_64);
420 result++;
421 }
422
423 /* this test crashes on win2k SP4 */
424 /*lpRes = StrCpyW(szBuff, NULL);*/
425 /*ok(lpRes == szBuff, "Wrong return value: got %p expected %p\n", lpRes, szBuff);*/
426
427 /* this test crashes on win2k SP4 */
428 /*lpRes = StrCpyW(NULL, szSrc);*/
429 /*ok(lpRes == NULL, "Wrong return value: got %p expected NULL\n", lpRes);*/
430
431 /* this test crashes on win2k SP4 */
432 /*lpRes = StrCpyW(NULL, NULL);*/
433 /*ok(lpRes == NULL, "Wrong return value: got %p expected NULL\n", lpRes);*/
434}
435
436static void test_StrChrNW(void)
437{
438 static const WCHAR string[] = {'T','e','s','t','i','n','g',' ','S','t','r','i','n','g',0};
439 LPWSTR p;
440
441 if (!pStrChrNW)
442 {
443 win_skip("StrChrNW not available\n");
444 return;
445 }
446
447 p = pStrChrNW(string,'t',10);
448 ok(*p=='t',"Found wrong 't'\n");
449 ok(*(p+1)=='i',"next should be 'i'\n");
450
451 p = pStrChrNW(string,'S',10);
452 ok(*p=='S',"Found wrong 'S'\n");
453
454 p = pStrChrNW(string,'r',10);
455 ok(p==NULL,"Should not have found 'r'\n");
456}
457
458static void test_StrToIntA(void)
459{
461 int return_val;
462
463 while (result->string)
464 {
465 return_val = StrToIntA(result->string);
466 ok(return_val == result->str_to_int, "converted '%s' wrong (%d)\n",
467 result->string, return_val);
468 result++;
469 }
470}
471
472static void test_StrToIntW(void)
473{
474 WCHAR szBuff[256];
476 int return_val;
477
478 while (result->string)
479 {
480 MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
481 return_val = StrToIntW(szBuff);
482 ok(return_val == result->str_to_int, "converted '%s' wrong (%d)\n",
483 result->string, return_val);
484 result++;
485 }
486}
487
488static void test_StrToIntExA(void)
489{
491 int return_val;
492 BOOL bRet;
493
494 while (result->string)
495 {
496 return_val = -1;
497 bRet = StrToIntExA(result->string,0,&return_val);
498 if (result->failure)
499 ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string);
500 else
501 ok(bRet, "Failed for '%s'\n", result->string);
502 if (bRet)
503 ok(return_val == (int)result->str_to_int64_ex, "converted '%s' wrong (%d)\n",
504 result->string, return_val);
505 result++;
506 }
507
509 while (result->string)
510 {
511 return_val = -1;
512 bRet = StrToIntExA(result->string,STIF_SUPPORT_HEX,&return_val);
513 if (result->failure)
514 ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string);
515 else
516 ok(bRet, "Failed for '%s'\n", result->string);
517 if (bRet)
518 ok(return_val == (int)result->str_to_int64_hex, "converted '%s' wrong (%d)\n",
519 result->string, return_val);
520 result++;
521 }
522}
523
524static void test_StrToIntExW(void)
525{
526 WCHAR szBuff[256];
528 int return_val;
529 BOOL bRet;
530
531 while (result->string)
532 {
533 return_val = -1;
534 MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
535 bRet = StrToIntExW(szBuff, 0, &return_val);
536 if (result->failure)
537 ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string);
538 else
539 ok(bRet, "Failed for '%s'\n", result->string);
540 if (bRet)
541 ok(return_val == (int)result->str_to_int64_ex, "converted '%s' wrong (%d)\n",
542 result->string, return_val);
543 result++;
544 }
545
547 while (result->string)
548 {
549 return_val = -1;
550 MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
551 bRet = StrToIntExW(szBuff, STIF_SUPPORT_HEX, &return_val);
552 if (result->failure)
553 ok(!bRet, "Got %d instead of failure for '%s'\n", return_val, result->string);
554 else
555 ok(bRet, "Failed for '%s'\n", result->string);
556 if (bRet)
557 ok(return_val == (int)result->str_to_int64_hex, "converted '%s' wrong (%d)\n",
558 result->string, return_val);
559 result++;
560 }
561
562 return_val = -1;
563 bRet = StrToIntExW(L"\x0661\x0662", 0, &return_val);
564 ok( !bRet, "Returned %d for Unicode digits\n", return_val );
565 bRet = StrToIntExW(L"\x07c3\x07c4", 0, &return_val);
566 ok( !bRet, "Returned %d for Unicode digits\n", return_val );
567 bRet = StrToIntExW(L"\xa0-2", 0, &return_val);
568 ok( !bRet, "Returned %d for Unicode space\n", return_val );
569}
570
571static void test_StrToInt64ExA(void)
572{
574 LONGLONG return_val;
575 BOOL bRet;
576
577 if (!pStrToInt64ExA)
578 {
579 win_skip("StrToInt64ExA() is not available\n");
580 return;
581 }
582
583 while (result->string)
584 {
585 return_val = -1;
586 bRet = pStrToInt64ExA(result->string,0,&return_val);
587 if (result->failure)
588 ok(!bRet, "Got %s instead of failure for '%s'\n",
589 wine_dbgstr_longlong(return_val), result->string);
590 else
591 ok(bRet, "Failed for '%s'\n", result->string);
592 if (bRet)
593 ok(return_val == result->str_to_int64_ex, "converted '%s' wrong (%s)\n",
594 result->string, wine_dbgstr_longlong(return_val));
595 result++;
596 }
597
599 while (result->string)
600 {
601 return_val = -1;
602 bRet = pStrToInt64ExA(result->string,STIF_SUPPORT_HEX,&return_val);
603 if (result->failure)
604 ok(!bRet, "Got %s instead of failure for '%s'\n",
605 wine_dbgstr_longlong(return_val), result->string);
606 else
607 ok(bRet, "Failed for '%s'\n", result->string);
608 if (bRet)
609 ok(return_val == result->str_to_int64_hex, "converted '%s' wrong (%s)\n",
610 result->string, wine_dbgstr_longlong(return_val));
611 result++;
612 }
613}
614
615static void test_StrToInt64ExW(void)
616{
617 WCHAR szBuff[256];
619 LONGLONG return_val;
620 BOOL bRet;
621
622 if (!pStrToInt64ExW)
623 {
624 win_skip("StrToInt64ExW() is not available\n");
625 return;
626 }
627
628 while (result->string)
629 {
630 return_val = -1;
631 MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
632 bRet = pStrToInt64ExW(szBuff, 0, &return_val);
633 if (result->failure)
634 ok(!bRet, "Got %s instead of failure for '%s'\n",
635 wine_dbgstr_longlong(return_val), result->string);
636 else
637 ok(bRet, "Failed for '%s'\n", result->string);
638 if (bRet)
639 ok(return_val == result->str_to_int64_ex, "converted '%s' wrong (%s)\n",
640 result->string, wine_dbgstr_longlong(return_val));
641 result++;
642 }
643
645 while (result->string)
646 {
647 return_val = -1;
648 MultiByteToWideChar(CP_ACP, 0, result->string, -1, szBuff, ARRAY_SIZE(szBuff));
649 bRet = pStrToInt64ExW(szBuff, STIF_SUPPORT_HEX, &return_val);
650 if (result->failure)
651 ok(!bRet, "Got %s instead of failure for '%s'\n",
652 wine_dbgstr_longlong(return_val), result->string);
653 else
654 ok(bRet, "Failed for '%s'\n", result->string);
655 if (bRet)
656 ok(return_val == result->str_to_int64_hex, "converted '%s' wrong (%s)\n",
657 result->string, wine_dbgstr_longlong(return_val));
658 result++;
659 }
660
661 return_val = -1;
662 bRet = pStrToInt64ExW(L"\x0661\x0662", 0, &return_val);
663 ok( !bRet, "Returned %s for Unicode digits\n", wine_dbgstr_longlong(return_val) );
664 bRet = pStrToInt64ExW(L"\x07c3\x07c4", 0, &return_val);
665 ok( !bRet, "Returned %s for Unicode digits\n", wine_dbgstr_longlong(return_val) );
666 bRet = pStrToInt64ExW(L"\xa0-2", 0, &return_val);
667 ok( !bRet, "Returned %s for Unicode space\n", wine_dbgstr_longlong(return_val) );
668}
669
670static void test_StrDupA(void)
671{
672 LPSTR lpszStr;
674
675 while(result->value)
676 {
677 lpszStr = StrDupA(result->byte_size_64);
678
679 ok(lpszStr != NULL, "Dup failed\n");
680 if (lpszStr)
681 {
682 ok(!strcmp(result->byte_size_64, lpszStr), "Copied string wrong\n");
683 LocalFree(lpszStr);
684 }
685 result++;
686 }
687
688 /* Later versions of shlwapi return NULL for this, but earlier versions
689 * returned an empty string (as Wine does).
690 */
691 lpszStr = StrDupA(NULL);
692 ok(lpszStr == NULL || *lpszStr == '\0', "NULL string returned %p\n", lpszStr);
693 LocalFree(lpszStr);
694}
695
697{
698 char szBuff[256];
700
701 if (!pStrFormatByteSize64A)
702 {
703 win_skip("StrFormatByteSize64A() is not available\n");
704 return;
705 }
706
707 while(result->value)
708 {
709 pStrFormatByteSize64A(result->value, szBuff, 256);
710
711 ok(!strcmp(result->byte_size_64, szBuff),
712 "Formatted %s wrong: got %s, expected %s\n",
713 wine_dbgstr_longlong(result->value), szBuff, result->byte_size_64);
714
715 result++;
716 }
717}
718
720{
721 WCHAR szBuff[256];
722 HRESULT hr;
723 LONGLONG test_value = 2147483647;
724
725 if (!pStrFormatByteSizeEx)
726 {
727 win_skip("StrFormatByteSizeEx is not available \n");
728 return;
729 }
730
731 hr = pStrFormatByteSizeEx(0xdeadbeef,
733 ok(hr == E_INVALIDARG, "Unexpected hr: %#lx expected: %#lx\n", hr, E_INVALIDARG);
734
735 hr = pStrFormatByteSizeEx(0xdeadbeef, 10, szBuff, 256);
736 ok(hr == E_INVALIDARG, "Unexpected hr: %#lx expected: %#lx\n", hr, E_INVALIDARG);
737
739 szBuff, 256);
740 ok(hr == S_OK, "Invalid arguments \n");
741 ok(!wcscmp(szBuff, L"2.00 GB"), "Formatted %s wrong: got %ls, expected 2.00 GB\n",
743
745 szBuff, 256);
746 ok(hr == S_OK, "Invalid arguments \n");
747 ok(!wcscmp(szBuff, L"1.99 GB"), "Formatted %s wrong: got %ls, expected 1.99 GB\n",
749}
750
751static void test_StrFormatKBSizeW(void)
752{
753 WCHAR szBuffW[256];
754 char szBuff[256];
756
757 if (!pStrFormatKBSizeW)
758 {
759 win_skip("StrFormatKBSizeW() is not available\n");
760 return;
761 }
762
763 while(result->value)
764 {
765 pStrFormatKBSizeW(result->value, szBuffW, 256);
766 WideCharToMultiByte(CP_ACP, 0, szBuffW, -1, szBuff, ARRAY_SIZE(szBuff), NULL, NULL);
767
768 ok(!strcmp(result->kb_size, szBuff), "Formatted %s wrong: got %s, expected %s\n",
769 wine_dbgstr_longlong(result->value), szBuff, result->kb_size);
770 result++;
771 }
772}
773
774static void test_StrFormatKBSizeA(void)
775{
776 char szBuff[256];
778
779 if (!pStrFormatKBSizeA)
780 {
781 win_skip("StrFormatKBSizeA() is not available\n");
782 return;
783 }
784
785 while(result->value)
786 {
787 pStrFormatKBSizeA(result->value, szBuff, 256);
788
789 /* shlwapi on Win98 SE does not appear to apply delimiters to the output
790 * and does not correctly handle extremely large values. */
791 ok(!strcmp(result->kb_size, szBuff) ||
792 (result->kb_size_broken && !strcmp(result->kb_size2, szBuff)),
793 "Formatted %s wrong: got %s, expected %s\n",
794 wine_dbgstr_longlong(result->value), szBuff, result->kb_size);
795 result++;
796 }
797}
798
800{
801 char szBuff[256];
803
804 while(result->ms)
805 {
806 StrFromTimeIntervalA(szBuff, 256, result->ms, result->digits);
807
808 ok(!strcmp(result->time_interval, szBuff), "Formatted %ld %d wrong: %s\n",
809 result->ms, result->digits, szBuff);
810 result++;
811 }
812}
813
814static void test_StrCmpA(void)
815{
816 static const char str1[] = {'a','b','c','d','e','f'};
817 static const char str2[] = {'a','B','c','d','e','f'};
818 ok(0 != StrCmpNA(str1, str2, 6), "StrCmpNA is case-insensitive\n");
819 ok(0 == StrCmpNIA(str1, str2, 6), "StrCmpNIA is case-sensitive\n");
820 if (pChrCmpIA) {
821 ok(!pChrCmpIA('a', 'a'), "ChrCmpIA doesn't work at all!\n");
822 ok(!pChrCmpIA('b', 'B'), "ChrCmpIA is not case-insensitive\n");
823 ok(pChrCmpIA('a', 'z'), "ChrCmpIA believes that a == z!\n");
824 }
825 else
826 win_skip("ChrCmpIA() is not available\n");
827
828 if (pStrIsIntlEqualA)
829 {
830 ok(pStrIsIntlEqualA(FALSE, str1, str2, 5), "StrIsIntlEqualA(FALSE,...) isn't case-insensitive\n");
831 ok(!pStrIsIntlEqualA(TRUE, str1, str2, 5), "StrIsIntlEqualA(TRUE,...) isn't case-sensitive\n");
832 }
833 else
834 win_skip("StrIsIntlEqualA() is not available\n");
835
836 if (pIntlStrEqWorkerA)
837 {
838 ok(pIntlStrEqWorkerA(FALSE, str1, str2, 5), "IntlStrEqWorkerA(FALSE,...) isn't case-insensitive\n");
839 ok(!pIntlStrEqWorkerA(TRUE, str1, str2, 5), "pIntlStrEqWorkerA(TRUE,...) isn't case-sensitive\n");
840 }
841 else
842 win_skip("IntlStrEqWorkerA() is not available\n");
843}
844
845static void test_StrCmpW(void)
846{
847 static const WCHAR str1[] = {'a','b','c','d','e','f'};
848 static const WCHAR str2[] = {'a','B','c','d','e','f'};
849 ok(0 != StrCmpNW(str1, str2, 5), "StrCmpNW is case-insensitive\n");
850 ok(0 == StrCmpNIW(str1, str2, 5), "StrCmpNIW is case-sensitive\n");
851 if (pChrCmpIW) {
852 ok(!pChrCmpIW('a', 'a'), "ChrCmpIW doesn't work at all!\n");
853 ok(!pChrCmpIW('b', 'B'), "ChrCmpIW is not case-insensitive\n");
854 ok(pChrCmpIW('a', 'z'), "ChrCmpIW believes that a == z!\n");
855 }
856 else
857 win_skip("ChrCmpIW() is not available\n");
858
859 if (pStrIsIntlEqualW)
860 {
861 ok(pStrIsIntlEqualW(FALSE, str1, str2, 5), "StrIsIntlEqualW(FALSE,...) isn't case-insensitive\n");
862 ok(!pStrIsIntlEqualW(TRUE, str1, str2, 5), "StrIsIntlEqualW(TRUE,...) isn't case-sensitive\n");
863 }
864 else
865 win_skip("StrIsIntlEqualW() is not available\n");
866
867 if (pIntlStrEqWorkerW)
868 {
869 ok(pIntlStrEqWorkerW(FALSE, str1, str2, 5), "IntlStrEqWorkerW(FALSE,...) isn't case-insensitive\n");
870 ok(!pIntlStrEqWorkerW(TRUE, str1, str2, 5), "IntlStrEqWorkerW(TRUE,...) isn't case-sensitive\n");
871 }
872 else
873 win_skip("IntlStrEqWorkerW() is not available\n");
874}
875
876static WCHAR *CoDupStrW(const char* src)
877{
878 INT len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0);
879 WCHAR* szTemp = CoTaskMemAlloc(len * sizeof(WCHAR));
880 MultiByteToWideChar(CP_ACP, 0, src, -1, szTemp, len);
881 return szTemp;
882}
883
884static void test_StrRetToBSTR(void)
885{
886 static const WCHAR szTestW[] = { 'T','e','s','t','\0' };
887 ITEMIDLIST iidl[10];
888 BSTR bstr;
889 STRRET strret;
890 HRESULT ret;
891
892 if (!pStrRetToBSTR)
893 {
894 win_skip("StrRetToBSTR() is not available\n");
895 return;
896 }
897
898 strret.uType = STRRET_WSTR;
899 strret.pOleStr = CoDupStrW("Test");
900 bstr = 0;
901 ret = pStrRetToBSTR(&strret, NULL, &bstr);
902 ok(ret == S_OK && bstr && !wcscmp(bstr, szTestW),
903 "STRRET_WSTR: dup failed, ret=0x%08lx, bstr %p\n", ret, bstr);
904 SysFreeString(bstr);
905
906 strret.uType = STRRET_CSTR;
907 lstrcpyA(strret.cStr, "Test");
908 ret = pStrRetToBSTR(&strret, NULL, &bstr);
909 ok(ret == S_OK && bstr && !wcscmp(bstr, szTestW),
910 "STRRET_CSTR: dup failed, ret=0x%08lx, bstr %p\n", ret, bstr);
911 SysFreeString(bstr);
912
913 strret.uType = STRRET_OFFSET;
914 strret.uOffset = 1;
915 strcpy((char*)&iidl, " Test");
916 ret = pStrRetToBSTR(&strret, iidl, &bstr);
917 ok(ret == S_OK && bstr && !wcscmp(bstr, szTestW),
918 "STRRET_OFFSET: dup failed, ret=0x%08lx, bstr %p\n", ret, bstr);
919 SysFreeString(bstr);
920
921 /* Native crashes if str is NULL */
922}
923
924static void test_StrCpyNXA(void)
925{
926 LPCSTR lpSrc = "hello";
927 LPSTR lpszRes;
928 char dest[8];
929
930 if (!pStrCpyNXA)
931 {
932 win_skip("StrCpyNXA() is not available\n");
933 return;
934 }
935
936 memset(dest, '\n', sizeof(dest));
937 lpszRes = pStrCpyNXA(dest, lpSrc, ARRAY_SIZE(dest));
938 ok(lpszRes == dest + 5 && !memcmp(dest, "hello\0\n\n", sizeof(dest)),
939 "StrCpyNXA: expected %p, \"hello\\0\\n\\n\", got %p, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
940 dest + 5, lpszRes, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
941}
942
943static void test_StrCpyNXW(void)
944{
945 static const WCHAR lpInit[] = { '\n','\n','\n','\n','\n','\n','\n','\n' };
946 static const WCHAR lpSrc[] = { 'h','e','l','l','o','\0' };
947 static const WCHAR lpRes[] = { 'h','e','l','l','o','\0','\n','\n' };
948 LPWSTR lpszRes;
949 WCHAR dest[8];
950
951 if (!pStrCpyNXW)
952 {
953 win_skip("StrCpyNXW() is not available\n");
954 return;
955 }
956
957 memcpy(dest, lpInit, sizeof(lpInit));
958 lpszRes = pStrCpyNXW(dest, lpSrc, ARRAY_SIZE(dest));
959 ok(lpszRes == dest + 5 && !memcmp(dest, lpRes, sizeof(dest)),
960 "StrCpyNXW: expected %p, \"hello\\0\\n\\n\", got %p, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
961 dest + 5, lpszRes, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
962}
963
964#define check_strrstri(type, str, pos, needle, exp) \
965 ret##type = StrRStrI##type(str, str+pos, needle); \
966 ok(ret##type == (exp), "Type " #type ", expected %p but got %p (string base %p)\n", \
967 (exp), ret##type, str);
968
969static void test_StrRStrI(void)
970{
971 static const CHAR szTest[] = "yAxxxxAy";
972 static const CHAR szTest2[] = "ABABABAB";
973 static const WCHAR wszTest[] = {'y','A','x','x','x','x','A','y',0};
974 static const WCHAR wszTest2[] = {'A','B','A','B','A','B','A','B',0};
975
976 static const WCHAR wszPattern1[] = {'A',0};
977 static const WCHAR wszPattern2[] = {'a','X',0};
978 static const WCHAR wszPattern3[] = {'A','y',0};
979 static const WCHAR wszPattern4[] = {'a','b',0};
980 LPWSTR retW;
981 LPSTR retA;
982
983 check_strrstri(A, szTest, 4, "A", szTest+1);
984 check_strrstri(A, szTest, 4, "aX", szTest+1);
985 check_strrstri(A, szTest, 4, "Ay", NULL);
986 check_strrstri(W, wszTest, 4, wszPattern1, wszTest+1);
987 check_strrstri(W, wszTest, 4, wszPattern2, wszTest+1);
988 check_strrstri(W, wszTest, 4, wszPattern3, NULL);
989
990 check_strrstri(A, szTest2, 4, "ab", szTest2+2);
991 check_strrstri(A, szTest2, 3, "ab", szTest2+2);
992 check_strrstri(A, szTest2, 2, "ab", szTest2);
993 check_strrstri(A, szTest2, 1, "ab", szTest2);
994 check_strrstri(A, szTest2, 0, "ab", NULL);
995 check_strrstri(W, wszTest2, 4, wszPattern4, wszTest2+2);
996 check_strrstri(W, wszTest2, 3, wszPattern4, wszTest2+2);
997 check_strrstri(W, wszTest2, 2, wszPattern4, wszTest2);
998 check_strrstri(W, wszTest2, 1, wszPattern4, wszTest2);
999 check_strrstri(W, wszTest2, 0, wszPattern4, NULL);
1000
1001}
1002
1003static void test_SHAnsiToAnsi(void)
1004{
1005 char dest[8];
1006 DWORD dwRet;
1007
1008 if (!pSHAnsiToAnsi)
1009 {
1010 win_skip("SHAnsiToAnsi() is not available\n");
1011 return;
1012 }
1013
1014 if (pSHAnsiToAnsi == (void *)pStrPBrkW)
1015 {
1016 win_skip("Ordinal 345 corresponds to StrPBrkW, skipping SHAnsiToAnsi tests\n");
1017 return;
1018 }
1019
1020 memset(dest, '\n', sizeof(dest));
1021 dwRet = pSHAnsiToAnsi("hello", dest, ARRAY_SIZE(dest));
1022 ok(dwRet == 6 && !memcmp(dest, "hello\0\n\n", sizeof(dest)),
1023 "SHAnsiToAnsi: expected 6, \"hello\\0\\n\\n\", got %ld, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
1024 dwRet, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
1025}
1026
1028{
1029 static const WCHAR lpInit[] = { '\n','\n','\n','\n','\n','\n','\n','\n' };
1030 static const WCHAR lpSrc[] = { 'h','e','l','l','o','\0' };
1031 static const WCHAR lpRes[] = { 'h','e','l','l','o','\0','\n','\n' };
1032 WCHAR dest[8];
1033 DWORD dwRet;
1034
1035 if (!pSHUnicodeToUnicode)
1036 {
1037 win_skip("SHUnicodeToUnicode() is not available\n");
1038 return;
1039 }
1040
1041 if (pSHUnicodeToUnicode == (void *)pStrRChrA)
1042 {
1043 win_skip("Ordinal 346 corresponds to StrRChrA, skipping SHUnicodeToUnicode tests\n");
1044 return;
1045 }
1046
1047 memcpy(dest, lpInit, sizeof(lpInit));
1048 dwRet = pSHUnicodeToUnicode(lpSrc, dest, ARRAY_SIZE(dest));
1049 ok(dwRet == 6 && !memcmp(dest, lpRes, sizeof(dest)),
1050 "SHUnicodeToUnicode: expected 6, \"hello\\0\\n\\n\", got %ld, \"%d,%d,%d,%d,%d,%d,%d,%d\"\n",
1051 dwRet, dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
1052}
1053
1054static void test_StrXXX_overflows(void)
1055{
1056 CHAR str1[2*MAX_PATH+1], buf[2*MAX_PATH];
1057 WCHAR wstr1[2*MAX_PATH+1], wbuf[2*MAX_PATH];
1058 const WCHAR fmt[] = {'%','s',0};
1059 STRRET strret;
1060 HRESULT hres;
1061 int ret;
1062 int i;
1063
1064 for (i=0; i<2*MAX_PATH; i++)
1065 {
1066 str1[i] = '0'+(i%10);
1067 wstr1[i] = '0'+(i%10);
1068 }
1069 str1[2*MAX_PATH] = 0;
1070 wstr1[2*MAX_PATH] = 0;
1071
1072 memset(buf, 0xbf, sizeof(buf));
1073 expect_eq(StrCpyNA(buf, str1, 10), buf, PCHAR, "%p");
1074 expect_eq(buf[9], 0, CHAR, "%x");
1075 expect_eq(buf[10], '\xbf', CHAR, "%x");
1076
1077 if (pStrCatBuffA)
1078 {
1079 expect_eq(pStrCatBuffA(buf, str1, 100), buf, PCHAR, "%p");
1080 expect_eq(buf[99], 0, CHAR, "%x");
1081 expect_eq(buf[100], '\xbf', CHAR, "%x");
1082 }
1083 else
1084 win_skip("StrCatBuffA() is not available\n");
1085
1086if (0)
1087{
1088 /* crashes on XP */
1089 StrCpyNW(wbuf, (LPCWSTR)0x1, 10);
1090 StrCpyNW((LPWSTR)0x1, wstr1, 10);
1091}
1092
1093 memset(wbuf, 0xbf, sizeof(wbuf));
1094 expect_eq(StrCpyNW(wbuf, (LPCWSTR)0x1, 1), wbuf, PWCHAR, "%p");
1095 expect_eq(wbuf[0], 0, WCHAR, "%x");
1096 expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x");
1097
1098 memset(wbuf, 0xbf, sizeof(wbuf));
1099 expect_eq(StrCpyNW(wbuf, 0, 10), wbuf, PWCHAR, "%p");
1100 expect_eq(wbuf[0], 0, WCHAR, "%x");
1101 expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x");
1102
1103 memset(wbuf, 0xbf, sizeof(wbuf));
1104 expect_eq(StrCpyNW(wbuf, 0, 0), wbuf, PWCHAR, "%p");
1105 expect_eq(wbuf[0], (WCHAR)0xbfbf, WCHAR, "%x");
1106 expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x");
1107
1108 memset(wbuf, 0xbf, sizeof(wbuf));
1109 expect_eq(StrCpyNW(wbuf, wstr1, 0), wbuf, PWCHAR, "%p");
1110 expect_eq(wbuf[0], (WCHAR)0xbfbf, WCHAR, "%x");
1111 expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x");
1112
1113 memset(wbuf, 0xbf, sizeof(wbuf));
1114 expect_eq(StrCpyNW(wbuf, wstr1, 10), wbuf, PWCHAR, "%p");
1115 expect_eq(wbuf[9], 0, WCHAR, "%x");
1116 expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
1117
1118 if (pStrCatBuffW)
1119 {
1120 expect_eq(pStrCatBuffW(wbuf, wstr1, 100), wbuf, PWCHAR, "%p");
1121 expect_eq(wbuf[99], 0, WCHAR, "%x");
1122 expect_eq(wbuf[100], (WCHAR)0xbfbf, WCHAR, "%x");
1123 }
1124 else
1125 win_skip("StrCatBuffW() is not available\n");
1126
1127 if (pStrRetToBufW)
1128 {
1129 memset(wbuf, 0xbf, sizeof(wbuf));
1130 strret.uType = STRRET_WSTR;
1131 strret.pOleStr = StrDupW(wstr1);
1132 hres = pStrRetToBufW(&strret, NULL, wbuf, 10);
1133 ok(hres == E_NOT_SUFFICIENT_BUFFER || broken(hres == S_OK) /* winxp */,
1134 "StrRetToBufW returned %08lx\n", hres);
1136 expect_eq(wbuf[0], 0, WCHAR, "%x");
1137 expect_eq(wbuf[9], 0, WCHAR, "%x");
1138 expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
1139
1140 memset(wbuf, 0xbf, sizeof(wbuf));
1141 strret.uType = STRRET_CSTR;
1142 StrCpyNA(strret.cStr, str1, MAX_PATH);
1143 hres = pStrRetToBufW(&strret, NULL, wbuf, 10);
1144 ok(hres == S_OK, "StrRetToBufW returned %08lx\n", hres);
1145 ok(!memcmp(wbuf, wstr1, 9*sizeof(WCHAR)) && !wbuf[9], "StrRetToBuf returned %s\n", wine_dbgstr_w(wbuf));
1146
1147 memset(wbuf, 0xbf, sizeof(wbuf));
1148 strret.uType = STRRET_WSTR;
1149 strret.pOleStr = NULL;
1150 hres = pStrRetToBufW(&strret, NULL, wbuf, 10);
1151 ok(hres == E_FAIL, "StrRetToBufW returned %08lx\n", hres);
1152 ok(!wbuf[0], "StrRetToBuf returned %s\n", wine_dbgstr_w(wbuf));
1153 }
1154 else
1155 win_skip("StrRetToBufW() is not available\n");
1156
1157 if (pStrRetToBufA)
1158 {
1159 memset(buf, 0xbf, sizeof(buf));
1160 strret.uType = STRRET_CSTR;
1161 StrCpyNA(strret.cStr, str1, MAX_PATH);
1162 expect_eq2(pStrRetToBufA(&strret, NULL, buf, 10), S_OK, E_NOT_SUFFICIENT_BUFFER /* Vista */, HRESULT, "%lx");
1163 expect_eq(buf[9], 0, CHAR, "%x");
1164 expect_eq(buf[10], (CHAR)0xbf, CHAR, "%x");
1165 }
1166 else
1167 win_skip("StrRetToBufA() is not available\n");
1168
1169 if (pwnsprintfA)
1170 {
1171 memset(buf, 0xbf, sizeof(buf));
1172 ret = pwnsprintfA(buf, 10, "%s", str1);
1173 ok(broken(ret == 9) || ret == -1 /* Vista */, "Unexpected wnsprintfA return %d, expected 9 or -1\n", ret);
1174 expect_eq(buf[9], 0, CHAR, "%x");
1175 expect_eq(buf[10], (CHAR)0xbf, CHAR, "%x");
1176
1177 memset(buf, 0xbf, sizeof(buf));
1178 ret = pwnsprintfA(buf + 1, -1, "%s", str1);
1179#ifdef __REACTOS__
1180 ok(ret == -1 || broken(ret == 0) /* WS03 */, "got %d.\n", ret);
1181#else
1182 ok(ret == -1, "got %d.\n", ret);
1183#endif
1184 expect_eq(buf[0], (CHAR)0xbf, CHAR, "%x");
1185 if (!broken(1))
1186 {
1187 /* This is 0xbf before Win8. */
1188 expect_eq(buf[1], 0, CHAR, "%x");
1189 }
1190 expect_eq(buf[2], (CHAR)0xbf, CHAR, "%x");
1191
1192 memset(buf, 0xbf, sizeof(buf));
1193 ret = pwnsprintfA(buf + 1, 0, "%s", str1);
1194#ifdef __REACTOS__
1195 ok(ret == -1 || broken(ret == 0) /* WS03 */, "got %d.\n", ret);
1196#else
1197 ok(ret == -1, "got %d.\n", ret);
1198#endif
1199 expect_eq(buf[0], (CHAR)0xbf, CHAR, "%x");
1200 expect_eq(buf[1], (CHAR)0xbf, CHAR, "%x");
1201
1202 memset(buf, 0xbf, sizeof(buf));
1203 ret = pwnsprintfA(buf, 1, "");
1204 ok(!ret, "got %d.\n", ret);
1205 expect_eq(buf[0], 0, CHAR, "%x");
1206 expect_eq(buf[1], (CHAR)0xbf, CHAR, "%x");
1207 }
1208 else
1209 win_skip("wnsprintfA() is not available\n");
1210
1211 if (pwnsprintfW)
1212 {
1213 memset(wbuf, 0xbf, sizeof(wbuf));
1214 ret = pwnsprintfW(wbuf, 10, fmt, wstr1);
1215 ok(broken(ret == 9) || ret == -1 /* Vista */, "Unexpected wnsprintfW return %d, expected 9 or -1\n", ret);
1216 expect_eq(wbuf[9], 0, WCHAR, "%x");
1217 expect_eq(wbuf[10], (WCHAR)0xbfbf, WCHAR, "%x");
1218
1219 memset(wbuf, 0xbf, sizeof(wbuf));
1220 ret = pwnsprintfW(wbuf + 1, -1, fmt, wstr1);
1221#ifdef __REACTOS__
1222 ok(ret == -1 || broken(ret == 0) /* WS03 */, "got %d.\n", ret);
1223#else
1224 ok(ret == -1, "got %d.\n", ret);
1225#endif
1226 expect_eq(wbuf[0], (WCHAR)0xbfbf, WCHAR, "%x");
1227 if (!broken(1))
1228 {
1229 /* This is 0xbfbf before Win8. */
1230 expect_eq(wbuf[1], 0, WCHAR, "%x");
1231 }
1232 expect_eq(wbuf[2], (WCHAR)0xbfbf, WCHAR, "%x");
1233
1234 memset(wbuf, 0xbf, sizeof(wbuf));
1235 ret = pwnsprintfW(wbuf + 1, 0, fmt, wstr1);
1236#ifdef __REACTOS__
1237 ok(ret == -1 || broken(ret == 0) /* WS03 */, "got %d.\n", ret);
1238#else
1239 ok(ret == -1, "got %d.\n", ret);
1240#endif
1241 expect_eq(wbuf[0], (WCHAR)0xbfbf, WCHAR, "%x");
1242 expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x");
1243
1244 memset(wbuf, 0xbf, sizeof(wbuf));
1245 ret = pwnsprintfW(wbuf, 1, L"");
1246 ok(!ret, "got %d.\n", ret);
1247 expect_eq(wbuf[0], 0, WCHAR, "%x");
1248 expect_eq(wbuf[1], (WCHAR)0xbfbf, WCHAR, "%x");
1249 }
1250 else
1251 win_skip("wnsprintfW() is not available\n");
1252}
1253
1254static void test_StrStrA(void)
1255{
1256 static const char *deadbeefA = "DeAdBeEf";
1257
1258 const struct
1259 {
1260 const char *search;
1261 const char *expect;
1262 } StrStrA_cases[] =
1263 {
1264 {"", NULL},
1265 {"DeAd", deadbeefA},
1266 {"dead", NULL},
1267 {"AdBe", deadbeefA + 2},
1268 {"adbe", NULL},
1269 {"BeEf", deadbeefA + 4},
1270 {"beef", NULL},
1271 };
1272
1273 LPSTR ret;
1274 int i;
1275
1276 /* Tests crash on Win2k */
1277 if (0)
1278 {
1279 ret = StrStrA(NULL, NULL);
1280 ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
1281
1282 ret = StrStrA(NULL, "");
1283 ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
1284
1285 ret = StrStrA("", NULL);
1286 ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
1287 }
1288
1289 ret = StrStrA("", "");
1290 ok(!ret, "Expected StrStrA to return NULL, got %p\n", ret);
1291
1292 for (i = 0; i < ARRAY_SIZE(StrStrA_cases); i++)
1293 {
1294 ret = StrStrA(deadbeefA, StrStrA_cases[i].search);
1295 ok(ret == StrStrA_cases[i].expect,
1296 "[%d] Expected StrStrA to return %p, got %p\n",
1297 i, StrStrA_cases[i].expect, ret);
1298 }
1299}
1300
1301static void test_StrStrW(void)
1302{
1303 static const WCHAR emptyW[] = {0};
1304 static const WCHAR deadbeefW[] = {'D','e','A','d','B','e','E','f',0};
1305 static const WCHAR deadW[] = {'D','e','A','d',0};
1306 static const WCHAR dead_lowerW[] = {'d','e','a','d',0};
1307 static const WCHAR adbeW[] = {'A','d','B','e',0};
1308 static const WCHAR adbe_lowerW[] = {'a','d','b','e',0};
1309 static const WCHAR beefW[] = {'B','e','E','f',0};
1310 static const WCHAR beef_lowerW[] = {'b','e','e','f',0};
1311
1312 const struct
1313 {
1314 const WCHAR *search;
1315 const WCHAR *expect;
1316 } StrStrW_cases[] =
1317 {
1318 {emptyW, NULL},
1319 {deadW, deadbeefW},
1320 {dead_lowerW, NULL},
1321 {adbeW, deadbeefW + 2},
1322 {adbe_lowerW, NULL},
1323 {beefW, deadbeefW + 4},
1324 {beef_lowerW, NULL},
1325 };
1326
1327 LPWSTR ret;
1328 int i;
1329
1330 /* Tests crash on Win2k */
1331 if (0)
1332 {
1333 ret = StrStrW(NULL, NULL);
1334 ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
1335
1336 ret = StrStrW(NULL, emptyW);
1337 ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
1338
1339 ret = StrStrW(emptyW, NULL);
1340 ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
1341 }
1342
1344 ok(!ret, "Expected StrStrW to return NULL, got %p\n", ret);
1345
1346 for (i = 0; i < ARRAY_SIZE(StrStrW_cases); i++)
1347 {
1348 ret = StrStrW(deadbeefW, StrStrW_cases[i].search);
1349 ok(ret == StrStrW_cases[i].expect,
1350 "[%d] Expected StrStrW to return %p, got %p\n",
1351 i, StrStrW_cases[i].expect, ret);
1352 }
1353}
1354
1355static void test_StrStrIA(void)
1356{
1357 static const char *deadbeefA = "DeAdBeEf";
1358
1359 const struct
1360 {
1361 const char *search;
1362 const char *expect;
1363 } StrStrIA_cases[] =
1364 {
1365 {"", NULL},
1366 {"DeAd", deadbeefA},
1367 {"dead", deadbeefA},
1368 {"AdBe", deadbeefA + 2},
1369 {"adbe", deadbeefA + 2},
1370 {"BeEf", deadbeefA + 4},
1371 {"beef", deadbeefA + 4},
1372 {"cafe", NULL},
1373 };
1374
1375 LPSTR ret;
1376 int i;
1377
1378 /* Tests crash on Win2k */
1379 if (0)
1380 {
1381 ret = StrStrIA(NULL, NULL);
1382 ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
1383
1384 ret = StrStrIA(NULL, "");
1385 ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
1386
1387 ret = StrStrIA("", NULL);
1388 ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
1389 }
1390
1391 ret = StrStrIA("", "");
1392 ok(!ret, "Expected StrStrIA to return NULL, got %p\n", ret);
1393
1394 for (i = 0; i < ARRAY_SIZE(StrStrIA_cases); i++)
1395 {
1396 ret = StrStrIA(deadbeefA, StrStrIA_cases[i].search);
1397 ok(ret == StrStrIA_cases[i].expect,
1398 "[%d] Expected StrStrIA to return %p, got %p\n",
1399 i, StrStrIA_cases[i].expect, ret);
1400 }
1401}
1402
1403static void test_StrStrIW(void)
1404{
1405 static const WCHAR emptyW[] = {0};
1406 static const WCHAR deadbeefW[] = {'D','e','A','d','B','e','E','f',0};
1407 static const WCHAR deadW[] = {'D','e','A','d',0};
1408 static const WCHAR dead_lowerW[] = {'d','e','a','d',0};
1409 static const WCHAR adbeW[] = {'A','d','B','e',0};
1410 static const WCHAR adbe_lowerW[] = {'a','d','b','e',0};
1411 static const WCHAR beefW[] = {'B','e','E','f',0};
1412 static const WCHAR beef_lowerW[] = {'b','e','e','f',0};
1413 static const WCHAR cafeW[] = {'c','a','f','e',0};
1414
1415 const struct
1416 {
1417 const WCHAR *search;
1418 const WCHAR *expect;
1419 } StrStrIW_cases[] =
1420 {
1421 {emptyW, NULL},
1422 {deadW, deadbeefW},
1423 {dead_lowerW, deadbeefW},
1424 {adbeW, deadbeefW + 2},
1425 {adbe_lowerW, deadbeefW + 2},
1426 {beefW, deadbeefW + 4},
1427 {beef_lowerW, deadbeefW + 4},
1428 {cafeW, NULL},
1429 };
1430
1431 LPWSTR ret;
1432 int i;
1433
1434 /* Tests crash on Win2k */
1435 if (0)
1436 {
1437 ret = StrStrIW(NULL, NULL);
1438 ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
1439
1440 ret = StrStrIW(NULL, emptyW);
1441 ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
1442
1443 ret = StrStrIW(emptyW, NULL);
1444 ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
1445 }
1446
1448 ok(!ret, "Expected StrStrIW to return NULL, got %p\n", ret);
1449
1450 for (i = 0; i < ARRAY_SIZE(StrStrIW_cases); i++)
1451 {
1452 ret = StrStrIW(deadbeefW, StrStrIW_cases[i].search);
1453 ok(ret == StrStrIW_cases[i].expect,
1454 "[%d] Expected StrStrIW to return %p, got %p\n",
1455 i, StrStrIW_cases[i].expect, ret);
1456 }
1457}
1458
1459static void test_StrStrNW(void)
1460{
1461 static const WCHAR emptyW[] = {0};
1462 static const WCHAR deadbeefW[] = {'D','e','A','d','B','e','E','f',0};
1463 static const WCHAR deadW[] = {'D','e','A','d',0};
1464 static const WCHAR dead_lowerW[] = {'d','e','a','d',0};
1465 static const WCHAR adbeW[] = {'A','d','B','e',0};
1466 static const WCHAR adbe_lowerW[] = {'a','d','b','e',0};
1467 static const WCHAR beefW[] = {'B','e','E','f',0};
1468 static const WCHAR beef_lowerW[] = {'b','e','e','f',0};
1469
1470 const struct
1471 {
1472 const WCHAR *search;
1473 const UINT count;
1474 const WCHAR *expect;
1475 } StrStrNW_cases[] =
1476 {
1477 {emptyW, ARRAY_SIZE(deadbeefW), NULL},
1478 {deadW, ARRAY_SIZE(deadbeefW), deadbeefW},
1479 {dead_lowerW, ARRAY_SIZE(deadbeefW), NULL},
1480 {adbeW, ARRAY_SIZE(deadbeefW), deadbeefW + 2},
1481 {adbe_lowerW, ARRAY_SIZE(deadbeefW), NULL},
1482 {beefW, ARRAY_SIZE(deadbeefW), deadbeefW + 4},
1483 {beef_lowerW, ARRAY_SIZE(deadbeefW), NULL},
1484 {beefW, 0, NULL},
1485 {beefW, 1, NULL},
1486 {beefW, 2, NULL},
1487 {beefW, 3, NULL},
1488 {beefW, 4, NULL},
1489 {beefW, 5, deadbeefW + 4},
1490 {beefW, 6, deadbeefW + 4},
1491 {beefW, 7, deadbeefW + 4},
1492 {beefW, 8, deadbeefW + 4},
1493 {beefW, 9, deadbeefW + 4},
1494 };
1495
1496 LPWSTR ret;
1497 UINT i;
1498
1499 if (!pStrStrNW)
1500 {
1501 win_skip("StrStrNW() is not available\n");
1502 return;
1503 }
1504
1505 ret = pStrStrNW(NULL, NULL, 0);
1506 ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
1507
1508 ret = pStrStrNW(NULL, NULL, 10);
1509 ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
1510
1511 ret = pStrStrNW(NULL, emptyW, 10);
1512 ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
1513
1514 ret = pStrStrNW(emptyW, NULL, 10);
1515 ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
1516
1517 ret = pStrStrNW(emptyW, emptyW, 10);
1518 ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
1519
1520 for (i = 0; i < ARRAY_SIZE(StrStrNW_cases); i++)
1521 {
1522 ret = pStrStrNW(deadbeefW, StrStrNW_cases[i].search, StrStrNW_cases[i].count);
1523 ok(ret == StrStrNW_cases[i].expect,
1524 "[%d] Expected StrStrNW to return %p, got %p\n",
1525 i, StrStrNW_cases[i].expect, ret);
1526 }
1527
1528 /* StrStrNW accepts counts larger than the search string length but rejects
1529 * counts larger than around 2G. The limit seems to change based on the
1530 * caller executable itself. */
1531 ret = pStrStrNW(deadbeefW, beefW, 100);
1532 ok(ret == deadbeefW + 4, "Expected StrStrNW to return deadbeefW + 4, got %p\n", ret);
1533
1534 if (0)
1535 {
1536 ret = pStrStrNW(deadbeefW, beefW, ~0U);
1537 ok(!ret, "Expected StrStrNW to return NULL, got %p\n", ret);
1538 }
1539}
1540
1541static void test_StrStrNIW(void)
1542{
1543 static const WCHAR emptyW[] = {0};
1544 static const WCHAR deadbeefW[] = {'D','e','A','d','B','e','E','f',0};
1545 static const WCHAR deadW[] = {'D','e','A','d',0};
1546 static const WCHAR dead_lowerW[] = {'d','e','a','d',0};
1547 static const WCHAR adbeW[] = {'A','d','B','e',0};
1548 static const WCHAR adbe_lowerW[] = {'a','d','b','e',0};
1549 static const WCHAR beefW[] = {'B','e','E','f',0};
1550 static const WCHAR beef_lowerW[] = {'b','e','e','f',0};
1551 static const WCHAR cafeW[] = {'c','a','f','e',0};
1552
1553 const struct
1554 {
1555 const WCHAR *search;
1556 const UINT count;
1557 const WCHAR *expect;
1558 } StrStrNIW_cases[] =
1559 {
1560 {emptyW, ARRAY_SIZE(deadbeefW), NULL},
1561 {deadW, ARRAY_SIZE(deadbeefW), deadbeefW},
1562 {dead_lowerW, ARRAY_SIZE(deadbeefW), deadbeefW},
1563 {adbeW, ARRAY_SIZE(deadbeefW), deadbeefW + 2},
1564 {adbe_lowerW, ARRAY_SIZE(deadbeefW), deadbeefW + 2},
1565 {beefW, ARRAY_SIZE(deadbeefW), deadbeefW + 4},
1566 {beef_lowerW, ARRAY_SIZE(deadbeefW), deadbeefW + 4},
1567 {cafeW, ARRAY_SIZE(deadbeefW), NULL},
1568 {beefW, 0, NULL},
1569 {beefW, 1, NULL},
1570 {beefW, 2, NULL},
1571 {beefW, 3, NULL},
1572 {beefW, 4, NULL},
1573 {beefW, 5, deadbeefW + 4},
1574 {beefW, 6, deadbeefW + 4},
1575 {beefW, 7, deadbeefW + 4},
1576 {beefW, 8, deadbeefW + 4},
1577 {beefW, 9, deadbeefW + 4},
1578 {beef_lowerW, 0, NULL},
1579 {beef_lowerW, 1, NULL},
1580 {beef_lowerW, 2, NULL},
1581 {beef_lowerW, 3, NULL},
1582 {beef_lowerW, 4, NULL},
1583 {beef_lowerW, 5, deadbeefW + 4},
1584 {beef_lowerW, 6, deadbeefW + 4},
1585 {beef_lowerW, 7, deadbeefW + 4},
1586 {beef_lowerW, 8, deadbeefW + 4},
1587 {beef_lowerW, 9, deadbeefW + 4},
1588 };
1589
1590 LPWSTR ret;
1591 UINT i;
1592
1593 if (!pStrStrNIW)
1594 {
1595 win_skip("StrStrNIW() is not available\n");
1596 return;
1597 }
1598
1599 ret = pStrStrNIW(NULL, NULL, 0);
1600 ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
1601
1602 ret = pStrStrNIW(NULL, NULL, 10);
1603 ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
1604
1605 ret = pStrStrNIW(NULL, emptyW, 10);
1606 ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
1607
1608 ret = pStrStrNIW(emptyW, NULL, 10);
1609 ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
1610
1611 ret = pStrStrNIW(emptyW, emptyW, 10);
1612 ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
1613
1614 for (i = 0; i < ARRAY_SIZE(StrStrNIW_cases); i++)
1615 {
1616 ret = pStrStrNIW(deadbeefW, StrStrNIW_cases[i].search, StrStrNIW_cases[i].count);
1617 ok(ret == StrStrNIW_cases[i].expect,
1618 "[%d] Expected StrStrNIW to return %p, got %p\n",
1619 i, StrStrNIW_cases[i].expect, ret);
1620 }
1621
1622 /* StrStrNIW accepts counts larger than the search string length but rejects
1623 * counts larger than around 2G. The limit seems to change based on the
1624 * caller executable itself. */
1625 ret = pStrStrNIW(deadbeefW, beefW, 100);
1626 ok(ret == deadbeefW + 4, "Expected StrStrNIW to return deadbeefW + 4, got %p\n", ret);
1627
1628 if (0)
1629 {
1630 ret = pStrStrNIW(deadbeefW, beefW, ~0U);
1631 ok(!ret, "Expected StrStrNIW to return NULL, got %p\n", ret);
1632 }
1633}
1634
1635static void test_StrCatChainW(void)
1636{
1637 static const WCHAR deadbeefW[] = {'D','e','A','d','B','e','E','f',0};
1638 static const WCHAR deadW[] = {'D','e','A','d',0};
1639 static const WCHAR beefW[] = {'B','e','E','f',0};
1640
1641 WCHAR buf[32 + 1];
1642 DWORD ret;
1643
1644 if (!pStrCatChainW)
1645 {
1646 win_skip("StrCatChainW is not available\n");
1647 return;
1648 }
1649
1650 /* Test with NULL buffer */
1651 ret = pStrCatChainW(NULL, 0, 0, beefW);
1652 ok(ret == 0, "Expected StrCatChainW to return 0, got %lu\n", ret);
1653
1654 /* Test with empty buffer */
1655 memset(buf, 0x11, sizeof(buf));
1656 ret = pStrCatChainW(buf, 0, 0, beefW);
1657 ok(ret == 0, "Expected StrCatChainW to return 0, got %lu\n", ret);
1658 ok(buf[0] == 0x1111, "Expected buf[0] = 0x1111, got %x\n", buf[0]);
1659
1660 memcpy(buf, deadbeefW, sizeof(deadbeefW));
1661 ret = pStrCatChainW(buf, 0, -1, beefW);
1662 ok(ret == 8, "Expected StrCatChainW to return 8, got %lu\n", ret);
1663 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1664
1665 /* Append data to existing string with offset = -1 */
1666 memset(buf, 0x11, sizeof(buf));
1667 ret = pStrCatChainW(buf, 32, 0, deadW);
1668 ok(ret == 4, "Expected StrCatChainW to return 4, got %lu\n", ret);
1669 ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1670
1671 ret = pStrCatChainW(buf, 32, -1, beefW);
1672 ok(ret == 8, "Expected StrCatChainW to return 8, got %lu\n", ret);
1673 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1674
1675 /* Append data at a fixed offset */
1676 memset(buf, 0x11, sizeof(buf));
1677 ret = pStrCatChainW(buf, 32, 0, deadW);
1678 ok(ret == 4, "Expected StrCatChainW to return 4, got %lu\n", ret);
1679 ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1680
1681 ret = pStrCatChainW(buf, 32, 4, beefW);
1682 ok(ret == 8, "Expected StrCatChainW to return 8, got %lu\n", ret);
1683 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1684
1685 /* Buffer exactly sufficient for string + terminating null */
1686 memset(buf, 0x11, sizeof(buf));
1687 ret = pStrCatChainW(buf, 5, 0, deadW);
1688 ok(ret == 4, "Expected StrCatChainW to return 4, got %lu\n", ret);
1689 ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1690
1691 /* Buffer too small, string will be truncated */
1692 memset(buf, 0x11, sizeof(buf));
1693 ret = pStrCatChainW(buf, 4, 0, deadW);
1694 if (ret == 4)
1695 {
1696 /* Windows 2000 and XP uses a slightly different implementation
1697 * for StrCatChainW, which doesn't ensure that strings are null-
1698 * terminated. Skip test if we detect such an implementation. */
1699 win_skip("Windows2000/XP behaviour detected for StrCatChainW, skipping tests\n");
1700 return;
1701 }
1702 ok(ret == 3, "Expected StrCatChainW to return 3, got %lu\n", ret);
1703 ok(!memcmp(buf, deadW, 3 * sizeof(WCHAR)), "Buffer contains wrong data\n");
1704 ok(!buf[3], "String is not nullterminated\n");
1705 ok(buf[4] == 0x1111, "Expected buf[4] = 0x1111, got %x\n", buf[4]);
1706
1707 /* Overwrite part of an existing string */
1708 ret = pStrCatChainW(buf, 4, 1, beefW);
1709 ok(ret == 3, "Expected StrCatChainW to return 3, got %lu\n", ret);
1710 ok(buf[0] == 'D', "Expected buf[0] = 'D', got %x\n", buf[0]);
1711 ok(buf[1] == 'B', "Expected buf[1] = 'B', got %x\n", buf[1]);
1712 ok(buf[2] == 'e', "Expected buf[2] = 'e', got %x\n", buf[2]);
1713 ok(!buf[3], "String is not nullterminated\n");
1714 ok(buf[4] == 0x1111, "Expected buf[4] = 0x1111, got %x\n", buf[4]);
1715
1716 /* Test appending to full buffer */
1717 memset(buf, 0x11, sizeof(buf));
1718 memcpy(buf, deadbeefW, sizeof(deadbeefW));
1719 memcpy(buf + 9, deadW, sizeof(deadW));
1720 ret = pStrCatChainW(buf, 9, 8, beefW);
1721 ok(ret == 8, "Expected StrCatChainW to return 8, got %lu\n", ret);
1722 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1723 ok(!memcmp(buf + 9, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1724
1725 /* Offset points at the end of the buffer */
1726 ret = pStrCatChainW(buf, 9, 9, beefW);
1727 ok(ret == 8, "Expected StrCatChainW to return 8, got %lu\n", ret);
1728 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1729 ok(!memcmp(buf + 9, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1730
1731 /* Offset points outside of the buffer */
1732 ret = pStrCatChainW(buf, 9, 10, beefW);
1733 ok(ret == 10, "Expected StrCatChainW to return 10, got %lu\n", ret);
1734 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1735 ok(!memcmp(buf + 9, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1736
1737 /* The same but without nullterminated string */
1738 memcpy(buf, deadbeefW, sizeof(deadbeefW));
1739 ret = pStrCatChainW(buf, 5, -1, deadW);
1740 ok(ret == 8, "Expected StrCatChainW to return 8, got %lu\n", ret);
1741 ok(!memcmp(buf, deadbeefW, sizeof(deadbeefW)), "Buffer contains wrong data\n");
1742
1743 ret = pStrCatChainW(buf, 5, 5, deadW);
1744 ok(ret == 4, "Expected StrCatChainW to return 4, got %lu\n", ret);
1745 ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1746 ok(buf[5] == 'e', "Expected buf[5] = 'e', got %x\n", buf[5]);
1747
1748 ret = pStrCatChainW(buf, 5, 6, deadW);
1749 ok(ret == 6, "Expected StrCatChainW to return 6, got %lu\n", ret);
1750 ok(!memcmp(buf, deadW, sizeof(deadW)), "Buffer contains wrong data\n");
1751 ok(buf[5] == 'e', "Expected buf[5] = 'e', got %x\n", buf[5]);
1752}
1753
1754static void test_printf_format(void)
1755{
1756 const struct
1757 {
1758 const char *spec;
1759 unsigned int arg_size;
1760 ULONG64 arg;
1761 const void *argw;
1762 }
1763 tests[] =
1764 {
1765 { "%qu", 0, 10 },
1766 { "%ll", 0, 10 },
1767 { "%lu", sizeof(ULONG), 65537 },
1768 { "%llu", sizeof(ULONG64), 10 },
1769 { "%lllllllu", sizeof(ULONG64), 10 },
1770 { "%#lx", sizeof(ULONG), 10 },
1771 { "%#llx", sizeof(ULONG64), 0x1000000000 },
1772 { "%#lllx", sizeof(ULONG64), 0x1000000000 },
1773 { "%hu", sizeof(ULONG), 65537 },
1774 { "%hlu", sizeof(ULONG), 65537 },
1775 { "%hllx", sizeof(ULONG64), 0x100000010 },
1776 { "%hlllx", sizeof(ULONG64), 0x100000010 },
1777 { "%llhx", sizeof(ULONG64), 0x100000010 },
1778 { "%lllhx", sizeof(ULONG64), 0x100000010 },
1779 { "%lhu", sizeof(ULONG), 65537 },
1780 { "%hhu", sizeof(ULONG), 65537 },
1781 { "%hwu", sizeof(ULONG), 65537 },
1782 { "%whu", sizeof(ULONG), 65537 },
1783 { "%##lhllwlx", sizeof(ULONG64), 0x1000000010 },
1784 { "%##lhlwlx", sizeof(ULONG), 0x1000000010 },
1785 { "%04lhlwllx", sizeof(ULONG64), 0x1000000010 },
1786 { "%s", sizeof(ULONG_PTR), (ULONG_PTR)"str", L"str" },
1787 { "%S", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1788 { "%ls", sizeof(ULONG_PTR), (ULONG_PTR)L"str" },
1789 { "%lS", sizeof(ULONG_PTR), (ULONG_PTR)L"str" },
1790 { "%lls", sizeof(ULONG_PTR), (ULONG_PTR)"str", L"str" },
1791 { "%llS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1792 { "%llls", sizeof(ULONG_PTR), (ULONG_PTR)L"str" },
1793 { "%lllS", sizeof(ULONG_PTR), (ULONG_PTR)L"str" },
1794 { "%lllls", sizeof(ULONG_PTR), (ULONG_PTR)"str", L"str" },
1795 { "%llllS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1796 { "%hs", sizeof(ULONG_PTR), (ULONG_PTR)"str" },
1797 { "%hS", sizeof(ULONG_PTR), (ULONG_PTR)"str" },
1798 { "%ws", sizeof(ULONG_PTR), (ULONG_PTR)L"str" },
1799 { "%wS", sizeof(ULONG_PTR), (ULONG_PTR)L"str" },
1800 { "%hhs", sizeof(ULONG_PTR), (ULONG_PTR)"str" },
1801 { "%hhS", sizeof(ULONG_PTR), (ULONG_PTR)"str" },
1802 { "%wws", sizeof(ULONG_PTR), (ULONG_PTR)L"str" },
1803 { "%wwS", sizeof(ULONG_PTR), (ULONG_PTR)L"str" },
1804 { "%wwws", sizeof(ULONG_PTR), (ULONG_PTR)L"str" },
1805 { "%wwwS", sizeof(ULONG_PTR), (ULONG_PTR)L"str" },
1806 { "%hws", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1807 { "%hwS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1808 { "%whs", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1809 { "%whS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1810 { "%hwls", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1811 { "%hwlls", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1812 { "%hwlS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1813 { "%hwllS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1814 { "%lhws", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1815 { "%llhws", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1816 { "%lhwS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1817 { "%llhwS", sizeof(ULONG_PTR), (ULONG_PTR)L"str", "str" },
1818 { "%c", sizeof(SHORT), 0x95c8 },
1819 { "%lc", sizeof(SHORT), 0x95c8 },
1820 { "%llc", sizeof(SHORT), 0x95c8 },
1821 { "%lllc", sizeof(SHORT), 0x95c8 },
1822 { "%llllc", sizeof(SHORT), 0x95c8 },
1823 { "%lllllc", sizeof(SHORT), 0x95c8 },
1824 { "%C", sizeof(SHORT), 0x95c8 },
1825 { "%lC", sizeof(SHORT), 0x95c8 },
1826 { "%llC", sizeof(SHORT), 0x95c8 },
1827 { "%lllC", sizeof(SHORT), 0x95c8 },
1828 { "%llllC", sizeof(SHORT), 0x95c8 },
1829 { "%lllllC", sizeof(SHORT), 0x95c8 },
1830 { "%hc", sizeof(BYTE), 0x95c8 },
1831 { "%hhc", sizeof(BYTE), 0x95c8 },
1832 { "%hhhc", sizeof(BYTE), 0x95c8 },
1833 { "%wc", sizeof(BYTE), 0x95c8 },
1834 { "%wC", sizeof(BYTE), 0x95c8 },
1835 { "%hwc", sizeof(BYTE), 0x95c8 },
1836 { "%whc", sizeof(BYTE), 0x95c8 },
1837 { "%hwC", sizeof(BYTE), 0x95c8 },
1838 { "%whC", sizeof(BYTE), 0x95c8 },
1839 { "%I64u", sizeof(ULONG64), 10 },
1840 { "%llI64u", sizeof(ULONG64), 10 },
1841 { "%I64llu", sizeof(ULONG64), 10 },
1842 { "%I64s", sizeof(ULONG_PTR), (ULONG_PTR)"str", L"str" },
1843 { "%q%u", sizeof(ULONG), 10 },
1844 { "%lhw%u", 0, 10 },
1845 { "%u% ", sizeof(ULONG), 10 },
1846 { "%u% %u", sizeof(ULONG), 10 },
1847 { "% ll u", 0, 10 },
1848 { "% llu", sizeof(ULONG64), 10 },
1849 { "%# llx", sizeof(ULONG64), 10 },
1850 { "% #llx", sizeof(ULONG64), 10 },
1851 };
1852 int (WINAPIV *ntdll__snprintf)(char *str, size_t len, const char *format, ...);
1853 int (WINAPIV *ntdll__snwprintf)( WCHAR *str, size_t len, const WCHAR *format, ... );
1854 WCHAR ws[256], expectedw[256], specw[256];
1855 unsigned int i, j;
1856 char expected[256], spec[256], s[256];
1857 int len_a, len_w = 0, expected_len_a, expected_len_w = 0;
1858 HANDLE hntdll = GetModuleHandleW(L"ntdll.dll");
1859
1860 ntdll__snprintf = (void *)GetProcAddress(hntdll, "_snprintf");
1861 ok(!!ntdll__snprintf, "_snprintf not found.\n");
1862 ntdll__snwprintf = (void *)GetProcAddress(hntdll, "_snwprintf");
1863 ok(!!ntdll__snwprintf, "_snwprintf not found.\n");
1864#ifdef __REACTOS__
1865 DWORD _ntVersion = GetVersion();
1866 BYTE _ntMajor = LOBYTE(LOWORD(_ntVersion));
1867 BYTE _ntMinor = HIBYTE(LOWORD(_ntVersion));
1868
1869 if (_ntMajor < 6 || (_ntMajor == 6 && _ntMinor == 0)) {
1870 skip("These tests are broken on WS03 and Vista.\n");
1871 return;
1872 }
1873#endif
1874
1875 for (i = 0; i < ARRAY_SIZE(tests); ++i)
1876 {
1877 strcpy(spec, tests[i].spec);
1878 winetest_push_context("%s", spec);
1879 strcat(spec,"|%s");
1880 *s = 0;
1881 *ws = 0;
1882 j = 0;
1883 do
1884 specw[j] = spec[j];
1885 while (specw[j++]);
1886 if (tests[i].argw)
1887 {
1888 len_w = pwnsprintfW(ws, ARRAY_SIZE(ws), specw, tests[i].argw, L"end");
1889 expected_len_w = ntdll__snwprintf(expectedw, ARRAY_SIZE(expectedw), specw, tests[i].argw, L"end");
1890 }
1891 switch (tests[i].arg_size)
1892 {
1893 case 0:
1894 len_a = pwnsprintfA(s, ARRAY_SIZE(s), spec, "end");
1895 expected_len_a = ntdll__snprintf(expected, ARRAY_SIZE(expected), spec, "end");
1896 len_w = pwnsprintfW(ws, ARRAY_SIZE(ws), specw, L"end");
1897 expected_len_w = ntdll__snwprintf(expectedw, ARRAY_SIZE(expectedw), specw, L"end");
1898 break;
1899 case 1:
1900 case 2:
1901 case 4:
1902 len_a = pwnsprintfA(s, ARRAY_SIZE(s), spec, (ULONG)tests[i].arg, "end");
1903 expected_len_a = ntdll__snprintf(expected, ARRAY_SIZE(expected), spec, (ULONG)tests[i].arg, "end");
1904 if (!tests[i].argw)
1905 {
1906 len_w = pwnsprintfW(ws, ARRAY_SIZE(ws), specw, (ULONG)tests[i].arg, L"end");
1907 expected_len_w = ntdll__snwprintf(expectedw, ARRAY_SIZE(expectedw), specw, (ULONG)tests[i].arg, L"end");
1908 }
1909 break;
1910 case 8:
1911 len_a = pwnsprintfA(s, ARRAY_SIZE(s), spec, (ULONG64)tests[i].arg, "end");
1912 expected_len_a = ntdll__snprintf(expected, ARRAY_SIZE(s), spec, (ULONG64)tests[i].arg, "end");
1913 if (!tests[i].argw)
1914 {
1915 len_w = pwnsprintfW(ws, ARRAY_SIZE(ws), specw, (ULONG64)tests[i].arg, L"end");
1916 expected_len_w = ntdll__snwprintf(expectedw, ARRAY_SIZE(expectedw), specw, (ULONG64)tests[i].arg, L"end");
1917 }
1918 break;
1919 default:
1920 len_a = len_w = expected_len_a = expected_len_w = 0;
1921 ok(0, "unknown length %u.\n", tests[i].arg_size);
1922 break;
1923 }
1924 ok(len_a == expected_len_a, "got len %d, expected %d.\n", len_a, expected_len_a);
1925 ok(!strcmp(s, expected), "got %s, expected %s.\n", debugstr_a(s), debugstr_a(expected));
1926 ok(len_w == expected_len_w, "got len %d, expected %d.\n", len_a, expected_len_a);
1927 ok(!wcscmp(ws, expectedw), "got %s, expected %s.\n", debugstr_w(ws), debugstr_w(expectedw));
1929 }
1930}
1931
1933{
1935 CHAR thousandDelim[8];
1936 CHAR decimalDelim[8];
1937 CoInitialize(0);
1938
1941
1942 hShlwapi = GetModuleHandleA("shlwapi");
1943 pChrCmpIA = (void *)GetProcAddress(hShlwapi, "ChrCmpIA");
1944 pChrCmpIW = (void *)GetProcAddress(hShlwapi, "ChrCmpIW");
1945 pIntlStrEqWorkerA = (void *)GetProcAddress(hShlwapi, "IntlStrEqWorkerA");
1946 pIntlStrEqWorkerW = (void *)GetProcAddress(hShlwapi, "IntlStrEqWorkerW");
1947 pSHAnsiToAnsi = (void *)GetProcAddress(hShlwapi, (LPSTR)345);
1948 pSHUnicodeToUnicode = (void *)GetProcAddress(hShlwapi, (LPSTR)346);
1949 pStrCatBuffA = (void *)GetProcAddress(hShlwapi, "StrCatBuffA");
1950 pStrCatBuffW = (void *)GetProcAddress(hShlwapi, "StrCatBuffW");
1951 pStrCatChainW = (void *)GetProcAddress(hShlwapi, "StrCatChainW");
1952 pStrCpyNXA = (void *)GetProcAddress(hShlwapi, (LPSTR)399);
1953 pStrCpyNXW = (void *)GetProcAddress(hShlwapi, (LPSTR)400);
1954 pStrChrNW = (void *)GetProcAddress(hShlwapi, "StrChrNW");
1955 pStrFormatByteSize64A = (void *)GetProcAddress(hShlwapi, "StrFormatByteSize64A");
1956 pStrFormatByteSizeEx = (void *)GetProcAddress(hShlwapi, "StrFormatByteSizeEx");
1957 pStrFormatKBSizeA = (void *)GetProcAddress(hShlwapi, "StrFormatKBSizeA");
1958 pStrFormatKBSizeW = (void *)GetProcAddress(hShlwapi, "StrFormatKBSizeW");
1959 pStrIsIntlEqualA = (void *)GetProcAddress(hShlwapi, "StrIsIntlEqualA");
1960 pStrIsIntlEqualW = (void *)GetProcAddress(hShlwapi, "StrIsIntlEqualW");
1961 pStrPBrkW = (void *)GetProcAddress(hShlwapi, "StrPBrkW");
1962 pStrRChrA = (void *)GetProcAddress(hShlwapi, "StrRChrA");
1963 pStrRetToBSTR = (void *)GetProcAddress(hShlwapi, "StrRetToBSTR");
1964 pStrRetToBufA = (void *)GetProcAddress(hShlwapi, "StrRetToBufA");
1965 pStrRetToBufW = (void *)GetProcAddress(hShlwapi, "StrRetToBufW");
1966 pStrStrNW = (void *)GetProcAddress(hShlwapi, "StrStrNW");
1967 pStrStrNIW = (void *)GetProcAddress(hShlwapi, "StrStrNIW");
1968 pwnsprintfA = (void *)GetProcAddress(hShlwapi, "wnsprintfA");
1969 pwnsprintfW = (void *)GetProcAddress(hShlwapi, "wnsprintfW");
1970 pStrToInt64ExA = (void *)GetProcAddress(hShlwapi, "StrToInt64ExA");
1971 pStrToInt64ExW = (void *)GetProcAddress(hShlwapi, "StrToInt64ExW");
1972
1973 test_StrChrA();
1974 test_StrChrW();
1975 test_StrChrIA();
1976 test_StrChrIW();
1977 test_StrRChrA();
1978 test_StrRChrW();
1979 test_StrCpyW();
1980 test_StrChrNW();
1987 test_StrDupA();
1988
1989 /* language-dependent test */
1991 {
1996 }
1997 else
1998 skip("An English UI and locale is required for the StrFormat*Size tests\n");
1999 if (is_lang_english())
2001 else
2002 skip("An English UI is required for the StrFromTimeInterval tests\n");
2003
2004 test_StrCmpA();
2005 test_StrCmpW();
2009 test_StrRStrI();
2013 test_StrStrA();
2014 test_StrStrW();
2015 test_StrStrIA();
2016 test_StrStrIW();
2017 test_StrStrNW();
2021
2023}
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ARRAY_SIZE(A)
Definition: main.h:20
#define U(x)
Definition: wordpad.c:45
Definition: ehthrow.cxx:93
static HMODULE hShlwapi
Definition: clsid.c:38
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
INT WINAPI StrToIntW(LPCWSTR lpString)
Definition: string.c:407
LPWSTR WINAPI StrChrIW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:631
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
LPWSTR WINAPI StrRChrW(LPCWSTR str, LPCWSTR end, WORD ch)
Definition: string.c:552
LPSTR WINAPI StrStrIA(LPCSTR lpszStr, LPCSTR lpszSearch)
Definition: string.c:351
INT WINAPI StrCmpNIA(LPCSTR lpszStr, LPCSTR lpszComp, INT iLen)
Definition: string.c:296
LPSTR WINAPI StrChrIA(LPCSTR lpszStr, WORD ch)
Definition: string.c:610
LPWSTR WINAPI StrStrW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
Definition: string.c:590
LPSTR WINAPI StrRChrA(LPCSTR lpszStr, LPCSTR lpszEnd, WORD ch)
Definition: string.c:521
INT WINAPI StrToIntA(LPCSTR lpszStr)
Definition: string.c:370
LPSTR WINAPI StrChrA(LPCSTR lpszStr, WORD ch)
Definition: string.c:266
INT WINAPI StrCmpNIW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:307
LPWSTR WINAPI StrStrIW(LPCWSTR lpszStr, LPCWSTR lpszSearch)
Definition: string.c:380
INT WINAPI StrCmpNW(LPCWSTR lpszStr, LPCWSTR lpszComp, INT iLen)
Definition: string.c:500
LPSTR WINAPI StrStrA(LPCSTR lpszStr, LPCSTR lpszSearch)
Definition: string.c:578
INT WINAPI StrCmpNA(LPCSTR lpszStr, LPCSTR lpszComp, INT iLen)
Definition: string.c:489
#define CP_ACP
Definition: compat.h:109
#define GetProcAddress(x, y)
Definition: compat.h:753
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
OLECHAR * BSTR
Definition: compat.h:2293
#define MAX_PATH
Definition: compat.h:34
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
INT WINAPI GetLocaleInfoA(LCID lcid, LCTYPE lctype, LPSTR buffer, INT len)
Definition: locale.c:1609
LANGID WINAPI GetUserDefaultLangID(void)
Definition: locale.c:1182
BOOL WINAPI StrToIntExW(const WCHAR *str, DWORD flags, INT *ret)
Definition: string.c:972
int WINAPI StrCmpW(const WCHAR *str, const WCHAR *comp)
Definition: string.c:450
BOOL WINAPI StrToIntExA(const char *str, DWORD flags, INT *ret)
Definition: string.c:960
WCHAR *WINAPI StrDupW(const WCHAR *str)
Definition: string.c:313
char *WINAPI StrDupA(const char *str)
Definition: string.c:292
WCHAR *WINAPI StrCpyNW(WCHAR *dst, const WCHAR *src, int count)
Definition: string.c:462
DWORD WINAPI GetVersion(void)
Definition: version.c:1458
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
INT WINAPI StrFromTimeIntervalA(LPSTR lpszStr, UINT cchMax, DWORD dwMS, int iDigits)
Definition: string.c:2131
LPWSTR WINAPI StrCpyW(LPWSTR lpszStr, LPCWSTR lpszSrc)
Definition: string.c:514
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
#define ULONG_PTR
Definition: config.h:101
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLenum src
Definition: glext.h:6340
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
static const WCHAR emptyW[]
Definition: navigate.c:40
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
#define S_OK
Definition: intsafe.h:52
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
USHORT LANGID
Definition: mui.h:9
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
#define win_skip
Definition: minitest.h:67
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
char string[160]
Definition: util.h:11
unsigned __int64 ULONG64
Definition: imports.h:198
static struct test_info tests[]
BOOL expected
Definition: store.c:2000
HRESULT hres
Definition: protocol.c:465
static HINSTANCE hkernel32
Definition: process.c:66
static int test_value
Definition: signal.c:25
static char int
Definition: string.c:81
#define expect_eq(expr, value, type, format)
Definition: string.c:58
static char * dest
Definition: rtl.c:135
static HMODULE hntdll
Definition: string.c:30
static LPSTR
Definition: string.c:39
static INT
Definition: string.c:39
static LPCSTR
Definition: string.c:33
static const ITEMIDLIST *static WCHAR * CoDupStrW(const char *src)
Definition: string.c:37
static DWORD
Definition: string.c:35
static void test_StrFormatByteSize64A(void)
Definition: string.c:696
static void test_StrChrIW(void)
Definition: string.c:317
static void test_StrStrIW(void)
Definition: string.c:1403
static void test_StrChrW(void)
Definition: string.c:265
static void test_StrFormatKBSizeA(void)
Definition: string.c:774
static BOOL is_locale_english(void)
Definition: string.c:233
static void test_StrStrNW(void)
Definition: string.c:1459
static void test_StrDupA(void)
Definition: string.c:670
static const StrFormatSizeResult StrFormatSize_results[]
Definition: string.c:125
#define check_strrstri(type, str, pos, needle, exp)
Definition: string.c:964
static void test_StrCmpA(void)
Definition: string.c:814
static void test_StrStrIA(void)
Definition: string.c:1355
static void test_printf_format(void)
Definition: string.c:1754
static void test_StrToInt64ExW(void)
Definition: string.c:615
static void test_StrFromTimeIntervalA(void)
Definition: string.c:799
static void test_SHUnicodeToUnicode(void)
Definition: string.c:1027
static void test_StrToInt64ExA(void)
Definition: string.c:571
static void test_StrToIntA(void)
Definition: string.c:458
static const StrFromTimeIntervalResult StrFromTimeInterval_results[]
Definition: string.c:153
static void test_StrRChrA(void)
Definition: string.c:344
static void test_StrRetToBSTR(void)
Definition: string.c:884
static void test_StrToIntExW(void)
Definition: string.c:524
static BOOL is_lang_english(void)
Definition: string.c:210
static void test_StrChrA(void)
Definition: string.c:239
static void test_StrCatChainW(void)
Definition: string.c:1635
static void test_StrRStrI(void)
Definition: string.c:969
static SFBS_FLAGS
Definition: string.c:55
static void test_StrStrW(void)
Definition: string.c:1301
static void test_SHAnsiToAnsi(void)
Definition: string.c:1003
static void test_StrToIntW(void)
Definition: string.c:472
static CHAR
Definition: string.c:43
#define expect_eq2(expr, val1, val2, type, fmt)
Definition: string.c:38
static void test_StrChrIA(void)
Definition: string.c:290
static void test_StrCpyW(void)
Definition: string.c:407
struct tagStrFormatSizeResult StrFormatSizeResult
static WORD
Definition: string.c:61
static void test_StrFormatKBSizeW(void)
Definition: string.c:751
static void test_StrToIntExA(void)
Definition: string.c:488
static void test_StrCmpW(void)
Definition: string.c:845
static void test_StrFormatByteSizeEx(void)
Definition: string.c:719
static void test_StrChrNW(void)
Definition: string.c:436
static LONGLONG *static LONGLONG *struct tagStrToIntResult StrToIntResult
static void test_StrStrNIW(void)
Definition: string.c:1541
static UINT
Definition: string.c:54
static void test_StrXXX_overflows(void)
Definition: string.c:1054
static void test_StrStrA(void)
Definition: string.c:1254
static LPCITEMIDLIST
Definition: string.c:62
static const StrToIntResult StrToInt_results[]
Definition: string.c:83
struct tagStrFromTimeIntervalResult StrFromTimeIntervalResult
static void test_StrRChrW(void)
Definition: string.c:375
static void test_StrCpyNXW(void)
Definition: string.c:943
static void test_StrCpyNXA(void)
Definition: string.c:924
static short search(int val, const short *table, int size)
Definition: msg711.c:255
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
#define LOCALE_USER_DEFAULT
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
#define LOWORD(l)
Definition: pedump.c:82
short SHORT
Definition: pedump.c:59
@ SFBS_FLAGS_TRUNCATE_UNDISPLAYED_DECIMAL_DIGITS
Definition: shlwapi.h:1265
@ SFBS_FLAGS_ROUND_TO_NEAREST_DISPLAYED_DIGIT
Definition: shlwapi.h:1264
#define STIF_SUPPORT_HEX
Definition: shlwapi.h:1059
#define StrCpyNA
Definition: shlwapi.h:1104
const WCHAR * str
#define WINAPIV
Definition: sdbpapi.h:64
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define LANG_ENGLISH
Definition: nls.h:52
#define PRIMARYLANGID(l)
Definition: nls.h:16
strcat
Definition: string.h:92
strcpy
Definition: string.h:131
#define memset(x, y, z)
Definition: compat.h:39
HRESULT hr
Definition: shlfolder.c:183
@ STRRET_CSTR
Definition: shtypes.idl:87
@ STRRET_OFFSET
Definition: shtypes.idl:86
@ STRRET_WSTR
Definition: shtypes.idl:85
const char * ws
Definition: skip_ws.cpp:7
Definition: polytest.cpp:36
char cStr[MAX_PATH]
Definition: shtypes.idl:98
UINT uType
Definition: shtypes.idl:93
LPWSTR pOleStr
Definition: shtypes.idl:96
UINT uOffset
Definition: shtypes.idl:97
Definition: dsound.c:943
Definition: format.c:58
const char * kb_size2
Definition: string.c:121
const char * kb_size
Definition: string.c:119
const char * byte_size_64
Definition: string.c:118
const char * time_interval
Definition: string.c:149
const char * string
Definition: string.c:76
LONGLONG str_to_int64_ex
Definition: string.c:78
LONGLONG str_to_int64_hex
Definition: string.c:79
int64_t LONGLONG
Definition: typedefs.h:68
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
void * arg
Definition: msvc.h:10
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define E_NOT_SUFFICIENT_BUFFER
Definition: winerror.h:3437
#define LOCALE_SDECIMAL
Definition: winnls.h:49
#define LOCALE_STHOUSAND
Definition: winnls.h:50
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char * LPSTR
Definition: xmlstorage.h:182
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193