test for Get(Long|Short|Ful)PathNamesA and *CurrentDirectoryA

Geoffrey Hausheer i134rth8d9s at phracturedblue.com
Tue Apr 9 09:08:32 CDT 2002


Here is a test for:
GetFullPathNamesA
GetLongPathNamesA
GetShortPathNamesA
GetCurrentDirectoryA
SetCurrentDirectoryA

Not too many functions, but the test was getting really long, and I thought 
it was about time to cut it off.
It has been tested on Win98 and Win2k.
Wine has some pretty serious issues with the *PathNamesA functions, so there 
are lots of TODOs

.Geoff
-------------- next part --------------
Index: dlls/kernel/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/kernel/Makefile.in,v
retrieving revision 1.30
diff -u -r1.30 Makefile.in
--- dlls/kernel/Makefile.in	2 Apr 2002 19:37:15 -0000	1.30
+++ dlls/kernel/Makefile.in	9 Apr 2002 13:56:57 -0000
@@ -42,6 +42,7 @@
 CTESTS = \
 	tests/alloc.c \
 	tests/directory.c \
+        tests/path.c \
 	tests/thread.c
 
 PLTESTS = \
Index: dlls/kernel/tests/.cvsignore
===================================================================
RCS file: /home/wine/wine/dlls/kernel/tests/.cvsignore,v
retrieving revision 1.4
diff -u -r1.4 .cvsignore
--- dlls/kernel/tests/.cvsignore	2 Apr 2002 19:37:15 -0000	1.4
+++ dlls/kernel/tests/.cvsignore	9 Apr 2002 13:56:58 -0000
@@ -1,6 +1,7 @@
 alloc.ok
 atom.ok
 directory.ok
+path.ok
 thread.ok
 kernel32_test.spec.c
 testlist.c
Index: dlls/kernel/tests/kernel32_test.spec
===================================================================
RCS file: /home/wine/wine/dlls/kernel/tests/kernel32_test.spec,v
retrieving revision 1.1
diff -u -r1.1 kernel32_test.spec
--- dlls/kernel/tests/kernel32_test.spec	22 Mar 2002 01:00:17 -0000	1.1
+++ dlls/kernel/tests/kernel32_test.spec	9 Apr 2002 13:56:58 -0000
@@ -3,3 +3,4 @@
 mode	cuiexe
 
 import kernel32.dll
