path.c

来自「Wine-20031016」· C语言 代码 · 共 957 行 · 第 1/3 页

C
957
字号
/* * 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 */#include <stdarg.h>#include <stdio.h>#include "wine/test.h"#include "windef.h"#include "winbase.h"#include "winuser.h"#include "winerror.h"#include "winnls.h"#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 Existent File"#define NONDIR_SHORT "notadir"#define NONDIR_LONG "Non Existent Directory"#define NOT_A_VALID_DRIVE '@'/* 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      |<>"*/static const CHAR funny_chars[]="!@#$%^&*()=+{}[],?'`";static const CHAR is_char_ok[] ="11111110111111111011";static const CHAR wine_todo[]  ="00000000000000000000";static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR,LPSTR,DWORD);/* 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(pGetLongPathNameA) {    ok((len=pGetLongPathNameA(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)) {    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);  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(pGetLongPathNameA) {    if(len==0) {      SetLastError(0);      len=pGetLongPathNameA(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=pGetLongPathNameA(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) {  int done,error;  int ext,fil;  int len,i;  len=lstrlenA(path);  ext=len; fil=len; done=0; error=0;/* walk backwards over path looking for '.' or '\\' separators */  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);/* Separate 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-existent 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],tmpstr1[MAX_PATH];  SLpassfail passfail;  test_ValidPathA(curdir,"",filename,tmpstr,&passfail,errstr);  if(valid) {    sprintf(tmpstr1,"%s\\%s",curdir,filename);    if(todo) {      todo_wine {        ok((passfail.shortlen==0 &&            (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||           (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),           "%s: GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]",           errstr,passfail.shortlen,passfail.shorterror,tmpstr);      }    } else {      ok((passfail.shortlen==0 &&          (passfail.shorterror==ERROR_FILE_NOT_FOUND || passfail.shorterror==ERROR_PATH_NOT_FOUND || !passfail.shorterror)) ||         (passfail.shortlen==strlen(tmpstr1) && lstrcmpiA(tmpstr,tmpstr1)==0),         "%s: GetShortPathNameA error: len=%ld error=%ld tmpstr=[%s]",         errstr,passfail.shortlen,passfail.shorterror,tmpstr);    }  } else {    if(todo) {      todo_wine {/* Win2k returns ERROR_INVALID_NAME, Win98, wine return ERROR_FILE_NOT_FOUND, NT4 doesn't set last error */        ok(passfail.shortlen==0 &&           (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),           "%s: GetShortPathA should have failed len=%ld, error=%ld",           errstr,passfail.shortlen,passfail.shorterror);      }    } else {      ok(passfail.shortlen==0 &&         (passfail.shorterror==ERROR_INVALID_NAME || passfail.shorterror==ERROR_FILE_NOT_FOUND || !passfail.shorterror),         "%s: GetShortPathA should have failed len=%ld, error=%ld",         errstr,passfail.shortlen,passfail.shorterror);    }  }  if(pGetLongPathNameA) {    ok(passfail.longlen==0,"GetLongPathNameA passed when it shouldn't have");    if(valid) {      ok(passfail.longerror==ERROR_FILE_NOT_FOUND,         "%s: GetLongPathA returned %ld 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 %ld 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",errstr);  } 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 directory, though it failed",

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?