Sylvain Petreolle wrote:
--- Tony Lambregts tony_lambregts@telusplanet.net a écrit : > Jeff Smith wrote:
What I have so far: in files/dos_fs.c:1343, drive is receiving the value -1. at line 1358, this is blindly added to 'A'. As you may know, in ASCII, 'A' - 1 = '@'.
The problem is that we don't check the status of DRIVE_FindDriveRoot, as you spotted it. The sources clearly states that -1 is error.
Well I was convinced it should not be an error. The path is valid if you are sitting at the mount point. Part of the problem is that the drives are initialized when the program starts, this sets the .ino for that drive, however the ino for a removeable drive can change depending on whether it is mounted or not.
DRIVE_FindDriveRootW does the same thing without relying on the .ino. I have modified DRIVE_FindDriveRoot to work the same way.
The way I see it is that if the drive is removable (or network) .ino is not a good way of dealing with it.
Change Log: Modify DRIVE_FindDriveRoot to not use .ino
Files: files/drive.c
Tony Lambregts
Index: drive.c =================================================================== RCS file: /home/wine/wine/files/drive.c,v retrieving revision 1.80 diff -u -r1.80 drive.c --- drive.c 7 Dec 2002 23:47:01 -0000 1.80 +++ drive.c 23 Dec 2002 05:21:21 -0000 @@ -408,63 +408,36 @@ */ int DRIVE_FindDriveRoot( const char **path ) { - /* Starting with the full path, check if the device and inode match any of - * the wine 'drives'. If not then remove the last path component and try - * again. If the last component was a '..' then skip a normal component - * since it's a directory that's ascended back out of. - */ - int drive, level, len; + int drive, rootdrive = -1; char buffer[MAX_PATHNAME_LEN]; char *p; - struct stat st; + int len = -1, match_len = -1 ;
strcpy( buffer, *path ); while ((p = strchr( buffer, '\' )) != NULL) - *p = '/'; - len = strlen(buffer); - - /* strip off trailing slashes */ - while (len > 1 && buffer[len - 1] == '/') buffer[--len] = 0; - - for (;;) + *p = '/'; + + for (drive = 0; drive < MAX_DOS_DRIVES; drive++) { - /* Find the drive */ - if (stat( buffer, &st ) == 0 && S_ISDIR( st.st_mode )) - { - for (drive = 0; drive < MAX_DOS_DRIVES; drive++) - { - if (!DOSDrives[drive].root || - (DOSDrives[drive].flags & DRIVE_DISABLED)) - continue; - - if ((DOSDrives[drive].dev == st.st_dev) && - (DOSDrives[drive].ino == st.st_ino)) - { - if (len == 1) len = 0; /* preserve root slash in returned path */ - TRACE( "%s -> drive %c:, root='%s', name='%s'\n", - *path, 'A' + drive, buffer, *path + len); - *path += len; - if (!**path) *path = "\"; - return drive; - } - } - } - if (len <= 1) return -1; /* reached root */ - - level = 0; - while (level < 1) - { - /* 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 (strcmp( buffer + len, "." ) != 0) - level += strcmp( buffer + len, ".." ) ? 1 : -1; - buffer[len] = 0; - /* strip off trailing slashes */ - while (len > 1 && buffer[len - 1] == '/') buffer[--len] = 0; - } + if (!DOSDrives[drive].root || + (DOSDrives[drive].flags & DRIVE_DISABLED)) continue; + + len = strlen(DOSDrives[drive].root); + if(strncmp(DOSDrives[drive].root, buffer, len)) continue; + + if(len <= match_len) continue; + match_len = len; + rootdrive = drive; + drive = MAX_DOS_DRIVES + 1; + } + if (rootdrive != -1) + { + TRACE("%s -> drive %c:, root='%s', name=%s\n", + *path, 'A' + rootdrive, DOSDrives[rootdrive].root, *path + len) ; + *path += len; + if (!**path) *path = "\"; } + return rootdrive; }