Пример #1
0
static LONG DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
{
    DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
    UCHAR* Ptr = (UCHAR*)Buffer;
    ULONG i, Length, Sectors;
    BOOLEAN ret;

    *Count = 0;
    i = 0;
    while (N > 0)
    {
        Length = N;
        if (Length > DISKREADBUFFER_SIZE)
            Length = DISKREADBUFFER_SIZE;
        Sectors = (Length + Context->SectorSize - 1) / Context->SectorSize;
        ret = MachDiskReadLogicalSectors(
            Context->DriveNumber,
            Context->SectorNumber + Context->SectorOffset + i,
            Sectors,
            (PVOID)DISKREADBUFFER);
        if (!ret)
            return EIO;
        RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length);
        Ptr += Length;
        *Count += Length;
        N -= Length;
        i += Sectors;
    }

    return ESUCCESS;
}
Пример #2
0
VOID
LoadAndBootDrive(IN OperatingSystemItem* OperatingSystem,
                 IN USHORT OperatingSystemVersion)
{
    ULONG_PTR    SectionId;
    PCSTR    SectionName = OperatingSystem->SystemPartition;
    CHAR    SettingName[80];
    CHAR    SettingValue[80];
    UCHAR    DriveNumber;

    // 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;
    }

    if (!IniReadSettingByName(SectionId, "BootDrive", SettingValue, sizeof(SettingValue)))
    {
        UiMessageBox("Boot drive not specified for selected OS!");
        return;
    }

    DriveNumber = DriveMapGetBiosDriveNumber(SettingValue);

    // Now try to read the boot sector (or mbr)
    // If this fails then abort
    if (!MachDiskReadLogicalSectors(DriveNumber, 0, 1, (PVOID)0x7C00))
    {
        UiMessageBox("Unable to read 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();
}
Пример #3
0
PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, ULONG BlockNumber)
{
    PCACHE_BLOCK    CacheBlock = NULL;

    TRACE("CacheInternalAddBlockToCache() BlockNumber = %d\n", BlockNumber);

    // Check the size of the cache so we don't exceed our limits
    CacheInternalCheckCacheSizeLimits(CacheDrive);

    // We will need to add the block to the
    // drive's list of cached blocks. So allocate
    // the block memory.
    CacheBlock = FrLdrTempAlloc(sizeof(CACHE_BLOCK), TAG_CACHE_BLOCK);
    if (CacheBlock == NULL)
    {
        return NULL;
    }

    // Now initialize the structure and
    // allocate room for the block data
    RtlZeroMemory(CacheBlock, sizeof(CACHE_BLOCK));
    CacheBlock->BlockNumber = BlockNumber;
    CacheBlock->BlockData = FrLdrTempAlloc(CacheDrive->BlockSize * CacheDrive->BytesPerSector,
                                           TAG_CACHE_DATA);
    if (CacheBlock->BlockData ==NULL)
    {
        FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK);
        return NULL;
    }

    // Now try to read in the block
    if (!MachDiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, DiskReadBuffer))
    {
        FrLdrTempFree(CacheBlock->BlockData, TAG_CACHE_DATA);
        FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK);
        return NULL;
    }
    RtlCopyMemory(CacheBlock->BlockData, DiskReadBuffer, CacheDrive->BlockSize * CacheDrive->BytesPerSector);

    // Add it to our list of blocks managed by the cache
    InsertTailList(&CacheDrive->CacheBlockHead, &CacheBlock->ListEntry);

    // Update the cache data
    CacheBlockCount++;
    CacheSizeCurrent = CacheBlockCount * (CacheDrive->BlockSize * CacheDrive->BytesPerSector);

    CacheInternalDumpBlockList(CacheDrive);

    return CacheBlock;
}
Пример #4
0
static LONG DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
{
    DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
    UCHAR* Ptr = (UCHAR*)Buffer;
    ULONG Length, TotalSectors, MaxSectors, ReadSectors;
    BOOLEAN ret;
    ULONGLONG SectorOffset;

    TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize;
    MaxSectors   = DISKREADBUFFER_SIZE / Context->SectorSize;
    SectorOffset = Context->SectorNumber + Context->SectorOffset;

    ret = 1;

    while (TotalSectors)
    {
        ReadSectors = TotalSectors;
        if (ReadSectors > MaxSectors)
            ReadSectors = MaxSectors;

        ret = MachDiskReadLogicalSectors(
            Context->DriveNumber,
            SectorOffset,
            ReadSectors,
            (PVOID)DISKREADBUFFER);
        if (!ret)
            break;

        Length = ReadSectors * Context->SectorSize;
        if (Length > N)
            Length = N;

        RtlCopyMemory(Ptr, (PVOID)DISKREADBUFFER, Length);

        Ptr += Length;
        N -= Length;
        SectorOffset += ReadSectors;
        TotalSectors -= ReadSectors;
    }

    *Count = (ULONG)(Ptr - (UCHAR*)Buffer);

    return (!ret) ? EIO : ESUCCESS;
}
Пример #5
0
BOOLEAN DiskReadBootRecord(UCHAR DriveNumber, ULONGLONG LogicalSectorNumber, PMASTER_BOOT_RECORD BootRecord)
{
    ULONG        Index;

    // Read master boot record
    if (!MachDiskReadLogicalSectors(DriveNumber, LogicalSectorNumber, 1, DiskReadBuffer))
    {
        return FALSE;
    }
    RtlCopyMemory(BootRecord, DiskReadBuffer, sizeof(MASTER_BOOT_RECORD));


    TRACE("Dumping partition table for drive 0x%x:\n", DriveNumber);
    TRACE("Boot record logical start sector = %d\n", LogicalSectorNumber);
    TRACE("sizeof(MASTER_BOOT_RECORD) = 0x%x.\n", sizeof(MASTER_BOOT_RECORD));

    for (Index=0; Index<4; Index++)
    {
        TRACE("-------------------------------------------\n");
        TRACE("Partition %d\n", (Index + 1));
        TRACE("BootIndicator: 0x%x\n", BootRecord->PartitionTable[Index].BootIndicator);
        TRACE("StartHead: 0x%x\n", BootRecord->PartitionTable[Index].StartHead);
        TRACE("StartSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].StartSector);
        TRACE("StartCylinder: 0x%x\n", BootRecord->PartitionTable[Index].StartCylinder);
        TRACE("SystemIndicator: 0x%x\n", BootRecord->PartitionTable[Index].SystemIndicator);
        TRACE("EndHead: 0x%x\n", BootRecord->PartitionTable[Index].EndHead);
        TRACE("EndSector (Plus 2 cylinder bits): 0x%x\n", BootRecord->PartitionTable[Index].EndSector);
        TRACE("EndCylinder: 0x%x\n", BootRecord->PartitionTable[Index].EndCylinder);
        TRACE("SectorCountBeforePartition: 0x%x\n", BootRecord->PartitionTable[Index].SectorCountBeforePartition);
        TRACE("PartitionSectorCount: 0x%x\n", BootRecord->PartitionTable[Index].PartitionSectorCount);
    }

    // Check the partition table magic value
    if (BootRecord->MasterBootRecordMagic != 0xaa55)
    {
        return FALSE;
    }

    return TRUE;
}
Пример #6
0
static VOID
DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
                PCONFIGURATION_COMPONENT_DATA BusKey)
{
    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
    PCM_INT13_DRIVE_PARAMETER Int13Drives;
    GEOMETRY Geometry;
    PCONFIGURATION_COMPONENT_DATA DiskKey, ControllerKey;
    UCHAR DiskCount, i;
    ULONG Size;
    BOOLEAN Changed;
    
    /* Count the number of visible drives */
    DiskReportError(FALSE);
    DiskCount = 0;
    
    /* There are some really broken BIOSes out there. There are even BIOSes
        * that happily report success when you ask them to read from non-existent
        * harddisks. So, we set the buffer to known contents first, then try to
        * read. If the BIOS reports success but the buffer contents haven't
        * changed then we fail anyway */
    memset((PVOID) DISKREADBUFFER, 0xcd, 512);
    while (MachDiskReadLogicalSectors(0x80 + DiskCount, 0ULL, 1, (PVOID)DISKREADBUFFER))
    {
        Changed = FALSE;
        for (i = 0; ! Changed && i < 512; i++)
        {
            Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd;
        }
        if (! Changed)
        {
            TRACE("BIOS reports success for disk %d but data didn't change\n",
                  (int)DiskCount);
            break;
        }
        DiskCount++;
        memset((PVOID) DISKREADBUFFER, 0xcd, 512);
    }
    DiskReportError(TRUE);
    TRACE("BIOS reports %d harddisk%s\n",
          (int)DiskCount, (DiskCount == 1) ? "": "s");
    
    //DetectBiosFloppyController(BusKey);
    
    /* Allocate resource descriptor */
    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
        sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
    PartialResourceList = MmHeapAlloc(Size);
    if (PartialResourceList == NULL)
    {
        ERR("Failed to allocate resource descriptor\n");
        return;
    }
    
    /* Initialize resource descriptor */
    memset(PartialResourceList, 0, Size);
    PartialResourceList->Version = 1;
    PartialResourceList->Revision = 1;
    PartialResourceList->Count = 1;
    PartialResourceList->PartialDescriptors[0].Type = CmResourceTypeDeviceSpecific;
    PartialResourceList->PartialDescriptors[0].ShareDisposition = 0;
    PartialResourceList->PartialDescriptors[0].Flags = 0;
    PartialResourceList->PartialDescriptors[0].u.DeviceSpecificData.DataSize =
        sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
    
    /* Get harddisk Int13 geometry data */
    Int13Drives = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
    for (i = 0; i < DiskCount; i++)
    {
        if (MachDiskGetDriveGeometry(0x80 + i, &Geometry))
        {
            Int13Drives[i].DriveSelect = 0x80 + i;
            Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
            Int13Drives[i].SectorsPerTrack = (USHORT)Geometry.Sectors;
            Int13Drives[i].MaxHeads = (USHORT)Geometry.Heads - 1;
            Int13Drives[i].NumberDrives = DiskCount;
            
            TRACE(
                      "Disk %x: %u Cylinders  %u Heads  %u Sectors  %u Bytes\n",
                      0x80 + i,
                      Geometry.Cylinders - 1,
                      Geometry.Heads -1,
                      Geometry.Sectors,
                      Geometry.BytesPerSector);
        }
    }
    
    FldrCreateComponentKey(BusKey,
                           ControllerClass,
                           DiskController,
                           Output | Input,
                           0,
                           0xFFFFFFFF,
                           NULL,
                           PartialResourceList,
                           Size,
                           &ControllerKey);
    TRACE("Created key: DiskController\\0\n");
    
    MmHeapFree(PartialResourceList);
    
    /* Create and fill subkey for each harddisk */
    for (i = 0; i < DiskCount; i++)
    {
        PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
        ULONG Size;
        CHAR Identifier[20];

        /* Get disk values */
        PartialResourceList = GetHarddiskConfigurationData(0x80 + i, &Size);
        GetHarddiskIdentifier(Identifier, 0x80 + i);

        /* Create disk key */
        FldrCreateComponentKey(ControllerKey,
                               PeripheralClass,
                               DiskPeripheral,
                               Output | Input,
                               0,
                               0xFFFFFFFF,
                               Identifier,
                               PartialResourceList,
                               Size,
                               &DiskKey);

        if (PartialResourceList)
            MmHeapFree(PartialResourceList);
    }
}
Пример #7
0
static VOID
GetHarddiskIdentifier(PCHAR Identifier,
		      UCHAR DriveNumber)
{
  PMASTER_BOOT_RECORD Mbr;
  ULONG *Buffer;
  ULONG i;
  ULONG Checksum;
  ULONG Signature;
  CHAR ArcName[256];
  PARTITION_TABLE_ENTRY PartitionTableEntry;

  /* 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 */
  odyssey_arc_disk_info[odyssey_disk_count].Signature = Signature;
  odyssey_arc_disk_info[odyssey_disk_count].CheckSum = Checksum;
  sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)", odyssey_disk_count);
  strcpy(odyssey_arc_strings[odyssey_disk_count], ArcName);
  odyssey_arc_disk_info[odyssey_disk_count].ArcName =
      odyssey_arc_strings[odyssey_disk_count];
  odyssey_disk_count++;

  sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(0)", DriveNumber - 0x80);
  FsRegisterDevice(ArcName, &DiskVtbl);

  /* Add partitions */
  i = 1;
  DiskReportError(FALSE);
  while (XboxDiskGetPartitionEntry(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);
}
Пример #8
0
BOOLEAN
HwInitializeBiosDisks(VOID)
{
    UCHAR DiskCount, DriveNumber;
    ULONG i;
    BOOLEAN Changed;
    CHAR BootPath[512];
    BOOLEAN BootDriveReported = FALSE;

    /* Count the number of visible drives */
    DiskReportError(FALSE);
    DiskCount = 0;
    DriveNumber = 0x80;

    /* There are some really broken BIOSes out there. There are even BIOSes
        * that happily report success when you ask them to read from non-existent
        * harddisks. So, we set the buffer to known contents first, then try to
        * read. If the BIOS reports success but the buffer contents haven't
        * changed then we fail anyway */
    memset((PVOID) DISKREADBUFFER, 0xcd, 512);
    while (MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
    {
        Changed = FALSE;
        for (i = 0; ! Changed && i < 512; i++)
        {
            Changed = ((PUCHAR)DISKREADBUFFER)[i] != 0xcd;
        }
        if (! Changed)
        {
            TRACE("BIOS reports success for disk %d but data didn't change\n",
                      (int)DiskCount);
            break;
        }

        GetHarddiskInformation(DriveNumber);

        if (FrldrBootDrive == DriveNumber)
            BootDriveReported = TRUE;

        DiskCount++;
        DriveNumber++;
        memset((PVOID) DISKREADBUFFER, 0xcd, 512);
    }
    DiskReportError(TRUE);

    /* Get the drive we're booting from */
    MachDiskGetBootPath(BootPath, sizeof(BootPath));

    /* Add it, if it's a floppy or cdrom */
    if ((FrldrBootDrive >= 0x80 && !BootDriveReported) ||
        DiskIsDriveRemovable(FrldrBootDrive))
    {
        /* TODO: Check if it's really a cdrom drive */
        ULONG* Buffer;
        ULONG Checksum = 0;

        /* Read the MBR */
        if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, (PVOID)DISKREADBUFFER))
        {
          ERR("Reading MBR failed\n");
          return FALSE;
        }

        Buffer = (ULONG*)DISKREADBUFFER;

        /* Calculate the MBR checksum */
        for (i = 0; i < 2048 / sizeof(ULONG); 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].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);
        DiskCount++;
    }

    PcBiosDiskCount = DiskCount;
    TRACE("BIOS reports %d harddisk%s\n",
          (int)DiskCount, (DiskCount == 1) ? "": "s");

    return DiskCount != 0;
}