Bugfix for trailing slashes, repetition of '/' or '\' and

SetLastError() in GetFullPathname.
oldstable
Juergen Schmied 1999-01-03 16:12:01 +00:00 committed by Alexandre Julliard
parent f7b0de3f26
commit 8640716a66
1 changed files with 56 additions and 30 deletions

View File

@ -970,27 +970,37 @@ static DWORD DOSFS_DoGetFullPathName( LPCSTR name, DWORD len, LPSTR result,
char buffer[MAX_PATHNAME_LEN]; char buffer[MAX_PATHNAME_LEN];
int drive; int drive;
char *p; char *p;
DWORD ret;
/* last possible position for a char != 0 */
char *endchar = buffer + sizeof(buffer) - 2;
*endchar = '\0';
TRACE(dosfs, "converting '%s'\n", name );
TRACE(dosfs, "converting %s\n", name ); if (!name || !result || ((drive = DOSFS_GetPathDrive( &name )) == -1) )
{ SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (!name || !result) return 0;
if ((drive = DOSFS_GetPathDrive( &name )) == -1) return 0;
p = buffer; p = buffer;
*p++ = 'A' + drive; *p++ = 'A' + drive;
*p++ = ':'; *p++ = ':';
if (IS_END_OF_NAME(*name) && (*name)) /* Absolute path */ if (IS_END_OF_NAME(*name) && (*name)) /* Absolute path */
{ {
while ((*name == '\\') || (*name == '/')) name++; while (((*name == '\\') || (*name == '/')) && (!*endchar) )
*p++ = *name++;
} }
else /* Relative path or empty path */ else /* Relative path or empty path */
{ {
*p++ = '\\'; *p++ = '\\';
lstrcpyn32A( p, DRIVE_GetDosCwd(drive), sizeof(buffer) - 3 ); lstrcpyn32A( p, DRIVE_GetDosCwd(drive), sizeof(buffer) - 4 );
if (*p) p += strlen(p); else p--; if ( *p )
{
p += strlen(p);
*p++ = '\\';
}
} }
if (!*name) /* empty path */
*p++ = '\\';
*p = '\0'; *p = '\0';
while (*name) while (*name)
@ -1007,41 +1017,54 @@ static DWORD DOSFS_DoGetFullPathName( LPCSTR name, DWORD len, LPSTR result,
{ {
name += 2; name += 2;
while ((*name == '\\') || (*name == '/')) name++; while ((*name == '\\') || (*name == '/')) name++;
while ((p > buffer + 2) && (*p != '\\')) p--;
*p = '\0'; /* Remove trailing separator */ if (p < buffer + 3) /* no previous dir component */
continue;
p--; /* skip previously added '\\' */
while ((*p == '\\') || (*p == '/')) p--;
/* skip previous dir component */
while ((*p != '\\') && (*p != '/')) p--;
p++;
continue; continue;
} }
} }
if (p >= buffer + sizeof(buffer) - 1) if ( *endchar )
{ { DOS_ERROR( ER_PathNotFound, EC_NotFound, SA_Abort, EL_Disk );
DOS_ERROR( ER_PathNotFound, EC_NotFound, SA_Abort, EL_Disk );
return 0; return 0;
} }
*p++ = '\\'; while (!IS_END_OF_NAME(*name) && (!*endchar) )
while (!IS_END_OF_NAME(*name) && (p < buffer + sizeof(buffer) - 1))
*p++ = *name++; *p++ = *name++;
*p = '\0'; while (((*name == '\\') || (*name == '/')) && (!*endchar) )
while ((*name == '\\') || (*name == '/')) name++; *p++ = *name++;
} }
*p = '\0';
if (!buffer[2])
{
buffer[2] = '\\';
buffer[3] = '\0';
}
if (!(DRIVE_GetFlags(drive) & DRIVE_CASE_PRESERVING)) if (!(DRIVE_GetFlags(drive) & DRIVE_CASE_PRESERVING))
CharUpper32A( buffer ); CharUpper32A( buffer );
if (unicode)
lstrcpynAtoW( (LPWSTR)result, buffer, len );
else
lstrcpyn32A( result, buffer, len );
if (unicode) lstrcpynAtoW( (LPWSTR)result, buffer, len ); TRACE(dosfs, "returning '%s'\n", buffer );
else lstrcpyn32A( result, buffer, len );
TRACE(dosfs, "returning %s\n", buffer ); /* If the lpBuffer buffer is too small, the return value is the
return strlen(buffer); size of the buffer, in characters, required to hold the path. */
ret = strlen(buffer);
if (ret >= len )
SetLastError( ERROR_INSUFFICIENT_BUFFER );
return ret;
} }
/*********************************************************************** /***********************************************************************
* GetFullPathName32A (KERNEL32.272) * GetFullPathName32A (KERNEL32.272)
* NOTES
* if the path closed with '\', *lastpart is 0
*/ */
DWORD WINAPI GetFullPathName32A( LPCSTR name, DWORD len, LPSTR buffer, DWORD WINAPI GetFullPathName32A( LPCSTR name, DWORD len, LPSTR buffer,
LPSTR *lastpart ) LPSTR *lastpart )
@ -1051,7 +1074,6 @@ DWORD WINAPI GetFullPathName32A( LPCSTR name, DWORD len, LPSTR buffer,
{ {
LPSTR p = buffer + strlen(buffer); LPSTR p = buffer + strlen(buffer);
/* if the path closed with '\', *lastpart is 0 */
if (*p != '\\') if (*p != '\\')
{ {
while ((p > buffer + 2) && (*p != '\\')) p--; while ((p > buffer + 2) && (*p != '\\')) p--;
@ -1075,8 +1097,12 @@ DWORD WINAPI GetFullPathName32W( LPCWSTR name, DWORD len, LPWSTR buffer,
if (ret && lastpart) if (ret && lastpart)
{ {
LPWSTR p = buffer + lstrlen32W(buffer); LPWSTR p = buffer + lstrlen32W(buffer);
while ((p > buffer + 2) && (*p != '\\')) p--; if (*p != (WCHAR)'\\')
*lastpart = p + 1; {
while ((p > buffer + 2) && (*p != (WCHAR)'\\')) p--;
*lastpart = p + 1;
}
else *lastpart = NULL;
} }
return ret; return ret;
} }