static LONG DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) { DISKCONTEXT* Context; UCHAR DriveNumber; ULONG DrivePartition, SectorSize; ULONGLONG SectorOffset = 0; ULONGLONG SectorCount = 0; PARTITION_TABLE_ENTRY PartitionTableEntry; CHAR FileName[1]; if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition)) return EINVAL; if (DrivePartition == 0xff) { /* This is a CD-ROM device */ SectorSize = 2048; } else { /* This is either a floppy disk device (DrivePartition == 0) or * a hard disk device (DrivePartition != 0 && DrivePartition != 0xFF) but * it doesn't matter which one because they both have 512 bytes per sector */ SectorSize = 512; } if (DrivePartition != 0xff && DrivePartition != 0) { if (!DiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry)) return EINVAL; SectorOffset = PartitionTableEntry.SectorCountBeforePartition; SectorCount = PartitionTableEntry.PartitionSectorCount; } Context = MmHeapAlloc(sizeof(DISKCONTEXT)); if (!Context) return ENOMEM; Context->DriveNumber = DriveNumber; Context->SectorSize = SectorSize; Context->SectorOffset = SectorOffset; Context->SectorCount = SectorCount; Context->SectorNumber = 0; FsSetDeviceSpecific(*FileId, Context); return ESUCCESS; }
VOID LoadAndBootPartition(IN OperatingSystemItem* OperatingSystem, IN USHORT OperatingSystemVersion) { ULONG_PTR SectionId; PCSTR SectionName = OperatingSystem->SystemPartition; CHAR SettingName[80]; CHAR SettingValue[80]; PARTITION_TABLE_ENTRY PartitionTableEntry; UCHAR DriveNumber; ULONG PartitionNumber; // Find all the message box settings and run them UiShowMessageBoxesInSection(SectionName); // Try to open the operating system section in the .ini file if (!IniOpenSection(SectionName, &SectionId)) { sprintf(SettingName, "Section [%s] not found in freeldr.ini.\n", SectionName); UiMessageBox(SettingName); return; } // Read the boot drive if (!IniReadSettingByName(SectionId, "BootDrive", SettingValue, sizeof(SettingValue))) { UiMessageBox("Boot drive not specified for selected OS!"); return; } DriveNumber = DriveMapGetBiosDriveNumber(SettingValue); // Read the boot partition if (!IniReadSettingByName(SectionId, "BootPartition", SettingValue, sizeof(SettingValue))) { UiMessageBox("Boot partition not specified for selected OS!"); return; } PartitionNumber = atoi(SettingValue); // Get the partition table entry if (!DiskGetPartitionEntry(DriveNumber, PartitionNumber, &PartitionTableEntry)) { return; } // Now try to read the partition boot sector // If this fails then abort if (!MachDiskReadLogicalSectors(DriveNumber, PartitionTableEntry.SectorCountBeforePartition, 1, (PVOID)0x7C00)) { UiMessageBox("Unable to read partition's boot sector."); return; } // Check for validity if (*((USHORT*)(0x7c00 + 0x1fe)) != 0xaa55) { UiMessageBox("Invalid boot sector magic (0xaa55)"); return; } UiUnInitialize("Booting..."); // Don't stop the floppy drive motor when we // are just booting a bootsector, or drive, or partition. // If we were to stop the floppy motor then // the BIOS wouldn't be informed and if the // next read is to a floppy then the BIOS will // still think the motor is on and this will // result in a read error. //DiskStopFloppyMotor(); //DisableA20(); ChainLoadBiosBootSectorCode(); }
VOID GetHarddiskInformation( UCHAR DriveNumber) { PMASTER_BOOT_RECORD Mbr; ULONG *Buffer; ULONG i; ULONG Checksum; ULONG Signature; CHAR ArcName[256]; PARTITION_TABLE_ENTRY PartitionTableEntry; PCHAR Identifier = PcDiskIdentifier[DriveNumber - 0x80]; /* Read the MBR */ if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER)) { ERR("Reading MBR failed\n"); return; } Buffer = (ULONG*)DISKREADBUFFER; Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER; Signature = Mbr->Signature; TRACE("Signature: %x\n", Signature); /* Calculate the MBR checksum */ Checksum = 0; for (i = 0; i < 128; i++) { Checksum += Buffer[i]; } Checksum = ~Checksum + 1; TRACE("Checksum: %x\n", Checksum); /* Fill out the ARC disk block */ reactos_arc_disk_info[reactos_disk_count].Signature = Signature; reactos_arc_disk_info[reactos_disk_count].CheckSum = Checksum; sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)", reactos_disk_count); strcpy(reactos_arc_strings[reactos_disk_count], ArcName); reactos_arc_disk_info[reactos_disk_count].ArcName = reactos_arc_strings[reactos_disk_count]; reactos_disk_count++; sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(0)", DriveNumber - 0x80); FsRegisterDevice(ArcName, &DiskVtbl); /* Add partitions */ i = 1; DiskReportError(FALSE); while (DiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry)) { if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED) { sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(%lu)", DriveNumber - 0x80, i); FsRegisterDevice(ArcName, &DiskVtbl); } i++; } DiskReportError(TRUE); /* Convert checksum and signature to identifier string */ Identifier[0] = Hex[(Checksum >> 28) & 0x0F]; Identifier[1] = Hex[(Checksum >> 24) & 0x0F]; Identifier[2] = Hex[(Checksum >> 20) & 0x0F]; Identifier[3] = Hex[(Checksum >> 16) & 0x0F]; Identifier[4] = Hex[(Checksum >> 12) & 0x0F]; Identifier[5] = Hex[(Checksum >> 8) & 0x0F]; Identifier[6] = Hex[(Checksum >> 4) & 0x0F]; Identifier[7] = Hex[Checksum & 0x0F]; Identifier[8] = '-'; Identifier[9] = Hex[(Signature >> 28) & 0x0F]; Identifier[10] = Hex[(Signature >> 24) & 0x0F]; Identifier[11] = Hex[(Signature >> 20) & 0x0F]; Identifier[12] = Hex[(Signature >> 16) & 0x0F]; Identifier[13] = Hex[(Signature >> 12) & 0x0F]; Identifier[14] = Hex[(Signature >> 8) & 0x0F]; Identifier[15] = Hex[(Signature >> 4) & 0x0F]; Identifier[16] = Hex[Signature & 0x0F]; Identifier[17] = '-'; Identifier[18] = 'A'; Identifier[19] = 0; TRACE("Identifier: %s\n", Identifier); }