ReactOS  0.4.14-dev-49-gfb4591c
dir.c
Go to the documentation of this file.
1 /*
2  * Unit test suite for dir functions
3  *
4  * Copyright 2006 CodeWeavers, Aric Stewart
5  *
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.
10  *
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.
15  *
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
19  */
20 
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>
35 
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);
40 
41 static void init(void)
42 {
43  HMODULE hmod = GetModuleHandleA("msvcrt.dll");
44 
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");
49 }
50 
51 typedef struct
52 {
53  const char* buffer;
54  const char* drive;
55  const char* dir;
56  const char* file;
57  const char* ext;
58  const char* expected;
60 
61 #define USE_BUFF ((char*)~0ul)
62 static const makepath_case makepath_cases[] =
63 {
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" }
87 };
88 
89 static void test_makepath(void)
90 {
91  WCHAR driveW[MAX_PATH];
92  WCHAR dirW[MAX_PATH];
94  WCHAR extW[MAX_PATH];
95  WCHAR bufferW[MAX_PATH];
96  char buffer[MAX_PATH];
97 
98  unsigned int i, n;
99 
100  for (i = 0; i < ARRAY_SIZE(makepath_cases); ++i)
101  {
102  const makepath_case* p = &makepath_cases[i];
103 
104  memset(buffer, 'X', MAX_PATH);
105  if (p->buffer)
106  strcpy(buffer, p->buffer);
107 
108  /* Ascii */
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);
114 
115  buffer[MAX_PATH - 1] = '\0';
116  ok(!strcmp(p->expected, buffer), "got '%s' for case %d\n", buffer, i);
117 
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);
123 
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);
128 
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);
134 
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);
138  }
139 }
140 
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'};
153 
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'};
159 
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'};
170 
171 typedef struct
172 {
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;
183 
185 {
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},
216 };
217 
218 static void test_makepath_s(void)
219 {
220  WCHAR driveW[MAX_PATH];
221  WCHAR dirW[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;
228 
229  if (!p_makepath_s || !p_wmakepath_s)
230  {
231  win_skip("Safe makepath functions are not available\n");
232  return;
233  }
234 
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);
239 
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);
244 
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);
249 
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);
254 
255  /* Test with the normal _makepath cases. */
256  for (i = 0; i < ARRAY_SIZE(makepath_cases); i++)
257  {
258  const makepath_case *p = makepath_cases + i;
259 
260  memset(buffer, 'X', MAX_PATH);
261  if (p->buffer)
262  strcpy(buffer, p->buffer);
263 
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);
271 
272  buffer[MAX_PATH - 1] = '\0';
273  ok(!strcmp(p->expected, buffer), "got '%s' for case %d\n", buffer, i);
274 
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);
280 
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);
285 
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);
292 
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);
296  }
297 
298  /* Try insufficient length cases. */
299  for (i = 0; i < ARRAY_SIZE(makepath_s_cases); i++)
300  {
301  const makepath_s_case *p = makepath_s_cases + i;
302 
303  memset(buffer, 'X', MAX_PATH);
304  if (p->buffer)
305  strcpy(buffer, p->buffer);
306 
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);
317 
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);
323 
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);
328 
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);
337 
338  ok(!memcmp(p->expected_unicode, bufferW, p->expected_length * sizeof(WCHAR)), "unexpected output for case %d\n", i);
339  }
340 }
341 
342 static void test_fullpath(void)
343 {
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;
352 
353  free1=free2=TRUE;
354  GetCurrentDirectoryA(MAX_PATH, prevpath);
355  GetTempPathA(MAX_PATH,tmppath);
356  strcpy(level1,tmppath);
357  strcat(level1,"msvcrt-test\\");
358 
359  rc = CreateDirectoryA(level1,NULL);
360  if (!rc && GetLastError()==ERROR_ALREADY_EXISTS)
361  free1=FALSE;
362 
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);
369 
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");
384 
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);
391 
392  SetCurrentDirectoryA(prevpath);
393  if (free2)
394  RemoveDirectoryA(level2);
395  if (free1)
396  RemoveDirectoryA(level1);
397 }
398 
399 static void test_splitpath(void)
400 {
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();
404 
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);
412 
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);
420 
421  _setmbcp(prev_cp);
422 }
423 
424 static void test_searchenv(void)
425 {
426  const char *dirs[] = {
427  "\\search_env_test",
428  "\\search_env_test\\dir1",
429  "\\search_env_test\\dir2",
430  "\\search_env_test\\dir3longer"
431  };
432 
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"
439  };
440 
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};
444 
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;
450 
451  if (getenv("TEST_PATH")) {
452  skip("TEST_PATH environment variable already set\n");
453  return;
454  }
455 
456  path_len = GetTempPathA(MAX_PATH, tmppath);
457  ok(path_len, "GetTempPath failed\n");
458  memcpy(path, tmppath, path_len);
459 
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);
463  }
464 
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);
470  }
471 
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, ";");
478 
479  strcat(env2, tmppath);
480  strcat(env2, dirs[i]);
481  strcat(env2, ";;");
482  }
483 
484  if (!p_searchenv_s || !p_wsearchenv_s)
485  win_skip("searchenv_s or wsearchenv_s function is not available\n");
486 
487  putenv(env1);
488  memset(result, 'x', sizeof(result));
489  _searchenv("fail", "TEST_PATH", result);
490  ok(!result[0], "got %s, expected ''\n", result);
491 
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);
497  }
498 
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);
504 
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);
510  }
511 
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);
516 
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);
522  }
523 
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);
529 
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);
535  }
536 
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);
541 
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);
547  }
548 
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);
555 
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);
561  }
562 
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);
567 
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);
573  }
574 
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);
580 
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);
586  }
587 
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);
592 
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);
598  }
599 
600  putenv("TEST_PATH=");
601 
602  for (i=ARRAY_SIZE(files)-1; i>=0; i--) {
603  strcpy(path+path_len, files[i]);
604  ok(!remove(path), "remove failed (file = %s)\n", path);
605  }
606 
607  for (i=ARRAY_SIZE(dirs)-1; i>=0; i--) {
608  strcpy(path+path_len, dirs[i]);
609  ok(!rmdir(path), "rmdir failed (dir = %s)\n", path);
610  }
611 }
612 
614 {
615  init();
616 
617  test_fullpath();
618  test_makepath();
619  test_makepath_s();
620  test_splitpath();
621  test_searchenv();
622 }
const char * ext
Definition: dir.c:178
static const WCHAR expected13[]
Definition: dir.c:155
static const WCHAR expected15[]
Definition: dir.c:157
_CRTIMP void __cdecl _wmakepath(_Pre_notnull_ _Post_z_ wchar_t *_ResultPath, _In_opt_z_ const wchar_t *_Drive, _In_opt_z_ const wchar_t *_Dir, _In_opt_z_ const wchar_t *_Filename, _In_opt_z_ const wchar_t *_Ext)
static const WCHAR expected21[]
Definition: dir.c:164
static size_t
Definition: dir.c:36
#define TRUE
Definition: types.h:120
_Check_return_ _CRTIMP int __cdecl putenv(_In_z_ const char *_EnvString)
_Check_return_ _CRTIMP char *__cdecl _fullpath(_Out_writes_opt_z_(_SizeInBytes) char *_FullPath, _In_z_ const char *_Path, _In_ size_t _SizeInBytes)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define WideCharToMultiByte
Definition: compat.h:101
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define __cdecl
Definition: accygwin.h:79
static const WCHAR expected12[]
Definition: dir.c:154
_CRTIMP void __cdecl _makepath(_Pre_notnull_ _Post_z_ char *_Path, _In_opt_z_ const char *_Drive, _In_opt_z_ const char *_Dir, _In_opt_z_ const char *_Filename, _In_opt_z_ const char *_Ext)
const char * expected
Definition: dir.c:179
static const WCHAR expected25[]
Definition: dir.c:168
#define CP_ACP
Definition: compat.h:99
const WCHAR * expected_unicode
Definition: dir.c:180
static const makepath_case makepath_cases[]
Definition: dir.c:62
Definition: arc.h:39
const char * file
Definition: dir.c:56
#define free
Definition: debug_ros.c:5
static const WCHAR expected22[]
Definition: dir.c:165
static void test_searchenv(void)
Definition: dir.c:424
const char * dir
Definition: dir.c:176
GLdouble n
Definition: glext.h:7729
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
GLuint buffer
Definition: glext.h:5915
_CRTIMP void __cdecl _splitpath(_In_z_ const char *_FullPath, _Pre_maybenull_ _Post_z_ char *_Drive, _Pre_maybenull_ _Post_z_ char *_Dir, _Pre_maybenull_ _Post_z_ char *_Filename, _Pre_maybenull_ _Post_z_ char *_Ext)
static const WCHAR expected2[]
Definition: dir.c:143
int errno
Definition: arc.h:36
_CRTIMP int __cdecl _getmbcp(void)
Definition: locale.c:1472
static const WCHAR expected18[]
Definition: dir.c:161
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
unsigned int BOOL
Definition: ntddk_ex.h:94
static void test_splitpath(void)
Definition: dir.c:399
static void test_makepath_s(void)
Definition: dir.c:218
const char * buffer
Definition: dir.c:53
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
static const WCHAR expected4[]
Definition: dir.c:145
smooth NULL
Definition: ftsmooth.c:416
char ext[3]
Definition: mkdosfs.c:358
static const WCHAR expected11[]
Definition: dir.c:152
unsigned int dir
Definition: maze.c:112
static const WCHAR expected16[]
Definition: dir.c:158
static void test_makepath(void)
Definition: dir.c:89
_CRTIMP void __cdecl _wsearchenv(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_EnvVar, _Pre_notnull_ _Post_z_ wchar_t *_ResultPath)
START_TEST(dir)
Definition: dir.c:613
const char * drive
Definition: dir.c:54
const char * file
Definition: dir.c:177
const char * expected
Definition: dir.c:58
static const WCHAR expected8[]
Definition: dir.c:149
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const WCHAR expected1[]
Definition: dir.c:142
#define mkdir
Definition: acwin.h:101
int __cdecl _setmbcp(int)
Definition: _setmbcp.c:218
static const WCHAR expected9[]
Definition: dir.c:150
static const WCHAR expected23[]
Definition: dir.c:166
#define MAX_PATH
Definition: compat.h:26
static void init(void)
Definition: dir.c:41
const char * drive
Definition: dir.c:175
#define ERANGE
Definition: acclib.h:92
int ret
#define USE_BUFF
Definition: dir.c:61
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2205
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static const WCHAR expected7[]
Definition: dir.c:148
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
static const WCHAR expected3[]
Definition: dir.c:144
const char * dir
Definition: dir.c:55
size_t length
Definition: dir.c:174
static const WCHAR expected6[]
Definition: dir.c:147
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:141
static const WCHAR expected17[]
Definition: dir.c:160
static const WCHAR expected19[]
Definition: dir.c:162
static const WCHAR expected5[]
Definition: dir.c:146
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
static DWORD path_len
Definition: batch.c:31
static const WCHAR expected20[]
Definition: dir.c:163
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2053
static void test_fullpath(void)
Definition: dir.c:342
static int(__cdecl *p_makepath_s)(char *
#define ARRAY_SIZE(a)
Definition: main.h:24
_CRTIMP void __cdecl _searchenv(_In_z_ const char *_Filename, _In_z_ const char *_EnvVar, _Pre_notnull_ _Post_z_ char *_ResultPath)
#define ok(value,...)
Definition: atltest.h:57
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2145
Definition: services.c:325
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
Definition: arc.h:46
DWORD exp
Definition: msg.c:15681
#define MultiByteToWideChar
Definition: compat.h:100
#define skip(...)
Definition: atltest.h:64
static const WCHAR expected14[]
Definition: dir.c:156
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static const makepath_s_case makepath_s_cases[]
Definition: dir.c:184
#define GetProcAddress(x, y)
Definition: compat.h:410
static const WCHAR expected24[]
Definition: dir.c:167
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
GLfloat GLfloat p
Definition: glext.h:8902
int remove
Definition: msacm.c:1353
const char * buffer
Definition: dir.c:173
#define rmdir
Definition: syshdrs.h:70
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
static const WCHAR fileW[]
Definition: url.c:111
size_t expected_length
Definition: dir.c:181
#define win_skip
Definition: test.h:141
static const WCHAR expected26[]
Definition: dir.c:169
static const WCHAR expected0[]
Definition: dir.c:141
const char * ext
Definition: dir.c:57
static const WCHAR expected10[]
Definition: dir.c:151