3 * Copyright (C) 1999, 2000, 2001 Brian Palmer <brianp@sginet.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 /////////////////////////////////////////////////////////////////////////////////////////////
32 /////////////////////////////////////////////////////////////////////////////////////////////
34 GEOMETRY DriveGeometry
;
35 ULONG VolumeHiddenSectors
;
36 ULONG CurrentlyOpenDriveNumber
;
37 ULONG FileSystemType
= 0; // Type of filesystem on boot device, set by OpenDiskDrive()
39 /////////////////////////////////////////////////////////////////////////////////////////////
41 /////////////////////////////////////////////////////////////////////////////////////////////
43 VOID
FileSystemError(PUCHAR ErrorString
)
45 DbgPrint((DPRINT_FILESYSTEM
, "%s\n", ErrorString
));
49 MessageBox(ErrorString
);
53 printf("%s", ErrorString
);
54 printf("\nPress any key\n");
61 * BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber);
63 * This function is called to open a disk drive for file access.
64 * It must be called before any of the file functions will work.
65 * It takes two parameters:
67 * Drive: The BIOS drive number of the disk to open
68 * Partition: This is zero for floppy drives.
69 * If the disk is a hard disk then this specifies
70 * The partition number to open (1 - 4)
71 * If it is zero then it opens the active (bootable) partition
74 BOOL
OpenDiskDrive(ULONG DriveNumber
, ULONG PartitionNumber
)
76 ULONG BootablePartitionCount
= 0;
77 ULONG BootPartition
= 0;
78 ULONG PartitionStartHead
;
79 ULONG PartitionStartSector
;
80 ULONG PartitionStartCylinder
;
81 MASTER_BOOT_RECORD DriveMasterBootRecord
;
83 DbgPrint((DPRINT_FILESYSTEM
, "OpenDiskDrive() DriveNumber: 0x%x PartitionNumber: 0x%x\n", DriveNumber
, PartitionNumber
));
85 CurrentlyOpenDriveNumber
= DriveNumber
;
88 // Check and see if it is a floppy drive
89 // If so then just assume FAT12 file system type
91 if (DriveNumber
< 0x80)
93 DbgPrint((DPRINT_FILESYSTEM
, "Drive is a floppy diskette drive. Assuming FAT12 file system.\n"));
95 FileSystemType
= FS_FAT
;
96 return FatOpenVolume(DriveNumber
, 0, 0, 1, FAT12
);
100 // Read master boot record
102 if (!BiosInt13Read(DriveNumber
, 0, 0, 1, 1, &DriveMasterBootRecord
))
104 FileSystemError("Disk read error.");
111 DbgPrint((DPRINT_FILESYSTEM
, "Drive is a hard disk, dumping partition table:\n"));
112 DbgPrint((DPRINT_FILESYSTEM
, "sizeof(MASTER_BOOT_RECORD) = 0x%x.\n", sizeof(MASTER_BOOT_RECORD
)));
114 for (BootPartition
=0; BootPartition
<4; BootPartition
++)
116 DbgPrint((DPRINT_FILESYSTEM
, "-------------------------------------------\n"));
117 DbgPrint((DPRINT_FILESYSTEM
, "Partition %d\n", (BootPartition
+ 1)));
118 DbgPrint((DPRINT_FILESYSTEM
, "BootIndicator: 0x%x\n", DriveMasterBootRecord
.PartitionTable
[BootPartition
].BootIndicator
));
119 DbgPrint((DPRINT_FILESYSTEM
, "StartHead: 0x%x\n", DriveMasterBootRecord
.PartitionTable
[BootPartition
].StartHead
));
120 DbgPrint((DPRINT_FILESYSTEM
, "StartSector (Plus 2 cylinder bits): 0x%x\n", DriveMasterBootRecord
.PartitionTable
[BootPartition
].StartSector
));
121 DbgPrint((DPRINT_FILESYSTEM
, "StartCylinder: 0x%x\n", DriveMasterBootRecord
.PartitionTable
[BootPartition
].StartCylinder
));
122 DbgPrint((DPRINT_FILESYSTEM
, "SystemIndicator: 0x%x\n", DriveMasterBootRecord
.PartitionTable
[BootPartition
].SystemIndicator
));
123 DbgPrint((DPRINT_FILESYSTEM
, "EndHead: 0x%x\n", DriveMasterBootRecord
.PartitionTable
[BootPartition
].EndHead
));
124 DbgPrint((DPRINT_FILESYSTEM
, "EndSector (Plus 2 cylinder bits): 0x%x\n", DriveMasterBootRecord
.PartitionTable
[BootPartition
].EndSector
));
125 DbgPrint((DPRINT_FILESYSTEM
, "EndCylinder: 0x%x\n", DriveMasterBootRecord
.PartitionTable
[BootPartition
].EndCylinder
));
126 DbgPrint((DPRINT_FILESYSTEM
, "SectorCountBeforePartition: 0x%x\n", DriveMasterBootRecord
.PartitionTable
[BootPartition
].SectorCountBeforePartition
));
127 DbgPrint((DPRINT_FILESYSTEM
, "PartitionSectorCount: 0x%x\n", DriveMasterBootRecord
.PartitionTable
[BootPartition
].PartitionSectorCount
));
130 #endif // defined DEBUG
134 // Check the partition table magic value
136 if (DriveMasterBootRecord
.MasterBootRecordMagic
!= 0xaa55)
138 FileSystemError("Invalid partition table magic (0xaa55)");
142 if (PartitionNumber
== 0)
145 // Count the bootable partitions
147 if (DriveMasterBootRecord
.PartitionTable
[0].BootIndicator
== 0x80)
149 BootablePartitionCount
++;
152 if (DriveMasterBootRecord
.PartitionTable
[1].BootIndicator
== 0x80)
154 BootablePartitionCount
++;
157 if (DriveMasterBootRecord
.PartitionTable
[2].BootIndicator
== 0x80)
159 BootablePartitionCount
++;
162 if (DriveMasterBootRecord
.PartitionTable
[3].BootIndicator
== 0x80)
164 BootablePartitionCount
++;
169 // Make sure there was only one bootable partition
171 if (BootablePartitionCount
!= 1)
173 FileSystemError("Too many bootable partitions or none found.");
179 // We found the boot partition, so set the partition number
181 PartitionNumber
= BootPartition
;
186 // Right now the partition number is one-based
187 // and we need zero based
192 // Check for valid partition
194 if (DriveMasterBootRecord
.PartitionTable
[PartitionNumber
].SystemIndicator
== PARTITION_ENTRY_UNUSED
)
196 FileSystemError("Invalid partition.");
200 PartitionStartHead
= DriveMasterBootRecord
.PartitionTable
[PartitionNumber
].StartHead
;
201 PartitionStartSector
= DriveMasterBootRecord
.PartitionTable
[PartitionNumber
].StartSector
& 0x3F;
202 PartitionStartCylinder
= MAKE_CYLINDER(
203 DriveMasterBootRecord
.PartitionTable
[PartitionNumber
].StartCylinder
,
204 DriveMasterBootRecord
.PartitionTable
[PartitionNumber
].StartSector
);
206 DbgPrint((DPRINT_FILESYSTEM
, "PartitionStartHead: %d\n", PartitionStartHead
));
207 DbgPrint((DPRINT_FILESYSTEM
, "PartitionStartSector: %d\n", PartitionStartSector
));
208 DbgPrint((DPRINT_FILESYSTEM
, "PartitionStartCylinder: %d\n", PartitionStartCylinder
));
209 DbgPrint((DPRINT_FILESYSTEM
, "PartitionNumber: %d\n", PartitionNumber
));
211 switch (DriveMasterBootRecord
.PartitionTable
[PartitionNumber
].SystemIndicator
)
213 case PARTITION_FAT_12
:
214 FileSystemType
= FS_FAT
;
215 return FatOpenVolume(DriveNumber
, PartitionStartHead
, PartitionStartCylinder
, PartitionStartSector
, FAT12
);
216 case PARTITION_FAT_16
:
218 case PARTITION_XINT13
:
219 FileSystemType
= FS_FAT
;
220 return FatOpenVolume(DriveNumber
, PartitionStartHead
, PartitionStartCylinder
, PartitionStartSector
, FAT16
);
221 case PARTITION_FAT32
:
222 case PARTITION_FAT32_XINT13
:
223 FileSystemType
= FS_FAT
;
224 return FatOpenVolume(DriveNumber
, PartitionStartHead
, PartitionStartCylinder
, PartitionStartSector
, FAT32
);
227 FileSystemError("Unsupported file system.");
234 PFILE
OpenFile(PUCHAR FileName
)
236 PFILE FileHandle
= NULL
;
239 // Print status message
241 DbgPrint((DPRINT_FILESYSTEM
, "Opening file '%s'...\n", FileName
));
244 // Check file system type and pass off to appropriate handler
246 if (FileSystemType
== FS_FAT
)
248 FileHandle
= FatOpenFile(FileName
);
252 FileSystemError("Error: Unknown filesystem.");
257 // Check return value
259 if (FileHandle
!= NULL
)
261 DbgPrint((DPRINT_FILESYSTEM
, "OpenFile() succeeded. FileHandle: 0x%x\n", FileHandle
));
265 DbgPrint((DPRINT_FILESYSTEM
, "OpenFile() failed.\n"));
267 #endif // defined DEBUG
272 VOID
CloseFile(PFILE FileHandle
)
278 * returns number of bytes read or EOF
280 BOOL
ReadFile(PFILE FileHandle
, ULONG BytesToRead
, PULONG BytesRead
, PVOID Buffer
)
283 // Set the number of bytes read equal to zero
285 if (BytesRead
!=NULL
)
290 switch (FileSystemType
)
294 return FatReadFile(FileHandle
, BytesToRead
, BytesRead
, Buffer
);
298 FileSystemError("Unknown file system.");
305 ULONG
GetFileSize(PFILE FileHandle
)
307 switch (FileSystemType
)
311 return FatGetFileSize(FileHandle
);
314 FileSystemError("Unknown file system.");
321 VOID
SetFilePointer(PFILE FileHandle
, ULONG NewFilePointer
)
323 switch (FileSystemType
)
327 FatSetFilePointer(FileHandle
, NewFilePointer
);
331 FileSystemError("Unknown file system.");
336 ULONG
GetFilePointer(PFILE FileHandle
)
338 switch (FileSystemType
)
342 return FatGetFilePointer(FileHandle
);
346 FileSystemError("Unknown file system.");
353 BOOL
IsEndOfFile(PFILE FileHandle
)
355 if (GetFilePointer(FileHandle
) >= GetFileSize(FileHandle
))