From 073329fa1bc0e69afb79652c1454b55574713088 Mon Sep 17 00:00:00 2001 From: Rein Klazes Date: Thu, 28 Oct 2004 21:00:36 +0000 Subject: [PATCH] =?UTF-8?q?In=20VOLUME=5FReadFATSuperblock:=20-=20do=20not?= =?UTF-8?q?=20test=20on=20the=20JMP=20instruction:=20most=20boot=20blocks?= =?UTF-8?q?=20have=20that=20-=20test=20instead=20on=20the=20"FAT"=20string?= =?UTF-8?q?s=20first,=20before=20the=20size=20=20=20calculation=20-=20do?= =?UTF-8?q?=20some=20parameter=20checking=20to=20prevent=20arithmetic=20er?= =?UTF-8?q?rors=20-=20use=20meaningful=20names=20instead=20of=20block=20of?= =?UTF-8?q?fsets=20(based=20on=20a=20rejected=20patch=20from=20Vincent=20B?= =?UTF-8?q?=C3=A9ron).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dlls/kernel/volume.c | 55 ++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/dlls/kernel/volume.c b/dlls/kernel/volume.c index a09a332bc8..7da60e3a5b 100644 --- a/dlls/kernel/volume.c +++ b/dlls/kernel/volume.c @@ -491,29 +491,50 @@ static enum fs_type VOLUME_ReadFATSuperblock( HANDLE handle, BYTE *buff ) 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; - sz = GETWORD(buff, 0x16); - if (!sz) sz = GETLONG(buff, 0x24); - nsect = GETWORD(buff, 0x13); - if (!nsect) nsect = GETLONG(buff, 0x20); - nsect -= GETWORD(buff, 0x0e) + buff[0x10] * sz + - (GETWORD(buff, 0x11) * 32 + (GETWORD(buff, 0x0b) - 1)) / GETWORD(buff, 0x0b); - nclust = nsect / buff[0x0d]; - + int reasonable; + unsigned int sectors, + sect_per_fat, + total_sectors, + num_boot_sectors, + num_fats, + num_root_dir_ents, + bytes_per_sector, + sectors_per_cluster, + nclust; + sect_per_fat = GETWORD(buff, 0x16); + if (!sect_per_fat) sect_per_fat = GETLONG(buff, 0x24); + total_sectors = GETWORD(buff, 0x13); + if (!total_sectors) + total_sectors = GETLONG(buff, 0x20); + num_boot_sectors = GETWORD(buff, 0x0e); + num_fats = buff[0x10]; + num_root_dir_ents = GETWORD(buff, 0x11); + bytes_per_sector = GETWORD(buff, 0x0b); + sectors_per_cluster = buff[0x0d]; + /* check if the parameters are reasonable and will not cause + * arithmetic errors in the calculation */ + reasonable = num_boot_sectors < 16 && + num_fats < 16 && + bytes_per_sector >= 512 && bytes_per_sector % 512 == 0 && + sectors_per_cluster > 1; + if (!reasonable) return FS_UNKNOWN; + sectors = total_sectors - num_boot_sectors - num_fats * sect_per_fat - + (num_root_dir_ents * 32 + bytes_per_sector - 1) / bytes_per_sector; + nclust = sectors / sectors_per_cluster; + if ((buff[0x42] == 0x28 || buff[0x42] == 0x29) && + !memcmp(buff+0x52, "FAT", 3)) return FS_FAT32; 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 :) - */ + if ((buff[0x26] == 0x28 || buff[0x26] == 0x29) && + !memcmp(buff+0x36, "FAT", 3)) return FS_FAT1216; - } } - else if (!memcmp(buff+0x52, "FAT", 3)) return FS_FAT32; } return FS_UNKNOWN; }