Le mer 22/09/2004 à 15:39, Joris Huizer a écrit :
> Robbert Xerox wrote:
> > Hi, in quite a few programs i can not browse the
> > filesystem when opening a "listbox"; to be more clear:
> > for example when i do in winword Open and the listbox
> > appears, and i try to open the pull down menu winword
> > just quits(without an error message in wine).  In
> > another program like "Camel join" it quits as soon as
> > i go up to the level of "my computer" with a message
> > "division by zero in Volme_ReadFATSuperblock. I was
> > able to
> > track the problem down to the following lines in
> > volume.c (starting from line 502)
> > 
> >       nsect -= GETWORD(buff, 0x0e) + buff[0x10] * sz +
> >             (GETWORD(buff, 0x11) * 32 + (GETWORD(buff,
> > 0x0b) - 1)) / GETWORD(buff, 0x0b);
> >         nclust = nsect / buff[0x0d];
> > 
> > 
> 
> if (GETWORD(buff, 0x0b) == 0)
> {
>      /* what to do about this?? */
> }
> else
> {
>      nsect -= GETWORD(buff, 0x0e) + buff[0x10] * sz +
>              (GETWORD(buff, 0x11) * 32 + (GETWORD(buff,
>               0x0b) - 1)) / GETWORD(buff, 0x0b);
>      if (buff[0x0d] == 0)
>      {
>          /* what to do about this one?? */
>      }
>      else
>      {
>          nclust = nsect / buff[0x0d];
>      }
> }
> 
> Now, how come those values become zero? I don't know, so I can't fill in 
> the missing stuff there

>From an IRC session with the original user (or at least somebody pasting
the exact same question), he was using Wine as root, with a z: drive
pointing to /. The permissions on his / partition allowed Wine to read
the device directly.

Running Wine as a normal user fixed it for him.

Now onto what I think is a proper fix:
Note that the following check
    if (buff[0] == 0xE9 || (buff[0] == 0xEB && buff[2] == 0x90))
did pass before the above code snippet is executed, and doesn't
discriminate against other types of bootloaders (as that's what's
usually in the first sector, even a FAT). Indeed, my /dev/hde (boot
drive) MBR does pass the test as grub is installed in /dev/hde. If grub
had been installed in /dev/hde2 (/boot), the test would fail, but if I
had a single partition for /boot and / (rest of tree doesn't matter),
and installed grub in it's first sector rather than MBR, it'd pass.

So maybe we should actually check for the FAT signature at buff[0x36] or
buff[0x52] first, and then do the calculations if we actually do find
one of them.

Changelog:
Make sure we're really looking at a FAT before doing some calculations
based on the contents of the first sector of a partition.

Vincent
Index: wine/dlls/kernel/volume.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/volume.c,v
retrieving revision 1.20
diff -u -r1.20 volume.c
--- wine/dlls/kernel/volume.c	10 Aug 2004 23:43:21 -0000	1.20
+++ wine/dlls/kernel/volume.c	22 Sep 2004 20:05:08 -0000
@@ -491,7 +491,10 @@
         size != SUPERBLOCK_SIZE)
         return FS_ERROR;
 
-    if (buff[0] == 0xE9 || (buff[0] == 0xEB && buff[2] == 0x90))
+    /* FIXME: do really all FAT have their name beginning with
+     * "FAT" ? (At least FAT12, FAT16 and FAT32 have :)
+     */
+    if (!memcmp(buff+0x36, "FAT", 3) || !memcmp(buff+0x52, "FAT", 3))
     {
         /* guess which type of FAT we have */
         unsigned int sz, nsect, nclust;
@@ -506,14 +509,9 @@
         if (nclust < 65525)
         {
             if (buff[0x26] == 0x29 && !memcmp(buff+0x36, "FAT", 3))
-            {
-                /* FIXME: do really all FAT have their name beginning with
-                 * "FAT" ? (At least FAT12, FAT16 and FAT32 have :)
-                 */
                 return FS_FAT1216;
-            }
         }
-        else if (!memcmp(buff+0x52, "FAT", 3)) return FS_FAT32;
+        else if (buff[0x42] == 0x29 && !memcmp(buff+0x52, "FAT", 3)) return FS_FAT32;
     }
     return FS_UNKNOWN;
 }

Reply via email to