Added full disk partition management functions
authorBrian Palmer <brianp@sginet.com>
Tue, 26 Feb 2002 00:26:35 +0000 (00:26 +0000)
committerBrian Palmer <brianp@sginet.com>
Tue, 26 Feb 2002 00:26:35 +0000 (00:26 +0000)
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

15 files changed:
freeldr/freeldr/arch/Makefile
freeldr/freeldr/arch/i386/disk.S
freeldr/freeldr/cache/blocklist.c
freeldr/freeldr/debug.c
freeldr/freeldr/disk.h
freeldr/freeldr/disk/Makefile
freeldr/freeldr/disk/disk.c
freeldr/freeldr/disk/geometry.c
freeldr/freeldr/disk/partition.c [new file with mode: 0644]
freeldr/freeldr/fs.h
freeldr/freeldr/fs/fat.c
freeldr/freeldr/fs/filesys.h [deleted file]
freeldr/freeldr/fs/fs.c
freeldr/freeldr/multiboot.c
freeldr/freeldr/rules.mk

index 5c4685e..5baf058 100644 (file)
@@ -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:
index 0e8cdc5..8b3c197 100644 (file)
@@ -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
+
 
index 3b899b6..1802884 100644 (file)
@@ -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);
index dfdafbf..9f93e05 100644 (file)
@@ -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;
 
index f00a622..d9232e8 100644 (file)
@@ -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
index 9f95c12..2d918bb 100644 (file)
@@ -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
index 9abe851..eafe878 100644 (file)
@@ -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;
-}
index e28313f..61f2561 100644 (file)
 #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;
 }
diff --git a/freeldr/freeldr/disk/partition.c b/freeldr/freeldr/disk/partition.c
new file mode 100644 (file)
index 0000000..89cf40a
--- /dev/null
@@ -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;
+}
index 26aec03..3da0315 100644 (file)
 #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 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        FS_FAT                  1
+#define        FS_NTFS                 2
+#define        FS_EXT2                 3
+#define FS_REISER              4
 
-#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
index ca09a7e..b9bdecc 100644 (file)
@@ -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
diff --git a/freeldr/freeldr/fs/filesys.h b/freeldr/freeldr/fs/filesys.h
deleted file mode 100644 (file)
index 5184c8a..0000000
+++ /dev/null
@@ -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
index 331cfb8..eebf2ac 100644 (file)
@@ -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;
index dd54d15..123e563 100644 (file)
@@ -254,4 +254,4 @@ BOOL MultiBootCloseModule(PVOID ModuleBase, DWORD dwModuleSize)
        }
 
        return(FALSE);
-}
\ No newline at end of file
+}
index 904b9c8..521c9a4 100644 (file)
@@ -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