Make DRIVE_FindRootW really behave like DRIVE_FindRoot.
This commit is contained in:
parent
3dec4c5219
commit
cce7e25827
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue