dxgi/tests: Fix output ownership test failures on Win10 1909.
[wine.git] / dlls / msvcrt / tests / dir.c
blob6c817dfb2ecc245367b03db98ca6712ae316d499
1 /*
2 * Unit test suite for dir functions
4 * Copyright 2006 CodeWeavers, Aric Stewart
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/test.h"
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <fcntl.h>
26 #include <direct.h>
27 #include <sys/stat.h>
28 #include <io.h>
29 #include <mbctype.h>
30 #include <windef.h>
31 #include <winbase.h>
32 #include <winnls.h>
33 #include <process.h>
34 #include <errno.h>
36 static int (__cdecl *p_makepath_s)(char *, size_t, const char *, const char *, const char *, const char *);
37 static int (__cdecl *p_wmakepath_s)(wchar_t *, size_t, const wchar_t *,const wchar_t *, const wchar_t *, const wchar_t *);
38 static int (__cdecl *p_searchenv_s)(const char*, const char*, char*, size_t);
39 static int (__cdecl *p_wsearchenv_s)(const wchar_t*, const wchar_t*, wchar_t*, size_t);
41 static void init(void)
43 HMODULE hmod = GetModuleHandleA("msvcrt.dll");
45 p_makepath_s = (void *)GetProcAddress(hmod, "_makepath_s");
46 p_wmakepath_s = (void *)GetProcAddress(hmod, "_wmakepath_s");
47 p_searchenv_s = (void *)GetProcAddress(hmod, "_searchenv_s");
48 p_wsearchenv_s = (void *)GetProcAddress(hmod, "_wsearchenv_s");
51 typedef struct
53 const char* buffer;
54 const char* drive;
55 const char* dir;
56 const char* file;
57 const char* ext;
58 const char* expected;
59 } makepath_case;
61 #define USE_BUFF ((char*)~0ul)
62 static const makepath_case makepath_cases[] =
64 { NULL, NULL, NULL, NULL, NULL, "" }, /* 0 */
65 { NULL, "c", NULL, NULL, NULL, "c:" },
66 { NULL, "c:", NULL, NULL, NULL, "c:" },
67 { NULL, "c:\\", NULL, NULL, NULL, "c:" },
68 { NULL, NULL, "dir", NULL, NULL, "dir\\" },
69 { NULL, NULL, "dir\\", NULL, NULL, "dir\\" },
70 { NULL, NULL, "\\dir", NULL, NULL, "\\dir\\" },
71 { NULL, NULL, NULL, "file", NULL, "file" },
72 { NULL, NULL, NULL, "\\file", NULL, "\\file" },
73 { NULL, NULL, NULL, "file", NULL, "file" },
74 { NULL, NULL, NULL, NULL, "ext", ".ext" }, /* 10 */
75 { NULL, NULL, NULL, NULL, ".ext", ".ext" },
76 { "foo", NULL, NULL, NULL, NULL, "" },
77 { "foo", USE_BUFF, NULL, NULL, NULL, "f:" },
78 { "foo", NULL, USE_BUFF, NULL, NULL, "foo\\" },
79 { "foo", NULL, NULL, USE_BUFF, NULL, "foo" },
80 { "foo", NULL, USE_BUFF, "file", NULL, "foo\\file" },
81 { "foo", NULL, USE_BUFF, "file", "ext", "foo\\file.ext" },
82 { "foo", NULL, NULL, USE_BUFF, "ext", "foo.ext" },
83 /* remaining combinations of USE_BUFF crash native */
84 { NULL, "c", "dir", "file", "ext", "c:dir\\file.ext" },
85 { NULL, "c:", "dir", "file", "ext", "c:dir\\file.ext" }, /* 20 */
86 { NULL, "c:\\", "dir", "file", "ext", "c:dir\\file.ext" }
89 static void test_makepath(void)
91 WCHAR driveW[MAX_PATH];
92 WCHAR dirW[MAX_PATH];
93 WCHAR fileW[MAX_PATH];
94 WCHAR extW[MAX_PATH];
95 WCHAR bufferW[MAX_PATH];
96 char buffer[MAX_PATH];
98 unsigned int i, n;
100 for (i = 0; i < ARRAY_SIZE(makepath_cases); ++i)
102 const makepath_case* p = &makepath_cases[i];
104 memset(buffer, 'X', MAX_PATH);
105 if (p->buffer)
106 strcpy(buffer, p->buffer);
108 /* Ascii */
109 _makepath(buffer,
110 p->drive == USE_BUFF ? buffer : p->drive,
111 p->dir == USE_BUFF ? buffer : p->dir,
112 p->file == USE_BUFF? buffer : p->file,
113 p->ext == USE_BUFF ? buffer : p->ext);
115 buffer[MAX_PATH - 1] = '\0';
116 ok(!strcmp(p->expected, buffer), "got '%s' for case %d\n", buffer, i);
118 /* Unicode */
119 if (p->drive != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->drive, -1, driveW, MAX_PATH);
120 if (p->dir != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->dir, -1, dirW, MAX_PATH);
121 if (p->file != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->file, -1, fileW, MAX_PATH);
122 if (p->ext != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->ext, -1, extW, MAX_PATH);
124 memset(buffer, 0, MAX_PATH);
125 for (n = 0; n < MAX_PATH; ++n)
126 bufferW[n] = 'X';
127 if (p->buffer) MultiByteToWideChar( CP_ACP, 0, p->buffer, -1, bufferW, MAX_PATH);
129 _wmakepath(bufferW,
130 p->drive == USE_BUFF ? bufferW : p->drive ? driveW : NULL,
131 p->dir == USE_BUFF ? bufferW : p->dir ? dirW : NULL,
132 p->file == USE_BUFF? bufferW : p->file ? fileW : NULL,
133 p->ext == USE_BUFF ? bufferW : p->ext ? extW : NULL);
135 bufferW[MAX_PATH - 1] = '\0';
136 WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
137 ok(!strcmp(p->expected, buffer), "got '%s' for unicode case %d\n", buffer, i);
141 static const WCHAR expected0[] = {'\0','X','X','X','X','X','X','X','X','X','X','X','X'};
142 static const WCHAR expected1[] = {'\0','X','X','X','X','X','X','X','X','X','X','X','X'};
143 static const WCHAR expected2[] = {'\0',':','X','X','X','X','X','X','X','X','X','X','X'};
144 static const WCHAR expected3[] = {'\0',':','d','X','X','X','X','X','X','X','X','X','X'};
145 static const WCHAR expected4[] = {'\0',':','d','\\','X','X','X','X','X','X','X','X','X'};
146 static const WCHAR expected5[] = {'\0',':','d','\\','f','X','X','X','X','X','X','X','X'};
147 static const WCHAR expected6[] = {'\0',':','d','\\','f','i','X','X','X','X','X','X','X'};
148 static const WCHAR expected7[] = {'\0',':','d','\\','f','i','l','X','X','X','X','X','X'};
149 static const WCHAR expected8[] = {'\0',':','d','\\','f','i','l','e','X','X','X','X','X'};
150 static const WCHAR expected9[] = {'\0',':','d','\\','f','i','l','e','.','X','X','X','X'};
151 static const WCHAR expected10[] = {'\0',':','d','\\','f','i','l','e','.','e','X','X','X'};
152 static const WCHAR expected11[] = {'\0',':','d','\\','f','i','l','e','.','e','x','X','X'};
154 static const WCHAR expected12[] = {'\0',':','X','X','X','X','X','X','X','X'};
155 static const WCHAR expected13[] = {'\0',':','d','X','X','X','X','X','X','X'};
156 static const WCHAR expected14[] = {'\0',':','d','i','X','X','X','X','X','X'};
157 static const WCHAR expected15[] = {'\0',':','d','i','r','X','X','X','X','X'};
158 static const WCHAR expected16[] = {'\0',':','d','i','r','\\','X','X','X','X'};
160 static const WCHAR expected17[] = {'\0','o','o'};
161 static const WCHAR expected18[] = {'\0','o','o','\0','X'};
162 static const WCHAR expected19[] = {'\0','o','o','\0'};
163 static const WCHAR expected20[] = {'\0','o','o','\0','X','X','X','X','X'};
164 static const WCHAR expected21[] = {'\0','o','o','\\','f','i','l','X','X'};
165 static const WCHAR expected22[] = {'\0','o','o','\0','X','X','X','X','X','X','X','X','X'};
166 static const WCHAR expected23[] = {'\0','o','o','\\','f','i','l','X','X','X','X','X','X'};
167 static const WCHAR expected24[] = {'\0','o','o','\\','f','i','l','e','.','e','x','X','X'};
168 static const WCHAR expected25[] = {'\0','o','o','\0','X','X','X','X'};
169 static const WCHAR expected26[] = {'\0','o','o','.','e','x','X','X'};
171 typedef struct
173 const char* buffer;
174 size_t length;
175 const char* drive;
176 const char* dir;
177 const char* file;
178 const char* ext;
179 const char* expected;
180 const WCHAR *expected_unicode;
181 size_t expected_length;
182 } makepath_s_case;
184 static const makepath_s_case makepath_s_cases[] =
186 /* Behavior with directory parameter containing backslash. */
187 {NULL, 1, "c:", "d\\", "file", "ext", "\0XXXXXXXXXXXX", expected0, 13},
188 {NULL, 2, "c:", "d\\", "file", "ext", "\0XXXXXXXXXXXX", expected1, 13},
189 {NULL, 3, "c:", "d\\", "file", "ext", "\0:XXXXXXXXXXX", expected2, 13},
190 {NULL, 4, "c:", "d\\", "file", "ext", "\0:dXXXXXXXXXX", expected3, 13},
191 {NULL, 5, "c:", "d\\", "file", "ext", "\0:d\\XXXXXXXXX", expected4, 13},
192 {NULL, 6, "c:", "d\\", "file", "ext", "\0:d\\fXXXXXXXX", expected5, 13},
193 {NULL, 7, "c:", "d\\", "file", "ext", "\0:d\\fiXXXXXXX", expected6, 13},
194 {NULL, 8, "c:", "d\\", "file", "ext", "\0:d\\filXXXXXX", expected7, 13},
195 {NULL, 9, "c:", "d\\", "file", "ext", "\0:d\\fileXXXXX", expected8, 13},
196 {NULL, 10, "c:", "d\\", "file", "ext", "\0:d\\file.XXXX", expected9, 13},
197 {NULL, 11, "c:", "d\\", "file", "ext", "\0:d\\file.eXXX", expected10, 13},
198 {NULL, 12, "c:", "d\\", "file", "ext", "\0:d\\file.exXX", expected11, 13},
199 /* Behavior with directory parameter lacking backslash. */
200 {NULL, 3, "c:", "dir", "f", "ext", "\0:XXXXXXXX", expected12, 10},
201 {NULL, 4, "c:", "dir", "f", "ext", "\0:dXXXXXXX", expected13, 10},
202 {NULL, 5, "c:", "dir", "f", "ext", "\0:diXXXXXX", expected14, 10},
203 {NULL, 6, "c:", "dir", "f", "ext", "\0:dirXXXXX", expected15, 10},
204 {NULL, 7, "c:", "dir", "f", "ext", "\0:dir\\XXXX", expected16, 10},
205 /* Behavior with overlapped buffer. */
206 {"foo", 2, USE_BUFF, NULL, NULL, NULL, "\0oo", expected17, 3},
207 {"foo", 4, NULL, USE_BUFF, NULL, NULL, "\0oo\0X", expected18, 5},
208 {"foo", 3, NULL, NULL, USE_BUFF, NULL, "\0oo\0", expected19, 4},
209 {"foo", 4, NULL, USE_BUFF, "file", NULL, "\0oo\0XXXXX", expected20, 9},
210 {"foo", 8, NULL, USE_BUFF, "file", NULL, "\0oo\\filXX", expected21, 9},
211 {"foo", 4, NULL, USE_BUFF, "file", "ext", "\0oo\0XXXXXXXXX", expected22, 13},
212 {"foo", 8, NULL, USE_BUFF, "file", "ext", "\0oo\\filXXXXXX", expected23, 13},
213 {"foo", 12, NULL, USE_BUFF, "file", "ext", "\0oo\\file.exXX", expected24, 13},
214 {"foo", 4, NULL, NULL, USE_BUFF, "ext", "\0oo\0XXXX", expected25, 8},
215 {"foo", 7, NULL, NULL, USE_BUFF, "ext", "\0oo.exXX", expected26, 8},
218 static void test_makepath_s(void)
220 WCHAR driveW[MAX_PATH];
221 WCHAR dirW[MAX_PATH];
222 WCHAR fileW[MAX_PATH];
223 WCHAR extW[MAX_PATH];
224 WCHAR bufferW[MAX_PATH];
225 char buffer[MAX_PATH];
226 int ret;
227 unsigned int i, n;
229 if (!p_makepath_s || !p_wmakepath_s)
231 win_skip("Safe makepath functions are not available\n");
232 return;
235 errno = EBADF;
236 ret = p_makepath_s(NULL, 0, NULL, NULL, NULL, NULL);
237 ok(ret == EINVAL, "Expected _makepath_s to return EINVAL, got %d\n", ret);
238 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
240 errno = EBADF;
241 ret = p_makepath_s(buffer, 0, NULL, NULL, NULL, NULL);
242 ok(ret == EINVAL, "Expected _makepath_s to return EINVAL, got %d\n", ret);
243 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
245 errno = EBADF;
246 ret = p_wmakepath_s(NULL, 0, NULL, NULL, NULL, NULL);
247 ok(ret == EINVAL, "Expected _wmakepath_s to return EINVAL, got %d\n", ret);
248 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
250 errno = EBADF;
251 ret = p_wmakepath_s(bufferW, 0, NULL, NULL, NULL, NULL);
252 ok(ret == EINVAL, "Expected _wmakepath_s to return EINVAL, got %d\n", ret);
253 ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
255 /* Test with the normal _makepath cases. */
256 for (i = 0; i < ARRAY_SIZE(makepath_cases); i++)
258 const makepath_case *p = makepath_cases + i;
260 memset(buffer, 'X', MAX_PATH);
261 if (p->buffer)
262 strcpy(buffer, p->buffer);
264 /* Ascii */
265 ret = p_makepath_s(buffer, MAX_PATH,
266 p->drive == USE_BUFF ? buffer : p->drive,
267 p->dir == USE_BUFF ? buffer : p->dir,
268 p->file == USE_BUFF? buffer : p->file,
269 p->ext == USE_BUFF ? buffer : p->ext);
270 ok(ret == 0, "[%d] Expected _makepath_s to return 0, got %d\n", i, ret);
272 buffer[MAX_PATH - 1] = '\0';
273 ok(!strcmp(p->expected, buffer), "got '%s' for case %d\n", buffer, i);
275 /* Unicode */
276 if (p->drive != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->drive, -1, driveW, MAX_PATH);
277 if (p->dir != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->dir, -1, dirW, MAX_PATH);
278 if (p->file != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->file, -1, fileW, MAX_PATH);
279 if (p->ext != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->ext, -1, extW, MAX_PATH);
281 memset(buffer, 0, MAX_PATH);
282 for (n = 0; n < MAX_PATH; ++n)
283 bufferW[n] = 'X';
284 if (p->buffer) MultiByteToWideChar( CP_ACP, 0, p->buffer, -1, bufferW, MAX_PATH);
286 ret = p_wmakepath_s(bufferW, MAX_PATH,
287 p->drive == USE_BUFF ? bufferW : p->drive ? driveW : NULL,
288 p->dir == USE_BUFF ? bufferW : p->dir ? dirW : NULL,
289 p->file == USE_BUFF? bufferW : p->file ? fileW : NULL,
290 p->ext == USE_BUFF ? bufferW : p->ext ? extW : NULL);
291 ok(ret == 0, "[%d] Expected _wmakepath_s to return 0, got %d\n", i, ret);
293 bufferW[MAX_PATH - 1] = '\0';
294 WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
295 ok(!strcmp(p->expected, buffer), "got '%s' for unicode case %d\n", buffer, i);
298 /* Try insufficient length cases. */
299 for (i = 0; i < ARRAY_SIZE(makepath_s_cases); i++)
301 const makepath_s_case *p = makepath_s_cases + i;
303 memset(buffer, 'X', MAX_PATH);
304 if (p->buffer)
305 strcpy(buffer, p->buffer);
307 /* Ascii */
308 errno = EBADF;
309 ret = p_makepath_s(buffer, p->length,
310 p->drive == USE_BUFF ? buffer : p->drive,
311 p->dir == USE_BUFF ? buffer : p->dir,
312 p->file == USE_BUFF? buffer : p->file,
313 p->ext == USE_BUFF ? buffer : p->ext);
314 ok(ret == ERANGE, "[%d] Expected _makepath_s to return ERANGE, got %d\n", i, ret);
315 ok(errno == ERANGE, "[%d] Expected errno to be ERANGE, got %d\n", i, errno);
316 ok(!memcmp(p->expected, buffer, p->expected_length), "unexpected output for case %d\n", i);
318 /* Unicode */
319 if (p->drive != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->drive, -1, driveW, MAX_PATH);
320 if (p->dir != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->dir, -1, dirW, MAX_PATH);
321 if (p->file != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->file, -1, fileW, MAX_PATH);
322 if (p->ext != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->ext, -1, extW, MAX_PATH);
324 memset(buffer, 0, MAX_PATH);
325 for (n = 0; n < MAX_PATH; ++n)
326 bufferW[n] = 'X';
327 if (p->buffer) MultiByteToWideChar( CP_ACP, 0, p->buffer, -1, bufferW, MAX_PATH);
329 errno = EBADF;
330 ret = p_wmakepath_s(bufferW, p->length,
331 p->drive == USE_BUFF ? bufferW : p->drive ? driveW : NULL,
332 p->dir == USE_BUFF ? bufferW : p->dir ? dirW : NULL,
333 p->file == USE_BUFF? bufferW : p->file ? fileW : NULL,
334 p->ext == USE_BUFF ? bufferW : p->ext ? extW : NULL);
335 ok(ret == ERANGE, "[%d] Expected _wmakepath_s to return ERANGE, got %d\n", i, ret);
336 ok(errno == ERANGE, "[%d] Expected errno to be ERANGE, got %d\n", i, errno);
338 ok(!memcmp(p->expected_unicode, bufferW, p->expected_length * sizeof(WCHAR)), "unexpected output for case %d\n", i);
342 static void test_fullpath(void)
344 char full[MAX_PATH];
345 char tmppath[MAX_PATH];
346 char prevpath[MAX_PATH];
347 char level1[MAX_PATH];
348 char level2[MAX_PATH];
349 char teststring[MAX_PATH];
350 char *freeme;
351 BOOL rc,free1,free2;
353 free1=free2=TRUE;
354 GetCurrentDirectoryA(MAX_PATH, prevpath);
355 GetTempPathA(MAX_PATH,tmppath);
356 strcpy(level1,tmppath);
357 strcat(level1,"msvcrt-test\\");
359 rc = CreateDirectoryA(level1,NULL);
360 if (!rc && GetLastError()==ERROR_ALREADY_EXISTS)
361 free1=FALSE;
363 strcpy(level2,level1);
364 strcat(level2,"nextlevel\\");
365 rc = CreateDirectoryA(level2,NULL);
366 if (!rc && GetLastError()==ERROR_ALREADY_EXISTS)
367 free2=FALSE;
368 SetCurrentDirectoryA(level2);
370 ok(_fullpath(full,"test", MAX_PATH)!=NULL,"_fullpath failed\n");
371 strcpy(teststring,level2);
372 strcat(teststring,"test");
373 ok(strcmp(full,teststring)==0,"Invalid Path returned %s\n",full);
374 ok(_fullpath(full,"\\test", MAX_PATH)!=NULL,"_fullpath failed\n");
375 memcpy(teststring,level2,3);
376 teststring[3]=0;
377 strcat(teststring,"test");
378 ok(strcmp(full,teststring)==0,"Invalid Path returned %s\n",full);
379 ok(_fullpath(full,"..\\test", MAX_PATH)!=NULL,"_fullpath failed\n");
380 strcpy(teststring,level1);
381 strcat(teststring,"test");
382 ok(strcmp(full,teststring)==0,"Invalid Path returned %s\n",full);
383 ok(_fullpath(full,"..\\test", 10)==NULL,"_fullpath failed to generate error\n");
385 freeme = _fullpath(NULL,"test", 0);
386 ok(freeme!=NULL,"No path returned\n");
387 strcpy(teststring,level2);
388 strcat(teststring,"test");
389 ok(strcmp(freeme,teststring)==0,"Invalid Path returned %s\n",freeme);
390 free(freeme);
392 SetCurrentDirectoryA(prevpath);
393 if (free2)
394 RemoveDirectoryA(level2);
395 if (free1)
396 RemoveDirectoryA(level1);
399 static void test_splitpath(void)
401 const char* path = "c:\\\x83\x5c\x83\x74\x83\x67.bin";
402 char drive[3], dir[MAX_PATH], fname[MAX_PATH], ext[MAX_PATH];
403 int prev_cp = _getmbcp();
405 /* SBCS codepage */
406 _setmbcp(1252);
407 _splitpath(path, drive, dir, fname, ext);
408 ok(!strcmp(drive, "c:"), "got %s\n", drive);
409 ok(!strcmp(dir, "\\\x83\x5c"), "got %s\n", dir);
410 ok(!strcmp(fname, "\x83\x74\x83\x67"), "got %s\n", fname);
411 ok(!strcmp(ext, ".bin"), "got %s\n", ext);
413 /* MBCS (Japanese) codepage */
414 _setmbcp(932);
415 _splitpath(path, drive, dir, fname, ext);
416 ok(!strcmp(drive, "c:"), "got %s\n", drive);
417 ok(!strcmp(dir, "\\"), "got %s\n", dir);
418 ok(!strcmp(fname, "\x83\x5c\x83\x74\x83\x67"), "got %s\n", fname);
419 ok(!strcmp(ext, ".bin"), "got %s\n", ext);
421 _setmbcp(prev_cp);
424 static void test_searchenv(void)
426 const char *dirs[] = {
427 "\\search_env_test",
428 "\\search_env_test\\dir1",
429 "\\search_env_test\\dir2",
430 "\\search_env_test\\dir3longer"
433 const char *files[] = {
434 "\\search_env_test\\dir1\\1.dat",
435 "\\search_env_test\\dir1\\2.dat",
436 "\\search_env_test\\dir2\\1.dat",
437 "\\search_env_test\\dir2\\3.dat",
438 "\\search_env_test\\dir3longer\\3.dat"
441 const WCHAR env_w[] = {'T','E','S','T','_','P','A','T','H',0};
442 const WCHAR dat1_w[] = {'1','.','d','a','t',0};
443 const WCHAR dat3_w[] = {'3','.','d','a','t',0};
445 char env1[4*MAX_PATH], env2[4*MAX_PATH], tmppath[MAX_PATH], path[2*MAX_PATH];
446 char result[MAX_PATH], exp[2*MAX_PATH];
447 WCHAR result_w[MAX_PATH];
448 int i, path_len;
449 FILE *tmp_file;
451 if (getenv("TEST_PATH")) {
452 skip("TEST_PATH environment variable already set\n");
453 return;
456 path_len = GetTempPathA(MAX_PATH, tmppath);
457 ok(path_len, "GetTempPath failed\n");
458 memcpy(path, tmppath, path_len);
460 for (i=0; i<ARRAY_SIZE(dirs); i++) {
461 strcpy(path+path_len, dirs[i]);
462 ok(!mkdir(path), "mkdir failed (dir = %s)\n", path);
465 for (i=0; i<ARRAY_SIZE(files); i++) {
466 strcpy(path+path_len, files[i]);
467 tmp_file = fopen(path, "wb");
468 ok(tmp_file != NULL, "fopen failed (file = %s)\n", path);
469 fclose(tmp_file);
472 strcpy(env1, "TEST_PATH=");
473 strcpy(env2, "TEST_PATH=;");
474 for (i=1; i<ARRAY_SIZE(dirs); i++) {
475 strcat(env1, tmppath);
476 strcat(env1, dirs[i]);
477 strcat(env1, ";");
479 strcat(env2, tmppath);
480 strcat(env2, dirs[i]);
481 strcat(env2, ";;");
484 if (!p_searchenv_s || !p_wsearchenv_s)
485 win_skip("searchenv_s or wsearchenv_s function is not available\n");
487 putenv(env1);
488 memset(result, 'x', sizeof(result));
489 _searchenv("fail", "TEST_PATH", result);
490 ok(!result[0], "got %s, expected ''\n", result);
492 if (p_searchenv_s) {
493 memset(result, 'x', sizeof(result));
494 i = p_searchenv_s("fail", "TEST_PATH", result, MAX_PATH);
495 ok(i == ENOENT, "searchenv_s returned %d\n", i);
496 ok(!result[0], "got %s, expected ''\n", result);
499 memset(result, 'x', sizeof(result));
500 strcpy(exp, tmppath);
501 strcat(exp, files[0]);
502 _searchenv("1.dat", "TEST_PATH", result);
503 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
505 if (p_searchenv_s) {
506 memset(result, 'x', sizeof(result));
507 i = p_searchenv_s("1.dat", "TEST_PATH", result, MAX_PATH);
508 ok(!i, "searchenv_s returned %d\n", i);
509 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
512 memset(result_w, 'x', sizeof(result_w));
513 _wsearchenv(dat1_w, env_w, result_w);
514 WideCharToMultiByte(CP_ACP, 0, result_w, -1, result, MAX_PATH, NULL, NULL);
515 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
517 if (p_wsearchenv_s) {
518 memset(result_w, 'x', sizeof(result_w));
519 i = p_wsearchenv_s(dat1_w, env_w, result_w, MAX_PATH);
520 ok(!i, "wsearchenv_s returned %d\n", i);
521 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
524 memset(result, 'x', sizeof(result));
525 strcpy(exp, tmppath);
526 strcat(exp, files[3]);
527 _searchenv("3.dat", "TEST_PATH", result);
528 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
530 if (p_searchenv_s) {
531 memset(result, 'x', sizeof(result));
532 i = p_searchenv_s("3.dat", "TEST_PATH", result, MAX_PATH);
533 ok(!i, "searchenv_s returned %d\n", i);
534 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
537 memset(result_w, 'x', sizeof(result_w));
538 _wsearchenv(dat3_w, env_w, result_w);
539 WideCharToMultiByte(CP_ACP, 0, result_w, -1, result, MAX_PATH, NULL, NULL);
540 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
542 if (p_wsearchenv_s) {
543 memset(result_w, 'x', sizeof(result_w));
544 i = p_wsearchenv_s(dat3_w, env_w, result_w, MAX_PATH);
545 ok(!i, "wsearchenv_s returned %d\n", i);
546 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
549 putenv(env2);
550 memset(result, 'x', sizeof(result));
551 strcpy(exp, tmppath);
552 strcat(exp, files[0]);
553 _searchenv("1.dat", "TEST_PATH", result);
554 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
556 if (p_searchenv_s) {
557 memset(result, 'x', sizeof(result));
558 i = p_searchenv_s("1.dat", "TEST_PATH", result, MAX_PATH);
559 ok(!i, "searchenv_s returned %d\n", i);
560 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
563 memset(result_w, 'x', sizeof(result_w));
564 _wsearchenv(dat1_w, env_w, result_w);
565 WideCharToMultiByte(CP_ACP, 0, result_w, -1, result, MAX_PATH, NULL, NULL);
566 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
568 if (p_wsearchenv_s) {
569 memset(result_w, 'x', sizeof(result_w));
570 i = p_wsearchenv_s(dat1_w, env_w, result_w, MAX_PATH);
571 ok(!i, "wsearchenv_s returned %d\n", i);
572 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
575 memset(result, 'x', sizeof(result));
576 strcpy(exp, tmppath);
577 strcat(exp, files[3]);
578 _searchenv("3.dat", "TEST_PATH", result);
579 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
581 if (p_searchenv_s) {
582 memset(result, 'x', sizeof(result));
583 i = p_searchenv_s("3.dat", "TEST_PATH", result, MAX_PATH);
584 ok(!i, "searchenv_s returned %d\n", i);
585 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
588 memset(result_w, 'x', sizeof(result_w));
589 _wsearchenv(dat3_w, env_w, result_w);
590 WideCharToMultiByte(CP_ACP, 0, result_w, -1, result, MAX_PATH, NULL, NULL);
591 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
593 if (p_wsearchenv_s) {
594 memset(result_w, 'x', sizeof(result_w));
595 i = p_wsearchenv_s(dat3_w, env_w, result_w, MAX_PATH);
596 ok(!i, "wsearchenv_s returned %d\n", i);
597 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
600 strcpy(env1, "TEST_PATH=");
601 strcat(env1, tmppath);
602 strcat(env1, "\"\\search_env_test\\\"d\"i\"r\"1");
603 putenv(env1);
604 strcpy(exp, tmppath);
605 strcat(exp, files[0]);
606 _searchenv("1.dat", "TEST_PATH", result);
607 ok(!strcmp(result, exp), "got %s, expected '%s'\n", result, exp);
609 strcat(env1, ";");
610 putenv(env1);
611 _searchenv("1.dat", "TEST_PATH", result);
612 ok(!result[0], "got %s, expected ''\n", result);
614 putenv("TEST_PATH=");
616 for (i=ARRAY_SIZE(files)-1; i>=0; i--) {
617 strcpy(path+path_len, files[i]);
618 ok(!remove(path), "remove failed (file = %s)\n", path);
621 for (i=ARRAY_SIZE(dirs)-1; i>=0; i--) {
622 strcpy(path+path_len, dirs[i]);
623 ok(!rmdir(path), "rmdir failed (dir = %s)\n", path);
627 START_TEST(dir)
629 init();
631 test_fullpath();
632 test_makepath();
633 test_makepath_s();
634 test_splitpath();
635 test_searchenv();