From b4ef4b5e8f0217c982afae4637fbb9cd8c716646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Fri, 12 Nov 2004 17:17:08 +0000 Subject: [PATCH] Add FATX support svn path=/trunk/; revision=11631 --- freeldr/freeldr/Makefile | 3 +- freeldr/freeldr/arch/i386/hardware.c | 4 +- freeldr/freeldr/arch/i386/i386disk.c | 87 +----- freeldr/freeldr/arch/i386/machpc.c | 4 +- freeldr/freeldr/arch/i386/machpc.h | 4 +- freeldr/freeldr/arch/i386/machxbox.c | 5 +- freeldr/freeldr/arch/i386/machxbox.h | 4 +- freeldr/freeldr/arch/i386/pcdisk.c | 90 ++++++- freeldr/freeldr/arch/i386/xboxdisk.c | 133 ++++++++- freeldr/freeldr/cache/blocklist.c | 15 +- freeldr/freeldr/cache/cache.c | 40 +-- freeldr/freeldr/cache/cm.h | 6 +- freeldr/freeldr/disk/geometry.c | 44 --- freeldr/freeldr/fs/ext2.c | 2 +- freeldr/freeldr/fs/fat.c | 387 +++++++++++++++++---------- freeldr/freeldr/fs/fat.h | 78 ++++-- freeldr/freeldr/fs/fs.c | 4 +- freeldr/freeldr/fs/fsrec.c | 4 +- freeldr/freeldr/include/disk.h | 5 - freeldr/freeldr/include/machine.h | 6 +- freeldr/freeldr/machine.c | 16 +- 21 files changed, 594 insertions(+), 347 deletions(-) delete mode 100644 freeldr/freeldr/disk/geometry.c diff --git a/freeldr/freeldr/Makefile b/freeldr/freeldr/Makefile index 4b1b6a86f51..f6adc2783b2 100644 --- a/freeldr/freeldr/Makefile +++ b/freeldr/freeldr/Makefile @@ -250,8 +250,7 @@ REACTOS_OBJS= arcname.o \ COMM_OBJS = rs232.o DISK_OBJS = disk.o \ - geometry.o \ - partition.o + partition.o MM_OBJS = mm.o \ meminit.o diff --git a/freeldr/freeldr/arch/i386/hardware.c b/freeldr/freeldr/arch/i386/hardware.c index 80b85a38da4..2d549b434d5 100644 --- a/freeldr/freeldr/arch/i386/hardware.c +++ b/freeldr/freeldr/arch/i386/hardware.c @@ -521,7 +521,7 @@ SetHarddiskConfigurationData(HKEY DiskKey, DiskGeometry->SectorsPerTrack = ExtGeometry.SectorsPerTrack; DiskGeometry->NumberOfHeads = ExtGeometry.Heads; } - else if(DiskGetDriveParameters(DriveNumber, &Geometry)) + else if(MachDiskGetDriveGeometry(DriveNumber, &Geometry)) { DiskGeometry->BytesPerSector = Geometry.BytesPerSector; DiskGeometry->NumberOfCylinders = Geometry.Cylinders; @@ -681,7 +681,7 @@ DetectBiosDisks(HKEY SystemKey, Int13Drives = ((PVOID)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR); for (i = 0; i < DiskCount; i++) { - if (DiskGetDriveParameters(0x80 + i, &Geometry)) + if (MachDiskGetDriveGeometry(0x80 + i, &Geometry)) { Int13Drives[i].DriveSelect = 0x80 + i; Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1; diff --git a/freeldr/freeldr/arch/i386/i386disk.c b/freeldr/freeldr/arch/i386/i386disk.c index a2e4b0a25fe..46c3116cc58 100644 --- a/freeldr/freeldr/arch/i386/i386disk.c +++ b/freeldr/freeldr/arch/i386/i386disk.c @@ -17,12 +17,13 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include -#include -#include -#include +#include "freeldr.h" +#include "disk.h" +#include "rtl.h" +#include "arch.h" +#include "debug.h" +#include "portio.h" +#include "machine.h" ///////////////////////////////////////////////////////////////////////////////////////////// @@ -132,55 +133,6 @@ VOID DiskStopFloppyMotor(VOID) WRITE_PORT_UCHAR((PUCHAR)0x3F2, 0); } -BOOL DiskGetDriveParameters(U32 DriveNumber, PGEOMETRY Geometry) -{ - REGS RegsIn; - REGS RegsOut; - U32 Cylinders; - - DbgPrint((DPRINT_DISK, "DiskGetDriveParameters()\n")); - - // BIOS Int 13h, function 08h - Get drive parameters - // AH = 08h - // DL = drive (bit 7 set for hard disk) - // ES:DI = 0000h:0000h to guard against BIOS bugs - // Return: - // CF set on error - // AH = status (07h) - // CF clear if successful - // AH = 00h - // AL = 00h on at least some BIOSes - // BL = drive type (AT/PS2 floppies only) - // CH = low eight bits of maximum cylinder number - // CL = maximum sector number (bits 5-0) - // high two bits of maximum cylinder number (bits 7-6) - // DH = maximum head number - // DL = number of drives - // ES:DI -> drive parameter table (floppies only) - RegsIn.b.ah = 0x08; - RegsIn.b.dl = DriveNumber; - RegsIn.w.es = 0x0000; - RegsIn.w.di = 0x0000; - - // Get drive parameters - Int386(0x13, &RegsIn, &RegsOut); - - if (!INT386_SUCCESS(RegsOut)) - { - return FALSE; - } - - Cylinders = (RegsOut.b.cl & 0xC0) << 2; - Cylinders += RegsOut.b.ch; - Cylinders++; - Geometry->Cylinders = Cylinders; - Geometry->Heads = RegsOut.b.dh + 1; - Geometry->Sectors = RegsOut.b.cl & 0x3F; - Geometry->BytesPerSector = 512; // Just assume 512 bytes per sector - - return TRUE; -} - BOOL DiskGetExtendedDriveParameters(U32 DriveNumber, PVOID Buffer, U16 BufferSize) { REGS RegsIn; @@ -220,29 +172,4 @@ BOOL DiskGetExtendedDriveParameters(U32 DriveNumber, PVOID Buffer, U16 BufferSiz return TRUE; } - - -U32 DiskGetCacheableBlockCount(U32 DriveNumber) -{ - GEOMETRY Geometry; - - // Get the disk geometry - // If this fails then we will just return 1 sector to be safe - if (!DiskGetDriveParameters(DriveNumber, &Geometry)) - { - return 1; - } - - // If LBA is supported then the block size will be 64 sectors (32k) - // If not then the block size is the size of one track - if (DiskInt13ExtensionsSupported(DriveNumber)) - { - return 64; - } - else - { - return Geometry.Sectors; - } -} - #endif // defined __i386__ diff --git a/freeldr/freeldr/arch/i386/machpc.c b/freeldr/freeldr/arch/i386/machpc.c index 06caa6ecb53..c7a57f3faef 100644 --- a/freeldr/freeldr/arch/i386/machpc.c +++ b/freeldr/freeldr/arch/i386/machpc.c @@ -1,4 +1,4 @@ -/* $Id: machpc.c,v 1.3 2004/11/10 23:45:37 gvg Exp $ +/* $Id: machpc.c,v 1.4 2004/11/12 17:17:07 gvg Exp $ * * FreeLoader * @@ -36,6 +36,8 @@ PcMachInit(VOID) MachVtbl.GetMemoryMap = PcMemGetMemoryMap; MachVtbl.DiskReadLogicalSectors = PcDiskReadLogicalSectors; MachVtbl.DiskGetPartitionEntry = PcDiskGetPartitionEntry; + MachVtbl.DiskGetDriveGeometry = PcDiskGetDriveGeometry; + MachVtbl.DiskGetCacheableBlockCount = PcDiskGetCacheableBlockCount; } /* EOF */ diff --git a/freeldr/freeldr/arch/i386/machpc.h b/freeldr/freeldr/arch/i386/machpc.h index 9387ec5dc9b..4c4c280ee52 100644 --- a/freeldr/freeldr/arch/i386/machpc.h +++ b/freeldr/freeldr/arch/i386/machpc.h @@ -1,4 +1,4 @@ -/* $Id: machpc.h,v 1.3 2004/11/10 23:45:37 gvg Exp $ +/* $Id: machpc.h,v 1.4 2004/11/12 17:17:07 gvg Exp $ * * FreeLoader * @@ -36,6 +36,8 @@ U32 PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize); BOOL PcDiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer); BOOL PcDiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry); +BOOL PcDiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY DriveGeometry); +U32 PcDiskGetCacheableBlockCount(U32 DriveNumber); #endif /* __I386_MACHPC_H_ */ diff --git a/freeldr/freeldr/arch/i386/machxbox.c b/freeldr/freeldr/arch/i386/machxbox.c index aff720a6e02..45276b3505b 100644 --- a/freeldr/freeldr/arch/i386/machxbox.c +++ b/freeldr/freeldr/arch/i386/machxbox.c @@ -1,4 +1,4 @@ -/* $Id: machxbox.c,v 1.3 2004/11/10 23:45:37 gvg Exp $ +/* $Id: machxbox.c,v 1.4 2004/11/12 17:17:07 gvg Exp $ * * FreeLoader * @@ -36,5 +36,6 @@ XboxMachInit(VOID) MachVtbl.GetMemoryMap = XboxMemGetMemoryMap; MachVtbl.DiskReadLogicalSectors = XboxDiskReadLogicalSectors; MachVtbl.DiskGetPartitionEntry = XboxDiskGetPartitionEntry; - + MachVtbl.DiskGetDriveGeometry = XboxDiskGetDriveGeometry; + MachVtbl.DiskGetCacheableBlockCount = XboxDiskGetCacheableBlockCount; } diff --git a/freeldr/freeldr/arch/i386/machxbox.h b/freeldr/freeldr/arch/i386/machxbox.h index 69bd21b6e00..68a6167ce35 100644 --- a/freeldr/freeldr/arch/i386/machxbox.h +++ b/freeldr/freeldr/arch/i386/machxbox.h @@ -1,4 +1,4 @@ -/* $Id: machxbox.h,v 1.3 2004/11/10 23:45:37 gvg Exp $ +/* $Id: machxbox.h,v 1.4 2004/11/12 17:17:07 gvg Exp $ * * FreeLoader * @@ -39,6 +39,8 @@ U32 XboxMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, U32 MaxMemoryMapSize); BOOL XboxDiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer); BOOL XboxDiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry); +BOOL XboxDiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY DriveGeometry); +U32 XboxDiskGetCacheableBlockCount(U32 DriveNumber); #endif /* __I386_HWXBOX_H_ */ diff --git a/freeldr/freeldr/arch/i386/pcdisk.c b/freeldr/freeldr/arch/i386/pcdisk.c index ec67180ef2e..94be75b51e7 100644 --- a/freeldr/freeldr/arch/i386/pcdisk.c +++ b/freeldr/freeldr/arch/i386/pcdisk.c @@ -17,12 +17,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include -#include -#include -#include -#include -#include +#include "freeldr.h" +#include "disk.h" +#include "rtl.h" +#include "arch.h" +#include "debug.h" +#include "portio.h" +#include "machine.h" +#include "machpc.h" typedef struct @@ -144,7 +146,7 @@ static BOOL PcDiskReadLogicalSectorsCHS(U32 DriveNumber, U64 SectorNumber, U32 S // // Get the drive geometry // - if (!DiskGetDriveGeometry(DriveNumber, &DriveGeometry)) + if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry)) { return FALSE; } @@ -371,4 +373,78 @@ PcDiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_E return DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry); } +BOOL +PcDiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY Geometry) +{ + REGS RegsIn; + REGS RegsOut; + U32 Cylinders; + + DbgPrint((DPRINT_DISK, "DiskGetDriveGeometry()\n")); + + /* BIOS Int 13h, function 08h - Get drive parameters + * AH = 08h + * DL = drive (bit 7 set for hard disk) + * ES:DI = 0000h:0000h to guard against BIOS bugs + * Return: + * CF set on error + * AH = status (07h) + * CF clear if successful + * AH = 00h + * AL = 00h on at least some BIOSes + * BL = drive type (AT/PS2 floppies only) + * CH = low eight bits of maximum cylinder number + * CL = maximum sector number (bits 5-0) + * high two bits of maximum cylinder number (bits 7-6) + * DH = maximum head number + * DL = number of drives + * ES:DI -> drive parameter table (floppies only) + */ + RegsIn.b.ah = 0x08; + RegsIn.b.dl = DriveNumber; + RegsIn.w.es = 0x0000; + RegsIn.w.di = 0x0000; + + /* Get drive parameters */ + Int386(0x13, &RegsIn, &RegsOut); + + if (! INT386_SUCCESS(RegsOut)) + { + return FALSE; + } + + Cylinders = (RegsOut.b.cl & 0xC0) << 2; + Cylinders += RegsOut.b.ch; + Cylinders++; + Geometry->Cylinders = Cylinders; + Geometry->Heads = RegsOut.b.dh + 1; + Geometry->Sectors = RegsOut.b.cl & 0x3F; + Geometry->BytesPerSector = 512; /* Just assume 512 bytes per sector */ + + return TRUE; +} + +U32 +PcDiskGetCacheableBlockCount(U32 DriveNumber) +{ + GEOMETRY Geometry; + + /* If LBA is supported then the block size will be 64 sectors (32k) + * If not then the block size is the size of one track */ + if (DiskInt13ExtensionsSupported(DriveNumber)) + { + return 64; + } + /* Get the disk geometry + * If this fails then we will just return 1 sector to be safe */ + else if (! PcDiskGetDriveGeometry(DriveNumber, &Geometry)) + { + return 1; + } + else + { + return Geometry.Sectors; + } +} + /* EOF */ diff --git a/freeldr/freeldr/arch/i386/xboxdisk.c b/freeldr/freeldr/arch/i386/xboxdisk.c index 0d8bf3fd0c6..dbc1a11949a 100644 --- a/freeldr/freeldr/arch/i386/xboxdisk.c +++ b/freeldr/freeldr/arch/i386/xboxdisk.c @@ -1,4 +1,4 @@ -/* $Id: xboxdisk.c,v 1.2 2004/11/10 23:45:37 gvg Exp $ +/* $Id: xboxdisk.c,v 1.3 2004/11/12 17:17:07 gvg Exp $ * * FreeLoader * @@ -176,6 +176,70 @@ static struct #define IDEWriteDriveControl(Address, Data) \ (WRITE_PORT_UCHAR((PUCHAR)((Address) + IDE_REG_DEV_CNTRL), (Data))) +/* IDE_DRIVE_IDENTIFY */ + +typedef struct _IDE_DRIVE_IDENTIFY +{ + U16 ConfigBits; /*00*/ + U16 LogicalCyls; /*01*/ + U16 Reserved02; /*02*/ + U16 LogicalHeads; /*03*/ + U16 BytesPerTrack; /*04*/ + U16 BytesPerSector; /*05*/ + U16 SectorsPerTrack; /*06*/ + U8 InterSectorGap; /*07*/ + U8 InterSectorGapSize; + U8 Reserved08H; /*08*/ + U8 BytesInPLO; + U16 VendorUniqueCnt; /*09*/ + char SerialNumber[20]; /*10*/ + U16 ControllerType; /*20*/ + U16 BufferSize; /*21*/ + U16 ECCByteCnt; /*22*/ + char FirmwareRev[8]; /*23*/ + char ModelNumber[40]; /*27*/ + U16 RWMultImplemented; /*47*/ + U16 DWordIo; /*48*/ + U16 Capabilities; /*49*/ +#define IDE_DRID_STBY_SUPPORTED 0x2000 +#define IDE_DRID_IORDY_SUPPORTED 0x0800 +#define IDE_DRID_IORDY_DISABLE 0x0400 +#define IDE_DRID_LBA_SUPPORTED 0x0200 +#define IDE_DRID_DMA_SUPPORTED 0x0100 + U16 Reserved50; /*50*/ + U16 MinPIOTransTime; /*51*/ + U16 MinDMATransTime; /*52*/ + U16 TMFieldsValid; /*53*/ + U16 TMCylinders; /*54*/ + U16 TMHeads; /*55*/ + U16 TMSectorsPerTrk; /*56*/ + U16 TMCapacityLo; /*57*/ + U16 TMCapacityHi; /*58*/ + U16 RWMultCurrent; /*59*/ + U16 TMSectorCountLo; /*60*/ + U16 TMSectorCountHi; /*61*/ + U16 DmaModes; /*62*/ + U16 MultiDmaModes; /*63*/ + U16 Reserved64[5]; /*64*/ + U16 Reserved69[2]; /*69*/ + U16 Reserved71[4]; /*71*/ + U16 MaxQueueDepth; /*75*/ + U16 Reserved76[4]; /*76*/ + U16 MajorRevision; /*80*/ + U16 MinorRevision; /*81*/ + U16 SupportedFeatures82; /*82*/ + U16 SupportedFeatures83; /*83*/ + U16 SupportedFeatures84; /*84*/ + U16 EnabledFeatures85; /*85*/ + U16 EnabledFeatures86; /*86*/ + U16 EnabledFeatures87; /*87*/ + U16 UltraDmaModes; /*88*/ + U16 Reserved89[11]; /*89*/ + U16 Max48BitAddress[4]; /*100*/ + U16 Reserved104[151]; /*104*/ + U16 Checksum; /*255*/ +} IDE_DRIVE_IDENTIFY, *PIDE_DRIVE_IDENTIFY; + /* XboxDiskPolledRead * * DESCRIPTION: @@ -441,4 +505,71 @@ XboxDiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE return DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry); } +BOOL +XboxDiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY Geometry) +{ + IDE_DRIVE_IDENTIFY DrvParms; + U32 i; + BOOL Atapi; + + Atapi = FALSE; /* FIXME */ + /* Get the Drive Identify block from drive or die */ + if (! XboxDiskPolledRead(XBOX_IDE_COMMAND_PORT, + XBOX_IDE_CONTROL_PORT, + 0, + 1, + 0, + 0, + 0, + (0 == (DriveNumber & 0x0f) ? IDE_DH_DRV0 : IDE_DH_DRV1), + (Atapi ? IDE_CMD_IDENT_ATAPI_DRV : IDE_CMD_IDENT_ATA_DRV), + (PUCHAR) &DrvParms)) + { + DbgPrint((DPRINT_DISK, "XboxDiskPolledRead() failed\n")); + return FALSE; + } + + Geometry->Cylinders = DrvParms.LogicalCyls; + Geometry->Heads = DrvParms.LogicalHeads; + Geometry->Sectors = DrvParms.SectorsPerTrack; + + if (! Atapi && 0 != (DrvParms.Capabilities & IDE_DRID_LBA_SUPPORTED)) + { + /* LBA ATA drives always have a sector size of 512 */ + Geometry->BytesPerSector = 512; + } + else + { + DbgPrint((DPRINT_DISK, "BytesPerSector %d\n", DrvParms.BytesPerSector)); + if (DrvParms.BytesPerSector == 0) + { + Geometry->BytesPerSector = 512; + } + else + { + for (i = 15; i >= 0; i--) + { + if (0 != (DrvParms.BytesPerSector & (1 << i))) + { + Geometry->BytesPerSector = 1 << i; + break; + } + } + } + } + DbgPrint((DPRINT_DISK, "Cylinders %d\n", Geometry->Cylinders)); + DbgPrint((DPRINT_DISK, "Heads %d\n", Geometry->Heads)); + DbgPrint((DPRINT_DISK, "Sectors %d\n", Geometry->Sectors)); + DbgPrint((DPRINT_DISK, "BytesPerSector %d\n", Geometry->BytesPerSector)); + + return TRUE; +} + +U32 +XboxDiskGetCacheableBlockCount(U32 DriveNumber) +{ + /* 64 seems a nice number, it is used by the machpc code for LBA devices */ + return 64; +} + /* EOF */ diff --git a/freeldr/freeldr/cache/blocklist.c b/freeldr/freeldr/cache/blocklist.c index 29b5fdaca7f..2a9cb6acce5 100644 --- a/freeldr/freeldr/cache/blocklist.c +++ b/freeldr/freeldr/cache/blocklist.c @@ -115,7 +115,7 @@ PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, U32 BlockNumb // allocate room for the block data RtlZeroMemory(CacheBlock, sizeof(CACHE_BLOCK)); CacheBlock->BlockNumber = BlockNumber; - CacheBlock->BlockData = MmAllocateMemory(CacheDrive->BlockSize * CacheDrive->DriveGeometry.BytesPerSector); + CacheBlock->BlockData = MmAllocateMemory(CacheDrive->BlockSize * CacheDrive->BytesPerSector); if (CacheBlock->BlockData ==NULL) { MmFreeMemory(CacheBlock); @@ -129,7 +129,7 @@ PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, U32 BlockNumb MmFreeMemory(CacheBlock); return NULL; } - RtlCopyMemory(CacheBlock->BlockData, (PVOID)DISKREADBUFFER, CacheDrive->BlockSize * CacheDrive->DriveGeometry.BytesPerSector); + RtlCopyMemory(CacheBlock->BlockData, (PVOID)DISKREADBUFFER, CacheDrive->BlockSize * CacheDrive->BytesPerSector); // Add it to our list of blocks managed by the cache if (CacheDrive->CacheBlockHead == NULL) @@ -143,7 +143,7 @@ PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, U32 BlockNumb // Update the cache data CacheBlockCount++; - CacheSizeCurrent = CacheBlockCount * (CacheDrive->BlockSize * CacheDrive->DriveGeometry.BytesPerSector); + CacheSizeCurrent = CacheBlockCount * (CacheDrive->BlockSize * CacheDrive->BytesPerSector); CacheInternalDumpBlockList(CacheDrive); @@ -188,7 +188,7 @@ BOOL CacheInternalFreeBlock(PCACHE_DRIVE CacheDrive) // Update the cache data CacheBlockCount--; - CacheSizeCurrent = CacheBlockCount * (CacheDrive->BlockSize * CacheDrive->DriveGeometry.BytesPerSector); + CacheSizeCurrent = CacheBlockCount * (CacheDrive->BlockSize * CacheDrive->BytesPerSector); return TRUE; } @@ -200,7 +200,7 @@ VOID CacheInternalCheckCacheSizeLimits(PCACHE_DRIVE CacheDrive) DbgPrint((DPRINT_CACHE, "CacheInternalCheckCacheSizeLimits()\n")); // Calculate the size of the cache if we added a block - NewCacheSize = (CacheBlockCount + 1) * (CacheDrive->BlockSize * CacheDrive->DriveGeometry.BytesPerSector); + NewCacheSize = (CacheBlockCount + 1) * (CacheDrive->BlockSize * CacheDrive->BytesPerSector); // Check the new size against the cache size limit if (NewCacheSize > CacheSizeLimit) @@ -215,10 +215,7 @@ VOID CacheInternalDumpBlockList(PCACHE_DRIVE CacheDrive) PCACHE_BLOCK CacheBlock; DbgPrint((DPRINT_CACHE, "Dumping block list for BIOS drive 0x%x.\n", CacheDrive->DriveNumber)); - DbgPrint((DPRINT_CACHE, "Cylinders: %d.\n", CacheDrive->DriveGeometry.Cylinders)); - DbgPrint((DPRINT_CACHE, "Heads: %d.\n", CacheDrive->DriveGeometry.Heads)); - DbgPrint((DPRINT_CACHE, "Sectors: %d.\n", CacheDrive->DriveGeometry.Sectors)); - DbgPrint((DPRINT_CACHE, "BytesPerSector: %d.\n", CacheDrive->DriveGeometry.BytesPerSector)); + DbgPrint((DPRINT_CACHE, "BytesPerSector: %d.\n", CacheDrive->BytesPerSector)); DbgPrint((DPRINT_CACHE, "BlockSize: %d.\n", CacheDrive->BlockSize)); DbgPrint((DPRINT_CACHE, "CacheSizeLimit: %d.\n", CacheSizeLimit)); DbgPrint((DPRINT_CACHE, "CacheSizeCurrent: %d.\n", CacheSizeCurrent)); diff --git a/freeldr/freeldr/cache/cache.c b/freeldr/freeldr/cache/cache.c index 04a731934d2..363653f13d4 100644 --- a/freeldr/freeldr/cache/cache.c +++ b/freeldr/freeldr/cache/cache.c @@ -22,6 +22,7 @@ #include "cm.h" #include #include +#include #include #include @@ -33,13 +34,14 @@ CACHE_DRIVE CacheManagerDrive; BOOL CacheManagerInitialized = FALSE; BOOL CacheManagerDataInvalid = FALSE; -U32 CacheBlockCount = 0; -U32 CacheSizeLimit = 0; -U32 CacheSizeCurrent = 0; +U32 CacheBlockCount = 0; +U32 CacheSizeLimit = 0; +U32 CacheSizeCurrent = 0; BOOL CacheInitializeDrive(U32 DriveNumber) { PCACHE_BLOCK NextCacheBlock; + GEOMETRY DriveGeometry; // If we already have a cache for this drive then // by all means lets keep it, unless it is a removable @@ -82,13 +84,14 @@ BOOL CacheInitializeDrive(U32 DriveNumber) // Initialize the structure RtlZeroMemory(&CacheManagerDrive, sizeof(CACHE_DRIVE)); CacheManagerDrive.DriveNumber = DriveNumber; - if (!DiskGetDriveGeometry(DriveNumber, &CacheManagerDrive.DriveGeometry)) + if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry)) { return FALSE; } + CacheManagerDrive.BytesPerSector = DriveGeometry.BytesPerSector; // Get the number of sectors in each cache block - CacheManagerDrive.BlockSize = DiskGetCacheableBlockCount(DriveNumber); + CacheManagerDrive.BlockSize = MachDiskGetCacheableBlockCount(DriveNumber); CacheBlockCount = 0; CacheSizeLimit = GetSystemMemorySize() / 8; @@ -101,10 +104,7 @@ BOOL CacheInitializeDrive(U32 DriveNumber) CacheManagerInitialized = TRUE; DbgPrint((DPRINT_CACHE, "Initializing BIOS drive 0x%x.\n", DriveNumber)); - DbgPrint((DPRINT_CACHE, "Cylinders: %d.\n", CacheManagerDrive.DriveGeometry.Cylinders)); - DbgPrint((DPRINT_CACHE, "Heads: %d.\n", CacheManagerDrive.DriveGeometry.Heads)); - DbgPrint((DPRINT_CACHE, "Sectors: %d.\n", CacheManagerDrive.DriveGeometry.Sectors)); - DbgPrint((DPRINT_CACHE, "BytesPerSector: %d.\n", CacheManagerDrive.DriveGeometry.BytesPerSector)); + DbgPrint((DPRINT_CACHE, "BytesPerSector: %d.\n", CacheManagerDrive.BytesPerSector)); DbgPrint((DPRINT_CACHE, "BlockSize: %d.\n", CacheManagerDrive.BlockSize)); DbgPrint((DPRINT_CACHE, "CacheSizeLimit: %d.\n", CacheSizeLimit)); @@ -164,14 +164,14 @@ BOOL CacheReadDiskSectors(U32 DiskNumber, U32 StartSector, U32 SectorCount, PVOI // Copy the portion requested into the buffer // RtlCopyMemory(Buffer, - (CacheBlock->BlockData + (SectorOffsetInStartBlock * CacheManagerDrive.DriveGeometry.BytesPerSector)), - (CopyLengthInStartBlock * CacheManagerDrive.DriveGeometry.BytesPerSector)); - DbgPrint((DPRINT_CACHE, "1 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, (CacheBlock->BlockData + (SectorOffsetInStartBlock * CacheManagerDrive.DriveGeometry.BytesPerSector)), (CopyLengthInStartBlock * CacheManagerDrive.DriveGeometry.BytesPerSector))); + (CacheBlock->BlockData + (SectorOffsetInStartBlock * CacheManagerDrive.BytesPerSector)), + (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector)); + DbgPrint((DPRINT_CACHE, "1 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, (CacheBlock->BlockData + (SectorOffsetInStartBlock * CacheManagerDrive.BytesPerSector)), (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector))); // // Update the buffer address // - Buffer += (CopyLengthInStartBlock * CacheManagerDrive.DriveGeometry.BytesPerSector); + Buffer += (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector); // // Update the block count @@ -198,13 +198,13 @@ BOOL CacheReadDiskSectors(U32 DiskNumber, U32 StartSector, U32 SectorCount, PVOI // RtlCopyMemory(Buffer, CacheBlock->BlockData, - CacheManagerDrive.BlockSize * CacheManagerDrive.DriveGeometry.BytesPerSector); - DbgPrint((DPRINT_CACHE, "2 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, CacheBlock->BlockData, CacheManagerDrive.BlockSize * CacheManagerDrive.DriveGeometry.BytesPerSector)); + CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector); + DbgPrint((DPRINT_CACHE, "2 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, CacheBlock->BlockData, CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector)); // // Update the buffer address // - Buffer += CacheManagerDrive.BlockSize * CacheManagerDrive.DriveGeometry.BytesPerSector; + Buffer += CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector; // // Update the block count @@ -231,13 +231,13 @@ BOOL CacheReadDiskSectors(U32 DiskNumber, U32 StartSector, U32 SectorCount, PVOI // RtlCopyMemory(Buffer, CacheBlock->BlockData, - SectorOffsetInEndBlock * CacheManagerDrive.DriveGeometry.BytesPerSector); - DbgPrint((DPRINT_CACHE, "3 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, CacheBlock->BlockData, SectorOffsetInEndBlock * CacheManagerDrive.DriveGeometry.BytesPerSector)); + SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector); + DbgPrint((DPRINT_CACHE, "3 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, CacheBlock->BlockData, SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector)); // // Update the buffer address // - Buffer += SectorOffsetInEndBlock * CacheManagerDrive.DriveGeometry.BytesPerSector; + Buffer += SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector; // // Update the block count @@ -317,7 +317,7 @@ BOOL CacheReleaseMemory(U32 MinimumAmountToRelease) } // It succeeded so increment the amount of memory we have freed - AmountReleased += CacheManagerDrive.BlockSize * CacheManagerDrive.DriveGeometry.BytesPerSector; + AmountReleased += CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector; } // Return status diff --git a/freeldr/freeldr/cache/cm.h b/freeldr/freeldr/cache/cm.h index 7e4e4cb141d..6780fff6b07 100644 --- a/freeldr/freeldr/cache/cm.h +++ b/freeldr/freeldr/cache/cm.h @@ -55,10 +55,10 @@ typedef struct /////////////////////////////////////////////////////////////////////////////////////// typedef struct { - U32 DriveNumber; - GEOMETRY DriveGeometry; + U32 DriveNumber; + U32 BytesPerSector; - U32 BlockSize; // Block size (in sectors) + U32 BlockSize; // Block size (in sectors) PCACHE_BLOCK CacheBlockHead; } CACHE_DRIVE, *PCACHE_DRIVE; diff --git a/freeldr/freeldr/disk/geometry.c b/freeldr/freeldr/disk/geometry.c deleted file mode 100644 index 627c2e1996d..00000000000 --- a/freeldr/freeldr/disk/geometry.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * FreeLoader - * Copyright (C) 1998-2003 Brian Palmer - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include - - -#ifdef __i386__ -BOOL DiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY DriveGeometry) -{ - // For now just return the geometry as the BIOS reports it - // BytesPerSector is always set to 512 by i386DiskGetDriveParameters() - if (!DiskGetDriveParameters(DriveNumber, DriveGeometry)) - { - DiskError("Drive geometry unknown.", 0); - return FALSE; - } - - return TRUE; -} -#else -BOOL DiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY DriveGeometry) -{ - UNIMPLEMENTED(); -} -#endif diff --git a/freeldr/freeldr/fs/ext2.c b/freeldr/freeldr/fs/ext2.c index d2a2758a0e8..0710196df09 100644 --- a/freeldr/freeldr/fs/ext2.c +++ b/freeldr/freeldr/fs/ext2.c @@ -54,7 +54,7 @@ BOOL Ext2OpenVolume(U8 DriveNumber, U64 VolumeStartSector) Ext2DriveNumber = DriveNumber; Ext2VolumeStartSector = VolumeStartSector; - if (!DiskGetDriveGeometry(DriveNumber, &Ext2DiskGeometry)) + if (!MachDiskGetDriveGeometry(DriveNumber, &Ext2DiskGeometry)) { return FALSE; } diff --git a/freeldr/freeldr/fs/fat.c b/freeldr/freeldr/fs/fat.c index b3c130ade44..670fdb24299 100644 --- a/freeldr/freeldr/fs/fat.c +++ b/freeldr/freeldr/fs/fat.c @@ -32,17 +32,24 @@ PFAT_BOOTSECTOR FatVolumeBootSector = NULL; PFAT32_BOOTSECTOR Fat32VolumeBootSector = NULL; +PFATX_BOOTSECTOR FatXVolumeBootSector = NULL; -U32 RootDirSectorStart; // Starting sector of the root directory (fat12/16) -U32 DataSectorStart; // Starting sector of the data area -U32 SectorsPerFat; // Sectors per FAT table -U32 RootDirSectors; // Number of sectors of the root directory (fat32) +U32 BytesPerSector; /* Number of bytes per sector */ +U32 SectorsPerCluster; /* Number of sectors per cluster */ +U32 FatVolumeStartSector; /* Absolute starting sector of the partition */ +U32 SectorsPerFat; // Sectors per FAT table +U32 RootDirSectorStart; // Starting sector of the root directory (non-fat32) +U32 RootDirSectors; // Number of sectors of the root directory (non-fat32) +U32 RootDirStartCluster; /* Starting cluster number of the root directory (fat32 only) */ +U32 DataSectorStart; // Starting sector of the data area -U32 FatType = 0; // FAT12, FAT16, or FAT32 -U32 FatDriveNumber = 0; +U32 FatType = 0; // FAT12, FAT16, FAT32, FATX16 or FATX32 +U32 FatDriveNumber = 0; -BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector) +BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector, U32 PartitionSectorCount) { + char ErrMsg[80]; + U32 FatSize; DbgPrint((DPRINT_FILESYSTEM, "FatOpenVolume() DriveNumber = 0x%x VolumeStartSector = %d\n", DriveNumber, VolumeStartSector)); @@ -65,6 +72,7 @@ BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector) // FatVolumeBootSector = (PFAT_BOOTSECTOR) MmAllocateMemory(512); Fat32VolumeBootSector = (PFAT32_BOOTSECTOR) FatVolumeBootSector; + FatXVolumeBootSector = (PFATX_BOOTSECTOR) FatVolumeBootSector; // // Make sure we got the memory @@ -84,13 +92,26 @@ BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector) RtlCopyMemory(FatVolumeBootSector, (PVOID)DISKREADBUFFER, 512); // Get the FAT type - FatType = FatDetermineFatType(FatVolumeBootSector); + FatType = FatDetermineFatType(FatVolumeBootSector, PartitionSectorCount); #ifdef DEBUG DbgPrint((DPRINT_FILESYSTEM, "Dumping boot sector:\n")); - if (FatType == FAT32) + if (ISFATX(FatType)) + { + DbgPrint((DPRINT_FILESYSTEM, "sizeof(FATX_BOOTSECTOR) = 0x%x.\n", sizeof(FATX_BOOTSECTOR))); + + DbgPrint((DPRINT_FILESYSTEM, "FileSystemType: %c%c%c%c.\n", FatXVolumeBootSector->FileSystemType[0], FatXVolumeBootSector->FileSystemType[1], FatXVolumeBootSector->FileSystemType[2], FatXVolumeBootSector->FileSystemType[3])); + DbgPrint((DPRINT_FILESYSTEM, "VolumeSerialNumber: 0x%x\n", FatXVolumeBootSector->VolumeSerialNumber)); + DbgPrint((DPRINT_FILESYSTEM, "SectorsPerCluster: %d\n", FatXVolumeBootSector->SectorsPerCluster)); + DbgPrint((DPRINT_FILESYSTEM, "NumberOfFats: %d\n", FatXVolumeBootSector->NumberOfFats)); + DbgPrint((DPRINT_FILESYSTEM, "Unknown: 0x%x\n", FatXVolumeBootSector->Unknown)); + + DbgPrint((DPRINT_FILESYSTEM, "FatType %s\n", FatType == FATX16 ? "FATX16" : "FATX32")); + + } + else if (FatType == FAT32) { DbgPrint((DPRINT_FILESYSTEM, "sizeof(FAT32_BOOTSECTOR) = 0x%x.\n", sizeof(FAT32_BOOTSECTOR))); @@ -155,14 +176,16 @@ BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector) // // Set the correct partition offset // - FatVolumeBootSector->HiddenSectors = VolumeStartSector; + FatVolumeStartSector = VolumeStartSector; // // Check the boot sector magic // - if (FatVolumeBootSector->BootSectorMagic != 0xaa55) + if (! ISFATX(FatType) && FatVolumeBootSector->BootSectorMagic != 0xaa55) { - FileSystemError("Invalid boot sector magic (0xaa55)"); + sprintf(ErrMsg, "Invalid boot sector magic on drive 0x%x (expected 0xaa55 found 0x%x)", + DriveNumber, FatVolumeBootSector->BootSectorMagic); + FileSystemError(ErrMsg); return FALSE; } @@ -170,7 +193,8 @@ BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector) // Check the FAT cluster size // We do not support clusters bigger than 64k // - if ((FatVolumeBootSector->SectorsPerCluster * FatVolumeBootSector->BytesPerSector) > (64 * 1024)) + if ((ISFATX(FatType) && 64 * 1024 < FatXVolumeBootSector->SectorsPerCluster * 512) || + (! ISFATX(FatType) && 64 * 1024 < FatVolumeBootSector->SectorsPerCluster * FatVolumeBootSector->BytesPerSector)) { FileSystemError("This file system has cluster sizes bigger than 64k.\nFreeLoader does not support this."); return FALSE; @@ -189,19 +213,37 @@ BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector) // root directory starting sector, // and data sector start // - if (FatType != FAT32) + if (ISFATX(FatType)) { + BytesPerSector = 512; + SectorsPerCluster = FatXVolumeBootSector->SectorsPerCluster; + FatSize = PartitionSectorCount / SectorsPerCluster * + (FATX16 == FatType ? 2 : 4); + SectorsPerFat = (((FatSize + 4095) / 4096) * 4096) / BytesPerSector; + + RootDirSectorStart = (4096 / BytesPerSector) + SectorsPerFat; + RootDirSectors = FatXVolumeBootSector->SectorsPerCluster; + + DataSectorStart = RootDirSectorStart + RootDirSectors; + } + else if (FatType != FAT32) + { + BytesPerSector = FatVolumeBootSector->BytesPerSector; + SectorsPerCluster = FatVolumeBootSector->SectorsPerCluster; SectorsPerFat = FatVolumeBootSector->SectorsPerFat; RootDirSectorStart = (FatVolumeBootSector->NumberOfFats * SectorsPerFat) + FatVolumeBootSector->ReservedSectors; - RootDirSectors = ((FatVolumeBootSector->RootDirEntries * 32) + (FatVolumeBootSector->BytesPerSector - 1)) / FatVolumeBootSector->BytesPerSector; + RootDirSectors = ((FatVolumeBootSector->RootDirEntries * 32) + (BytesPerSector - 1)) / BytesPerSector; DataSectorStart = FatVolumeBootSector->ReservedSectors + (FatVolumeBootSector->NumberOfFats * FatVolumeBootSector->SectorsPerFat) + RootDirSectors; } else { + BytesPerSector = Fat32VolumeBootSector->BytesPerSector; + SectorsPerCluster = Fat32VolumeBootSector->SectorsPerCluster; SectorsPerFat = Fat32VolumeBootSector->SectorsPerFatBig; + RootDirStartCluster = Fat32VolumeBootSector->RootDirStartCluster; DataSectorStart = FatVolumeBootSector->ReservedSectors + (FatVolumeBootSector->NumberOfFats * Fat32VolumeBootSector->SectorsPerFatBig) + RootDirSectors; @@ -229,9 +271,9 @@ BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector) // as long as it is FAT12 or FAT16. FAT32 can // have a multi-megabyte FAT so we don't want that. // - if (FatType != FAT32) + if (FatType != FAT32 && FatType != FATX32) { - if (!CacheForceDiskSectorsIntoCache(DriveNumber, FatVolumeBootSector->HiddenSectors + FatVolumeBootSector->ReservedSectors, FatVolumeBootSector->SectorsPerFat)) + if (!CacheForceDiskSectorsIntoCache(DriveNumber, FatVolumeStartSector + FatVolumeBootSector->ReservedSectors, FatVolumeBootSector->SectorsPerFat)) { return FALSE; } @@ -240,76 +282,94 @@ BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector) return TRUE; } -U32 FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector) +U32 FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, U32 PartitionSectorCount) { - U32 RootDirSectors; - U32 DataSectorCount; - U32 SectorsPerFat; - U32 TotalSectors; - U32 CountOfClusters; + U32 RootDirSectors; + U32 DataSectorCount; + U32 SectorsPerFat; + U32 TotalSectors; + U32 CountOfClusters; PFAT32_BOOTSECTOR Fat32BootSector = (PFAT32_BOOTSECTOR)FatBootSector; + PFATX_BOOTSECTOR FatXBootSector = (PFATX_BOOTSECTOR)FatBootSector; - RootDirSectors = ((FatBootSector->RootDirEntries * 32) + (FatBootSector->BytesPerSector - 1)) / FatBootSector->BytesPerSector; - SectorsPerFat = FatBootSector->SectorsPerFat ? FatBootSector->SectorsPerFat : Fat32BootSector->SectorsPerFatBig; - TotalSectors = FatBootSector->TotalSectors ? FatBootSector->TotalSectors : FatBootSector->TotalSectorsBig; - DataSectorCount = TotalSectors - (FatBootSector->ReservedSectors + (FatBootSector->NumberOfFats * SectorsPerFat) + RootDirSectors); + if (0 == strncmp(FatXBootSector->FileSystemType, "FATX", 4)) + { + CountOfClusters = PartitionSectorCount / FatXBootSector->SectorsPerCluster; + if (CountOfClusters < 65525) + { + /* Volume is FATX16 */ + return FATX16; + } + else + { + /* Volume is FAT32 */ + return FATX32; + } + } + else + { + RootDirSectors = ((FatBootSector->RootDirEntries * 32) + (FatBootSector->BytesPerSector - 1)) / FatBootSector->BytesPerSector; + SectorsPerFat = FatBootSector->SectorsPerFat ? FatBootSector->SectorsPerFat : Fat32BootSector->SectorsPerFatBig; + TotalSectors = FatBootSector->TotalSectors ? FatBootSector->TotalSectors : FatBootSector->TotalSectorsBig; + DataSectorCount = TotalSectors - (FatBootSector->ReservedSectors + (FatBootSector->NumberOfFats * SectorsPerFat) + RootDirSectors); //mjl - if (FatBootSector->SectorsPerCluster == 0) - CountOfClusters = 0; - else - CountOfClusters = DataSectorCount / FatBootSector->SectorsPerCluster; + if (FatBootSector->SectorsPerCluster == 0) + CountOfClusters = 0; + else + CountOfClusters = DataSectorCount / FatBootSector->SectorsPerCluster; - if (CountOfClusters < 4085) - { - /* Volume is FAT12 */ - return FAT12; - } - else if (CountOfClusters < 65525) - { - /* Volume is FAT16 */ - return FAT16; - } - else - { - /* Volume is FAT32 */ - return FAT32; + if (CountOfClusters < 4085) + { + /* Volume is FAT12 */ + return FAT12; + } + else if (CountOfClusters < 65525) + { + /* Volume is FAT16 */ + return FAT16; + } + else + { + /* Volume is FAT32 */ + return FAT32; + } } } -PVOID FatBufferDirectory(U32 DirectoryStartCluster, U32* EntryCountPointer, BOOL RootDirectory) +PVOID FatBufferDirectory(U32 DirectoryStartCluster, U32 *DirectorySize, BOOL RootDirectory) { - U32 RootDirectoryStartSector; - U32 RootDirectorySectorCount; PVOID DirectoryBuffer; - U32 DirectorySize; DbgPrint((DPRINT_FILESYSTEM, "FatBufferDirectory() DirectoryStartCluster = %d RootDirectory = %s\n", DirectoryStartCluster, (RootDirectory ? "TRUE" : "FALSE"))); + /* + * For FAT32, the root directory is nothing special. We can treat it the same + * as a subdirectory. + */ + if (RootDirectory && FAT32 == FatType) + { + DirectoryStartCluster = RootDirStartCluster; + RootDirectory = FALSE; + } + // // Calculate the size of the directory // - if ((RootDirectory) && (FatType != FAT32)) + if (RootDirectory) { - DirectorySize = ROUND_UP((FatVolumeBootSector->RootDirEntries * 32), FatVolumeBootSector->BytesPerSector); + *DirectorySize = RootDirSectors * BytesPerSector; } else { - if (RootDirectory) - { - DirectorySize = (FatCountClustersInChain(Fat32VolumeBootSector->RootDirStartCluster) * Fat32VolumeBootSector->SectorsPerCluster) * Fat32VolumeBootSector->BytesPerSector; - } - else - { - DirectorySize = (FatCountClustersInChain(DirectoryStartCluster) * FatVolumeBootSector->SectorsPerCluster) * FatVolumeBootSector->BytesPerSector; - } + *DirectorySize = FatCountClustersInChain(DirectoryStartCluster) * SectorsPerCluster * BytesPerSector; } // // Attempt to allocate memory for directory buffer // - DbgPrint((DPRINT_FILESYSTEM, "Trying to allocate (DirectorySize) %d bytes.\n", DirectorySize)); - DirectoryBuffer = MmAllocateMemory(DirectorySize); + DbgPrint((DPRINT_FILESYSTEM, "Trying to allocate (DirectorySize) %d bytes.\n", *DirectorySize)); + DirectoryBuffer = MmAllocateMemory(*DirectorySize); if (DirectoryBuffer == NULL) { @@ -321,27 +381,10 @@ PVOID FatBufferDirectory(U32 DirectoryStartCluster, U32* EntryCountPointer, BOOL // if (RootDirectory) { - if (FatType == FAT32) + if (!FatReadVolumeSectors(FatDriveNumber, RootDirSectorStart, RootDirSectors, DirectoryBuffer)) { - if (!FatReadClusterChain(Fat32VolumeBootSector->RootDirStartCluster, 0xFFFFFFFF, DirectoryBuffer)) - { - MmFreeMemory(DirectoryBuffer); - return NULL; - } - } - else - { - // - // FAT type is not FAT32 so the root directory comes right after the fat table - // - RootDirectoryStartSector = FatVolumeBootSector->ReservedSectors + (FatVolumeBootSector->NumberOfFats * FatVolumeBootSector->SectorsPerFat); - RootDirectorySectorCount = (DirectorySize / FatVolumeBootSector->BytesPerSector); - - if (!FatReadVolumeSectors(FatDriveNumber, RootDirectoryStartSector, RootDirectorySectorCount, DirectoryBuffer)) - { - MmFreeMemory(DirectoryBuffer); - return NULL; - } + MmFreeMemory(DirectoryBuffer); + return NULL; } } else @@ -353,28 +396,29 @@ PVOID FatBufferDirectory(U32 DirectoryStartCluster, U32* EntryCountPointer, BOOL } } - *EntryCountPointer = (DirectorySize / 32); - return DirectoryBuffer; } -BOOL FatSearchDirectoryBufferForFile(PVOID DirectoryBuffer, U32 EntryCount, PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer) +BOOL FatSearchDirectoryBufferForFile(PVOID DirectoryBuffer, U32 DirectorySize, PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer) { - U32 CurrentEntry; - PDIRENTRY DirEntry; + U32 EntryCount; + U32 CurrentEntry; + PDIRENTRY DirEntry; PLFN_DIRENTRY LfnDirEntry; - UCHAR LfnNameBuffer[265]; - UCHAR ShortNameBuffer[20]; - U32 StartCluster; + UCHAR LfnNameBuffer[265]; + UCHAR ShortNameBuffer[20]; + U32 StartCluster; + + EntryCount = DirectorySize / sizeof(DIRENTRY); DbgPrint((DPRINT_FILESYSTEM, "FatSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x EntryCount = %d FileName = %s\n", DirectoryBuffer, EntryCount, FileName)); memset(ShortNameBuffer, 0, 13 * sizeof(UCHAR)); memset(LfnNameBuffer, 0, 261 * sizeof(UCHAR)); - for (CurrentEntry=0; CurrentEntryFileNameSize) + { + break; + } + if (0xe5 == DirEntry->FileNameSize) + { + continue; + } + if (FileNameLen == DirEntry->FileNameSize && + 0 == strnicmp(FileName, DirEntry->FileName, FileNameLen)) + { + /* + * We found the entry, now fill in the FAT_FILE_INFO struct + */ + FatFileInfoPointer->FileSize = DirEntry->Size; + FatFileInfoPointer->FilePointer = 0; + + DbgPrint((DPRINT_FILESYSTEM, "FATX Directory Entry:\n")); + DbgPrint((DPRINT_FILESYSTEM, "FileNameSize = %d\n", DirEntry->FileNameSize)); + DbgPrint((DPRINT_FILESYSTEM, "Attr = 0x%x\n", DirEntry->Attr)); + DbgPrint((DPRINT_FILESYSTEM, "StartCluster = 0x%x\n", DirEntry->StartCluster)); + DbgPrint((DPRINT_FILESYSTEM, "Size = %d\n", DirEntry->Size)); + DbgPrint((DPRINT_FILESYSTEM, "Time = %d\n", DirEntry->Time)); + DbgPrint((DPRINT_FILESYSTEM, "Date = %d\n", DirEntry->Date)); + DbgPrint((DPRINT_FILESYSTEM, "CreateTime = %d\n", DirEntry->CreateTime)); + DbgPrint((DPRINT_FILESYSTEM, "CreateDate = %d\n", DirEntry->CreateDate)); + DbgPrint((DPRINT_FILESYSTEM, "LastAccessTime = %d\n", DirEntry->LastAccessTime)); + DbgPrint((DPRINT_FILESYSTEM, "LastAccessDate = %d\n", DirEntry->LastAccessDate)); + + /* + * Get the cluster chain + */ + FatFileInfoPointer->FileFatChain = FatGetClusterChainArray(DirEntry->StartCluster); + + /* + * See if memory allocation failed + */ + if (NULL == FatFileInfoPointer->FileFatChain) + { + return FALSE; + } + + return TRUE; + } + } + + return FALSE; +} + /* * FatLookupFile() * This function searches the file system for the - * specified filename and fills in a FAT_STRUCT structure + * specified filename and fills in a FAT_FILE_INFO structure * with info describing the file, etc. returns true * if the file exists or false otherwise */ BOOL FatLookupFile(PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer) { - int i; - U32 NumberOfPathParts; - UCHAR PathPart[261]; - PVOID DirectoryBuffer; - U32 DirectoryStartCluster = 0; - U32 DirectoryEntryCount; + int i; + U32 NumberOfPathParts; + UCHAR PathPart[261]; + PVOID DirectoryBuffer; + U32 DirectoryStartCluster = 0; + U32 DirectorySize; FAT_FILE_INFO FatFileInfo; DbgPrint((DPRINT_FILESYSTEM, "FatLookupFile() FileName = %s\n", FileName)); @@ -614,7 +721,7 @@ BOOL FatLookupFile(PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer) // // Buffer the directory contents // - DirectoryBuffer = FatBufferDirectory(DirectoryStartCluster, &DirectoryEntryCount, (i == 0) ); + DirectoryBuffer = FatBufferDirectory(DirectoryStartCluster, &DirectorySize, (i == 0) ); if (DirectoryBuffer == NULL) { return FALSE; @@ -623,10 +730,21 @@ BOOL FatLookupFile(PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer) // // Search for file name in directory // - if (!FatSearchDirectoryBufferForFile(DirectoryBuffer, DirectoryEntryCount, PathPart, &FatFileInfo)) + if (ISFATX(FatType)) { - MmFreeMemory(DirectoryBuffer); - return FALSE; + if (!FatXSearchDirectoryBufferForFile(DirectoryBuffer, DirectorySize, PathPart, &FatFileInfo)) + { + MmFreeMemory(DirectoryBuffer); + return FALSE; + } + } + else + { + if (!FatSearchDirectoryBufferForFile(DirectoryBuffer, DirectorySize, PathPart, &FatFileInfo)) + { + MmFreeMemory(DirectoryBuffer); + return FALSE; + } } MmFreeMemory(DirectoryBuffer); @@ -714,14 +832,14 @@ BOOL FatGetFatEntry(U32 Cluster, U32* ClusterPointer) case FAT12: FatOffset = Cluster + (Cluster / 2); - ThisFatSecNum = FatVolumeBootSector->ReservedSectors + (FatOffset / FatVolumeBootSector->BytesPerSector); - ThisFatEntOffset = (FatOffset % FatVolumeBootSector->BytesPerSector); + ThisFatSecNum = FatVolumeBootSector->ReservedSectors + (FatOffset / BytesPerSector); + ThisFatEntOffset = (FatOffset % BytesPerSector); DbgPrint((DPRINT_FILESYSTEM, "FatOffset: %d\n", FatOffset)); DbgPrint((DPRINT_FILESYSTEM, "ThisFatSecNum: %d\n", ThisFatSecNum)); DbgPrint((DPRINT_FILESYSTEM, "ThisFatEntOffset: %d\n", ThisFatEntOffset)); - if (ThisFatEntOffset == (FatVolumeBootSector->BytesPerSector - 1)) + if (ThisFatEntOffset == (BytesPerSector - 1)) { if (!FatReadVolumeSectors(FatDriveNumber, ThisFatSecNum, 2, (PVOID)FILESYSBUFFER)) { @@ -745,10 +863,11 @@ BOOL FatGetFatEntry(U32 Cluster, U32* ClusterPointer) break; case FAT16: + case FATX16: FatOffset = (Cluster * 2); - ThisFatSecNum = FatVolumeBootSector->ReservedSectors + (FatOffset / FatVolumeBootSector->BytesPerSector); - ThisFatEntOffset = (FatOffset % FatVolumeBootSector->BytesPerSector); + ThisFatSecNum = FatVolumeBootSector->ReservedSectors + (FatOffset / BytesPerSector); + ThisFatEntOffset = (FatOffset % BytesPerSector); if (!FatReadVolumeSectors(FatDriveNumber, ThisFatSecNum, 1, (PVOID)FILESYSBUFFER)) { @@ -760,11 +879,12 @@ BOOL FatGetFatEntry(U32 Cluster, U32* ClusterPointer) break; case FAT32: + case FATX32: FatOffset = (Cluster * 4); ThisFatSecNum = (Fat32VolumeBootSector->ExtendedFlags & 0x80) ? ((Fat32VolumeBootSector->ExtendedFlags & 0x0f) * Fat32VolumeBootSector->SectorsPerFatBig) : 0; // Get the active fat sector offset - ThisFatSecNum += FatVolumeBootSector->ReservedSectors + (FatOffset / FatVolumeBootSector->BytesPerSector); - ThisFatEntOffset = (FatOffset % FatVolumeBootSector->BytesPerSector); + ThisFatSecNum += FatVolumeBootSector->ReservedSectors + (FatOffset / BytesPerSector); + ThisFatEntOffset = (FatOffset % BytesPerSector); if (!FatReadVolumeSectors(FatDriveNumber, ThisFatSecNum, 1, (PVOID)FILESYSBUFFER)) { @@ -826,8 +946,8 @@ U32 FatCountClustersInChain(U32 StartCluster) // If end of chain then break out of our cluster counting loop // if (((FatType == FAT12) && (StartCluster >= 0xff8)) || - ((FatType == FAT16) && (StartCluster >= 0xfff8)) || - ((FatType == FAT32) && (StartCluster >= 0x0ffffff8))) + ((FatType == FAT16 || FatType == FATX16) && (StartCluster >= 0xfff8)) || + ((FatType == FAT32 || FatType == FATX32) && (StartCluster >= 0x0ffffff8))) { break; } @@ -887,8 +1007,8 @@ U32* FatGetClusterChainArray(U32 StartCluster) // Don't try to get next cluster for last cluster // if (((FatType == FAT12) && (StartCluster >= 0xff8)) || - ((FatType == FAT16) && (StartCluster >= 0xfff8)) || - ((FatType == FAT32) && (StartCluster >= 0x0ffffff8))) + ((FatType == FAT16 || FatType == FATX16) && (StartCluster >= 0xfff8)) || + ((FatType == FAT32 || FatType == FATX32) && (StartCluster >= 0x0ffffff8))) { Idx++; break; @@ -910,22 +1030,21 @@ U32* FatGetClusterChainArray(U32 StartCluster) /* * FatReadCluster() * Reads the specified cluster into memory - * and returns the number of bytes read */ BOOL FatReadCluster(U32 ClusterNumber, PVOID Buffer) { U32 ClusterStartSector; - ClusterStartSector = ((ClusterNumber - 2) * FatVolumeBootSector->SectorsPerCluster) + DataSectorStart; + ClusterStartSector = ((ClusterNumber - 2) * SectorsPerCluster) + DataSectorStart; DbgPrint((DPRINT_FILESYSTEM, "FatReadCluster() ClusterNumber = %d Buffer = 0x%x ClusterStartSector = %d\n", ClusterNumber, Buffer, ClusterStartSector)); - if (!FatReadVolumeSectors(FatDriveNumber, ClusterStartSector, FatVolumeBootSector->SectorsPerCluster, (PVOID)FILESYSBUFFER)) + if (!FatReadVolumeSectors(FatDriveNumber, ClusterStartSector, SectorsPerCluster, (PVOID)FILESYSBUFFER)) { return FALSE; } - memcpy(Buffer, (PVOID)FILESYSBUFFER, FatVolumeBootSector->SectorsPerCluster * FatVolumeBootSector->BytesPerSector); + memcpy(Buffer, (PVOID)FILESYSBUFFER, SectorsPerCluster * BytesPerSector); return TRUE; } @@ -947,17 +1066,17 @@ BOOL FatReadClusterChain(U32 StartClusterNumber, U32 NumberOfClusters, PVOID Buf // // Calculate starting sector for cluster // - ClusterStartSector = ((StartClusterNumber - 2) * FatVolumeBootSector->SectorsPerCluster) + DataSectorStart; + ClusterStartSector = ((StartClusterNumber - 2) * SectorsPerCluster) + DataSectorStart; // // Read cluster into memory // - if (!FatReadVolumeSectors(FatDriveNumber, ClusterStartSector, FatVolumeBootSector->SectorsPerCluster, (PVOID)FILESYSBUFFER)) + if (!FatReadVolumeSectors(FatDriveNumber, ClusterStartSector, SectorsPerCluster, (PVOID)FILESYSBUFFER)) { return FALSE; } - memcpy(Buffer, (PVOID)FILESYSBUFFER, FatVolumeBootSector->SectorsPerCluster * FatVolumeBootSector->BytesPerSector); + memcpy(Buffer, (PVOID)FILESYSBUFFER, SectorsPerCluster * BytesPerSector); // // Decrement count of clusters left to read @@ -967,7 +1086,7 @@ BOOL FatReadClusterChain(U32 StartClusterNumber, U32 NumberOfClusters, PVOID Buf // // Increment buffer address by cluster size // - Buffer += (FatVolumeBootSector->SectorsPerCluster * FatVolumeBootSector->BytesPerSector); + Buffer += SectorsPerCluster * BytesPerSector; // // Get next cluster @@ -981,8 +1100,8 @@ BOOL FatReadClusterChain(U32 StartClusterNumber, U32 NumberOfClusters, PVOID Buf // If end of chain then break out of our cluster reading loop // if (((FatType == FAT12) && (StartClusterNumber >= 0xff8)) || - ((FatType == FAT16) && (StartClusterNumber >= 0xfff8)) || - ((FatType == FAT32) && (StartClusterNumber >= 0x0ffffff8))) + ((FatType == FAT16 || FatType == FATX16) && (StartClusterNumber >= 0xfff8)) || + ((FatType == FAT32 || FatType == FATX32) && (StartClusterNumber >= 0x0ffffff8))) { break; } @@ -1001,9 +1120,9 @@ BOOL FatReadPartialCluster(U32 ClusterNumber, U32 StartingOffset, U32 Length, PV DbgPrint((DPRINT_FILESYSTEM, "FatReadPartialCluster() ClusterNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", ClusterNumber, StartingOffset, Length, Buffer)); - ClusterStartSector = ((ClusterNumber - 2) * FatVolumeBootSector->SectorsPerCluster) + DataSectorStart; + ClusterStartSector = ((ClusterNumber - 2) * SectorsPerCluster) + DataSectorStart; - if (!FatReadVolumeSectors(FatDriveNumber, ClusterStartSector, FatVolumeBootSector->SectorsPerCluster, (PVOID)FILESYSBUFFER)) + if (!FatReadVolumeSectors(FatDriveNumber, ClusterStartSector, SectorsPerCluster, (PVOID)FILESYSBUFFER)) { return FALSE; } @@ -1081,7 +1200,7 @@ BOOL FatReadFile(FILE *FileHandle, U32 BytesToRead, U32* BytesRead, PVOID Buffer // the last cluster. // - BytesPerCluster = (FatVolumeBootSector->SectorsPerCluster * FatVolumeBootSector->BytesPerSector); + BytesPerCluster = SectorsPerCluster * BytesPerSector; // // Only do the first read if we @@ -1201,15 +1320,5 @@ U32 FatGetFilePointer(FILE *FileHandle) BOOL FatReadVolumeSectors(U32 DriveNumber, U32 SectorNumber, U32 SectorCount, PVOID Buffer) { - //GEOMETRY DiskGeometry; - //BOOL ReturnValue; - //if (!DiskGetDriveGeometry(DriveNumber, &DiskGeometry)) - //{ - // return FALSE; - //} - //ReturnValue = MachDiskReadLogicalSectors(DriveNumber, SectorNumber + FatVolumeBootSector->HiddenSectors, SectorCount, (PVOID)DISKREADBUFFER); - //RtlCopyMemory(Buffer, (PVOID)DISKREADBUFFER, SectorCount * DiskGeometry.BytesPerSector); - //return ReturnValue; - - return CacheReadDiskSectors(DriveNumber, SectorNumber + FatVolumeBootSector->HiddenSectors, SectorCount, Buffer); + return CacheReadDiskSectors(DriveNumber, SectorNumber + FatVolumeStartSector, SectorCount, Buffer); } diff --git a/freeldr/freeldr/fs/fat.h b/freeldr/freeldr/fs/fat.h index d1ab0ff00f1..db21e0f315f 100644 --- a/freeldr/freeldr/fs/fat.h +++ b/freeldr/freeldr/fs/fat.h @@ -85,56 +85,82 @@ typedef struct _FAT32_BOOTSECTOR } PACKED FAT32_BOOTSECTOR, *PFAT32_BOOTSECTOR; +typedef struct _FATX_BOOTSECTOR +{ + U8 FileSystemType[4]; /* String "FATX" */ + U32 VolumeSerialNumber; /* Volume serial number */ + U32 SectorsPerCluster; /* Number of sectors in a cluster */ + U16 NumberOfFats; /* Number of FAT tables */ + U32 Unknown; /* Always 0? */ + U8 Unused[494]; /* Actually size should be 4078 (boot block is 4096 bytes) */ + +} PACKED FATX_BOOTSECTOR, *PFATX_BOOTSECTOR; + /* * Structure of MSDOS directory entry */ typedef struct //_DIRENTRY { UCHAR FileName[11]; /* Filename + extension */ - U8 Attr; /* File attributes */ - U8 ReservedNT; /* Reserved for use by Windows NT */ - U8 TimeInTenths; /* Millisecond stamp at file creation */ - U16 CreateTime; /* Time file was created */ - U16 CreateDate; /* Date file was created */ - U16 LastAccessDate; /* Date file was last accessed */ - U16 ClusterHigh; /* High word of this entry's start cluster */ - U16 Time; /* Time last modified */ - U16 Date; /* Date last modified */ - U16 ClusterLow; /* First cluster number low word */ - U32 Size; /* File size */ + U8 Attr; /* File attributes */ + U8 ReservedNT; /* Reserved for use by Windows NT */ + U8 TimeInTenths; /* Millisecond stamp at file creation */ + U16 CreateTime; /* Time file was created */ + U16 CreateDate; /* Date file was created */ + U16 LastAccessDate; /* Date file was last accessed */ + U16 ClusterHigh; /* High word of this entry's start cluster */ + U16 Time; /* Time last modified */ + U16 Date; /* Date last modified */ + U16 ClusterLow; /* First cluster number low word */ + U32 Size; /* File size */ } PACKED DIRENTRY, * PDIRENTRY; typedef struct { - U8 SequenceNumber; /* Sequence number for slot */ - WCHAR Name0_4[5]; /* First 5 characters in name */ - U8 EntryAttributes; /* Attribute byte */ - U8 Reserved; /* Always 0 */ - U8 AliasChecksum; /* Checksum for 8.3 alias */ + U8 SequenceNumber; /* Sequence number for slot */ + WCHAR Name0_4[5]; /* First 5 characters in name */ + U8 EntryAttributes; /* Attribute byte */ + U8 Reserved; /* Always 0 */ + U8 AliasChecksum; /* Checksum for 8.3 alias */ WCHAR Name5_10[6]; /* 6 more characters in name */ - U16 StartCluster; /* Starting cluster number */ + U16 StartCluster; /* Starting cluster number */ WCHAR Name11_12[2]; /* Last 2 characters in name */ } PACKED LFN_DIRENTRY, * PLFN_DIRENTRY; typedef struct { - U32 FileSize; // File size - U32 FilePointer; // File pointer - U32* FileFatChain; // File fat chain array - U32 DriveNumber; + U8 FileNameSize; /* Size of filename (max 42) */ + U8 Attr; /* File attributes */ + UCHAR FileName[42]; /* Filename in ASCII, padded with 0xff (not zero-terminated) */ + U32 StartCluster; /* Starting cluster number */ + U32 Size; /* File size */ + U16 Time; /* Time last modified */ + U16 Date; /* Date last modified */ + U16 CreateTime; /* Time file was created */ + U16 CreateDate; /* Date file was created */ + U16 LastAccessTime; /* Time file was last accessed */ + U16 LastAccessDate; /* Date file was last accessed */ +} PACKED FATX_DIRENTRY, * PFATX_DIRENTRY; + +typedef struct +{ + U32 FileSize; /* File size */ + U32 FilePointer; /* File pointer */ + U32* FileFatChain; /* File fat chain array */ + U32 DriveNumber; } FAT_FILE_INFO, * PFAT_FILE_INFO; -BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector); -U32 FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector); +BOOL FatOpenVolume(U32 DriveNumber, U32 VolumeStartSector, U32 PartitionSectorCount); +U32 FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, U32 PartitionSectorCount); PVOID FatBufferDirectory(U32 DirectoryStartCluster, U32* EntryCountPointer, BOOL RootDirectory); BOOL FatSearchDirectoryBufferForFile(PVOID DirectoryBuffer, U32 EntryCount, PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer); BOOL FatLookupFile(PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer); void FatParseShortFileName(PUCHAR Buffer, PDIRENTRY DirEntry); BOOL FatGetFatEntry(U32 Cluster, U32* ClusterPointer); FILE* FatOpenFile(PUCHAR FileName); -U32 FatCountClustersInChain(U32 StartCluster); +U32 FatCountClustersInChain(U32 StartCluster); U32* FatGetClusterChainArray(U32 StartCluster); BOOL FatReadCluster(U32 ClusterNumber, PVOID Buffer); BOOL FatReadClusterChain(U32 StartClusterNumber, U32 NumberOfClusters, PVOID Buffer); @@ -158,5 +184,9 @@ BOOL FatReadVolumeSectors(U32 DriveNumber, U32 SectorNumber, U32 SectorCount, PV #define FAT12 1 #define FAT16 2 #define FAT32 3 +#define FATX16 4 +#define FATX32 5 + +#define ISFATX(FT) ((FT) == FATX16 || (FT) == FATX32) #endif // #defined __FAT_H diff --git a/freeldr/freeldr/fs/fs.c b/freeldr/freeldr/fs/fs.c index 1e900f6a3d5..22aa1e6b2b2 100644 --- a/freeldr/freeldr/fs/fs.c +++ b/freeldr/freeldr/fs/fs.c @@ -79,7 +79,7 @@ BOOL FsOpenVolume(U32 DriveNumber, U32 PartitionNumber) DbgPrint((DPRINT_FILESYSTEM, "Drive is a floppy diskette drive. Assuming FAT12 file system.\n")); FileSystemType = FS_FAT; - return FatOpenVolume(DriveNumber, 0); + return FatOpenVolume(DriveNumber, 0, 0); } // Check for ISO9660 file system type @@ -138,7 +138,7 @@ BOOL FsOpenVolume(U32 DriveNumber, U32 PartitionNumber) case PARTITION_FAT32: case PARTITION_FAT32_XINT13: FileSystemType = FS_FAT; - return FatOpenVolume(DriveNumber, PartitionTableEntry.SectorCountBeforePartition); + return FatOpenVolume(DriveNumber, PartitionTableEntry.SectorCountBeforePartition, PartitionTableEntry.PartitionSectorCount); case PARTITION_EXT2: FileSystemType = FS_EXT2; return Ext2OpenVolume(DriveNumber, PartitionTableEntry.SectorCountBeforePartition); diff --git a/freeldr/freeldr/fs/fsrec.c b/freeldr/freeldr/fs/fsrec.c index affba0bc533..b3c84062f9b 100644 --- a/freeldr/freeldr/fs/fsrec.c +++ b/freeldr/freeldr/fs/fsrec.c @@ -106,6 +106,7 @@ BOOL FsRecIsFat(U32 DriveNumber, U32 VolumeStartSector) { PFAT_BOOTSECTOR BootSector = (PFAT_BOOTSECTOR)DISKREADBUFFER; PFAT32_BOOTSECTOR BootSector32 = (PFAT32_BOOTSECTOR)DISKREADBUFFER; + PFATX_BOOTSECTOR BootSectorX = (PFATX_BOOTSECTOR)DISKREADBUFFER; if (!MachDiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, BootSector)) { FileSystemError("Failed to read the boot sector."); @@ -114,7 +115,8 @@ BOOL FsRecIsFat(U32 DriveNumber, U32 VolumeStartSector) if (strncmp(BootSector->FileSystemType, "FAT12 ", 8) == 0 || strncmp(BootSector->FileSystemType, "FAT16 ", 8) == 0 || - strncmp(BootSector32->FileSystemType, "FAT32 ", 8) == 0) + strncmp(BootSector32->FileSystemType, "FAT32 ", 8) == 0 || + strncmp(BootSectorX->FileSystemType, "FATX", 4) == 0) { return TRUE; } diff --git a/freeldr/freeldr/include/disk.h b/freeldr/freeldr/include/disk.h index cc511aa5829..bc4451b29c0 100644 --- a/freeldr/freeldr/include/disk.h +++ b/freeldr/freeldr/include/disk.h @@ -109,11 +109,8 @@ typedef struct _MASTER_BOOT_RECORD BOOL DiskResetController(U32 DriveNumber); BOOL DiskInt13ExtensionsSupported(U32 DriveNumber); //VOID DiskStopFloppyMotor(VOID); -BOOL DiskGetDriveParameters(U32 DriveNumber, PGEOMETRY Geometry); BOOL DiskGetExtendedDriveParameters(U32 DriveNumber, PVOID Buffer, U16 BufferSize); -//U32 DiskGetCacheableBlockCount(U32 DriveNumber); - #endif // defined __i386__ /////////////////////////////////////////////////////////////////////////////////////// @@ -124,11 +121,9 @@ BOOL DiskGetExtendedDriveParameters(U32 DriveNumber, PVOID Buffer, U16 BufferSiz VOID DiskReportError (BOOL bError); VOID DiskError(PUCHAR ErrorString, U32 ErrorCode); PUCHAR DiskGetErrorCodeString(U32 ErrorCode); -BOOL DiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY DriveGeometry); BOOL DiskReadLogicalSectors(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer); // Implemented in i386disk.c BOOL DiskIsDriveRemovable(U32 DriveNumber); VOID DiskStopFloppyMotor(VOID); // Implemented in i386disk.c -U32 DiskGetCacheableBlockCount(U32 DriveNumber); // Implemented in i386disk.c /////////////////////////////////////////////////////////////////////////////////////// // diff --git a/freeldr/freeldr/include/machine.h b/freeldr/freeldr/include/machine.h index 2ec30e6f93e..20df83c1960 100644 --- a/freeldr/freeldr/include/machine.h +++ b/freeldr/freeldr/include/machine.h @@ -1,4 +1,4 @@ -/* $Id: machine.h,v 1.3 2004/11/10 23:45:37 gvg Exp $ +/* $Id: machine.h,v 1.4 2004/11/12 17:17:08 gvg Exp $ * * FreeLoader * @@ -38,6 +38,8 @@ typedef struct tagMACHVTBL BOOL (*DiskReadLogicalSectors)(U32 DriveNumber, U64 SectorNumber, U32 SectorCount, PVOID Buffer); BOOL (*DiskGetPartitionEntry)(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry); + BOOL (*DiskGetDriveGeometry)(U32 DriveNumber, PGEOMETRY DriveGeometry); + U32 (*DiskGetCacheableBlockCount)(U32 DriveNumber); } MACHVTBL, *PMACHVTBL; VOID MachInit(VOID); @@ -50,6 +52,8 @@ extern MACHVTBL MachVtbl; #define MachGetMemoryMap(MMap, Size) MachVtbl.GetMemoryMap((MMap), (Size)) #define MachDiskReadLogicalSectors(Drive, Start, Count, Buf) MachVtbl.DiskReadLogicalSectors((Drive), (Start), (Count), (Buf)) #define MachDiskGetPartitionEntry(Drive, Part, Entry) MachVtbl.DiskGetPartitionEntry((Drive), (Part), (Entry)) +#define MachDiskGetDriveGeometry(Drive, Geom) MachVtbl.DiskGetDriveGeometry((Drive), (Geom)) +#define MachDiskGetCacheableBlockCount(Drive) MachVtbl.DiskGetCacheableBlockCount(Drive) #endif /* __MACHINE_H_ */ diff --git a/freeldr/freeldr/machine.c b/freeldr/freeldr/machine.c index 90a69b58bb2..af6b2092d48 100644 --- a/freeldr/freeldr/machine.c +++ b/freeldr/freeldr/machine.c @@ -1,4 +1,4 @@ -/* $Id: machine.c,v 1.3 2004/11/10 23:45:37 gvg Exp $ +/* $Id: machine.c,v 1.4 2004/11/12 17:17:07 gvg Exp $ * * FreeLoader * @@ -26,6 +26,8 @@ #undef MachGetMemoryMap #undef MachDiskReadLogicalSectors #undef MachDiskGetPartitionEntry +#undef MachDiskGetDriveGeometry +#undef MachDiskGetCacheableBlockCount MACHVTBL MachVtbl; @@ -65,4 +67,16 @@ MachDiskGetPartitionEntry(U32 DriveNumber, U32 PartitionNumber, PPARTITION_TABLE return MachVtbl.DiskGetPartitionEntry(DriveNumber, PartitionNumber, PartitionTableEntry); } +BOOL +MachDiskGetDriveGeometry(U32 DriveNumber, PGEOMETRY DriveGeometry) +{ + return MachVtbl.DiskGetDriveGeometry(DriveNumber, DriveGeometry); +} + +U32 +MachDiskGetCacheableBlockCount(U32 DriveNumber) +{ + return MachVtbl.DiskGetCacheableBlockCount(DriveNumber); +} + /* EOF */