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 + -
显示快捷键?