+import user32.dll
--- /dev/null	Sat Dec 15 18:06:17 2001
+++ dlls/kernel/tests/path.c	Tue Apr  9 09:04:36 2002
@@ -0,0 +1,709 @@
+/*
+ * Unit test suite for Get*PathNamesA and (Get|Set)CurrentDirectoryA.
+ *
+ * Copyright 2002 Geoffrey Hausheer
+ */
+
+#include "wine/test.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winerror.h"
+
+#define WIN2K_PLUS(version) (version.dwMajorVersion==5)
+#define WIN98_PLUS(version) (version.dwMajorVersion==4 && \
+                             version.dwMajorVersion>0)
+#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"
+#define NONFILE_LONG "Non Existant File"
+#define NONDIR_SHORT "notadir"
+#define NONDIR_LONG "Non Existant Directory"
+
+OSVERSIONINFOA version;
+/* 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
+      |<>
+*/
+const CHAR funny_chars[]="!@#$%^&*()=+{}[],?'`\"";
+const CHAR is_char_ok[] ="111111101111111110110";
+const CHAR wine_todo[]  ="111111101100110000110";
+
+/* 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
+*/
+static void test_ValidPathA(CHAR *curdir, CHAR *subdir, CHAR *filename, 
+                         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+ */
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok((len=GetLongPathNameA(curdir,curdirlong,MAX_PATH)),
+       "%s: GetLongPathNameA failed",errstr);
+/*GetLongPathNameA can return a trailing '\\' but shouldn't do so here */
+    ok(! HAS_TRAIL_SLASH_A(curdirlong),
+       "%s: GetLongPathNameA should not have a trailing \\",errstr);
+  }
+  ok((len=GetShortPathNameA(curdir,curdirshort,MAX_PATH)),
+     "%s: GetShortPathNameA failed",errstr);
+/*GetShortPathNameA can return a trailing '\\' but shouldn't do so here */
+  ok(! HAS_TRAIL_SLASH_A(curdirshort),
+     "%s: GetShortPathNameA should not have a trailing \\",errstr);
+/* build relative and absolute paths from inputs */
+  if(lstrlenA(subdir)) {
+    wsprintfA(subpath,"%s\\%s",subdir,filename);
+  } else {
+    lstrcpyA(subpath,filename);
+  }
+  wsprintfA(fullpath,"%s\\%s",curdir,subpath);
+  wsprintfA(fullpathshort,"%s\\%s",curdirshort,subpath);
+  wsprintfA(fullpathlong,"%s\\%s",curdirlong,subpath);
+/* Test GetFullPathNameA functionality */
+  len=GetFullPathNameA(subpath,MAX_PATH,tmpstr,&strptr);
+  ok(len, "GetFullPathNameA failed for: '%s'",subpath);
+  if(HAS_TRAIL_SLASH_A(subpath)) {
+/* Wine strips off the trailing '\\'. Neither Win98 nor Win2k do this. */
+    todo_wine {
+      ok(strptr==NULL,
+         "%s: GetFullPathNameA should not return a filename ptr",errstr);
+      ok(lstrcmpiA(fullpath,tmpstr)==0,
+         "%s: GetFullPathNameA returned '%s' instead of '%s'",
+         errstr,tmpstr,fullpath);
+    }
+  } else { 
+    ok(lstrcmpiA(strptr,filename)==0,
+       "%s: GetFullPathNameA returned '%s' instead of '%s'",
+       errstr,strptr,filename);
+    ok(lstrcmpiA(fullpath,tmpstr)==0,
+       "%s: GetFullPathNameA returned '%s' instead of '%s'",
+       errstr,tmpstr,fullpath);
+  }
+/* Test GetShortPathNameA functionality */
+  SetLastError(0);
+  len=GetShortPathNameA(fullpathshort,shortstr,MAX_PATH);
+  if(passfail==NULL) {
+    ok(len, "%s: GetShortPathNameA failed",errstr);
+  } else {
+    passfail->shortlen=len;
+    passfail->shorterror=GetLastError();
+  }
+/* Test GetLongPathNameA functionality 
+   We test both conversion from GetFullPathNameA and from GetShortPathNameA
+*/
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    if(len==0) {
+      SetLastError(0);
+      len=GetLongPathNameA(shortstr,tmpstr,MAX_PATH);
+      if(passfail==NULL) {
+        ok(len, 
+          "%s: GetLongPathNameA failed during Short->Long conversion", errstr);
+        ok(lstrcmpiA(fullpathlong,tmpstr)==0,
+           "%s: GetLongPathNameA returned '%s' instead of '%s'",
+           errstr,tmpstr,fullpathlong);
+      } else {
+        passfail->s2llen=len;
+        passfail->s2lerror=GetLastError();
+      }
+    }
+    SetLastError(0);
+    len=GetLongPathNameA(fullpath,tmpstr,MAX_PATH);
+    if(passfail==NULL) {
+      ok(len, "%s: GetLongPathNameA failed",errstr);
+      if(HAS_TRAIL_SLASH_A(fullpath)) {
+/* Wine strips off the trailing '\\'  Neither Win98 nor Win2k do this */
+        todo_wine {
+          ok(lstrcmpiA(fullpathlong,tmpstr)==0,
+           "%s: GetLongPathNameA returned '%s' instead of '%s'",
+           errstr,tmpstr,fullpathlong);
+        }
+      } else {
+        ok(lstrcmpiA(fullpathlong,tmpstr)==0,
+          "%s: GetLongPathNameA returned '%s' instead of '%s'",
+          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) {
+  DWORD len,done,error;
+  DWORD ext,fil;
+  INT i;
+  len=lstrlenA(path);
+  ext=len; fil=len; done=0; error=0;
+/* walk backwards over path looking for '.' or '\\' seperators */
+  for(i=len-1;(i>=0) && (!done);i--) {
+    if(path[i]=='.') 
+      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 '.' */
+  ok(!error,"Illegal file found in 8.3 path '%s'",path);
+/* Seperate dir, root, and extension */
+  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,
+     "GetShortPathNAmeA did not return an 8.3 path");
+}
+
+/* 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,
+     "GetShortPathNameA returned '%s' instead of '%s'",dir,goodstr);
+  ok(lstrcmpiA(three,ext)==0,
+     "GetShortPathNameA returned '%s' with incorrect extension",three);
+}
+
+/* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
+   characters in the filename.
+     'valid' indicates whether this would be an allowed filename
+     'todo' indictaes that wine doesn't get this right yet.
+   NOTE: We always call this routine with a non-existant filename, so 
+         Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
+         should.
+*/
+static void test_FunnyChars(CHAR *curdir,CHAR *filename,
+                             INT valid,INT todo,CHAR *errstr) {
+  CHAR tmpstr[MAX_PATH];
+  SLpassfail passfail;
+
+  test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);
+  if(todo) {
+    todo_wine {
+      ok(passfail.shortlen==0,
+         "%s: GetShortPathNameA passed when it shouldn't have",errstr);
+    }
+  } else {
+    ok(passfail.shortlen==0,
+       "%s: GetShortPathNameA passed when it shouldn't have",errstr);
+  }
+  if(valid) {
+    if(todo) {
+      todo_wine {
+        ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
+           "%s: GetShortPathA returned %d and not %d",
+           errstr,passfail.shorterror,ERROR_FILE_NOT_FOUND);
+      }
+    } else {
+      ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
+         "%s: GetShortPathA returned %d and not %d",
+          errstr,passfail.shorterror,ERROR_FILE_NOT_FOUND);
+    }
+  } else {
+    if(todo) {
+      todo_wine {
+/* Win2k returns ERROR_INVALID_NAME, Win98, wine return ERROR_FILE_NOT_FOUND */
+        ok(passfail.shorterror==ERROR_INVALID_NAME ||
+           passfail.shorterror==ERROR_FILE_NOT_FOUND,
+           "%s: GetShortPathA returned %d and not %d or %d",
+           errstr,passfail.shorterror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
+      }
+    } else {
+      ok(passfail.shorterror==ERROR_INVALID_NAME ||
+         passfail.shorterror==ERROR_FILE_NOT_FOUND,
+         "%s: GetShortPathA returned %d and not %d or %d",
+         errstr,passfail.shorterror,ERROR_INVALID_NAME,ERROR_FILE_NOT_FOUND);
+    }
+  }
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
+    if(valid) {
+      ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
+         "%s: GetLongPathA returned %d and not %d",
+         errstr,passfail.longerror,ERROR_FILE_NOT_FOUND);
+    } else {
+      ok(passfail.longerror==ERROR_INVALID_NAME ||
+         passfail.longerror==ERROR_FILE_NOT_FOUND,
+         "%s: GetLongPathA returned %d and not %d or %d'",
+         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);
+    ok(val,"%s: SetCurrentDirectoryA failed",errstr);
+    ok(len==chklen,
+       "%s: SetCurrentDirectory did not change the directory, though it passed",
+       errstr);
+    ok(lstrcmpiA(dirptr,tmppath)==0,
+       "%s: SetCurrentDirectory did not change the directory, though it passed",
+       errstr);
+    ok(SetCurrentDirectoryA(olddir),
+       "%s: Couldn't set directory to it's original value");
+  } else {
+/* else thest that it fails correctly */
+    chklen=lstrlenA(olddir);
+    ok(val==0,
+       "%s: SetCurrentDirectoryA passed when it should have failed",errstr); 
+    ok(len==chklen,
+       "%s: SetCurrentDirectory changed the directrory, though it failed",
+       errstr);
+    ok(lstrcmpiA(olddir,tmppath)==0,
+       "%s: SetCurrentDirectory changed the directrory, though it failed",
+       errstr);
+  }
+}
+static void test_InitPathA(CHAR *newdir)
+{
+  CHAR tmppath[MAX_PATH], /*path to TEMP */
+       tmpstr[MAX_PATH],
+       tmpstr1[MAX_PATH];
+  DWORD len,len1;
+  INT id;
+  HANDLE hndl;
+
+/* Test GetTempPathA */
+  len=GetTempPathA(MAX_PATH,tmppath);
+  ok(len!=0 && len < MAX_PATH,"GetTempPathA failed");
+  ok(HAS_TRAIL_SLASH_A(tmppath),
+     "GetTempPathA returned a path that did not end in '\\'");
+  lstrcpyA(tmpstr,"aaaaaaaa");
+  len1=GetTempPathA(len,tmpstr);
+  ok(len1==len+1,
+     "GetTempPathA should return string length %d instead of %d",len+1,len1);
+  if(WIN2K_PLUS(version)) {
+/* in Win2k, the path won't be modified, but in win98, wine  it is */
+    todo_wine {
+      ok(lstrcmpiA(tmpstr,"aaaaaaaa")==0,
+         "GetTempPathA should not have modified the buffer");
+    }
+  }
+/* Test GetTmpFileNameA 
+   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)
+*/
+  ok((id=GetTempFileNameA(tmppath,"path",0,newdir)),"GetTempFileNameA failed");
+  wsprintfA(tmpstr,"pat%.4x.tmp",id);
+  wsprintfA(tmpstr1,"pat%x.tmp",id);
+  ok(lstrcmpiA(newdir+(lstrlenA(newdir)-lstrlenA(tmpstr)),tmpstr)==0 ||
+     lstrcmpiA(newdir+(lstrlenA(newdir)-lstrlenA(tmpstr1)),tmpstr1)==0,
+     "GetTempPath returned '%s' which doesn't match '%s' or '%s'",
+     newdir,tmpstr,tmpstr1);
+ 
+/* 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,
+     "CreateDirectoryA succeeded even though a file of the same name exists");
+  ok(DeleteFileA(newdir),"Couldn't delete the temporary file we just created");
+  ok(CreateDirectoryA(newdir,NULL),"CreateDirectoryA failed");
+/* Create some files to test other functions.  Note, we will test CreateFileA
+   at some later point
+*/
+  wsprintfA(tmpstr,"%s\\%s",newdir,SHORTDIR);
+  ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed");
+  wsprintfA(tmpstr,"%s\\%s",newdir,LONGDIR);
+  ok(CreateDirectoryA(tmpstr,NULL),"CreateDirectoryA failed");
+  wsprintfA(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,SHORTFILE);
+  hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
+                   CREATE_NEW,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
+  ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed");
+  ok(CloseHandle(hndl),"CloseHandle failed");
+  wsprintfA(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,LONGFILE);
+  hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
+                   CREATE_NEW,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
+  ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed");
+  ok(CloseHandle(hndl),"CloseHandle failed");
+  wsprintfA(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,SHORTFILE);
+  hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
+                   CREATE_NEW,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
+  ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed");
+  ok(CloseHandle(hndl),"CloseHandle failed");
+  wsprintfA(tmpstr,"%s\\%s\\%s",newdir,LONGDIR,LONGFILE);
+  hndl=CreateFileA(tmpstr,GENERIC_WRITE,0,NULL,
+                   CREATE_NEW,FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
+  ok(hndl!=INVALID_HANDLE_VALUE,"CreateFileA failed");
+  ok(CloseHandle(hndl),"CloseHandle failed");
+}
+
+/* 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);
+  ok(len!=0 && len < MAX_PATH,"GetCurrentDirectoryA failed");
+  ok(lstrcmpiA(origdir+(len-1),"\\")!=0,
+     "GetCurrentDirectoryA should not have a trailing \\");
+/* 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);
+  ok(len1==len+1, "GetCurrentDirectoryA returned %d instead of %d",len1,len+1);
+  ok(lstrcmpiA(tmpstr,"aaaaaaa")==0,
+     "GetCurrentDirectoryA should not have modified the buffer");
+/* SetCurrentDirectoryA shouldn't care whether the string has a 
+   trailing '\\' or not
+*/
+  wsprintfA(tmpstr,"%s\\",newdir);
+  test_setdir(origdir,tmpstr,newdir,1,"check 1");
+  test_setdir(origdir,newdir,NULL,1,"check 2");
+/* Set the directory to the working area.  We just tested that this works, 
+   so why check it again.
+*/
+  SetCurrentDirectoryA(newdir);
+/* Check that SetCurrentDirectory fails when a non-existant dir is specified */
+  wsprintfA(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_SHORT);
+  test_setdir(newdir,tmpstr,NULL,0,"check 3");
+/* Check that SetCurrentDirectory fails for a non-existant lond directory */
+  wsprintfA(tmpstr,"%s\\%s\\%s",newdir,SHORTDIR,NONDIR_LONG);
+  test_setdir(newdir,tmpstr,NULL,0,"check 4");
+/* Check that SetCurrentDirectory passes with a long directory */
+  wsprintfA(tmpstr,"%s\\%s",newdir,LONGDIR);
+  test_setdir(newdir,tmpstr,NULL,1,"check 5");
+/* Check that SetCurrentDirectory passes with a short relative directory */
+  wsprintfA(tmpstr,"%s",SHORTDIR);
+  wsprintfA(tmpstr1,"%s\\%s",newdir,SHORTDIR);
+  test_setdir(newdir,tmpstr,tmpstr1,1,"check 6");
+/* starting with a '.' */
+  wsprintfA(tmpstr,".\\%s",SHORTDIR);
+  test_setdir(newdir,tmpstr,tmpstr1,1,"check 7");
+/* Check that SetCurrentDirectory passes with a short relative directory */
+  wsprintfA(tmpstr,"%s",LONGDIR);
+  wsprintfA(tmpstr1,"%s\\%s",newdir,LONGDIR);
+  test_setdir(newdir,tmpstr,tmpstr1,1,"check 8");
+/* starting with a '.' */
+  wsprintfA(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];
+  wsprintfA(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,SHORTFILE);
+  ok(DeleteFileA(tmpstr),"DeleteFileA failed");
+  wsprintfA(tmpstr,"%s\\%s\\%s",curdir,SHORTDIR,LONGFILE);
+  ok(DeleteFileA(tmpstr),"DeleteFileA failed");
+  wsprintfA(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,SHORTFILE);
+  ok(DeleteFileA(tmpstr),"DeleteFileA failed");
+  wsprintfA(tmpstr,"%s\\%s\\%s",curdir,LONGDIR,LONGFILE);
+  ok(DeleteFileA(tmpstr),"DeleteFileA failed");
+  wsprintfA(tmpstr,"%s\\%s",curdir,SHORTDIR);
+  ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed");
+  wsprintfA(tmpstr,"%s\\%s",curdir,LONGDIR);
+  ok(RemoveDirectoryA(tmpstr),"RemoveDirectoryA failed");
+  ok(SetCurrentDirectoryA(origdir),"SetCurrentDirectoryA failed");
+  ok(RemoveDirectoryA(curdir),"RemoveDirectoryA failed");
+}
+
+/* This routine will test Get(Full|Short|Long)PathNameA */
+static void test_PathNameA(CHAR *curdir)
+{
+  CHAR curdir_short[MAX_PATH],
+       longdir_short[MAX_PATH];
+  CHAR tmpstr[MAX_PATH],tmpstr1[MAX_PATH];
+  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)),
+     "GetShortPathNameA failed");
+  ok(!HAS_TRAIL_SLASH_A(curdir_short),
+     "GetShortPathNameA should not have a trailing \\");
+/* Get the short form of the absolute-path to LONGDIR */
+  wsprintfA(tmpstr,"%s\\%s",curdir_short,LONGDIR);
+  ok((len=GetShortPathNameA(tmpstr,longdir_short,MAX_PATH)),
+     "GetShortPathNameA failed");
+  ok(lstrcmpiA(longdir_short+(len-1),"\\")!=0,
+     "GetShortPathNameA should not have a trailing \\");
+
+/* 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");
+  wsprintfA(tmpstr1,"%s\\%s\\%s",curdir_short,SHORTDIR,SHORTFILE);
+  ok(lstrcmpiA(tmpstr,tmpstr1)==0,
+     "GetShortPathNameA returned '%s' instead of '%s'",tmpstr,tmpstr1);
+/* Now try a 8.3 directory, long file name */
+  test_ValidPathA(curdir,SHORTDIR,LONGFILE,tmpstr,NULL,"test2");
+  wsprintfA(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");
+  wsprintfA(tmpstr1,"%s\\%s",longdir_short,SHORTFILE);
+  ok(lstrcmpiA(tmpstr,tmpstr1)==0,
+     "GetShortPathNameA returned '%s' instead of '%s'",tmpstr,tmpstr1);
+/*Lastly a long directory, long file */
+  test_ValidPathA(curdir,LONGDIR,LONGFILE,tmpstr,NULL,"test4");
+  test_LongtoShortA(tmpstr,longdir_short,"PAT","test4");
+
+/* Now check all of the invalid file w/ valid directroy combinations */
+/* Start with a 8.3 directory, 8.3 filename */
+  test_ValidPathA(curdir,SHORTDIR,NONFILE_SHORT,tmpstr,&passfail,"test5");
+  todo_wine {
+    ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
+    ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
+       "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'");
+  }
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
+    ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
+       "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'");
+  }
+/* Now try a 8.3 directory, long file name */
+  test_ValidPathA(curdir,SHORTDIR,NONFILE_LONG,tmpstr,&passfail,"test6");
+  ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
+  ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
+     "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'");
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
+    ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
+       "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'");
+  }
+/* Next is a long directory, 8.3 file */
+  test_ValidPathA(curdir,LONGDIR,NONFILE_SHORT,tmpstr,&passfail,"test7");
+  todo_wine {
+    ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
+    ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
+       "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'");
+  }
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
+    ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
+      "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'");
+  }
+/*Lastly a long directory, long file */
+  test_ValidPathA(curdir,LONGDIR,NONFILE_LONG,tmpstr,&passfail,"test8");
+  ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
+  ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
+     "GetShortPathA should have returned 'ERROR_FILE_NOT_FOUND'");
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
+    ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
+       "GetlongPathA should have returned 'ERROR_FILE_NOT_FOUND'");
+  }
+/* Now try again with directories that don't exist */
+/* 8.3 directory, 8.3 filename */
+  test_ValidPathA(curdir,NONDIR_SHORT,SHORTFILE,tmpstr,&passfail,"test9");
+  todo_wine {
+    ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
+    ok(passfail.shorterror==ERROR_PATH_NOT_FOUND || 
+       passfail.shorterror==ERROR_FILE_NOT_FOUND,
+       "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
+        passfail.shorterror);
+  }
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
+    ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
+       passfail.longerror==ERROR_FILE_NOT_FOUND,
+       "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
+       passfail.longerror);
+  }
+/* Now try a 8.3 directory, long file name */
+  test_ValidPathA(curdir,NONDIR_SHORT,LONGFILE,tmpstr,&passfail,"test10");
+  ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
+  ok(passfail.shorterror==ERROR_PATH_NOT_FOUND || 
+     passfail.shorterror==ERROR_FILE_NOT_FOUND,
+     "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
+      passfail.shorterror);
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
+    ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
+       passfail.longerror==ERROR_FILE_NOT_FOUND,
+       "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
+       passfail.longerror);
+  }
+/* Next is a long directory, 8.3 file */
+  test_ValidPathA(curdir,NONDIR_LONG,SHORTFILE,tmpstr,&passfail,"test11");
+  ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
+  ok(passfail.shorterror==ERROR_PATH_NOT_FOUND || 
+     passfail.shorterror==ERROR_FILE_NOT_FOUND,
+     "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
+      passfail.shorterror);
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
+    ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
+       passfail.longerror==ERROR_FILE_NOT_FOUND,
+       "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
+       passfail.longerror);
+  }
+/*Lastly a long directory, long file */
+  test_ValidPathA(curdir,NONDIR_LONG,LONGFILE,tmpstr,&passfail,"test12");
+  ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
+  ok(passfail.shorterror==ERROR_PATH_NOT_FOUND || 
+     passfail.shorterror==ERROR_FILE_NOT_FOUND,
+     "GetShortPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
+      passfail.shorterror);
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
+    ok(passfail.longerror==ERROR_PATH_NOT_FOUND ||
+       passfail.longerror==ERROR_FILE_NOT_FOUND,
+       "GetLongPathA returned %d and not 'ERROR_PATH_NOT_FOUND'",
+       passfail.longerror);
+  }
+/* Next try directories ending with '\\' */
+/* Existing Directories */
+  wsprintfA(tmpstr,"%s\\",SHORTDIR);
+  test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test13");
+  wsprintfA(tmpstr,"%s\\",LONGDIR);
+  test_ValidPathA(curdir,"",tmpstr,tmpstr1,NULL,"test14");
+/* Non-existant directories */
+  wsprintfA(tmpstr,"%s\\",NONDIR_SHORT);
+  test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test15");
+  todo_wine {
+    ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
+    ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
+     "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'",
+      passfail.shorterror);
+  }
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
+    ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
+       "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'",
+       passfail.longerror);
+  }
+  wsprintfA(tmpstr,"%s\\",NONDIR_LONG);
+  test_ValidPathA(curdir,"",tmpstr,tmpstr1,&passfail,"test16");
+  ok(passfail.shortlen==0,"GetShortPathNameA passed when it shouldn't have");
+  ok(passfail.shorterror==ERROR_FILE_NOT_FOUND,
+     "GetShortPathA returned %d and not 'ERROR_FILE_NOT_FOUND'",
+      passfail.shorterror);
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");
+    ok(passfail.longerror==ERROR_FILE_NOT_FOUND,
+       "GetLongPathA returned %d and not 'ERROR_FILE_NOT_FOUND'",
+       passfail.longerror);
+  }
+/* Now try some relative paths */
+  ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed");
+  test_SplitShortPathA(tmpstr,dir,eight,three);
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(GetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed");
+    todo_wine {
+      ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
+         "GetLongPathNameA returned '%s' instead of '%s'",tmpstr1,LONGDIR);
+    }
+  }
+  wsprintfA(tmpstr,".\\%s",LONGDIR);
+  ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed");
+  test_SplitShortPathA(tmpstr1,dir,eight,three);
+  ok(lstrcmpiA(dir,".")==0,"GetShortPathNameA did not keep relative directory");
+  if(WIN2K_PLUS(version) || WIN98_PLUS(version)) {
+    ok(GetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetShortPathNameA failed");
+    todo_wine {
+      ok(lstrcmpiA(tmpstr1,tmpstr)==0,
+         "GetLongPathNameA returned '%s' instead of '%s'",tmpstr1,tmpstr);
+    }
+  }
+/* Check out Get*PathNameA on some funny characters */
+  for(i=0;i<lstrlenA(funny_chars);i++) {
+    INT valid,todo;
+    valid=(is_char_ok[i]=='0') ? 0 : 1;
+    todo=(wine_todo[i]=='0') ? 0 : 1;
+    wsprintfA(tmpstr1,"check%d-1",i);
+    wsprintfA(tmpstr,"file%c000.ext",funny_chars[i]);
+    test_FunnyChars(curdir,tmpstr,valid,todo,tmpstr1);
+    wsprintfA(tmpstr1,"check%d-2",i);
+    wsprintfA(tmpstr,"file000.e%ct",funny_chars[i]);
+    test_FunnyChars(curdir,tmpstr,valid,todo,tmpstr1);
+    wsprintfA(tmpstr1,"check%d-3",i);
+    wsprintfA(tmpstr,"%cfile000.ext",funny_chars[i]);
+    test_FunnyChars(curdir,tmpstr,valid,todo,tmpstr1);
+    wsprintfA(tmpstr1,"check%d-4",i);
+    wsprintfA(tmpstr,"file000%c.ext",funny_chars[i]);
+    test_FunnyChars(curdir,tmpstr,valid,todo,tmpstr1);
+    wsprintfA(tmpstr1,"check%d-5",i);
+    wsprintfA(tmpstr,"Long %c File",funny_chars[i]);
+    test_FunnyChars(curdir,tmpstr,valid,0,tmpstr1);
+    wsprintfA(tmpstr1,"check%d-6",i);
+    wsprintfA(tmpstr,"%c Long File",funny_chars[i]);
+    test_FunnyChars(curdir,tmpstr,valid,0,tmpstr1);
+    wsprintfA(tmpstr1,"check%d-7",i);
+    wsprintfA(tmpstr,"Long File %c",funny_chars[i]);
+    test_FunnyChars(curdir,tmpstr,valid,0,tmpstr1);
+  }
+/* ':' is a special case and is allowed only in certain cases */
+    test_FunnyChars(curdir,"file:000.ext",1,1,"check-1");
+    test_FunnyChars(curdir,"file000.e:t" ,1,1,"check-2");
+    test_FunnyChars(curdir,":file000.ext",0,1,"check-3");
+    test_FunnyChars(curdir,"file000:.ext",1,1,"check-4");
+    test_FunnyChars(curdir,"Long : File" ,1,0,"check-5");
+    test_FunnyChars(curdir,": Long File" ,0,0,"check-6");
+    test_FunnyChars(curdir,"Long File :" ,0,0,"check-7");
+}
+
+START_TEST(path)
+{
+    CHAR origdir[MAX_PATH],curdir[MAX_PATH];
+    version.dwOSVersionInfoSize=sizeof(OSVERSIONINFOA);
+    ok(GetVersionExA(&version),"GetVersionEx failed: %d",GetLastError());
+    test_InitPathA(curdir);
+    test_CurrentDirectoryA(origdir,curdir);
+    test_PathNameA(curdir);
+    test_CleanupPathA(origdir,curdir);
+}


More information about the wine-patches mailing list