Make DRIVE_FindRootW really behave like DRIVE_FindRoot.

This commit is contained in:
Alexandre Julliard 2003-04-08 03:58:42 +00:00
parent 3dec4c5219
commit cce7e25827
1 changed files with 65 additions and 24 deletions

View File

@ -476,35 +476,76 @@ int DRIVE_FindDriveRoot( const char **path )
*/ */
int DRIVE_FindDriveRootW( LPCWSTR *path ) int DRIVE_FindDriveRootW( LPCWSTR *path )
{ {
int drive, rootdrive = -1; int drive, level, len;
char buffer[MAX_PATHNAME_LEN]; WCHAR buffer[MAX_PATHNAME_LEN];
LPCWSTR p = *path; WCHAR *p;
int len, match_len = -1; struct stat st;
strcpyW( buffer, *path );
while ((p = strchrW( buffer, '\\' )) != NULL)
*p = '/';
len = strlenW(buffer);
/* strip off trailing slashes */
while (len > 1 && buffer[len - 1] == '/') buffer[--len] = 0;
for (;;)
{
int codepage = -1;
/* Find the drive */
for (drive = 0; drive < MAX_DOS_DRIVES; drive++) for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
{ {
char buffA[MAX_PATHNAME_LEN];
if (!DOSDrives[drive].root || if (!DOSDrives[drive].root ||
(DOSDrives[drive].flags & DRIVE_DISABLED)) continue; (DOSDrives[drive].flags & DRIVE_DISABLED))
WideCharToMultiByte(DOSDrives[drive].codepage, 0, *path, -1,
buffer, MAX_PATHNAME_LEN, NULL, NULL);
len = strlen(DOSDrives[drive].root);
if(strncmp(DOSDrives[drive].root, buffer, len))
continue; continue;
if(len <= match_len) continue;
match_len = len; if (codepage != DOSDrives[drive].codepage)
rootdrive = drive; {
p = *path + len; WideCharToMultiByte( DOSDrives[drive].codepage, 0, buffer, -1,
buffA, sizeof(buffA), NULL, NULL );
if (stat( buffA, &st ) == -1 || !S_ISDIR( st.st_mode ))
{
codepage = -1;
continue;
}
codepage = DOSDrives[drive].codepage;
} }
if (rootdrive != -1) if ((DOSDrives[drive].dev == st.st_dev) &&
(DOSDrives[drive].ino == st.st_ino))
{ {
*path = p; static const WCHAR rootW[] = {'\\',0};
TRACE("%s -> drive %c:, root='%s', name=%s\n",
buffer, 'A' + rootdrive, DOSDrives[rootdrive].root, debugstr_w(*path) ); if (len == 1) len = 0; /* preserve root slash in returned path */
TRACE( "%s -> drive %c:, root=%s, name=%s\n",
debugstr_w(*path), 'A' + drive, debugstr_w(buffer), debugstr_w(*path + len));
*path += len;
if (!**path) *path = rootW;
return drive;
}
}
if (len <= 1) return -1; /* reached root */
level = 0;
while (level < 1)
{
static const WCHAR dotW[] = {'.',0};
static const WCHAR dotdotW[] = {'.','.',0};
/* find start of the last path component */
while (len > 1 && buffer[len - 1] != '/') len--;
if (!buffer[len]) break; /* empty component -> reached root */
/* does removing it take us up a level? */
if (strcmpW( buffer + len, dotW ) != 0)
level += strcmpW( buffer + len, dotdotW ) ? 1 : -1;
buffer[len] = 0;
/* strip off trailing slashes */
while (len > 1 && buffer[len - 1] == '/') buffer[--len] = 0;
}
} }
return rootdrive;
} }