mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Add FATX support
svn path=/trunk/; revision=11631
This commit is contained in:
parent
69b5fdb8f1
commit
b4ef4b5e8f
21 changed files with 594 additions and 347 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -17,12 +17,13 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <disk.h>
|
||||
#include <rtl.h>
|
||||
#include <arch.h>
|
||||
#include <debug.h>
|
||||
#include <portio.h>
|
||||
#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__
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <disk.h>
|
||||
#include <rtl.h>
|
||||
#include <arch.h>
|
||||
#include <debug.h>
|
||||
#include <portio.h>
|
||||
#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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
15
freeldr/freeldr/cache/blocklist.c
vendored
15
freeldr/freeldr/cache/blocklist.c
vendored
|
@ -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));
|
||||
|
|
40
freeldr/freeldr/cache/cache.c
vendored
40
freeldr/freeldr/cache/cache.c
vendored
|
@ -22,6 +22,7 @@
|
|||
#include "cm.h"
|
||||
#include <mm.h>
|
||||
#include <disk.h>
|
||||
#include <machine.h>
|
||||
#include <rtl.h>
|
||||
#include <debug.h>
|
||||
|
||||
|
@ -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
|
||||
|
|
6
freeldr/freeldr/cache/cm.h
vendored
6
freeldr/freeldr/cache/cm.h
vendored
|
@ -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;
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* 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 <freeldr.h>
|
||||
#include <disk.h>
|
||||
#include <rtl.h>
|
||||
#include <mm.h>
|
||||
|
||||
|
||||
#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
|
|
@ -54,7 +54,7 @@ BOOL Ext2OpenVolume(U8 DriveNumber, U64 VolumeStartSector)
|
|||
Ext2DriveNumber = DriveNumber;
|
||||
Ext2VolumeStartSector = VolumeStartSector;
|
||||
|
||||
if (!DiskGetDriveGeometry(DriveNumber, &Ext2DiskGeometry))
|
||||
if (!MachDiskGetDriveGeometry(DriveNumber, &Ext2DiskGeometry))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -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; CurrentEntry<EntryCount; CurrentEntry++)
|
||||
DirEntry = (PDIRENTRY) DirectoryBuffer;
|
||||
for (CurrentEntry=0; CurrentEntry<EntryCount; CurrentEntry++, DirEntry++)
|
||||
{
|
||||
DirEntry = (PDIRENTRY)(DirectoryBuffer + (CurrentEntry * 32) );
|
||||
LfnDirEntry = (PLFN_DIRENTRY)DirEntry;
|
||||
|
||||
//DbgPrint((DPRINT_FILESYSTEM, "Dumping directory entry %d:\n", CurrentEntry));
|
||||
|
@ -516,8 +560,7 @@ BOOL FatSearchDirectoryBufferForFile(PVOID DirectoryBuffer, U32 EntryCount, PUCH
|
|||
// See if the file name matches either the short or long name
|
||||
//
|
||||
if (((strlen(FileName) == strlen(LfnNameBuffer)) && (stricmp(FileName, LfnNameBuffer) == 0)) ||
|
||||
((strlen(FileName) == strlen(ShortNameBuffer)) && (stricmp(FileName, ShortNameBuffer) == 0)))
|
||||
{
|
||||
((strlen(FileName) == strlen(ShortNameBuffer)) && (stricmp(FileName, ShortNameBuffer) == 0))) {
|
||||
//
|
||||
// We found the entry, now fill in the FAT_FILE_INFO struct
|
||||
//
|
||||
|
@ -567,21 +610,85 @@ BOOL FatSearchDirectoryBufferForFile(PVOID DirectoryBuffer, U32 EntryCount, PUCH
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL FatXSearchDirectoryBufferForFile(PVOID DirectoryBuffer, U32 DirectorySize, PUCHAR FileName, PFAT_FILE_INFO FatFileInfoPointer)
|
||||
{
|
||||
U32 EntryCount;
|
||||
U32 CurrentEntry;
|
||||
PFATX_DIRENTRY DirEntry;
|
||||
U32 FileNameLen;
|
||||
|
||||
EntryCount = DirectorySize / sizeof(FATX_DIRENTRY);
|
||||
|
||||
DbgPrint((DPRINT_FILESYSTEM, "FatXSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x EntryCount = %d FileName = %s\n", DirectoryBuffer, EntryCount, FileName));
|
||||
|
||||
FileNameLen = strlen(FileName);
|
||||
DirEntry = (PFATX_DIRENTRY) DirectoryBuffer;
|
||||
for (CurrentEntry = 0; CurrentEntry < EntryCount; CurrentEntry++, DirEntry++)
|
||||
{
|
||||
if (0xff == DirEntry->FileNameSize)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
|
|
@ -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_ */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue