Commit 9ccb73a8 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

Reimplemented Get{Short|Long}PathName and updated the regression

tests.
parent 87323579
......@@ -51,6 +51,7 @@ C_SRCS = \
module.c \
ne_module.c \
ne_segment.c \
path.c \
powermgnt.c \
process.c \
profile.c \
......
......@@ -141,7 +141,7 @@ static void test_ValidPathA(CHAR *curdir, CHAR *subdir, CHAR *filename,
We test both conversion from GetFullPathNameA and from GetShortPathNameA
*/
if(pGetLongPathNameA) {
if(len==0) {
if(len!=0) {
SetLastError(0);
len=pGetLongPathNameA(shortstr,tmpstr,MAX_PATH);
if(passfail==NULL) {
......@@ -160,12 +160,9 @@ static void test_ValidPathA(CHAR *curdir, CHAR *subdir, CHAR *filename,
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'",
......@@ -229,7 +226,7 @@ static void test_LongtoShortA(CHAR *teststr,CHAR *goodstr,
/* 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.
'todo' indicates 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.
......@@ -518,14 +515,12 @@ static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
"GetLongPathNameA: wrong return code, %ld instead of %d",
rc1, strlen(tmpstr)+1);
todo_wine {
sprintf(dir,"%c:",curDrive);
rc1=(*pGetLongPathNameA)(dir,tmpstr,sizeof(tmpstr));
ok(strcmp(dir,tmpstr)==0,
"GetLongPathNameA: returned '%s' instead of '%s' (rc=%ld)",
tmpstr,dir,rc1);
}
}
/* Check the cases where both file and directory exist first */
/* Start with a 8.3 directory, 8.3 filename */
......@@ -773,24 +768,21 @@ static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
ok(GetShortPathNameA(LONGDIR,tmpstr,MAX_PATH),"GetShortPathNameA failed");
test_SplitShortPathA(tmpstr,dir,eight,three);
if(pGetLongPathNameA) {
ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed");
todo_wine {
ok(pGetLongPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetLongPathNameA failed");
ok(lstrcmpiA(tmpstr1,LONGDIR)==0,
"GetLongPathNameA returned '%s' instead of '%s'",tmpstr1,LONGDIR);
}
}
sprintf(tmpstr,".\\%s",LONGDIR);
ok(GetShortPathNameA(tmpstr,tmpstr1,MAX_PATH),"GetShortPathNameA failed");
test_SplitShortPathA(tmpstr1,dir,eight,three);
ok(lstrcmpiA(dir,".")==0 || dir[0]=='\0',
"GetShortPathNameA did not keep relative directory [%s]",tmpstr1);
if(pGetLongPathNameA) {
ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetShortPathNameA failed");
todo_wine {
ok(pGetLongPathNameA(tmpstr1,tmpstr1,MAX_PATH),"GetLongPathNameA failed %s",
tmpstr);
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;
......
......@@ -615,6 +615,7 @@ DWORD WINAPI RtlGetLongestNtPathLength(void)
BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3( const UNICODE_STRING *unicode,
OEM_STRING *oem, BOOLEAN *spaces )
{
static const char* illegal = "*?<>|\"+=,;[]:/\\\345";
int dot = -1;
unsigned int i;
char buffer[12];
......@@ -655,7 +656,7 @@ BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3( const UNICODE_STRING *unicode,
dot = i;
break;
default:
/* FIXME: check for invalid chars */
if (strchr(illegal, oem->Buffer[i])) return FALSE;
break;
}
}
......
......@@ -1173,278 +1173,6 @@ BOOL DOSFS_GetFullName( LPCWSTR name, BOOL check_last, DOS_FULL_NAME *full )
/***********************************************************************
* GetShortPathNameW (KERNEL32.@)
*
* NOTES
* observed:
* longpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0
* longpath="" or invalid: LastError=ERROR_BAD_PATHNAME, ret=0
*
* more observations ( with NT 3.51 (WinDD) ):
* longpath <= 8.3 -> just copy longpath to shortpath
* longpath > 8.3 ->
* a) file does not exist -> return 0, LastError = ERROR_FILE_NOT_FOUND
* b) file does exist -> set the short filename.
* - trailing slashes are reproduced in the short name, even if the
* file is not a directory
* - the absolute/relative path of the short name is reproduced like found
* in the long name
* - longpath and shortpath may have the same address
* Peter Ganten, 1999
*/
DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortlen )
{
DOS_FULL_NAME full_name;
WCHAR tmpshortpath[MAX_PATHNAME_LEN];
const WCHAR *p;
DWORD sp = 0, lp = 0;
int drive;
DWORD tmplen;
UINT flags;
BOOL unixabsolute = *longpath == '/';
TRACE("%s\n", debugstr_w(longpath));
if (!longpath) {
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!longpath[0]) {
SetLastError(ERROR_BAD_PATHNAME);
return 0;
}
/* check for drive letter */
if (!unixabsolute && longpath[1] == ':' ) {
tmpshortpath[0] = longpath[0];
tmpshortpath[1] = ':';
sp = 2;
}
if ( ( drive = DOSFS_GetPathDrive ( &longpath )) == -1 ) return 0;
flags = DRIVE_GetFlags ( drive );
if (unixabsolute && drive != DRIVE_GetCurrentDrive()) {
tmpshortpath[0] = drive + 'A';
tmpshortpath[1] = ':';
sp = 2;
}
while ( longpath[lp] ) {
/* check for path delimiters and reproduce them */
if ( longpath[lp] == '\\' || longpath[lp] == '/' ) {
if (!sp || tmpshortpath[sp-1]!= '\\')
{
/* strip double "\\" */
tmpshortpath[sp] = '\\';
sp++;
}
tmpshortpath[sp]=0;/*terminate string*/
lp++;
continue;
}
tmplen = 0;
for(p = longpath + lp; *p && *p != '/' && *p != '\\'; p++)
tmplen++;
lstrcpynW(tmpshortpath + sp, longpath + lp, tmplen + 1);
/* Check, if the current element is a valid dos name */
if ( DOSFS_ValidDOSName ( longpath + lp, !(flags & DRIVE_CASE_SENSITIVE) ) ) {
sp += tmplen;
lp += tmplen;
continue;
}
/* Check if the file exists and use the existing file name */
if ( DOSFS_GetFullName ( tmpshortpath, TRUE, &full_name ) ) {
strcpyW(tmpshortpath + sp, strrchrW(full_name.short_name, '\\') + 1);
sp += strlenW(tmpshortpath + sp);
lp += tmplen;
continue;
}
TRACE("not found!\n" );
SetLastError ( ERROR_FILE_NOT_FOUND );
return 0;
}
tmpshortpath[sp] = 0;
tmplen = strlenW(tmpshortpath) + 1;
if (tmplen <= shortlen)
{
strcpyW(shortpath, tmpshortpath);
TRACE("returning %s\n", debugstr_w(shortpath));
tmplen--; /* length without 0 */
}
return tmplen;
}
/***********************************************************************
* GetShortPathNameA (KERNEL32.@)
*/
DWORD WINAPI GetShortPathNameA( LPCSTR longpath, LPSTR shortpath, DWORD shortlen )
{
UNICODE_STRING longpathW;
WCHAR shortpathW[MAX_PATH];
DWORD ret, retW;
if (!longpath)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
TRACE("%s\n", debugstr_a(longpath));
if (!RtlCreateUnicodeStringFromAsciiz(&longpathW, longpath))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
retW = GetShortPathNameW(longpathW.Buffer, shortpathW, MAX_PATH);
if (!retW)
ret = 0;
else if (retW > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
ret = 0;
}
else
{
ret = WideCharToMultiByte(CP_ACP, 0, shortpathW, -1, NULL, 0, NULL, NULL);
if (ret <= shortlen)
{
WideCharToMultiByte(CP_ACP, 0, shortpathW, -1, shortpath, shortlen, NULL, NULL);
ret--; /* length without 0 */
}
}
RtlFreeUnicodeString(&longpathW);
return ret;
}
/***********************************************************************
* GetLongPathNameW (KERNEL32.@)
*
* NOTES
* observed (Win2000):
* shortpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0
* shortpath="": LastError=ERROR_PATH_NOT_FOUND, ret=0
*/
DWORD WINAPI GetLongPathNameW( LPCWSTR shortpath, LPWSTR longpath, DWORD longlen )
{
DOS_FULL_NAME full_name;
const char *root;
LPWSTR p;
int drive;
DWORD ret, len = 0;
if (!shortpath) {
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!shortpath[0]) {
SetLastError(ERROR_PATH_NOT_FOUND);
return 0;
}
TRACE("%s,%p,%ld\n", debugstr_w(shortpath), longpath, longlen);
if(shortpath[0]=='\\' && shortpath[1]=='\\')
{
ERR("UNC pathname %s\n",debugstr_w(shortpath));
lstrcpynW( longpath, full_name.short_name, longlen );
return strlenW(longpath);
}
if (!DOSFS_GetFullName( shortpath, TRUE, &full_name )) return 0;
root = full_name.long_name;
drive = DRIVE_FindDriveRoot(&root);
ret = MultiByteToWideChar(CP_UNIXCP, 0, root, -1, NULL, 0);
ret += 3; /* A:\ */
/* reproduce terminating slash */
if (ret > 4) /* if not drive root */
{
len = strlenW(shortpath);
if (shortpath[len - 1] == '\\' || shortpath[len - 1] == '/')
len = 1;
}
ret += len;
if (ret <= longlen)
{
longpath[0] = 'A' + drive;
longpath[1] = ':';
MultiByteToWideChar(CP_UNIXCP, 0, root, -1, longpath + 2, longlen - 2);
for (p = longpath; *p; p++) if (*p == '/') *p = '\\';
if (len)
{
longpath[ret - 2] = '\\';
longpath[ret - 1] = 0;
}
TRACE("returning %s\n", debugstr_w(longpath));
ret--; /* length without 0 */
}
return ret;
}
/***********************************************************************
* GetLongPathNameA (KERNEL32.@)
*/
DWORD WINAPI GetLongPathNameA( LPCSTR shortpath, LPSTR longpath, DWORD longlen )
{
UNICODE_STRING shortpathW;
WCHAR longpathW[MAX_PATH];
DWORD ret, retW;
if (!shortpath)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
TRACE("%s\n", debugstr_a(shortpath));
if (!RtlCreateUnicodeStringFromAsciiz(&shortpathW, shortpath))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
retW = GetLongPathNameW(shortpathW.Buffer, longpathW, MAX_PATH);
if (!retW)
ret = 0;
else if (retW > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
ret = 0;
}
else
{
ret = WideCharToMultiByte(CP_ACP, 0, longpathW, -1, NULL, 0, NULL, NULL);
if (ret <= longlen)
{
WideCharToMultiByte(CP_ACP, 0, longpathW, -1, longpath, longlen, NULL, NULL);
ret--; /* length without 0 */
}
}
RtlFreeUnicodeString(&shortpathW);
return ret;
}
/***********************************************************************
* DOSFS_DoGetFullPathName
*
* Implementation of GetFullPathNameA/W.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment