Serious problem with / and mount points

Tony Lambregts tony_lambregts at telusplanet.net
Sun Dec 22 23:20:11 CST 2002


  Sylvain Petreolle wrote:

> --- Tony Lambregts <tony_lambregts at 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


-------------- next part --------------
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;
 }
 
 


More information about the wine-patches mailing list