Commit f22bea0a authored by Peter Ganten's avatar Peter Ganten Committed by Alexandre Julliard

Better implementation of GetShortPathNameA/W.

parent bd3771c2
...@@ -870,38 +870,105 @@ BOOL DOSFS_GetFullName( LPCSTR name, BOOL check_last, DOS_FULL_NAME *full ) ...@@ -870,38 +870,105 @@ BOOL DOSFS_GetFullName( LPCSTR name, BOOL check_last, DOS_FULL_NAME *full )
/*********************************************************************** /***********************************************************************
* GetShortPathName32A (KERNEL32.271) * GetShortPathNameA (KERNEL32.271)
* *
* NOTES * NOTES
* observed: * observed:
* longpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0 * longpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0
* *longpath="" or invalid: LastError=ERROR_BAD_PATHNAME, 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 in the
* same way, like the long name
* - longpath and shortpath may have the same adress
* Peter Ganten, 1999
*/ */
DWORD WINAPI GetShortPathNameA( LPCSTR longpath, LPSTR shortpath, DWORD WINAPI GetShortPathNameA( LPCSTR longpath, LPSTR shortpath,
DWORD shortlen ) DWORD shortlen )
{ {
DOS_FULL_NAME full_name; DOS_FULL_NAME full_name;
LPSTR tmpshortpath;
if (!longpath) DWORD length = 0, pos = 0;
{ INT start=-1, end=-1, tmplen;
SetLastError(ERROR_INVALID_PARAMETER);
return 0; if (!longpath) {
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!longpath[0]) {
SetLastError(ERROR_BAD_PATHNAME);
return 0;
} }
if (!longpath[0]) tmpshortpath = HeapAlloc( GetProcessHeap(), 0, MAX_PATHNAME_LEN );
{ if ( !tmpshortpath ) {
SetLastError(ERROR_BAD_PATHNAME); SetLastError ( ERROR_NOT_ENOUGH_MEMORY );
return 0; return 0;
} }
/* FIXME: is it correct to always return a fully qualified short path? */ /* Check for Drive-Letter */
if (!DOSFS_GetFullName( longpath, TRUE, &full_name )) if ( longpath[1] == ':' ) {
{ lstrcpynA ( tmpshortpath, longpath, 3 );
SetLastError(ERROR_BAD_PATHNAME); length = 2;
return 0; pos = 2;
}
/* loop over each part of the name */
while ( longpath[pos] ) {
if (( longpath[pos] == '\\' ) ||
( longpath[pos+1] == '\0' ) ||
( longpath[pos] == '/')) {
if ( start != -1 ) {
if ( DOSFS_ValidDOSName ( longpath + start, TRUE )) {
tmplen = end - start + ( (( longpath[pos] == '\\' ) || ( longpath[pos] == '/' )) ? 1 : 2 );
lstrcpynA ( tmpshortpath+length, longpath+start, tmplen );
length += tmplen - 1;
}
else {
DOSFS_Hash ( longpath + start, tmpshortpath+length, FALSE, FALSE );
length = lstrlenA ( tmpshortpath );
/* Check if the path, up to this point exists */
if ( !DOSFS_GetFullName ( tmpshortpath, TRUE, &full_name ) ) {
SetLastError ( ERROR_FILE_NOT_FOUND );
return 0;
}
}
}
if (( longpath[pos] == '\\' ) || ( longpath[pos] == '/' )) {
tmpshortpath[length] = '\\';
tmpshortpath[length+1]='\0';
length++;
}
pos++;
start = -1;
end = -1;
continue;
}
if ( start == -1 ) {
start = pos;
}
pos++;
end = pos;
} }
lstrcpynA( shortpath, full_name.short_name, shortlen );
return strlen( full_name.short_name ); lstrcpynA ( shortpath, tmpshortpath, shortlen );
length = lstrlenA ( tmpshortpath );
HeapFree ( GetProcessHeap(), 0, tmpshortpath );
return length;
} }
...@@ -911,33 +978,19 @@ DWORD WINAPI GetShortPathNameA( LPCSTR longpath, LPSTR shortpath, ...@@ -911,33 +978,19 @@ DWORD WINAPI GetShortPathNameA( LPCSTR longpath, LPSTR shortpath,
DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath,
DWORD shortlen ) DWORD shortlen )
{ {
DOS_FULL_NAME full_name; LPSTR longpathA, shortpathA;
LPSTR longpathA ;
DWORD ret = 0; DWORD ret = 0;
if (!longpath)
{ SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!longpath[0])
{ SetLastError(ERROR_BAD_PATHNAME);
return 0;
}
longpathA = HEAP_strdupWtoA( GetProcessHeap(), 0, longpath ); longpathA = HEAP_strdupWtoA( GetProcessHeap(), 0, longpath );
shortpathA = HEAP_xalloc ( GetProcessHeap(), 0, shortlen );
/* FIXME: is it correct to always return a fully qualified short path? */ ret = GetShortPathNameA ( longpathA, shortpathA, shortlen );
if (DOSFS_GetFullName( longpathA, TRUE, &full_name )) lstrcpynAtoW ( shortpath, shortpathA, shortlen );
{
ret = strlen( full_name.short_name );
lstrcpynAtoW( shortpath, full_name.short_name, shortlen );
}
SetLastError(ERROR_BAD_PATHNAME);
HeapFree( GetProcessHeap(), 0, longpathA ); HeapFree( GetProcessHeap(), 0, longpathA );
return 0; HeapFree( GetProcessHeap(), 0, shortpathA );
return ret;
} }
......
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