path.c 38.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Unit test suite for Get*PathNamesA and (Get|Set)CurrentDirectoryA.
 *
 * Copyright 2002 Geoffrey Hausheer
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

21
#include <stdarg.h>
22 23
#include <stdio.h>
#include "wine/test.h"
24
#include "windef.h"
25 26 27
#include "winbase.h"
#include "winuser.h"
#include "winerror.h"
28
#include "winnls.h"
29 30 31 32 33 34 35 36

#define HAS_TRAIL_SLASH_A(string) (string[lstrlenA(string)-1]=='\\')

#define LONGFILE "Long File test.path"
#define SHORTFILE "pathtest.pth"
#define SHORTDIR "shortdir"
#define LONGDIR "Long Directory"
#define NONFILE_SHORT "noexist.pth"
37
#define NONFILE_LONG "Non Existent File"
38
#define NONDIR_SHORT "notadir"
39
#define NONDIR_LONG "Non Existent Directory"
40

41 42
#define NOT_A_VALID_DRIVE '@'

43 44 45 46
/* the following characters don't work well with GetFullPathNameA
   in Win98.  I don't know if this is a FAT thing, or if it is an OS thing
   but I don't test these characters now.
   NOTE: Win2k allows GetFullPathNameA to work with them though
47
      |<>"
48
*/
49 50
static const CHAR funny_chars[]="!@#$%^&*()=+{}[],?'`";
static const CHAR is_char_ok[] ="11111110111111111011";
51 52

static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR,LPSTR,DWORD);
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

/* a structure to deal with wine todos somewhat cleanly */
typedef struct {
  DWORD shortlen;
  DWORD shorterror;
  DWORD s2llen;
  DWORD s2lerror;
  DWORD longlen;
  DWORD longerror;
} SLpassfail;

/* function that tests GetFullPathNameA, GetShortPathNameA,GetLongPathNameA */
/* NOTE: the passfail structure is used to allow cutomizeable todo checking
         for wine.  It is not very pretty, but it sure beats duplicating this
         function lots of times
*/
69
static void test_ValidPathA(CHAR *curdir, CHAR *subdir, CHAR *filename,
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
                         CHAR *shortstr, SLpassfail *passfail, CHAR *errstr) {
  CHAR tmpstr[MAX_PATH],
       fullpath[MAX_PATH],      /*full path to the file (not short/long) */
       subpath[MAX_PATH],       /*relative path to the file */
       fullpathshort[MAX_PATH], /*absolue path to the file (short format) */
       fullpathlong[MAX_PATH],  /*absolute path to the file (long format) */
       curdirshort[MAX_PATH],   /*absolute path to the current dir (short) */
       curdirlong[MAX_PATH];    /*absolute path to the current dir (long) */
  LPSTR strptr;                 /*ptr to the filename portion of the path */
  DWORD len;
/* if passfail is NULL, we can perform all checks within this function,
   otherwise, we will return the relevant data in the passfail struct, so
   we must initialize it first
*/
  if(passfail!=NULL) {
    passfail->shortlen=-1;passfail->s2llen=-1;passfail->longlen=-1;
    passfail->shorterror=0;passfail->s2lerror=0;passfail->longerror=0;
  }
/* GetLongPathNameA is only supported on Win2k+ and Win98+ */
89 90
  if(pGetLongPathNameA) {
    ok((len=pGetLongPathNameA(curdir,curdirlong,MAX_PATH)),
91
       "%s: GetLongPathNameA failed\n",errstr);
92 93
/*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
    ok(! HAS_TRAIL_SLASH_A(curdirlong),
94
       "%s: GetLongPathNameA should not have a trailing \\\n",errstr);
95 96
  }
  ok((len=GetShortPathNameA(curdir,curdirshort,MAX_PATH)),
97
     "%s: GetShortPathNameA failed\n",errstr);
98 99
/*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
  ok(! HAS_TRAIL_SLASH_A(curdirshort),
100
     "%s: GetShortPathNameA should not have a trailing \\\n",errstr);
101 102 103 104 105 106 107 108 109 110 111
/* build relative and absolute paths from inputs */
  if(lstrlenA(subdir)) {
    sprintf(subpath,"%s\\%s",subdir,filename);
  } else {
    lstrcpyA(subpath,filename);
  }
  sprintf(fullpath,"%s\\%s",curdir,subpath);
  sprintf(fullpathshort,"%s\\%s",curdirshort,subpath);
  sprintf(fullpathlong,"%s\\%s",curdirlong,subpath);
/* Test GetFullPathNameA functionality */
  len=GetFullPathNameA(subpath,MAX_PATH,tmpstr,&strptr);
112
  ok(len, "GetFullPathNameA failed for: '%s'\n",subpath);
113
  if(HAS_TRAIL_SLASH_A(subpath)) {
114
    ok(strptr==NULL,
115
       "%s: GetFullPathNameA should not return a filename ptr\n",errstr);
116
    ok(lstrcmpiA(fullpath,tmpstr)==0,
117
       "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
118
       errstr,tmpstr,fullpath);
119
  } else {
120
    ok(lstrcmpiA(strptr,filename)==0,
121
       "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
122 123
       errstr,strptr,filename);
    ok(lstrcmpiA(fullpath,tmpstr)==0,
124
       "%s: GetFullPathNameA returned '%s' instead of '%s'\n",
125 126 127 128 129 130
       errstr,tmpstr,fullpath);
  }
/* Test GetShortPathNameA functionality */
  SetLastError(0);
  len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
  if(passfail==NULL) {
131
    ok(len, "%s: GetShortPathNameA failed\n",errstr);
132 133 134 135
  } else {
    passfail->shortlen=len;
    passfail->shorterror=GetLastError();
  }
136
/* Test GetLongPathNameA functionality
137 138
   We test both conversion from GetFullPathNameA and from GetShortPathNameA
*/
139
  if(pGetLongPathNameA) {
140
    if(len!=0) {
141
      SetLastError(0);
142
      len=pGetLongPathNameA(shortstr,tmpstr,MAX_PATH);
143
      if(passfail==NULL) {
144
        ok(len,
145
          "%s: GetLongPathNameA failed during Short->Long conversion\n", errstr);
146
        ok(lstrcmpiA(fullpathlong,tmpstr)==0,
147
           "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
148 149 150 151 152 153 154
           errstr,tmpstr,fullpathlong);
      } else {
        passfail->s2llen=len;
        passfail->s2lerror=GetLastError();
      }
    }
    SetLastError(0);
155
    len=pGetLongPathNameA(fullpath,tmpstr,MAX_PATH);
156
    if(passfail==NULL) {
157
      ok(len, "%s: GetLongPathNameA failed\n",errstr);
158
      if(HAS_TRAIL_SLASH_A(fullpath)) {
159
        ok(lstrcmpiA(fullpathlong,tmpstr)==0,
160
           "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
161 162 163
           errstr,tmpstr,fullpathlong);
      } else {
        ok(lstrcmpiA(fullpathlong,tmpstr)==0,
164
          "%s: GetLongPathNameA returned '%s' instead of '%s'\n",
165 166 167 168 169 170 171 172 173 174 175
          errstr,tmpstr,fullpathlong);
      }
    } else {
      passfail->longlen=len;
      passfail->longerror=GetLastError();
    }
  }
}

/* split path into leading directory, and 8.3 filename */
static void test_SplitShortPathA(CHAR *path,CHAR *dir,CHAR *eight,CHAR *three) {
176 177 178
  int done,error;
  int ext,fil;
  int len,i;
179 180
  len=lstrlenA(path);
  ext=len; fil=len; done=0; error=0;
Francois Gouget's avatar
Francois Gouget committed
181
/* walk backwards over path looking for '.' or '\\' separators */
182
  for(i=len-1;(i>=0) && (!done);i--) {
183
    if(path[i]=='.')
184 185 186 187 188 189 190 191 192 193 194
      if(ext!=len) error=1; else ext=i;
    else if(path[i]=='\\') {
      if(i==len-1) {
        error=1;
      } else {
        fil=i;
        done=1;
      }
    }
  }
/* Check that we didn't find a trailing '\\' or multiple '.' */
195
  ok(!error,"Illegal file found in 8.3 path '%s'\n",path);
196
/* Separate dir, root, and extension */
197 198 199 200 201 202 203 204 205 206
  if(ext!=len) lstrcpyA(three,path+ext+1); else lstrcpyA(three,"");
  if(fil!=len) {
    lstrcpynA(eight,path+fil+1,ext-fil);
    lstrcpynA(dir,path,fil+1);
  } else {
    lstrcpynA(eight,path,ext+1);
    lstrcpyA(dir,"");
  }
/* Validate that root and extension really are 8.3 */
  ok(lstrlenA(eight)<=8 && lstrlenA(three)<=3,
207
     "GetShortPathNAmeA did not return an 8.3 path\n");
208 209 210 211 212 213 214 215 216
}

/* Check that GetShortPathNameA returns a valid 8.3 path */
static void test_LongtoShortA(CHAR *teststr,CHAR *goodstr,
                              CHAR *ext,CHAR *errstr) {
  CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];

  test_SplitShortPathA(teststr,dir,eight,three);
  ok(lstrcmpiA(dir,goodstr)==0,
217
     "GetShortPathNameA returned '%s' instead of '%s'\n",dir,goodstr);
218
  ok(lstrcmpiA(three,ext)==0,
219
     "GetShortPathNameA returned '%s' with incorrect extension\n",three);
220 221 222 223 224
}

/* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
   characters in the filename.
     'valid' indicates whether this would be an allowed filename
225
     'todo' indicates that wine doesn't get this right yet.
226
   NOTE: We always call this routine with a non-existent filename, so
227 228 229
         Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
         should.
*/
230
static void test_FunnyChars(CHAR *curdir,CHAR *curdir_short,CHAR *filename, INT valid,CHAR *errstr)
231
{
232
  CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
233 234 235 236
  SLpassfail passfail;

  test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
  if(valid) {
237
    sprintf(tmpstr1,"%s\\%s",curdir_short,filename);
238
      ok((passfail.shortlen==0 &&
239
          (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||
240
         (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
241
         "%s: GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
242
         errstr,passfail.shortlen,passfail.shorterror,tmpstr);
243
  } else {
244
      ok(passfail.shortlen==0 &&
245
         (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),
246
         "%s: GetShortPathA should have failed len=%ld, error=%ld\n",
247
         errstr,passfail.shortlen,passfail.shorterror);
248
  }
249
  if(pGetLongPathNameA) {
250
    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
251 252
    if(valid) {
      ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
253
         "%s: GetLongPathA returned %ld and not %d\n",
254 255 256 257
         errstr,passfail.longerror,ERROR_FILE_NOT_FOUND);
    } else {
      ok(passfail.longerror==ERROR_INVALID_NAME ||
         passfail.longerror==ERROR_FILE_NOT_FOUND,
258
         "%s: GetLongPathA returned %ld and not %d or %d'\n",
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
         errstr, passfail.longerror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
    }
  }
}

/* Routine to test that SetCurrentDirectory behaves as expected. */
static void test_setdir(CHAR *olddir,CHAR *newdir,
                        CHAR *cmprstr, INT pass,CHAR *errstr)
{
  CHAR tmppath[MAX_PATH], *dirptr;
  DWORD val,len,chklen;

  val=SetCurrentDirectoryA(newdir);
  len=GetCurrentDirectoryA(MAX_PATH,tmppath);
/* if 'pass' then the SetDirectoryA was supposed to pass */
  if(pass) {
    dirptr=(cmprstr==NULL) ? newdir : cmprstr;
    chklen=lstrlenA(dirptr);
277
    ok(val,"%s: SetCurrentDirectoryA failed\n",errstr);
278
    ok(len==chklen,
279
       "%s: SetCurrentDirectory did not change the directory, though it passed\n",
280 281
       errstr);
    ok(lstrcmpiA(dirptr,tmppath)==0,
282
       "%s: SetCurrentDirectory did not change the directory, though it passed\n",
283 284
       errstr);
    ok(SetCurrentDirectoryA(olddir),
285
       "%s: Couldn't set directory to it's original value\n",errstr);
286 287 288 289
  } else {
/* else thest that it fails correctly */
    chklen=lstrlenA(olddir);
    ok(val==0,
290
       "%s: SetCurrentDirectoryA passed when it should have failed\n",errstr);
291
    ok(len==chklen,
292
       "%s: SetCurrentDirectory changed the directory, though it failed\n",
293 294
       errstr);
    ok(lstrcmpiA(olddir,tmppath)==0,
295
       "%s: SetCurrentDirectory changed the directory, though it failed\n",
296 297 298
       errstr);
  }
}
299
static void test_InitPathA(CHAR *newdir, CHAR *curDrive, CHAR *otherDrive)
300 301 302 303
{
  CHAR tmppath[MAX_PATH], /*path to TEMP */
       tmpstr[MAX_PATH],
       tmpstr1[MAX_PATH];
304
  DWORD len,len1,drives;
305 306 307
  INT id;
  HANDLE hndl;

308 309 310 311 312 313 314 315
  *curDrive = *otherDrive = NOT_A_VALID_DRIVE;

/* Get the current drive letter */
  if( GetCurrentDirectoryA( MAX_PATH, tmpstr))
    *curDrive = tmpstr[0];
  else
    trace( "Unable to discover current drive, some tests will not be conducted.\n");

316 317
/* Test GetTempPathA */
  len=GetTempPathA(MAX_PATH,tmppath);
318
  ok(len!=0 && len < MAX_PATH,"GetTempPathA failed\n");
319
  ok(HAS_TRAIL_SLASH_A(tmppath),
320
     "GetTempPathA returned a path that did not end in '\\'\n");
321 322 323
  lstrcpyA(tmpstr,"aaaaaaaa");
  len1=GetTempPathA(len,tmpstr);
  ok(len1==len+1,
324
     "GetTempPathA should return string length %ld instead of %ld\n",len+1,len1);
325

326
/* Test GetTmpFileNameA
327 328 329 330
   The only test we do here is whether GetTempFileNameA passes or not.
   We do not thoroughly test this function yet (specifically, whether
   it behaves correctly when 'unique' is non zero)
*/
331
  ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed\n");
332 333 334 335
  sprintf(tmpstr,"pat%.4x.tmp",id & 0xffff);
  sprintf(tmpstr1,"pat%x.tmp",id & 0xffff);
  ok(lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr)==0 ||
     lstrcmpiA(newdir+lstrlenA(tmppath),tmpstr1)==0,
336
     "GetTempPath returned '%s' which doesn't match '%s' or '%s'. id=%x\n",
337
     newdir,tmpstr,tmpstr1,id);
338

339 340 341 342 343 344 345 346 347
/* Find first valid drive letter that is neither newdir[0] nor curDrive */
  drives = GetLogicalDrives() & ~(1<<(newdir[0]-'A'));
  if( *curDrive != NOT_A_VALID_DRIVE)
    drives &= ~(1<<(*curDrive-'A'));
  if( drives)
    for( *otherDrive='A'; (drives & 1) == 0; drives>>=1, (*otherDrive)++);
  else
    trace( "Could not find alternative drive, some tests will not be conducted.\n");

348 349 350 351 352 353
/* Do some CreateDirectoryA tests */
/* It would be nice to do test the SECURITY_ATTRIBUTES, but I don't
   really understand how they work.
   More formal tests should be done along with CreateFile tests
*/
  ok(CreateDirectoryA(newdir,NULL)==0,
354 355 356
     "CreateDirectoryA succeeded even though a file of the same name exists\n");
  ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created\n");
  ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed\n");
357 358 359 360
/* Create some files to test other functions.  Note, we will test CreateFileA
   at some later point
*/
  sprintf(tmpstr,"%s\\%s",newdir,SHORTDIR);
361
  ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
362
  sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
363
  ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed\n");
364 365
  sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
  hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
366
                   CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
367 368
  ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
  ok(CloseHandle(hndl),"CloseHandle failed\n");
369 370
  sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
  hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
371
                   CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
372 373
  ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
  ok(CloseHandle(hndl),"CloseHandle failed\n");
374 375
  sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
  hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
376
                   CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
377 378
  ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
  ok(CloseHandle(hndl),"CloseHandle failed\n");
379 380
  sprintf(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
  hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
381
                   CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
382 383
  ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed\n");
  ok(CloseHandle(hndl),"CloseHandle failed\n");
384 385 386 387 388 389 390 391 392 393 394
}

/* Test GetCurrentDirectory & SetCurrentDirectory */
static void test_CurrentDirectoryA(CHAR *origdir, CHAR *newdir)
{
  CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
  DWORD len,len1;
/* Save the original directory, so that we can return to it at the end
   of the test
*/
  len=GetCurrentDirectoryA(MAX_PATH,origdir);
395
  ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed\n");
396
  ok(lstrcmpiA(origdir+(len-1),"\\")!=0,
397
     "GetCurrentDirectoryA should not have a trailing \\\n");
398 399 400 401 402
/* Make sure that CetCurrentDirectoryA doesn't overwrite the buffer when the
   buffer size is too small to hold the current directory
*/
  lstrcpyA(tmpstr,"aaaaaaa");
  len1=GetCurrentDirectoryA(len,tmpstr);
403
  ok(len1==len+1, "GetCurrentDirectoryA returned %ld instead of %ld\n",len1,len+1);
404
  ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
405
     "GetCurrentDirectoryA should not have modified the buffer\n");
406
/* SetCurrentDirectoryA shouldn't care whether the string has a
407 408 409 410 411
   trailing '\\' or not
*/
  sprintf(tmpstr,"%s\\",newdir);
  test_setdir(origdir,tmpstr,newdir,1,"check 1");
  test_setdir(origdir,newdir,NULL,1,"check 2");
412
/* Set the directory to the working area.  We just tested that this works,
413 414 415
   so why check it again.
*/
  SetCurrentDirectoryA(newdir);
416
/* Check that SetCurrentDirectory fails when a non-existent dir is specified */
417 418
  sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
  test_setdir(newdir,tmpstr,NULL,0,"check 3");
419
/* Check that SetCurrentDirectory fails for a non-existent lond directory */
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
  sprintf(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
  test_setdir(newdir,tmpstr,NULL,0,"check 4");
/* Check that SetCurrentDirectory passes with a long directory */
  sprintf(tmpstr,"%s\\%s",newdir,LONGDIR);
  test_setdir(newdir,tmpstr,NULL,1,"check 5");
/* Check that SetCurrentDirectory passes with a short relative directory */
  sprintf(tmpstr,"%s",SHORTDIR);
  sprintf(tmpstr1,"%s\\%s",newdir,SHORTDIR);
  test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
/* starting with a '.' */
  sprintf(tmpstr,".\\%s",SHORTDIR);
  test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
/* Check that SetCurrentDirectory passes with a short relative directory */
  sprintf(tmpstr,"%s",LONGDIR);
  sprintf(tmpstr1,"%s\\%s",newdir,LONGDIR);
  test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
/* starting with a '.' */
  sprintf(tmpstr,".\\%s",LONGDIR);
  test_setdir(newdir,tmpstr,tmpstr1,1,"check 9");
}

/* Cleanup the mess we made while executing these tests */
static void test_CleanupPathA(CHAR *origdir, CHAR *curdir)
{
  CHAR tmpstr[MAX_PATH];
  sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
446
  ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
447
  sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
448
  ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
449
  sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
450
  ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
451
  sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
452
  ok(DeleteFileA(tmpstr),"DeleteFileA failed\n");
453
  sprintf(tmpstr,"%s\\%s",curdir,SHORTDIR);
454
  ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
455
  sprintf(tmpstr,"%s\\%s",curdir,LONGDIR);
456 457 458
  ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed\n");
  ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed\n");
  ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed\n");
459 460 461
}

/* This routine will test Get(Full|Short|Long)PathNameA */
462
static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
463 464 465
{
  CHAR curdir_short[MAX_PATH],
       longdir_short[MAX_PATH];
466
  CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH],tmpstr2[MAX_PATH];
467
  LPSTR strptr;                 /*ptr to the filename portion of the path */
468 469 470 471 472 473 474
  DWORD len;
  INT i;
  CHAR dir[MAX_PATH],eight[MAX_PATH],three[MAX_PATH];
  SLpassfail passfail;

/* Get the short form of the current directory */
  ok((len=GetShortPathNameA(curdir,curdir_short,MAX_PATH)),
475
     "GetShortPathNameA failed\n");
476
  ok(!HAS_TRAIL_SLASH_A(curdir_short),
477
     "GetShortPathNameA should not have a trailing \\\n");
478 479 480
/* Get the short form of the absolute-path to LONGDIR */
  sprintf(tmpstr,"%s\\%s",curdir_short,LONGDIR);
  ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
481
     "GetShortPathNameA failed\n");
482
  ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
483
     "GetShortPathNameA should not have a trailing \\\n");
484

485
  if (pGetLongPathNameA) {
486
    DWORD rc1,rc2;
487
    sprintf(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
488 489 490
    rc1=(*pGetLongPathNameA)(tmpstr,NULL,0);
    rc2=(*pGetLongPathNameA)(curdir,NULL,0);
    ok((rc1-strlen(tmpstr))==(rc2-strlen(curdir)),
491
       "GetLongPathNameA: wrong return code, %ld instead of %d\n",
492
       rc1, strlen(tmpstr)+1);
493

494 495 496
    sprintf(dir,"%c:",curDrive);
    rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
    ok(strcmp(dir,tmpstr)==0,
497
       "GetLongPathNameA: returned '%s' instead of '%s' (rc=%ld)\n",
498
       tmpstr,dir,rc1);
499 500
  }

501 502 503 504 505
/* Check the cases where both file and directory exist first */
/* Start with a 8.3 directory, 8.3 filename */
  test_ValidPathA(curdir,SHORTDIR,SHORTFILE,tmpstr,NULL,"test1");
  sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
  ok(lstrcmpiA(tmpstr,tmpstr1)==0,
506
     "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
507 508 509 510 511 512 513 514
/* Now try a 8.3 directory, long file name */
  test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
  sprintf(tmpstr1,"%s\\%s",curdir_short,SHORTDIR);
  test_LongtoShortA(tmpstr,tmpstr1,"PAT","test2");
/* Next is a long directory, 8.3 file */
  test_ValidPathA(curdir,LONGDIR,SHORTFILE,tmpstr,NULL,"test3");
  sprintf(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
  ok(lstrcmpiA(tmpstr,tmpstr1)==0,
515
     "GetShortPathNameA returned '%s' instead of '%s'\n",tmpstr,tmpstr1);
516 517 518 519
/*Lastly a long directory, long file */
  test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
  test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");

520
/* Now check all of the invalid file w/ valid directory combinations */
521 522
/* Start with a 8.3 directory, 8.3 filename */
  test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
523 524 525 526 527
  sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,NONFILE_SHORT);
  ok((passfail.shortlen==0 &&
      (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
       passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
     (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
528
     "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
529
     passfail.shortlen,passfail.shorterror,tmpstr);
530
  if(pGetLongPathNameA) {
531
    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
532
    ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
533
       "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
534 535 536
  }
/* Now try a 8.3 directory, long file name */
  test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
537
  ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
538
  ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
539 540
     passfail.shorterror==ERROR_FILE_NOT_FOUND ||
     !passfail.shorterror,
541
     "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
542
  if(pGetLongPathNameA) {
543
    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
544
    ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
545
       "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
546 547 548
  }
/* Next is a long directory, 8.3 file */
  test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
549 550 551 552 553 554 555
  sprintf(tmpstr2,"%s\\%s",curdir_short,LONGDIR);
  GetShortPathNameA(tmpstr2,tmpstr1,MAX_PATH);
  strcat(tmpstr1,"\\" NONFILE_SHORT);
  ok((passfail.shortlen==0 &&
      (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
       passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
     (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
556
     "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
557
     passfail.shortlen,passfail.shorterror,tmpstr);
558
  if(pGetLongPathNameA) {
559
    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
560
    ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
561
      "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
562 563 564
  }
/*Lastly a long directory, long file */
  test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
565
  ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
566
  ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
567 568
     passfail.shorterror==ERROR_FILE_NOT_FOUND ||
     !passfail.shorterror,
569
     "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
570
  if(pGetLongPathNameA) {
571
    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
572
    ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
573
       "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'\n");
574 575 576 577
  }
/* Now try again with directories that don't exist */
/* 8.3 directory, 8.3 filename */
  test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
578 579 580 581 582
  sprintf(tmpstr1,"%s\\%s\\%s",curdir_short,NONDIR_SHORT,SHORTFILE);
  ok((passfail.shortlen==0 &&
      (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
       passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
     (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),
583
     "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
584
     passfail.shortlen,passfail.shorterror,tmpstr);
585
  if(pGetLongPathNameA) {
586
    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
587 588
    ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
       passfail.longerror==ERROR_FILE_NOT_FOUND,
589
       "GetLongPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
590 591 592 593
       passfail.longerror);
  }
/* Now try a 8.3 directory, long file name */
  test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
594
  ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
595
  ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
596 597
     passfail.shorterror==ERROR_FILE_NOT_FOUND ||
     !passfail.shorterror,
598
     "GetShortPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
599
      passfail.shorterror);
600
  if(pGetLongPathNameA) {
601
    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
602 603
    ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
       passfail.longerror==ERROR_FILE_NOT_FOUND,
604
       "GetLongPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
605 606 607 608
       passfail.longerror);
  }
/* Next is a long directory, 8.3 file */
  test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
609
  ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
610
  ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
611 612
     passfail.shorterror==ERROR_FILE_NOT_FOUND ||
     !passfail.shorterror,
613
     "GetShortPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
614
      passfail.shorterror);
615
  if(pGetLongPathNameA) {
616
    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
617 618
    ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
       passfail.longerror==ERROR_FILE_NOT_FOUND,
619
       "GetLongPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
620 621 622 623
       passfail.longerror);
  }
/*Lastly a long directory, long file */
  test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
624
  ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
625
  ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
626 627
     passfail.shorterror==ERROR_FILE_NOT_FOUND ||
     !passfail.shorterror,
628
     "GetShortPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
629
      passfail.shorterror);
630
  if(pGetLongPathNameA) {
631
    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
632 633
    ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
       passfail.longerror==ERROR_FILE_NOT_FOUND,
634
       "GetLongPathA returned %ld and not 'ERROR_PATH_NOT_FOUND'\n",
635 636 637 638 639 640 641 642
       passfail.longerror);
  }
/* Next try directories ending with '\\' */
/* Existing Directories */
  sprintf(tmpstr,"%s\\",SHORTDIR);
  test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
  sprintf(tmpstr,"%s\\",LONGDIR);
  test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
643
/* Non-existent directories */
644 645
  sprintf(tmpstr,"%s\\",NONDIR_SHORT);
  test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
646
  sprintf(tmpstr2,"%s\\%s",curdir_short,tmpstr);
647 648 649 650
  ok((passfail.shortlen==0 &&
      (passfail.shorterror==ERROR_PATH_NOT_FOUND ||
       passfail.shorterror==ERROR_FILE_NOT_FOUND)) ||
     (passfail.shortlen==strlen(tmpstr2) && lstrcmpiA(tmpstr1,tmpstr2)==0),
651
     "GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]\n",
652
     passfail.shortlen,passfail.shorterror,tmpstr);
653
  if(pGetLongPathNameA) {
654
    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
655
    ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
656
       "GetLongPathA returned %ld and not 'ERROR_FILE_NOT_FOUND'\n",
657 658 659 660
       passfail.longerror);
  }
  sprintf(tmpstr,"%s\\",NONDIR_LONG);
  test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
661
  ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have\n");
662
  ok(passfail.shorterror==ERROR_PATH_NOT_FOUND ||
663 664
     passfail.shorterror==ERROR_FILE_NOT_FOUND ||
     !passfail.shorterror,
665
     "GetShortPathA returned %ld and not 'ERROR_FILE_NOT_FOUND'\n",
666
      passfail.shorterror);
667
  if(pGetLongPathNameA) {
668
    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have\n");
669
    ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
670
       "GetLongPathA returned %ld and not 'ERROR_FILE_NOT_FOUND'\n",
671 672
       passfail.longerror);
  }
673
/* Test GetFullPathNameA with drive letters */
674
  if( curDrive != NOT_A_VALID_DRIVE) {
675 676
    sprintf(tmpstr,"%c:",curdir[0]);
    ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr2,&strptr),
677
       "GetFullPathNameA(%c:) failed\n", curdir[0]);
678 679 680
    GetCurrentDirectoryA(MAX_PATH,tmpstr);
    sprintf(tmpstr1,"%s\\",tmpstr);
    ok(lstrcmpiA(tmpstr,tmpstr2)==0 || lstrcmpiA(tmpstr1,tmpstr2)==0,
681
       "GetFullPathNameA(%c:) returned '%s' instead of '%s' or '%s'\n",
682 683
       curdir[0],tmpstr2,tmpstr,tmpstr1);

684
    sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
685
    ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
686
    ok(lstrcmpiA(tmpstr,tmpstr1)==0,
687
       "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
688
    ok(lstrcmpiA(SHORTFILE,strptr)==0,
689
       "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
690
  }
691 692
/* Without a leading slash, insert the current directory if on the current drive */
  sprintf(tmpstr,"%c:%s\\%s",curdir[0],SHORTDIR,SHORTFILE);
693
  ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
694 695
  sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
  ok(lstrcmpiA(tmpstr,tmpstr1)==0,
696
      "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
697
  ok(lstrcmpiA(SHORTFILE,strptr)==0,
698
      "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
699
/* Otherwise insert the missing leading slash */
700 701
  if( otherDrive != NOT_A_VALID_DRIVE) {
    sprintf(tmpstr,"%c:%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
702
    ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed for %s\n", tmpstr);
703 704
    sprintf(tmpstr,"%c:\\%s\\%s",otherDrive,SHORTDIR,SHORTFILE);
    ok(lstrcmpiA(tmpstr,tmpstr1)==0,
705
       "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
706
    ok(lstrcmpiA(SHORTFILE,strptr)==0,
707
       "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
708
  }
709 710
/* Xilinx tools like to mix Unix and DOS formats, which Windows handles fine.
   So test for them. */
711 712
  if( curDrive != NOT_A_VALID_DRIVE) {
    sprintf(tmpstr,"%c:/%s\\%s",curDrive,SHORTDIR,SHORTFILE);
713
    ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
714 715
    sprintf(tmpstr,"%c:\\%s\\%s",curDrive,SHORTDIR,SHORTFILE);
    ok(lstrcmpiA(tmpstr,tmpstr1)==0,
716
       "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
717
    ok(lstrcmpiA(SHORTFILE,strptr)==0,
718
       "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
719
  }
720 721
/**/
  sprintf(tmpstr,"%c:%s/%s",curdir[0],SHORTDIR,SHORTFILE);
722
  ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
723 724
  sprintf(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
  ok(lstrcmpiA(tmpstr,tmpstr1)==0,
725
      "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
726
  ok(lstrcmpiA(SHORTFILE,strptr)==0,
727
      "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
728
/* Windows will insert a drive letter in front of an absolute UNIX path */
729
  sprintf(tmpstr,"/%s/%s",SHORTDIR,SHORTFILE);
730
  ok(GetFullPathNameA(tmpstr,MAX_PATH,tmpstr1,&strptr),"GetFullPathNameA failed\n");
731 732 733
  sprintf(tmpstr,"%c:\\%s\\%s",*tmpstr1,SHORTDIR,SHORTFILE);
  ok(lstrcmpiA(tmpstr,tmpstr1)==0,
     "GetFullPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
734 735
/* This passes in Wine because it still contains the pointer from the previous test */
  ok(lstrcmpiA(SHORTFILE,strptr)==0,
736
      "GetFullPathNameA returned part '%s' instead of '%s'\n",strptr,SHORTFILE);
737

738
/* Now try some relative paths */
739
  ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed\n");
740
  test_SplitShortPathA(tmpstr,dir,eight,three);
741
  if(pGetLongPathNameA) {
742
    ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed\n");
743
    ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
744
       "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,LONGDIR);
745 746
  }
  sprintf(tmpstr,".\\%s",LONGDIR);
747
  ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed\n");
748
  test_SplitShortPathA(tmpstr1,dir,eight,three);
749
  ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
750
     "GetShortPathNameA did not keep relative directory [%s]\n",tmpstr1);
751
  if(pGetLongPathNameA) {
752
    ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s\n",
753 754
       tmpstr);
    ok(lstrcmpiA(tmpstr1,tmpstr)==0,
755
       "GetLongPathNameA returned '%s' instead of '%s'\n",tmpstr1,tmpstr);
756 757 758
  }
/* Check out Get*PathNameA on some funny characters */
  for(i=0;i<lstrlenA(funny_chars);i++) {
759
    INT valid;
760 761 762
    valid=(is_char_ok[i]=='0') ? 0 : 1;
    sprintf(tmpstr1,"check%d-1",i);
    sprintf(tmpstr,"file%c000.ext",funny_chars[i]);
763
    test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
764 765
    sprintf(tmpstr1,"check%d-2",i);
    sprintf(tmpstr,"file000.e%ct",funny_chars[i]);
766
    test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
767 768
    sprintf(tmpstr1,"check%d-3",i);
    sprintf(tmpstr,"%cfile000.ext",funny_chars[i]);
769
    test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
770 771
    sprintf(tmpstr1,"check%d-4",i);
    sprintf(tmpstr,"file000%c.ext",funny_chars[i]);
772
    test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
773 774
    sprintf(tmpstr1,"check%d-5",i);
    sprintf(tmpstr,"Long %c File",funny_chars[i]);
775
    test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
776 777
    sprintf(tmpstr1,"check%d-6",i);
    sprintf(tmpstr,"%c Long File",funny_chars[i]);
778
    test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
779 780
    sprintf(tmpstr1,"check%d-7",i);
    sprintf(tmpstr,"Long File %c",funny_chars[i]);
781
    test_FunnyChars(curdir,curdir_short,tmpstr,valid,tmpstr1);
782 783 784
  }
}

785
static void test_GetTempPathA(char* tmp_dir)
786
{
787
    DWORD len, len_with_null;
788 789
    char buf[MAX_PATH];

790 791
    len_with_null = strlen(tmp_dir) + 1;

792 793
    lstrcpyA(buf, "foo");
    len = GetTempPathA(MAX_PATH, buf);
794 795 796
    ok(len <= MAX_PATH, "should fit into MAX_PATH\n");
    ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
    ok(len == strlen(buf), "returned length should be equal to the length of string\n");
797

798 799 800 801 802 803
    /* Some versions of Windows touch the buffer, some don't so we don't
     * test that. Also, NT sometimes exagerates the required buffer size
     * so we cannot test for an exact match. Finally, the
     * 'len_with_null - 1' case is so buggy on Windows it's not testable.
     * For instance in some cases Win98 returns len_with_null - 1 instead
     * of len_with_null.
804 805
     */
    len = GetTempPathA(1, buf);
806
    ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
807

808
    len = GetTempPathA(0, NULL);
809
    ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
810

811 812 813
    /* The call above gave us the buffer size that Windows thinks is needed
     * so the next call should work
     */
814
    lstrcpyA(buf, "foo");
815
    len = GetTempPathA(len, buf);
816 817
    ok(lstrcmpiA(buf, tmp_dir) == 0, "expected [%s], got [%s]\n",tmp_dir,buf);
    ok(len == strlen(buf), "returned length should be equal to the length of string\n");
818 819
}

820
static void test_GetTempPathW(char* tmp_dir)
821
{
822
    DWORD len, len_with_null;
823
    WCHAR buf[MAX_PATH];
824
    WCHAR tmp_dirW[MAX_PATH];
825 826
    static const WCHAR fooW[] = {'f','o','o',0};

827 828 829 830 831 832 833 834 835 836 837 838
    MultiByteToWideChar(CP_ACP,0,tmp_dir,-1,tmp_dirW,sizeof(tmp_dirW)/sizeof(*tmp_dirW));
    len_with_null = lstrlenW(tmp_dirW) + 1;

    /* This one is different from ANSI version: ANSI version doesn't
     * touch the buffer, unicode version usually truncates the buffer
     * to zero size. NT still exagerates the required buffer size
     * sometimes so we cannot test for an exact match. Finally, the
     * 'len_with_null - 1' case is so buggy on Windows it's not testable.
     * For instance on NT4 it will sometimes return a path without the
     * trailing '\\' and sometimes return an error.
     */

839 840
    lstrcpyW(buf, fooW);
    len = GetTempPathW(MAX_PATH, buf);
841 842
    if (len==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
        return;
843 844
    ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
    ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
845 846 847

    lstrcpyW(buf, fooW);
    len = GetTempPathW(1, buf);
848 849
    ok(buf[0] == 0, "unicode version should truncate the buffer to zero size\n");
    ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
850

851
    len = GetTempPathW(0, NULL);
852
    ok(len >= len_with_null, "Expected >= %lu, got %lu\n", len_with_null, len);
853 854

    lstrcpyW(buf, fooW);
855
    len = GetTempPathW(len, buf);
856 857
    ok(lstrcmpiW(buf, tmp_dirW) == 0, "GetTempPathW returned an incorrect temporary path\n");
    ok(len == lstrlenW(buf), "returned length should be equal to the length of string\n");
858 859 860 861 862 863 864 865 866 867 868 869
}

static void test_GetTempPath(void)
{
    char save_TMP[MAX_PATH];
    char windir[MAX_PATH];
    char buf[MAX_PATH];

    GetEnvironmentVariableA("TMP", save_TMP, sizeof(save_TMP));

    /* test default configuration */
    trace("TMP=%s\n", save_TMP);
870 871 872 873 874
    strcpy(buf,save_TMP);
    if (buf[strlen(buf)-1]!='\\')
        strcat(buf,"\\");
    test_GetTempPathA(buf);
    test_GetTempPathW(buf);
875 876 877 878 879 880

    /* TMP=C:\WINDOWS */
    GetWindowsDirectoryA(windir, sizeof(windir));
    SetEnvironmentVariableA("TMP", windir);
    GetEnvironmentVariableA("TMP", buf, sizeof(buf));
    trace("TMP=%s\n", buf);
881 882 883
    strcat(windir,"\\");
    test_GetTempPathA(windir);
    test_GetTempPathW(windir);
884 885 886 887 888 889 890

    /* TMP=C:\ */
    GetWindowsDirectoryA(windir, sizeof(windir));
    windir[3] = 0;
    SetEnvironmentVariableA("TMP", windir);
    GetEnvironmentVariableA("TMP", buf, sizeof(buf));
    trace("TMP=%s\n", buf);
891 892
    test_GetTempPathA(windir);
    test_GetTempPathW(windir);
893 894 895 896 897 898 899 900

    /* TMP=C: i.e. use current working directory of the specified drive */
    GetWindowsDirectoryA(windir, sizeof(windir));
    SetCurrentDirectoryA(windir);
    windir[2] = 0;
    SetEnvironmentVariableA("TMP", windir);
    GetEnvironmentVariableA("TMP", buf, sizeof(buf));
    trace("TMP=%s\n", buf);
901 902 903 904
    GetWindowsDirectoryA(windir, sizeof(windir));
    strcat(windir,"\\");
    test_GetTempPathA(windir);
    test_GetTempPathW(windir);
905 906 907 908

    SetEnvironmentVariableA("TMP", save_TMP);
}

909 910
START_TEST(path)
{
911
    CHAR origdir[MAX_PATH],curdir[MAX_PATH], curDrive, otherDrive;
912 913
    pGetLongPathNameA = (void*)GetProcAddress( GetModuleHandleA("kernel32.dll"),
                                               "GetLongPathNameA" );
914
    test_InitPathA(curdir, &curDrive, &otherDrive);
915
    test_CurrentDirectoryA(origdir,curdir);
916
    test_PathNameA(curdir, curDrive, otherDrive);
917
    test_CleanupPathA(origdir,curdir);
918
    test_GetTempPath();
919
}