X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fboot%2Ffreeldr%2Ffreeldr%2Farch%2Fi386%2Fhardware.c;h=d4654ccd138327d9ba3a366837a34399fcfe6420;hp=2f800beb1d927f5105b0a79c74f480d20ada890f;hb=3874d4ff4e65bea3cece017935e66508f13ea89f;hpb=f9c2afd00a4d2b5452d46ea44ea500a394e229c2 diff --git a/reactos/boot/freeldr/freeldr/arch/i386/hardware.c b/reactos/boot/freeldr/freeldr/arch/i386/hardware.c index 2f800beb1d9..d4654ccd138 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/hardware.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/hardware.c @@ -2,6 +2,7 @@ * FreeLoader * * Copyright (C) 2003, 2004 Eric Kohl + * Copyright (C) 2009 Hervé Poussineau * * 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 @@ -13,9 +14,9 @@ * 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. + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include @@ -402,6 +403,7 @@ typedef struct tagDISKCONTEXT ULONG DriveNumber; ULONG SectorSize; ULONGLONG SectorOffset; + ULONGLONG SectorCount; ULONGLONG SectorNumber; } DISKCONTEXT; @@ -415,7 +417,13 @@ static LONG DiskClose(ULONG FileId) static LONG DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information) { - return EINVAL; + DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); + + RtlZeroMemory(Information, sizeof(FILEINFORMATION)); + Information->EndingAddress.QuadPart = (Context->SectorOffset + Context->SectorCount) * Context->SectorSize; + Information->CurrentAddress.LowPart = (Context->SectorOffset + Context->SectorNumber) * Context->SectorSize; + + return ESUCCESS; } static LONG DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) @@ -423,17 +431,35 @@ static LONG DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) DISKCONTEXT* Context; ULONG DriveNumber, DrivePartition, SectorSize; ULONGLONG SectorOffset = 0; + ULONGLONG SectorCount = 0; PARTITION_TABLE_ENTRY PartitionTableEntry; + GEOMETRY Geometry; + EXTENDED_GEOMETRY ExtGeometry; CHAR FileName[1]; if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition)) return EINVAL; - SectorSize = (DrivePartition == 0xff ? 2048 : 512); + + ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY); + if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size)) + { + SectorSize = ExtGeometry.BytesPerSector; + SectorCount = ExtGeometry.Sectors; + } + else if (MachDiskGetDriveGeometry(DriveNumber, &Geometry)) + { + SectorSize = Geometry.BytesPerSector; + SectorCount = Geometry.Sectors; + } + else + return EINVAL; + if (DrivePartition != 0xff && DrivePartition != 0) { - if (!MachDiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry)) + if (!DiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry)) return EINVAL; SectorOffset = PartitionTableEntry.SectorCountBeforePartition; + SectorCount = PartitionTableEntry.PartitionSectorCount; } Context = MmHeapAlloc(sizeof(DISKCONTEXT)); @@ -442,6 +468,7 @@ static LONG DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) Context->DriveNumber = DriveNumber; Context->SectorSize = SectorSize; Context->SectorOffset = SectorOffset; + Context->SectorCount = SectorCount; Context->SectorNumber = 0; FsSetDeviceSpecific(*FileId, Context); @@ -452,15 +479,16 @@ static LONG DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) { DISKCONTEXT* Context = FsGetDeviceSpecific(FileId); UCHAR* Ptr = (UCHAR*)Buffer; - ULONG i; + ULONG i, Length; BOOLEAN ret; *Count = 0; - if (N & (Context->SectorSize - 1)) - return EINVAL; - - for (i = 0; i < N / Context->SectorSize; i++) + i = 0; + while (N > 0) { + Length = N; + if (Length > Context->SectorSize) + Length = Context->SectorSize; ret = MachDiskReadLogicalSectors( Context->DriveNumber, Context->SectorNumber + Context->SectorOffset + i, @@ -468,11 +496,13 @@ static LONG DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count) (PVOID)DISKREADBUFFER); if (!ret) return EIO; - RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Context->SectorSize); - Ptr += Context->SectorSize; + RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length); + Ptr += Length; + *Count += Length; + N -= Length; + i++; } - *Count = N; return ESUCCESS; } @@ -545,9 +575,9 @@ GetHarddiskIdentifier(PCHAR Identifier, FsRegisterDevice(ArcName, &DiskVtbl); /* Add partitions */ - i = 0; + i = 1; DiskReportError(FALSE); - while (MachDiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry)) + while (DiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry)) { if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED) { @@ -903,7 +933,7 @@ GetDiskCount(PCONFIGURATION_COMPONENT_DATA BusKey) // // Return number of disks // - DPRINTM(DPRINT_HWDETECT, "Retrieving %lu INT13 disks\\0\n"); + DPRINTM(DPRINT_HWDETECT, "Retrieving %lu INT13 disks\\0\n", DiskCount); return DiskCount; }; @@ -963,6 +993,29 @@ DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA BusKey) DiskIsDriveRemovable(BootDrive)) { /* TODO: Check if it's really a cdrom drive */ + ULONG* Buffer; + ULONG Checksum = 0; + + /* Read the MBR */ + if (!MachDiskReadLogicalSectors(BootDrive, 16ULL, 1, (PVOID)DISKREADBUFFER)) + { + DPRINTM(DPRINT_HWDETECT, "Reading MBR failed\n"); + return; + } + + Buffer = (ULONG*)DISKREADBUFFER; + + /* Calculate the MBR checksum */ + for (i = 0; i < 2048 / sizeof(ULONG); i++) Checksum += Buffer[i]; + DPRINTM(DPRINT_HWDETECT, "Checksum: %x\n", Checksum); + + /* Fill out the ARC disk block */ + reactos_arc_disk_info[reactos_disk_count].CheckSum = Checksum; + strcpy(reactos_arc_strings[reactos_disk_count], BootPath); + reactos_arc_disk_info[reactos_disk_count].ArcName = + reactos_arc_strings[reactos_disk_count]; + reactos_disk_count++; + FsRegisterDevice(BootPath, &DiskVtbl); } }