mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
Added full disk partition management functions
Extended partitions are supported (untested) If you call OpenDrive() with Partition == 0 you get the active (or bootable) partition Partitions 1 - 4 are the primary partitions Partitions 5 - n are the extended partitions Also added disk parameter detection code (always assumes 512 byte sector size, I don't like that but I don't see any other way) svn path=/trunk/; revision=2651
This commit is contained in:
parent
f83db8cc84
commit
c66e8c39d3
|
@ -21,11 +21,13 @@ include ../rules.mk
|
|||
|
||||
TARGET = i386
|
||||
|
||||
OBJS = $(TARGET)/arch.S $(TARGET)/boot.S $(TARGET)/mb.S $(TARGET)/mem.S $(TARGET)/disk.S
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
all: arch.a
|
||||
|
||||
arch.a:
|
||||
arch.a: $(OBJS)
|
||||
$(MAKE) -C $(TARGET)
|
||||
|
||||
clean:
|
||||
|
|
|
@ -385,8 +385,8 @@ EXTERN(_get_heads)
|
|||
int $0x13
|
||||
jc _get_heads_error
|
||||
|
||||
incb %dh
|
||||
movzbl %dh,%edx
|
||||
incl %edx
|
||||
movl %edx,_biosdisk_retval
|
||||
jmp _get_heads_done
|
||||
|
||||
|
@ -512,4 +512,94 @@ _get_sectors_done:
|
|||
ret
|
||||
|
||||
|
||||
/*
|
||||
* BOOL BiosInt13GetDriveParameters(ULONG Drive, PGEOMETRY Geometry);
|
||||
*/
|
||||
_bios_int13_cylinders:
|
||||
.long 0
|
||||
_bios_int13_heads:
|
||||
.long 0
|
||||
_bios_int13_sectors:
|
||||
.long 0
|
||||
_bios_int13_bytes_per_sector:
|
||||
.long 0
|
||||
_bios_int13_drive_parameters_struct_address:
|
||||
.long 0
|
||||
EXTERN(_BiosInt13GetDriveParameters)
|
||||
.code32
|
||||
|
||||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
push %edi
|
||||
push %esi
|
||||
push %es
|
||||
|
||||
/* Get drive */
|
||||
movl 0x1c(%esp),%eax
|
||||
movl %eax,_biosdisk_drive
|
||||
movl 0x20(%esp),%eax
|
||||
movl %eax,_bios_int13_drive_parameters_struct_address
|
||||
|
||||
call switch_to_real
|
||||
|
||||
.code16
|
||||
|
||||
movb $0x08,%ah
|
||||
movb _biosdisk_drive,%dl
|
||||
int $0x13
|
||||
jc _BiosInt13GetDriveParameters_Error
|
||||
|
||||
// Get the heads
|
||||
movzbl %dh,%eax
|
||||
incl %eax
|
||||
movl %eax,_bios_int13_heads
|
||||
|
||||
// Get the sectors
|
||||
movw %cx,%dx
|
||||
andb $0x3f,%dl
|
||||
movzbl %dl,%edx
|
||||
movl %edx,_bios_int13_sectors
|
||||
|
||||
// Get the cylinders
|
||||
xorl %edx,%edx
|
||||
andb $0xc0,%cl
|
||||
shrb $0x06,%cl
|
||||
movb %cl,%dh
|
||||
movb %ch,%dl
|
||||
incl %edx
|
||||
movl %edx,_bios_int13_cylinders
|
||||
|
||||
// Get the bytes per sector
|
||||
movl $512,_bios_int13_bytes_per_sector // Just assume 512 bytes per sector
|
||||
movl $0x01,_biosdisk_retval
|
||||
jmp _BiosInt13GetDriveParameters_Done
|
||||
|
||||
_BiosInt13GetDriveParameters_Error:
|
||||
movl $0x00,_biosdisk_retval
|
||||
|
||||
_BiosInt13GetDriveParameters_Done:
|
||||
|
||||
call switch_to_prot
|
||||
|
||||
.code32
|
||||
|
||||
// Copy drive parameters to structure
|
||||
movl $_bios_int13_cylinders,%esi
|
||||
movl _bios_int13_drive_parameters_struct_address,%edi
|
||||
movl $0x04,%ecx
|
||||
cld
|
||||
rep movsl
|
||||
|
||||
movl _biosdisk_retval,%eax // Get return value
|
||||
|
||||
pop %es
|
||||
pop %esi
|
||||
pop %edi
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
|
2
freeldr/freeldr/cache/blocklist.c
vendored
2
freeldr/freeldr/cache/blocklist.c
vendored
|
@ -122,7 +122,7 @@ PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, ULONG BlockNu
|
|||
}
|
||||
|
||||
// Now try to read in the block
|
||||
if (!DiskReadMultipleLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, (PVOID)DISKREADBUFFER))
|
||||
if (!DiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, (PVOID)DISKREADBUFFER))
|
||||
{
|
||||
FreeMemory(CacheBlock->BlockData);
|
||||
FreeMemory(CacheBlock);
|
||||
|
|
|
@ -39,11 +39,12 @@ ULONG DebugPrintMask = DPRINT_WARNING | DPRINT_MEMORY | DPRINT_FILESYSTEM |
|
|||
|
||||
#define BOCHS_OUTPUT_PORT 0xe9
|
||||
|
||||
//ULONG DebugPort = RS232;
|
||||
ULONG DebugPort = RS232;
|
||||
//ULONG DebugPort = SCREEN;
|
||||
ULONG DebugPort = BOCHS;
|
||||
//ULONG DebugPort = BOCHS;
|
||||
ULONG ComPort = COM1;
|
||||
ULONG BaudRate = 19200;
|
||||
//ULONG BaudRate = 19200;
|
||||
ULONG BaudRate = 115200;
|
||||
|
||||
BOOL DebugStartOfLine = TRUE;
|
||||
|
||||
|
|
|
@ -30,6 +30,55 @@ typedef struct _GEOMETRY
|
|||
|
||||
} GEOMETRY, *PGEOMETRY;
|
||||
|
||||
//
|
||||
// Define the structure of a partition table entry
|
||||
//
|
||||
typedef struct _PARTITION_TABLE_ENTRY
|
||||
{
|
||||
BYTE BootIndicator; // 0x00 - non-bootable partition, 0x80 - bootable partition (one partition only)
|
||||
BYTE StartHead; // Beginning head number
|
||||
BYTE StartSector; // Beginning sector (2 high bits of cylinder #)
|
||||
BYTE StartCylinder; // Beginning cylinder# (low order bits of cylinder #)
|
||||
BYTE SystemIndicator; // System indicator
|
||||
BYTE EndHead; // Ending head number
|
||||
BYTE EndSector; // Ending sector (2 high bits of cylinder #)
|
||||
BYTE EndCylinder; // Ending cylinder# (low order bits of cylinder #)
|
||||
DWORD SectorCountBeforePartition; // Number of sectors preceding the partition
|
||||
DWORD PartitionSectorCount; // Number of sectors in the partition
|
||||
|
||||
} PACKED PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
|
||||
|
||||
//
|
||||
// Define the structure of the master boot record
|
||||
//
|
||||
typedef struct _MASTER_BOOT_RECORD
|
||||
{
|
||||
BYTE MasterBootRecordCodeAndData[0x1be];
|
||||
PARTITION_TABLE_ENTRY PartitionTable[4];
|
||||
WORD MasterBootRecordMagic;
|
||||
|
||||
} PACKED MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD;
|
||||
|
||||
//
|
||||
// Partition type defines
|
||||
//
|
||||
#define PARTITION_ENTRY_UNUSED 0x00 // Entry unused
|
||||
#define PARTITION_FAT_12 0x01 // 12-bit FAT entries
|
||||
#define PARTITION_XENIX_1 0x02 // Xenix
|
||||
#define PARTITION_XENIX_2 0x03 // Xenix
|
||||
#define PARTITION_FAT_16 0x04 // 16-bit FAT entries
|
||||
#define PARTITION_EXTENDED 0x05 // Extended partition entry
|
||||
#define PARTITION_HUGE 0x06 // Huge partition MS-DOS V4
|
||||
#define PARTITION_IFS 0x07 // IFS Partition
|
||||
#define PARTITION_OS2BOOTMGR 0x0A // OS/2 Boot Manager/OPUS/Coherent swap
|
||||
#define PARTITION_FAT32 0x0B // FAT32
|
||||
#define PARTITION_FAT32_XINT13 0x0C // FAT32 using extended int13 services
|
||||
#define PARTITION_XINT13 0x0E // Win95 partition using extended int13 services
|
||||
#define PARTITION_XINT13_EXTENDED 0x0F // Same as type 5 but uses extended int13 services
|
||||
#define PARTITION_PREP 0x41 // PowerPC Reference Platform (PReP) Boot Partition
|
||||
#define PARTITION_LDM 0x42 // Logical Disk Manager partition
|
||||
#define PARTITION_UNIX 0x63 // Unix
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BIOS Disk Functions
|
||||
|
@ -46,6 +95,7 @@ void stop_floppy(void); // Implemented in asmcode.S
|
|||
int get_heads(int drive); // Implemented in asmcode.S
|
||||
int get_cylinders(int drive); // Implemented in asmcode.S
|
||||
int get_sectors(int drive); // Implemented in asmcode.S
|
||||
BOOL BiosInt13GetDriveParameters(ULONG Drive, PGEOMETRY Geometry); // Implemented in disk.S
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -54,8 +104,18 @@ int get_sectors(int drive); // Implemented in asmcode.S
|
|||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
VOID DiskError(PUCHAR ErrorString);
|
||||
BOOL DiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY DriveGeometry);
|
||||
BOOL DiskSetDriveGeometry(ULONG DriveNumber, ULONG Cylinders, ULONG Heads, ULONG Sectors, ULONG BytesPerSector);
|
||||
BOOL DiskReadMultipleLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer);
|
||||
BOOL DiskReadLogicalSector(ULONG DriveNumber, ULONG SectorNumber, PVOID Buffer);
|
||||
BOOL DiskReadLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Fixed Disk Partition Management Functions
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOL DiskIsDriveRemovable(ULONG DriveNumber);
|
||||
BOOL DiskGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||
BOOL DiskGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||
BOOL DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||
BOOL DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||
BOOL DiskReadBootRecord(ULONG DriveNumber, ULONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord);
|
||||
|
||||
#endif // defined __DISK_H
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
include ../rules.mk
|
||||
|
||||
OBJS = disk.o geometry.o
|
||||
OBJS = disk.o geometry.o partition.o
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
|
@ -34,6 +34,9 @@ disk.o: disk.c ../disk.h
|
|||
geometry.o: geometry.c ../disk.h
|
||||
$(CC) $(FLAGS) -o geometry.o -c geometry.c
|
||||
|
||||
partition.o: partition.c ../disk.h
|
||||
$(CC) $(FLAGS) -o partition.o -c partition.c
|
||||
|
||||
clean:
|
||||
- $(RM) *.o
|
||||
- $(RM) *.a
|
||||
|
|
|
@ -50,7 +50,7 @@ VOID DiskError(PUCHAR ErrorString)
|
|||
}
|
||||
}
|
||||
|
||||
BOOL DiskReadMultipleLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
|
||||
BOOL DiskReadLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorCount, PVOID Buffer)
|
||||
{
|
||||
ULONG PhysicalSector;
|
||||
ULONG PhysicalHead;
|
||||
|
@ -151,76 +151,3 @@ BOOL DiskReadMultipleLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DiskReadLogicalSector(ULONG DriveNumber, ULONG SectorNumber, PVOID Buffer)
|
||||
{
|
||||
ULONG PhysicalSector;
|
||||
ULONG PhysicalHead;
|
||||
ULONG PhysicalTrack;
|
||||
GEOMETRY DriveGeometry;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "ReadLogicalSector() DriveNumber: 0x%x SectorNumber: %d Buffer: 0x%x\n", DriveNumber, SectorNumber, Buffer));
|
||||
|
||||
//
|
||||
// Check to see if it is a fixed disk drive
|
||||
// If so then check to see if Int13 extensions work
|
||||
// If they do then use them, otherwise default back to BIOS calls
|
||||
//
|
||||
if ((DriveNumber >= 0x80) && (BiosInt13ExtensionsSupported(DriveNumber)))
|
||||
{
|
||||
DbgPrint((DPRINT_DISK, "Using Int 13 Extensions for read. BiosInt13ExtensionsSupported(%d) = %s\n", DriveNumber, BiosInt13ExtensionsSupported(DriveNumber) ? "TRUE" : "FALSE"));
|
||||
|
||||
//
|
||||
// LBA is easy, nothing to calculate
|
||||
// Just do the read
|
||||
//
|
||||
if (!BiosInt13ReadExtended(DriveNumber, SectorNumber, 1, Buffer))
|
||||
{
|
||||
DiskError("Disk read error.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Get the drive geometry
|
||||
//
|
||||
if (!DiskGetDriveGeometry(DriveNumber, &DriveGeometry))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate the physical disk offsets
|
||||
//
|
||||
PhysicalSector = 1 + (SectorNumber % DriveGeometry.Sectors);
|
||||
PhysicalHead = (SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads;
|
||||
PhysicalTrack = (SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads;
|
||||
|
||||
DbgPrint((DPRINT_DISK, "Calling BiosInt13Read() with PhysicalHead: %d\n", PhysicalHead));
|
||||
DbgPrint((DPRINT_DISK, "Calling BiosInt13Read() with PhysicalTrack: %d\n", PhysicalTrack));
|
||||
DbgPrint((DPRINT_DISK, "Calling BiosInt13Read() with PhysicalSector: %d\n", PhysicalSector));
|
||||
|
||||
//
|
||||
// Make sure the read is within the geometry boundaries
|
||||
//
|
||||
if ((PhysicalHead >= DriveGeometry.Heads) ||
|
||||
(PhysicalTrack >= DriveGeometry.Cylinders) ||
|
||||
(PhysicalSector > DriveGeometry.Sectors))
|
||||
{
|
||||
DiskError("Disk read exceeds drive geometry limits.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Perform the read
|
||||
//
|
||||
if (!BiosInt13Read(DriveNumber, PhysicalHead, PhysicalTrack, PhysicalSector, 1, Buffer))
|
||||
{
|
||||
DiskError("Disk read error.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -23,104 +23,15 @@
|
|||
#include <mm.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LIST_ITEM ListEntry;
|
||||
|
||||
ULONG DriveNumber;
|
||||
GEOMETRY DriveGeometry;
|
||||
|
||||
} DRIVE_GEOMETRY, *PDRIVE_GEOMETRY;
|
||||
|
||||
|
||||
PDRIVE_GEOMETRY DriveGeometryListHead = NULL;
|
||||
|
||||
|
||||
BOOL DiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY DriveGeometry)
|
||||
{
|
||||
PDRIVE_GEOMETRY DriveGeometryListEntry;
|
||||
|
||||
//
|
||||
// Search the drive geometry list for the requested drive
|
||||
//
|
||||
DriveGeometryListEntry = DriveGeometryListHead;
|
||||
while (DriveGeometryListEntry != NULL)
|
||||
{
|
||||
//
|
||||
// Check to see if this is the drive we want
|
||||
//
|
||||
if (DriveGeometryListEntry->DriveNumber == DriveNumber)
|
||||
{
|
||||
//
|
||||
// Yep - return the information
|
||||
//
|
||||
RtlCopyMemory(DriveGeometry, &DriveGeometryListEntry->DriveGeometry, sizeof(GEOMETRY));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Nope, get next item
|
||||
//
|
||||
DriveGeometryListEntry = (PDRIVE_GEOMETRY)RtlListGetNext((PLIST_ITEM)DriveGeometryListEntry);
|
||||
}
|
||||
|
||||
DiskError("Drive geometry unknown.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL DiskSetDriveGeometry(ULONG DriveNumber, ULONG Cylinders, ULONG Heads, ULONG Sectors, ULONG BytesPerSector)
|
||||
{
|
||||
PDRIVE_GEOMETRY DriveGeometryListEntry;
|
||||
|
||||
//
|
||||
// Search the drive geometry list for the requested drive
|
||||
//
|
||||
DriveGeometryListEntry = DriveGeometryListHead;
|
||||
while (DriveGeometryListEntry != NULL)
|
||||
{
|
||||
//
|
||||
// Check to see if this is the drive
|
||||
//
|
||||
if (DriveGeometryListEntry->DriveNumber == DriveNumber)
|
||||
{
|
||||
//
|
||||
// Yes, we already have this drive's geometry information
|
||||
// so just return
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Nope, get next item
|
||||
//
|
||||
DriveGeometryListEntry = (PDRIVE_GEOMETRY)RtlListGetNext((PLIST_ITEM)DriveGeometryListEntry);
|
||||
}
|
||||
|
||||
//
|
||||
// If we get here then this is a new drive and we have
|
||||
// to add it's information to our list
|
||||
//
|
||||
DriveGeometryListEntry = (PDRIVE_GEOMETRY)AllocateMemory(sizeof(DRIVE_GEOMETRY));
|
||||
if (DriveGeometryListEntry == NULL)
|
||||
// For now just return the geometry as the BIOS reports it
|
||||
// BytesPerSector is always set to 512 by BiosInt13GetDriveParameters()
|
||||
if (!BiosInt13GetDriveParameters(DriveNumber, DriveGeometry))
|
||||
{
|
||||
DiskError("Drive geometry unknown.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlZeroMemory(DriveGeometryListEntry, sizeof(DRIVE_GEOMETRY));
|
||||
DriveGeometryListEntry->DriveNumber = DriveNumber;
|
||||
DriveGeometryListEntry->DriveGeometry.Cylinders = Cylinders;
|
||||
DriveGeometryListEntry->DriveGeometry.Heads = Heads;
|
||||
DriveGeometryListEntry->DriveGeometry.Sectors = Sectors;
|
||||
DriveGeometryListEntry->DriveGeometry.BytesPerSector = BytesPerSector;
|
||||
|
||||
if (DriveGeometryListHead == NULL)
|
||||
{
|
||||
DriveGeometryListHead = DriveGeometryListEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlListInsertTail((PLIST_ITEM)DriveGeometryListHead, (PLIST_ITEM)DriveGeometryListEntry);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
233
freeldr/freeldr/disk/partition.c
Normal file
233
freeldr/freeldr/disk/partition.c
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 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>
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
|
||||
BOOL DiskIsDriveRemovable(ULONG DriveNumber)
|
||||
{
|
||||
// Hard disks use drive numbers >= 0x80
|
||||
// So if the drive number indicates a hard disk
|
||||
// then return FALSE
|
||||
if (DriveNumber >= 0x80)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Drive is a floppy diskette so return TRUE
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DiskGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
{
|
||||
ULONG BootablePartitionCount = 0;
|
||||
MASTER_BOOT_RECORD MasterBootRecord;
|
||||
|
||||
// Read master boot record
|
||||
if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Count the bootable partitions
|
||||
if (MasterBootRecord.PartitionTable[0].BootIndicator == 0x80)
|
||||
{
|
||||
BootablePartitionCount++;
|
||||
BootPartition = 0;
|
||||
}
|
||||
if (MasterBootRecord.PartitionTable[1].BootIndicator == 0x80)
|
||||
{
|
||||
BootablePartitionCount++;
|
||||
BootPartition = 1;
|
||||
}
|
||||
if (MasterBootRecord.PartitionTable[2].BootIndicator == 0x80)
|
||||
{
|
||||
BootablePartitionCount++;
|
||||
BootPartition = 2;
|
||||
}
|
||||
if (MasterBootRecord.PartitionTable[3].BootIndicator == 0x80)
|
||||
{
|
||||
BootablePartitionCount++;
|
||||
BootPartition = 3;
|
||||
}
|
||||
|
||||
// Make sure there was only one bootable partition
|
||||
if (BootablePartitionCount != 1)
|
||||
{
|
||||
DiskError("Too many bootable partitions or none found.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Copy the partition table entry
|
||||
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord.PartitionTable[BootPartition], sizeof(PARTITION_TABLE_ENTRY));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DiskGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
{
|
||||
MASTER_BOOT_RECORD MasterBootRecord;
|
||||
PARTITION_TABLE_ENTRY ExtendedPartitionTableEntry;
|
||||
ULONG ExtendedPartitionNumber;
|
||||
ULONG Index;
|
||||
|
||||
// Read master boot record
|
||||
if (!DiskReadBootRecord(DriveNumber, 0, &MasterBootRecord))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// If they are asking for a primary
|
||||
// partition then things are easy
|
||||
if (PartitionNumber < 5)
|
||||
{
|
||||
// PartitionNumber is one-based and we need it zero-based
|
||||
PartitionNumber--;
|
||||
|
||||
// Copy the partition table entry
|
||||
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord.PartitionTable[PartitionNumber], sizeof(PARTITION_TABLE_ENTRY));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// They want an extended partition entry so we will need
|
||||
// to loop through all the extended partitions on the disk
|
||||
// and return the one they want.
|
||||
|
||||
ExtendedPartitionNumber = PartitionNumber - 5;
|
||||
|
||||
for (Index=0; Index<=ExtendedPartitionNumber; Index++)
|
||||
{
|
||||
// Get the extended partition table entry
|
||||
if (!DiskGetFirstExtendedPartitionEntry(&MasterBootRecord, &ExtendedPartitionTableEntry))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Read the partition boot record
|
||||
if (!DiskReadBootRecord(DriveNumber, ExtendedPartitionTableEntry.SectorCountBeforePartition, &MasterBootRecord))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get the first real partition table entry
|
||||
if (!DiskGetFirstPartitionEntry(&MasterBootRecord, PartitionTableEntry))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// When we get here we should have the correct entry
|
||||
// already stored in PartitionTableEntry
|
||||
// so just return TRUE
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
for (Index=0; Index<4; Index++)
|
||||
{
|
||||
// Check the system indicator
|
||||
// If it's not an extended or unused partition
|
||||
// then we're done
|
||||
if ((MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_ENTRY_UNUSED) &&
|
||||
(MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_EXTENDED) &&
|
||||
(MasterBootRecord->PartitionTable[Index].SystemIndicator != PARTITION_XINT13_EXTENDED))
|
||||
{
|
||||
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL DiskGetFirstExtendedPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
for (Index=0; Index<4; Index++)
|
||||
{
|
||||
// Check the system indicator
|
||||
// If it an extended partition then we're done
|
||||
if ((MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_EXTENDED) ||
|
||||
(MasterBootRecord->PartitionTable[Index].SystemIndicator == PARTITION_XINT13_EXTENDED))
|
||||
{
|
||||
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord->PartitionTable[Index], sizeof(PARTITION_TABLE_ENTRY));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL DiskReadBootRecord(ULONG DriveNumber, ULONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
// Read master boot record
|
||||
if (!DiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, BootRecord))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
DbgPrint((DPRINT_DISK, "Dumping partition table for drive 0x%x:\n", DriveNumber));
|
||||
DbgPrint((DPRINT_DISK, "Boot record logical start sector = %d\n", LogicalSectorNumber));
|
||||
DbgPrint((DPRINT_DISK, "sizeof(MASTER_BOOT_RECORD) = 0x%x.\n", sizeof(MASTER_BOOT_RECORD)));
|
||||
|
||||
for (Index=0; Index<4; Index++)
|
||||
{
|
||||
DbgPrint((DPRINT_DISK, "-------------------------------------------\n"));
|
||||
DbgPrint((DPRINT_DISK, "Partition %d\n", (Index + 1)));
|
||||
DbgPrint((DPRINT_DISK, "BootIndicator: 0x%x\n", BootRecord->PartitionTable[Index].BootIndicator));
|
||||
DbgPrint((DPRINT_DISK, "StartHead: 0x%x\n", BootRecord->PartitionTable[Index].StartHead));
|
||||
DbgPrint((DPRINT_DISK, "StartSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].StartSector));
|
||||
DbgPrint((DPRINT_DISK, "StartCylinder: 0x%x\n", BootRecord->PartitionTable[Index].StartCylinder));
|
||||
DbgPrint((DPRINT_DISK, "SystemIndicator: 0x%x\n", BootRecord->PartitionTable[Index].SystemIndicator));
|
||||
DbgPrint((DPRINT_DISK, "EndHead: 0x%x\n", BootRecord->PartitionTable[Index].EndHead));
|
||||
DbgPrint((DPRINT_DISK, "EndSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].EndSector));
|
||||
DbgPrint((DPRINT_DISK, "EndCylinder: 0x%x\n", BootRecord->PartitionTable[Index].EndCylinder));
|
||||
DbgPrint((DPRINT_DISK, "SectorCountBeforePartition: 0x%x\n", BootRecord->PartitionTable[Index].SectorCountBeforePartition));
|
||||
DbgPrint((DPRINT_DISK, "PartitionSectorCount: 0x%x\n", BootRecord->PartitionTable[Index].PartitionSectorCount));
|
||||
}
|
||||
|
||||
#endif // defined DEBUG
|
||||
|
||||
// Check the partition table magic value
|
||||
if (BootRecord->MasterBootRecordMagic != 0xaa55)
|
||||
{
|
||||
DiskError("Invalid partition table magic (0xaa55)");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
|
@ -20,63 +20,16 @@
|
|||
#ifndef __FS_H
|
||||
#define __FS_H
|
||||
|
||||
//
|
||||
// Define the structure of a partition table entry
|
||||
//
|
||||
typedef struct _PARTITION_TABLE_ENTRY
|
||||
{
|
||||
BYTE BootIndicator; // 0x00 - non-bootable partition, 0x80 - bootable partition (one partition only)
|
||||
BYTE StartHead; // Beginning head number
|
||||
BYTE StartSector; // Beginning sector (2 high bits of cylinder #)
|
||||
BYTE StartCylinder; // Beginning cylinder# (low order bits of cylinder #)
|
||||
BYTE SystemIndicator; // System indicator
|
||||
BYTE EndHead; // Ending head number
|
||||
BYTE EndSector; // Ending sector (2 high bits of cylinder #)
|
||||
BYTE EndCylinder; // Ending cylinder# (low order bits of cylinder #)
|
||||
DWORD SectorCountBeforePartition; // Number of sectors preceding the partition
|
||||
DWORD PartitionSectorCount; // Number of sectors in the partition
|
||||
|
||||
} PACKED PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
|
||||
#define EOF -1
|
||||
|
||||
//
|
||||
// This macro will return the cylinder when you pass it a cylinder/sector
|
||||
// pair where the high 2 bits of the cylinder are stored in the sector byte
|
||||
//
|
||||
#define MAKE_CYLINDER(cylinder, sector) ( cylinder + ((((WORD)sector) & 0xC0) << 2) )
|
||||
#define FS_FAT 1
|
||||
#define FS_NTFS 2
|
||||
#define FS_EXT2 3
|
||||
#define FS_REISER 4
|
||||
|
||||
//
|
||||
// Define the structure of the master boot record
|
||||
//
|
||||
typedef struct _MASTER_BOOT_RECORD
|
||||
{
|
||||
BYTE MasterBootRecordCodeAndData[0x1be];
|
||||
PARTITION_TABLE_ENTRY PartitionTable[4];
|
||||
WORD MasterBootRecordMagic;
|
||||
|
||||
} PACKED MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD;
|
||||
|
||||
//
|
||||
// Partition type defines
|
||||
//
|
||||
#define PARTITION_ENTRY_UNUSED 0x00 // Entry unused
|
||||
#define PARTITION_FAT_12 0x01 // 12-bit FAT entries
|
||||
#define PARTITION_XENIX_1 0x02 // Xenix
|
||||
#define PARTITION_XENIX_2 0x03 // Xenix
|
||||
#define PARTITION_FAT_16 0x04 // 16-bit FAT entries
|
||||
#define PARTITION_EXTENDED 0x05 // Extended partition entry
|
||||
#define PARTITION_HUGE 0x06 // Huge partition MS-DOS V4
|
||||
#define PARTITION_IFS 0x07 // IFS Partition
|
||||
#define PARTITION_OS2BOOTMGR 0x0A // OS/2 Boot Manager/OPUS/Coherent swap
|
||||
#define PARTITION_FAT32 0x0B // FAT32
|
||||
#define PARTITION_FAT32_XINT13 0x0C // FAT32 using extended int13 services
|
||||
#define PARTITION_XINT13 0x0E // Win95 partition using extended int13 services
|
||||
#define PARTITION_XINT13_EXTENDED 0x0F // Same as type 5 but uses extended int13 services
|
||||
#define PARTITION_PREP 0x41 // PowerPC Reference Platform (PReP) Boot Partition
|
||||
#define PARTITION_LDM 0x42 // Logical Disk Manager partition
|
||||
#define PARTITION_UNIX 0x63 // Unix
|
||||
|
||||
#define FILE VOID
|
||||
#define PFILE FILE *
|
||||
#define FILE VOID
|
||||
#define PFILE FILE *
|
||||
|
||||
VOID FileSystemError(PUCHAR ErrorString);
|
||||
BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber);
|
||||
|
@ -88,11 +41,4 @@ VOID SetFilePointer(PFILE FileHandle, ULONG NewFilePointer);
|
|||
ULONG GetFilePointer(PFILE FileHandle);
|
||||
BOOL IsEndOfFile(PFILE FileHandle);
|
||||
|
||||
|
||||
#define EOF -1
|
||||
|
||||
#define FS_FAT 1
|
||||
#define FS_NTFS 2
|
||||
#define FS_EXT2 3
|
||||
|
||||
#endif // #defined __FS_H
|
||||
|
|
|
@ -43,9 +43,6 @@ ULONG FatDriveNumber = 0;
|
|||
|
||||
BOOL FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector)
|
||||
{
|
||||
ULONG PhysicalTrack;
|
||||
ULONG PhysicalHead;
|
||||
ULONG PhysicalSector;
|
||||
|
||||
DbgPrint((DPRINT_FILESYSTEM, "FatOpenVolume() DriveNumber = 0x%x VolumeStartSector = %d\n", DriveNumber, VolumeStartSector));
|
||||
|
||||
|
@ -80,26 +77,9 @@ BOOL FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector)
|
|||
|
||||
// Now try to read the boot sector
|
||||
// If this fails then abort
|
||||
if (BiosInt13ExtensionsSupported(DriveNumber))
|
||||
if (!DiskReadLogicalSectors(DriveNumber, VolumeStartSector, 1, FatVolumeBootSector))
|
||||
{
|
||||
if (!BiosInt13ReadExtended(DriveNumber, VolumeStartSector, 1, FatVolumeBootSector))
|
||||
{
|
||||
FileSystemError("Disk read error.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate the physical disk offsets
|
||||
PhysicalSector = 1 + (VolumeStartSector % get_sectors(DriveNumber));
|
||||
PhysicalHead = (VolumeStartSector / get_sectors(DriveNumber)) % get_heads(DriveNumber);
|
||||
PhysicalTrack = (VolumeStartSector / get_sectors(DriveNumber)) / get_heads(DriveNumber);
|
||||
|
||||
if (!BiosInt13Read(DriveNumber, PhysicalHead, PhysicalTrack, PhysicalSector, 1, FatVolumeBootSector))
|
||||
{
|
||||
FileSystemError("Disk read error.");
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Get the FAT type
|
||||
|
@ -180,14 +160,6 @@ BOOL FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Set the drive geometry
|
||||
//
|
||||
if (!DiskSetDriveGeometry(DriveNumber, get_cylinders(DriveNumber), get_heads(DriveNumber), get_sectors(DriveNumber), FatVolumeBootSector->BytesPerSector))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Check the FAT cluster size
|
||||
// We do not support clusters bigger than 64k
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 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 <fs.h>
|
||||
|
||||
#ifndef __FILESYS_H
|
||||
#define __FILESYS_H
|
||||
|
||||
BOOL FsInternalIsDiskPartitioned(ULONG DriveNumber); // Returns TRUE if the disk contains partitions, FALSE if floppy disk
|
||||
BOOL FsInternalGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry); // Returns the active partition table entry
|
||||
BOOL FsInternalGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry); // Returns the active partition table entry
|
||||
ULONG FsInternalGetPartitionCount(ULONG DriveNumber); // Returns the number of partitions on the disk
|
||||
|
||||
#endif // #defined __FILESYS_H
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#include <freeldr.h>
|
||||
#include <fs.h>
|
||||
#include "filesys.h"
|
||||
#include "fat.h"
|
||||
#include <disk.h>
|
||||
#include <rtl.h>
|
||||
|
@ -71,14 +70,13 @@ VOID FileSystemError(PUCHAR ErrorString)
|
|||
*/
|
||||
BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber)
|
||||
{
|
||||
MASTER_BOOT_RECORD DriveMasterBootRecord;
|
||||
PARTITION_TABLE_ENTRY PartitionTableEntry;
|
||||
|
||||
DbgPrint((DPRINT_FILESYSTEM, "OpenDiskDrive() DriveNumber: 0x%x PartitionNumber: 0x%x\n", DriveNumber, PartitionNumber));
|
||||
|
||||
// Check and see if it is a floppy drive
|
||||
// If so then just assume FAT12 file system type
|
||||
if (FsInternalIsDiskPartitioned(DriveNumber) == FALSE)
|
||||
if (DiskIsDriveRemovable(DriveNumber))
|
||||
{
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Drive is a floppy diskette drive. Assuming FAT12 file system.\n"));
|
||||
|
||||
|
@ -86,52 +84,14 @@ BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber)
|
|||
return FatOpenVolume(DriveNumber, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// Read master boot record
|
||||
//
|
||||
if (!BiosInt13Read(DriveNumber, 0, 0, 1, 1, &DriveMasterBootRecord))
|
||||
{
|
||||
FileSystemError("Disk read error.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Drive is a hard disk, dumping partition table:\n"));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "sizeof(MASTER_BOOT_RECORD) = 0x%x.\n", sizeof(MASTER_BOOT_RECORD)));
|
||||
|
||||
for (BootPartition=0; BootPartition<4; BootPartition++)
|
||||
{
|
||||
DbgPrint((DPRINT_FILESYSTEM, "-------------------------------------------\n"));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Partition %d\n", (BootPartition + 1)));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "BootIndicator: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].BootIndicator));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "StartHead: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].StartHead));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "StartSector (Plus 2 cylinder bits): 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].StartSector));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "StartCylinder: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].StartCylinder));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "SystemIndicator: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].SystemIndicator));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "EndHead: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].EndHead));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "EndSector (Plus 2 cylinder bits): 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].EndSector));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "EndCylinder: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].EndCylinder));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "SectorCountBeforePartition: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].SectorCountBeforePartition));
|
||||
DbgPrint((DPRINT_FILESYSTEM, "PartitionSectorCount: 0x%x\n", DriveMasterBootRecord.PartitionTable[BootPartition].PartitionSectorCount));
|
||||
}
|
||||
|
||||
#endif // defined DEBUG
|
||||
|
||||
|
||||
// Check the partition table magic value
|
||||
if (DriveMasterBootRecord.MasterBootRecordMagic != 0xaa55)
|
||||
{
|
||||
FileSystemError("Invalid partition table magic (0xaa55)");
|
||||
return FALSE;
|
||||
}
|
||||
// Set the boot partition
|
||||
BootPartition = PartitionNumber;
|
||||
|
||||
// Get the requested partition entry
|
||||
if (PartitionNumber == 0)
|
||||
{
|
||||
// Partition requested was zero which means the boot partition
|
||||
if (FsInternalGetActivePartitionEntry(DriveNumber, &PartitionTableEntry) == FALSE)
|
||||
if (DiskGetActivePartitionEntry(DriveNumber, &PartitionTableEntry) == FALSE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -139,7 +99,7 @@ BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber)
|
|||
else
|
||||
{
|
||||
// Get requested partition
|
||||
if (FsInternalGetPartitionEntry(DriveNumber, PartitionNumber, &PartitionTableEntry) == FALSE)
|
||||
if (DiskGetPartitionEntry(DriveNumber, PartitionNumber, &PartitionTableEntry) == FALSE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -171,87 +131,6 @@ BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FsInternalIsDiskPartitioned(ULONG DriveNumber)
|
||||
{
|
||||
// Hard disks use drive numbers >= 0x80
|
||||
// So if the drive number indicates a hard disk
|
||||
// then return TRUE
|
||||
if (DriveNumber >= 0x80)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Drive is a floppy diskette so return FALSE
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL FsInternalGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
{
|
||||
ULONG BootablePartitionCount = 0;
|
||||
MASTER_BOOT_RECORD MasterBootRecord;
|
||||
|
||||
// Read master boot record
|
||||
if (!BiosInt13Read(DriveNumber, 0, 0, 1, 1, &MasterBootRecord))
|
||||
{
|
||||
FileSystemError("Disk read error.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Count the bootable partitions
|
||||
if (MasterBootRecord.PartitionTable[0].BootIndicator == 0x80)
|
||||
{
|
||||
BootablePartitionCount++;
|
||||
BootPartition = 0;
|
||||
}
|
||||
if (MasterBootRecord.PartitionTable[1].BootIndicator == 0x80)
|
||||
{
|
||||
BootablePartitionCount++;
|
||||
BootPartition = 1;
|
||||
}
|
||||
if (MasterBootRecord.PartitionTable[2].BootIndicator == 0x80)
|
||||
{
|
||||
BootablePartitionCount++;
|
||||
BootPartition = 2;
|
||||
}
|
||||
if (MasterBootRecord.PartitionTable[3].BootIndicator == 0x80)
|
||||
{
|
||||
BootablePartitionCount++;
|
||||
BootPartition = 3;
|
||||
}
|
||||
|
||||
// Make sure there was only one bootable partition
|
||||
if (BootablePartitionCount != 1)
|
||||
{
|
||||
FileSystemError("Too many bootable partitions or none found.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Copy the partition table entry
|
||||
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord.PartitionTable[BootPartition], sizeof(PARTITION_TABLE_ENTRY));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FsInternalGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
{
|
||||
MASTER_BOOT_RECORD MasterBootRecord;
|
||||
|
||||
// Read master boot record
|
||||
if (!BiosInt13Read(DriveNumber, 0, 0, 1, 1, &MasterBootRecord))
|
||||
{
|
||||
FileSystemError("Disk read error.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// PartitionNumber is one-based and we need it zero-based
|
||||
PartitionNumber--;
|
||||
|
||||
// Copy the partition table entry
|
||||
RtlCopyMemory(PartitionTableEntry, &MasterBootRecord.PartitionTable[PartitionNumber], sizeof(PARTITION_TABLE_ENTRY));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PFILE OpenFile(PUCHAR FileName)
|
||||
{
|
||||
PFILE FileHandle = NULL;
|
||||
|
|
|
@ -254,4 +254,4 @@ BOOL MultiBootCloseModule(PVOID ModuleBase, DWORD dwModuleSize)
|
|||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ CP = cmd /C copy
|
|||
MAKE = make
|
||||
|
||||
# For a release build uncomment this line
|
||||
FLAGS = -Wall -nostdlib -nostdinc -fno-builtin -I./ -I../ -I../../ -O3
|
||||
#FLAGS = -Wall -nostdlib -nostdinc -fno-builtin -I./ -I../ -I../../ -O3
|
||||
|
||||
# For a debug build uncomment this line
|
||||
#FLAGS = -Wall -nostdlib -nostdinc -fno-builtin -I./ -I../ -I../../ -DDEBUG -O3
|
||||
FLAGS = -Wall -nostdlib -nostdinc -fno-builtin -I./ -I../ -I../../ -DDEBUG -O3
|
||||
|
|
Loading…
Reference in a new issue