mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
[FREELDR] Change GEOMETRY "Sectors" to "SectorsPerTrack" and introduce a new "Sectors" field (#7379)
----
Thanks to the following testers!
- Dmitry Borisov (@disean) for testing on NEC PC-98 emulator;
- Justin Miller (@DarkFire01) for testing on UEFI platform;
- Stanislav Motylkov (@binarymaster) for testing on Xbox emulator
(xemu), both livecd and bootcd.
----
"SectorsPerTrack" is for the legacy Cylinders/Heads/Sectors(PerTrack)
scheme.
- On BIOS-based PCs, INT 13h can return (for LBA-only drives) an invalid
geometry, like: C/H/S = (-1)/(-1)/(-1). This is also what happens in
our hwide.c driver (see IdentifyDevice() for ATAPI devices):
db419efbf2/boot/freeldr/freeldr/arch/drivers/hwide.c (L918-L928)
as well as on VirtualBox for CD-ROMs:
https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Devices/PC/BIOS/disk.c#L155
- Therefore, we cannot reliably calculate a valid total number of sectors
by multiplying the Cylinders*Heads*SectorsPerTrack values. In addition,
such a multiplication could overflow a 32-bit ULONG.
Thus, a separate ULONGLONG Sectors member is required to hold such a
value, that is retrieved differently. For example for ATAPI devices,
our hwide.c driver does return a valid TotalSectors value, even though
CHS values are invalid. Other platforms, like UEFI, just work using
logical block addressing (LBA) values (see EFI_BLOCK_IO_MEDIA).
- uefidisk.c : Per the spec, EFI_BLOCK_IO_MEDIA::LastBlock contains
"The last LBA on the device. [...] For ATA devices, this is reported
in IDENTIFY DEVICE data words 60-61 (i.e., Total number of user
addressable logical sectors) _minus one_.
For SCSI devices, this is reported in the READ CAPACITY parameter
data 'Returned Logical Block Address field' _minus one_."
In other words, LastBlock is a zero-based LBA index quantity. The
corresponding total number of valid "sectors"/blocks of the device
is therefore, (LastBlock + 1).
- Cleanup some old disabled code.
This commit is contained in:
parent
f4be6dc36f
commit
3a7fe56a5d
11 changed files with 93 additions and 104 deletions
|
@ -137,7 +137,7 @@ DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
|
||||||
}
|
}
|
||||||
|
|
||||||
SectorOffset = 0;
|
SectorOffset = 0;
|
||||||
SectorCount = (ULONGLONG)Geometry.Cylinders * Geometry.Heads * Geometry.Sectors;
|
SectorCount = Geometry.Sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
|
Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
|
||||||
|
|
|
@ -121,13 +121,10 @@ PcGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
|
||||||
{
|
{
|
||||||
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
|
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
|
||||||
PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
|
PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
|
||||||
// EXTENDED_GEOMETRY ExtGeometry;
|
|
||||||
GEOMETRY Geometry;
|
GEOMETRY Geometry;
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
|
|
||||||
//
|
/* Initialize returned size */
|
||||||
// Initialize returned size
|
|
||||||
//
|
|
||||||
*pSize = 0;
|
*pSize = 0;
|
||||||
|
|
||||||
/* Set 'Configuration Data' value */
|
/* Set 'Configuration Data' value */
|
||||||
|
@ -155,22 +152,11 @@ PcGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
|
||||||
DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
|
DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
|
||||||
|
|
||||||
/* Get the disk geometry */
|
/* Get the disk geometry */
|
||||||
#if 0 // This is somehow replaced by what PcDiskGetDriveGeometry() does internally.
|
|
||||||
ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
|
|
||||||
if (DiskGetExtendedDriveParameters(DriveNumber, &ExtGeometry, ExtGeometry.Size))
|
|
||||||
{
|
|
||||||
DiskGeometry->BytesPerSector = ExtGeometry.BytesPerSector;
|
|
||||||
DiskGeometry->NumberOfCylinders = ExtGeometry.Cylinders;
|
|
||||||
DiskGeometry->SectorsPerTrack = ExtGeometry.SectorsPerTrack;
|
|
||||||
DiskGeometry->NumberOfHeads = ExtGeometry.Heads;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
if (PcDiskGetDriveGeometry(DriveNumber, &Geometry))
|
if (PcDiskGetDriveGeometry(DriveNumber, &Geometry))
|
||||||
{
|
{
|
||||||
DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
|
DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
|
||||||
DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
|
DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
|
||||||
DiskGeometry->SectorsPerTrack = Geometry.Sectors;
|
DiskGeometry->SectorsPerTrack = Geometry.SectorsPerTrack;
|
||||||
DiskGeometry->NumberOfHeads = Geometry.Heads;
|
DiskGeometry->NumberOfHeads = Geometry.Heads;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -186,9 +172,7 @@ PcGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
|
||||||
DiskGeometry->SectorsPerTrack,
|
DiskGeometry->SectorsPerTrack,
|
||||||
DiskGeometry->BytesPerSector);
|
DiskGeometry->BytesPerSector);
|
||||||
|
|
||||||
//
|
/* Return configuration data */
|
||||||
// Return configuration data
|
|
||||||
//
|
|
||||||
*pSize = Size;
|
*pSize = Size;
|
||||||
return PartialResourceList;
|
return PartialResourceList;
|
||||||
}
|
}
|
||||||
|
|
|
@ -443,8 +443,12 @@ InitDriveGeometry(
|
||||||
Cylinders++;
|
Cylinders++;
|
||||||
DiskDrive->Geometry.Cylinders = Cylinders;
|
DiskDrive->Geometry.Cylinders = Cylinders;
|
||||||
DiskDrive->Geometry.Heads = RegsOut.b.dh + 1;
|
DiskDrive->Geometry.Heads = RegsOut.b.dh + 1;
|
||||||
DiskDrive->Geometry.Sectors = RegsOut.b.cl & 0x3F;
|
DiskDrive->Geometry.SectorsPerTrack = RegsOut.b.cl & 0x3F;
|
||||||
DiskDrive->Geometry.BytesPerSector = 512; /* Just assume 512 bytes per sector */
|
DiskDrive->Geometry.BytesPerSector = 512; /* Just assume 512 bytes per sector */
|
||||||
|
|
||||||
|
DiskDrive->Geometry.Sectors = (ULONGLONG)DiskDrive->Geometry.Cylinders *
|
||||||
|
DiskDrive->Geometry.Heads *
|
||||||
|
DiskDrive->Geometry.SectorsPerTrack;
|
||||||
|
|
||||||
TRACE("Regular Int13h(0x%x) returned:\n"
|
TRACE("Regular Int13h(0x%x) returned:\n"
|
||||||
"Cylinders : 0x%x\n"
|
"Cylinders : 0x%x\n"
|
||||||
|
@ -454,7 +458,7 @@ InitDriveGeometry(
|
||||||
DriveNumber,
|
DriveNumber,
|
||||||
DiskDrive->Geometry.Cylinders,
|
DiskDrive->Geometry.Cylinders,
|
||||||
DiskDrive->Geometry.Heads,
|
DiskDrive->Geometry.Heads,
|
||||||
DiskDrive->Geometry.Sectors, RegsOut.b.cl,
|
DiskDrive->Geometry.SectorsPerTrack, RegsOut.b.cl,
|
||||||
DiskDrive->Geometry.BytesPerSector);
|
DiskDrive->Geometry.BytesPerSector);
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
|
@ -645,40 +649,35 @@ PcDiskReadLogicalSectorsCHS(
|
||||||
ULONG RetryCount;
|
ULONG RetryCount;
|
||||||
|
|
||||||
DriveGeometry = DiskDrive->Geometry;
|
DriveGeometry = DiskDrive->Geometry;
|
||||||
if (DriveGeometry.Sectors == 0 || DriveGeometry.Heads == 0)
|
if (DriveGeometry.SectorsPerTrack == 0 || DriveGeometry.Heads == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
while (SectorCount > 0)
|
while (SectorCount > 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Calculate the physical disk offsets.
|
* Calculate the physical disk offsets.
|
||||||
* Note: DriveGeometry.Sectors < 64
|
* Note: DriveGeometry.SectorsPerTrack < 64
|
||||||
*/
|
*/
|
||||||
PhysicalSector = 1 + (UCHAR)(SectorNumber % DriveGeometry.Sectors);
|
PhysicalSector = 1 + (UCHAR)(SectorNumber % DriveGeometry.SectorsPerTrack);
|
||||||
PhysicalHead = (UCHAR)((SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads);
|
PhysicalHead = (UCHAR)((SectorNumber / DriveGeometry.SectorsPerTrack) % DriveGeometry.Heads);
|
||||||
PhysicalTrack = (ULONG)((SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads);
|
PhysicalTrack = (ULONG)((SectorNumber / DriveGeometry.SectorsPerTrack) / DriveGeometry.Heads);
|
||||||
|
|
||||||
/* Calculate how many sectors we need to read this round */
|
/* Calculate how many sectors we need to read this round */
|
||||||
if (PhysicalSector > 1)
|
if (PhysicalSector > 1)
|
||||||
{
|
{
|
||||||
if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
|
NumberOfSectorsToRead = min(SectorCount,
|
||||||
NumberOfSectorsToRead = (DriveGeometry.Sectors - (PhysicalSector - 1));
|
(DriveGeometry.SectorsPerTrack - (PhysicalSector - 1)));
|
||||||
else
|
|
||||||
NumberOfSectorsToRead = SectorCount;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (SectorCount >= DriveGeometry.Sectors)
|
NumberOfSectorsToRead = min(SectorCount, DriveGeometry.SectorsPerTrack);
|
||||||
NumberOfSectorsToRead = DriveGeometry.Sectors;
|
|
||||||
else
|
|
||||||
NumberOfSectorsToRead = SectorCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the read is within the geometry boundaries */
|
/* Make sure the read is within the geometry boundaries */
|
||||||
if ((PhysicalHead >= DriveGeometry.Heads) ||
|
if ((PhysicalHead >= DriveGeometry.Heads) ||
|
||||||
(PhysicalTrack >= DriveGeometry.Cylinders) ||
|
(PhysicalTrack >= DriveGeometry.Cylinders) ||
|
||||||
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
|
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.SectorsPerTrack + 1)) ||
|
||||||
(PhysicalSector > DriveGeometry.Sectors))
|
(PhysicalSector > DriveGeometry.SectorsPerTrack))
|
||||||
{
|
{
|
||||||
DiskError("Disk read exceeds drive geometry limits.", 0);
|
DiskError("Disk read exceeds drive geometry limits.", 0);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -817,8 +816,9 @@ PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
|
||||||
/* Extended geometry has been initialized, return it */
|
/* Extended geometry has been initialized, return it */
|
||||||
Geometry->Cylinders = DiskDrive->ExtGeometry.Cylinders;
|
Geometry->Cylinders = DiskDrive->ExtGeometry.Cylinders;
|
||||||
Geometry->Heads = DiskDrive->ExtGeometry.Heads;
|
Geometry->Heads = DiskDrive->ExtGeometry.Heads;
|
||||||
Geometry->Sectors = DiskDrive->ExtGeometry.SectorsPerTrack;
|
Geometry->SectorsPerTrack = DiskDrive->ExtGeometry.SectorsPerTrack;
|
||||||
Geometry->BytesPerSector = DiskDrive->ExtGeometry.BytesPerSector;
|
Geometry->BytesPerSector = DiskDrive->ExtGeometry.BytesPerSector;
|
||||||
|
Geometry->Sectors = DiskDrive->ExtGeometry.Sectors;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Fall back to legacy BIOS geometry */
|
/* Fall back to legacy BIOS geometry */
|
||||||
|
@ -845,7 +845,7 @@ PcDiskGetCacheableBlockCount(UCHAR DriveNumber)
|
||||||
if (DiskDrive->Int13ExtensionsSupported)
|
if (DiskDrive->Int13ExtensionsSupported)
|
||||||
return 64;
|
return 64;
|
||||||
else
|
else
|
||||||
return DiskDrive->Geometry.Sectors;
|
return DiskDrive->Geometry.SectorsPerTrack;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -394,7 +394,7 @@ DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
|
||||||
{
|
{
|
||||||
Int13Drives[i].DriveSelect = DriveNumber;
|
Int13Drives[i].DriveSelect = DriveNumber;
|
||||||
Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
|
Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
|
||||||
Int13Drives[i].SectorsPerTrack = (USHORT)Geometry.Sectors;
|
Int13Drives[i].SectorsPerTrack = (USHORT)Geometry.SectorsPerTrack;
|
||||||
Int13Drives[i].MaxHeads = (USHORT)Geometry.Heads - 1;
|
Int13Drives[i].MaxHeads = (USHORT)Geometry.Heads - 1;
|
||||||
Int13Drives[i].NumberDrives = DiskCount;
|
Int13Drives[i].NumberDrives = DiskCount;
|
||||||
|
|
||||||
|
@ -402,7 +402,7 @@ DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
|
||||||
DriveNumber,
|
DriveNumber,
|
||||||
Geometry.Cylinders - 1,
|
Geometry.Cylinders - 1,
|
||||||
Geometry.Heads - 1,
|
Geometry.Heads - 1,
|
||||||
Geometry.Sectors,
|
Geometry.SectorsPerTrack,
|
||||||
Geometry.BytesPerSector);
|
Geometry.BytesPerSector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -268,11 +268,11 @@ Pc98DiskReadLogicalSectorsCHS(
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Calculate the physical disk offsets.
|
* Calculate the physical disk offsets.
|
||||||
* Note: DriveGeometry.Sectors < 64
|
* Note: DriveGeometry.SectorsPerTrack < 64
|
||||||
*/
|
*/
|
||||||
PhysicalSector = (UCHAR)(SectorNumber % DriveGeometry.Sectors);
|
PhysicalSector = (UCHAR)(SectorNumber % DriveGeometry.SectorsPerTrack);
|
||||||
PhysicalHead = (UCHAR)((SectorNumber / DriveGeometry.Sectors) % DriveGeometry.Heads);
|
PhysicalHead = (UCHAR)((SectorNumber / DriveGeometry.SectorsPerTrack) % DriveGeometry.Heads);
|
||||||
PhysicalTrack = (ULONG)((SectorNumber / DriveGeometry.Sectors) / DriveGeometry.Heads);
|
PhysicalTrack = (ULONG)((SectorNumber / DriveGeometry.SectorsPerTrack) / DriveGeometry.Heads);
|
||||||
|
|
||||||
/* Floppy sectors value always start at 1 */
|
/* Floppy sectors value always start at 1 */
|
||||||
if (DiskDrive->Type & DRIVE_FDD)
|
if (DiskDrive->Type & DRIVE_FDD)
|
||||||
|
@ -281,24 +281,19 @@ Pc98DiskReadLogicalSectorsCHS(
|
||||||
/* Calculate how many sectors we need to read this round */
|
/* Calculate how many sectors we need to read this round */
|
||||||
if (PhysicalSector > 1)
|
if (PhysicalSector > 1)
|
||||||
{
|
{
|
||||||
if (SectorCount >= (DriveGeometry.Sectors - (PhysicalSector - 1)))
|
NumberOfSectorsToRead = min(SectorCount,
|
||||||
NumberOfSectorsToRead = (DriveGeometry.Sectors - (PhysicalSector - 1));
|
(DriveGeometry.SectorsPerTrack - (PhysicalSector - 1)));
|
||||||
else
|
|
||||||
NumberOfSectorsToRead = SectorCount;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (SectorCount >= DriveGeometry.Sectors)
|
NumberOfSectorsToRead = min(SectorCount, DriveGeometry.SectorsPerTrack);
|
||||||
NumberOfSectorsToRead = DriveGeometry.Sectors;
|
|
||||||
else
|
|
||||||
NumberOfSectorsToRead = SectorCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the read is within the geometry boundaries */
|
/* Make sure the read is within the geometry boundaries */
|
||||||
if ((PhysicalHead >= DriveGeometry.Heads) ||
|
if ((PhysicalHead >= DriveGeometry.Heads) ||
|
||||||
(PhysicalTrack >= DriveGeometry.Cylinders) ||
|
(PhysicalTrack >= DriveGeometry.Cylinders) ||
|
||||||
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.Sectors + 1)) ||
|
((NumberOfSectorsToRead + PhysicalSector) > (DriveGeometry.SectorsPerTrack + 1)) ||
|
||||||
(PhysicalSector > DriveGeometry.Sectors))
|
(PhysicalSector > DriveGeometry.SectorsPerTrack))
|
||||||
{
|
{
|
||||||
DiskError("Disk read exceeds drive geometry limits.", 0);
|
DiskError("Disk read exceeds drive geometry limits.", 0);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -439,7 +434,7 @@ InitScsiDrive(
|
||||||
|
|
||||||
DiskDrive->Geometry.Cylinders = RegsOut.w.cx;
|
DiskDrive->Geometry.Cylinders = RegsOut.w.cx;
|
||||||
DiskDrive->Geometry.Heads = RegsOut.b.dh;
|
DiskDrive->Geometry.Heads = RegsOut.b.dh;
|
||||||
DiskDrive->Geometry.Sectors = RegsOut.b.dl;
|
DiskDrive->Geometry.SectorsPerTrack = RegsOut.b.dl;
|
||||||
DiskDrive->Geometry.BytesPerSector = RegsOut.w.bx;
|
DiskDrive->Geometry.BytesPerSector = RegsOut.w.bx;
|
||||||
DiskDrive->LBASupported = FALSE;
|
DiskDrive->LBASupported = FALSE;
|
||||||
DiskDrive->IsRemovable = FALSE;
|
DiskDrive->IsRemovable = FALSE;
|
||||||
|
@ -454,7 +449,7 @@ InitScsiDrive(
|
||||||
/* CD-ROM */
|
/* CD-ROM */
|
||||||
DiskDrive->Geometry.Cylinders = 0xFFFF;
|
DiskDrive->Geometry.Cylinders = 0xFFFF;
|
||||||
DiskDrive->Geometry.Heads = 0xFFFF;
|
DiskDrive->Geometry.Heads = 0xFFFF;
|
||||||
DiskDrive->Geometry.Sectors = 0xFFFF;
|
DiskDrive->Geometry.SectorsPerTrack = 0xFFFF;
|
||||||
DiskDrive->Geometry.BytesPerSector = 2048;
|
DiskDrive->Geometry.BytesPerSector = 2048;
|
||||||
DiskDrive->Type = DRIVE_CDROM;
|
DiskDrive->Type = DRIVE_CDROM;
|
||||||
DiskDrive->LBASupported = TRUE;
|
DiskDrive->LBASupported = TRUE;
|
||||||
|
@ -465,7 +460,7 @@ InitScsiDrive(
|
||||||
/* Magneto-optical drive */
|
/* Magneto-optical drive */
|
||||||
DiskDrive->Geometry.Cylinders = 0xFFFF;
|
DiskDrive->Geometry.Cylinders = 0xFFFF;
|
||||||
DiskDrive->Geometry.Heads = 8;
|
DiskDrive->Geometry.Heads = 8;
|
||||||
DiskDrive->Geometry.Sectors = 32;
|
DiskDrive->Geometry.SectorsPerTrack = 32;
|
||||||
DiskDrive->Geometry.BytesPerSector = 512;
|
DiskDrive->Geometry.BytesPerSector = 512;
|
||||||
DiskDrive->Type = DRIVE_MO;
|
DiskDrive->Type = DRIVE_MO;
|
||||||
DiskDrive->LBASupported = TRUE;
|
DiskDrive->LBASupported = TRUE;
|
||||||
|
@ -483,6 +478,10 @@ InitScsiDrive(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DiskDrive->Geometry.Sectors = (ULONGLONG)DiskDrive->Geometry.Cylinders *
|
||||||
|
DiskDrive->Geometry.Heads *
|
||||||
|
DiskDrive->Geometry.SectorsPerTrack;
|
||||||
|
|
||||||
DiskDrive->DaUa = DaUa;
|
DiskDrive->DaUa = DaUa;
|
||||||
DiskDrive->Type |= DRIVE_SCSI;
|
DiskDrive->Type |= DRIVE_SCSI;
|
||||||
DiskDrive->Initialized = TRUE;
|
DiskDrive->Initialized = TRUE;
|
||||||
|
@ -495,7 +494,7 @@ InitScsiDrive(
|
||||||
DaUa,
|
DaUa,
|
||||||
DiskDrive->Geometry.Cylinders,
|
DiskDrive->Geometry.Cylinders,
|
||||||
DiskDrive->Geometry.Heads,
|
DiskDrive->Geometry.Heads,
|
||||||
DiskDrive->Geometry.Sectors,
|
DiskDrive->Geometry.SectorsPerTrack,
|
||||||
DiskDrive->Geometry.BytesPerSector);
|
DiskDrive->Geometry.BytesPerSector);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -513,8 +512,10 @@ InitIdeDrive(
|
||||||
{
|
{
|
||||||
DiskDrive->Geometry.Cylinders = DeviceUnit->Cylinders;
|
DiskDrive->Geometry.Cylinders = DeviceUnit->Cylinders;
|
||||||
DiskDrive->Geometry.Heads = DeviceUnit->Heads;
|
DiskDrive->Geometry.Heads = DeviceUnit->Heads;
|
||||||
DiskDrive->Geometry.Sectors = DeviceUnit->Sectors;
|
DiskDrive->Geometry.SectorsPerTrack = DeviceUnit->Sectors;
|
||||||
DiskDrive->Geometry.BytesPerSector = DeviceUnit->SectorSize;
|
DiskDrive->Geometry.BytesPerSector = DeviceUnit->SectorSize;
|
||||||
|
DiskDrive->Geometry.Sectors = DeviceUnit->TotalSectors;
|
||||||
|
|
||||||
DiskDrive->DaUa = 0xFF;
|
DiskDrive->DaUa = 0xFF;
|
||||||
DiskDrive->IdeUnitNumber = UnitNumber;
|
DiskDrive->IdeUnitNumber = UnitNumber;
|
||||||
DiskDrive->Type = DRIVE_IDE | DRIVE_CDROM;
|
DiskDrive->Type = DRIVE_IDE | DRIVE_CDROM;
|
||||||
|
@ -530,7 +531,7 @@ InitIdeDrive(
|
||||||
UnitNumber,
|
UnitNumber,
|
||||||
DiskDrive->Geometry.Cylinders,
|
DiskDrive->Geometry.Cylinders,
|
||||||
DiskDrive->Geometry.Heads,
|
DiskDrive->Geometry.Heads,
|
||||||
DiskDrive->Geometry.Sectors,
|
DiskDrive->Geometry.SectorsPerTrack,
|
||||||
DiskDrive->Geometry.BytesPerSector);
|
DiskDrive->Geometry.BytesPerSector);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -582,8 +583,13 @@ InitHardDrive(
|
||||||
|
|
||||||
DiskDrive->Geometry.Cylinders = RegsOut.w.cx;
|
DiskDrive->Geometry.Cylinders = RegsOut.w.cx;
|
||||||
DiskDrive->Geometry.Heads = RegsOut.b.dh;
|
DiskDrive->Geometry.Heads = RegsOut.b.dh;
|
||||||
DiskDrive->Geometry.Sectors = RegsOut.b.dl;
|
DiskDrive->Geometry.SectorsPerTrack = RegsOut.b.dl;
|
||||||
DiskDrive->Geometry.BytesPerSector = RegsOut.w.bx;
|
DiskDrive->Geometry.BytesPerSector = RegsOut.w.bx;
|
||||||
|
|
||||||
|
DiskDrive->Geometry.Sectors = (ULONGLONG)DiskDrive->Geometry.Cylinders *
|
||||||
|
DiskDrive->Geometry.Heads *
|
||||||
|
DiskDrive->Geometry.SectorsPerTrack;
|
||||||
|
|
||||||
DiskDrive->DaUa = DaUa;
|
DiskDrive->DaUa = DaUa;
|
||||||
DiskDrive->Type = DRIVE_IDE;
|
DiskDrive->Type = DRIVE_IDE;
|
||||||
DiskDrive->LBASupported = FALSE;
|
DiskDrive->LBASupported = FALSE;
|
||||||
|
@ -598,7 +604,7 @@ InitHardDrive(
|
||||||
DaUa,
|
DaUa,
|
||||||
DiskDrive->Geometry.Cylinders,
|
DiskDrive->Geometry.Cylinders,
|
||||||
DiskDrive->Geometry.Heads,
|
DiskDrive->Geometry.Heads,
|
||||||
DiskDrive->Geometry.Sectors,
|
DiskDrive->Geometry.SectorsPerTrack,
|
||||||
DiskDrive->Geometry.BytesPerSector);
|
DiskDrive->Geometry.BytesPerSector);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -647,14 +653,14 @@ InitFloppyDrive(
|
||||||
/* 320 kB 2DD */
|
/* 320 kB 2DD */
|
||||||
DiskDrive->Geometry.Cylinders = 80;
|
DiskDrive->Geometry.Cylinders = 80;
|
||||||
DiskDrive->Geometry.Heads = 2;
|
DiskDrive->Geometry.Heads = 2;
|
||||||
DiskDrive->Geometry.Sectors = 16;
|
DiskDrive->Geometry.SectorsPerTrack = 16;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* 1 MB 2HD */
|
/* 1 MB 2HD */
|
||||||
DiskDrive->Geometry.Cylinders = 77;
|
DiskDrive->Geometry.Cylinders = 77;
|
||||||
DiskDrive->Geometry.Heads = 2;
|
DiskDrive->Geometry.Heads = 2;
|
||||||
DiskDrive->Geometry.Sectors = 26;
|
DiskDrive->Geometry.SectorsPerTrack = 26;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -664,21 +670,21 @@ InitFloppyDrive(
|
||||||
/* 1.44 MB 2HD */
|
/* 1.44 MB 2HD */
|
||||||
DiskDrive->Geometry.Cylinders = 80;
|
DiskDrive->Geometry.Cylinders = 80;
|
||||||
DiskDrive->Geometry.Heads = 2;
|
DiskDrive->Geometry.Heads = 2;
|
||||||
DiskDrive->Geometry.Sectors = 18;
|
DiskDrive->Geometry.SectorsPerTrack = 18;
|
||||||
}
|
}
|
||||||
else if (DeviceAddress == 0x70 || DeviceAddress == 0xF0)
|
else if (DeviceAddress == 0x70 || DeviceAddress == 0xF0)
|
||||||
{
|
{
|
||||||
/* 720/640 kB 2DD */
|
/* 720/640 kB 2DD */
|
||||||
DiskDrive->Geometry.Cylinders = 80;
|
DiskDrive->Geometry.Cylinders = 80;
|
||||||
DiskDrive->Geometry.Heads = 2;
|
DiskDrive->Geometry.Heads = 2;
|
||||||
DiskDrive->Geometry.Sectors = 8;
|
DiskDrive->Geometry.SectorsPerTrack = 8;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* 1.2 MB 2HC */
|
/* 1.2 MB 2HC */
|
||||||
DiskDrive->Geometry.Cylinders = 80;
|
DiskDrive->Geometry.Cylinders = 80;
|
||||||
DiskDrive->Geometry.Heads = 2;
|
DiskDrive->Geometry.Heads = 2;
|
||||||
DiskDrive->Geometry.Sectors = 15;
|
DiskDrive->Geometry.SectorsPerTrack = 15;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -686,7 +692,7 @@ InitFloppyDrive(
|
||||||
/* 1.25 MB 2HD */
|
/* 1.25 MB 2HD */
|
||||||
DiskDrive->Geometry.Cylinders = 77;
|
DiskDrive->Geometry.Cylinders = 77;
|
||||||
DiskDrive->Geometry.Heads = 2;
|
DiskDrive->Geometry.Heads = 2;
|
||||||
DiskDrive->Geometry.Sectors = 8;
|
DiskDrive->Geometry.SectorsPerTrack = 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -695,6 +701,10 @@ InitFloppyDrive(
|
||||||
}
|
}
|
||||||
|
|
||||||
DiskDrive->Geometry.BytesPerSector = BytesPerSector;
|
DiskDrive->Geometry.BytesPerSector = BytesPerSector;
|
||||||
|
DiskDrive->Geometry.Sectors = (ULONGLONG)DiskDrive->Geometry.Cylinders *
|
||||||
|
DiskDrive->Geometry.Heads *
|
||||||
|
DiskDrive->Geometry.SectorsPerTrack;
|
||||||
|
|
||||||
DiskDrive->DaUa = DaUa;
|
DiskDrive->DaUa = DaUa;
|
||||||
DiskDrive->Type = DRIVE_FDD;
|
DiskDrive->Type = DRIVE_FDD;
|
||||||
DiskDrive->LBASupported = FALSE;
|
DiskDrive->LBASupported = FALSE;
|
||||||
|
@ -709,7 +719,7 @@ InitFloppyDrive(
|
||||||
DaUa,
|
DaUa,
|
||||||
DiskDrive->Geometry.Cylinders,
|
DiskDrive->Geometry.Cylinders,
|
||||||
DiskDrive->Geometry.Heads,
|
DiskDrive->Geometry.Heads,
|
||||||
DiskDrive->Geometry.Sectors,
|
DiskDrive->Geometry.SectorsPerTrack,
|
||||||
DiskDrive->Geometry.BytesPerSector);
|
DiskDrive->Geometry.BytesPerSector);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -898,5 +908,5 @@ Pc98DiskGetCacheableBlockCount(UCHAR DriveNumber)
|
||||||
if (DiskDrive->LBASupported)
|
if (DiskDrive->LBASupported)
|
||||||
return 64;
|
return 64;
|
||||||
else
|
else
|
||||||
return DiskDrive->Geometry.Sectors;
|
return DiskDrive->Geometry.SectorsPerTrack;
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,7 +349,7 @@ Pc98GetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
|
||||||
{
|
{
|
||||||
DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
|
DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
|
||||||
DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
|
DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
|
||||||
DiskGeometry->SectorsPerTrack = Geometry.Sectors;
|
DiskGeometry->SectorsPerTrack = Geometry.SectorsPerTrack;
|
||||||
DiskGeometry->NumberOfHeads = Geometry.Heads;
|
DiskGeometry->NumberOfHeads = Geometry.Heads;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -423,7 +423,7 @@ DetectBiosDisks(
|
||||||
{
|
{
|
||||||
Int13Drives[i].DriveSelect = DriveNumber;
|
Int13Drives[i].DriveSelect = DriveNumber;
|
||||||
Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
|
Int13Drives[i].MaxCylinders = Geometry.Cylinders - 1;
|
||||||
Int13Drives[i].SectorsPerTrack = (USHORT)Geometry.Sectors;
|
Int13Drives[i].SectorsPerTrack = (USHORT)Geometry.SectorsPerTrack;
|
||||||
Int13Drives[i].MaxHeads = (USHORT)Geometry.Heads - 1;
|
Int13Drives[i].MaxHeads = (USHORT)Geometry.Heads - 1;
|
||||||
Int13Drives[i].NumberDrives = DiskCount;
|
Int13Drives[i].NumberDrives = DiskCount;
|
||||||
|
|
||||||
|
@ -431,7 +431,7 @@ DetectBiosDisks(
|
||||||
DriveNumber,
|
DriveNumber,
|
||||||
Geometry.Cylinders - 1,
|
Geometry.Cylinders - 1,
|
||||||
Geometry.Heads - 1,
|
Geometry.Heads - 1,
|
||||||
Geometry.Sectors,
|
Geometry.SectorsPerTrack,
|
||||||
Geometry.BytesPerSector);
|
Geometry.BytesPerSector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,13 +95,10 @@ XboxGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
|
||||||
{
|
{
|
||||||
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
|
PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
|
||||||
PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
|
PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
|
||||||
//EXTENDED_GEOMETRY ExtGeometry;
|
|
||||||
GEOMETRY Geometry;
|
GEOMETRY Geometry;
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
|
|
||||||
//
|
/* Initialize returned size */
|
||||||
// Initialize returned size
|
|
||||||
//
|
|
||||||
*pSize = 0;
|
*pSize = 0;
|
||||||
|
|
||||||
/* Set 'Configuration Data' value */
|
/* Set 'Configuration Data' value */
|
||||||
|
@ -129,13 +126,11 @@ XboxGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
|
||||||
DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
|
DiskGeometry = (PVOID)(((ULONG_PTR)PartialResourceList) + sizeof(CM_PARTIAL_RESOURCE_LIST));
|
||||||
|
|
||||||
/* Get the disk geometry */
|
/* Get the disk geometry */
|
||||||
//ExtGeometry.Size = sizeof(EXTENDED_GEOMETRY);
|
|
||||||
|
|
||||||
if (XboxDiskGetDriveGeometry(DriveNumber, &Geometry))
|
if (XboxDiskGetDriveGeometry(DriveNumber, &Geometry))
|
||||||
{
|
{
|
||||||
DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
|
DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
|
||||||
DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
|
DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
|
||||||
DiskGeometry->SectorsPerTrack = Geometry.Sectors;
|
DiskGeometry->SectorsPerTrack = Geometry.SectorsPerTrack;
|
||||||
DiskGeometry->NumberOfHeads = Geometry.Heads;
|
DiskGeometry->NumberOfHeads = Geometry.Heads;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -151,9 +146,7 @@ XboxGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* pSize)
|
||||||
DiskGeometry->SectorsPerTrack,
|
DiskGeometry->SectorsPerTrack,
|
||||||
DiskGeometry->BytesPerSector);
|
DiskGeometry->BytesPerSector);
|
||||||
|
|
||||||
//
|
/* Return configuration data */
|
||||||
// Return configuration data
|
|
||||||
//
|
|
||||||
*pSize = Size;
|
*pSize = Size;
|
||||||
return PartialResourceList;
|
return PartialResourceList;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,8 +112,9 @@ XboxDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
|
||||||
|
|
||||||
Geometry->Cylinders = DeviceUnit->Cylinders;
|
Geometry->Cylinders = DeviceUnit->Cylinders;
|
||||||
Geometry->Heads = DeviceUnit->Heads;
|
Geometry->Heads = DeviceUnit->Heads;
|
||||||
Geometry->Sectors = DeviceUnit->Sectors;
|
Geometry->SectorsPerTrack = DeviceUnit->Sectors;
|
||||||
Geometry->BytesPerSector = DeviceUnit->SectorSize;
|
Geometry->BytesPerSector = DeviceUnit->SectorSize;
|
||||||
|
Geometry->Sectors = DeviceUnit->TotalSectors;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,7 +185,7 @@ UefiDiskOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
|
||||||
}
|
}
|
||||||
|
|
||||||
SectorOffset = 0;
|
SectorOffset = 0;
|
||||||
SectorCount = (ULONGLONG)Geometry.Cylinders * Geometry.Heads * Geometry.Sectors;
|
SectorCount = Geometry.Sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
|
Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
|
||||||
|
@ -577,10 +577,11 @@ UefiDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
|
||||||
|
|
||||||
UefiDriveNumber = InternalUefiDisk[DriveNumber - FIRST_BIOS_DISK].UefiRootNumber;
|
UefiDriveNumber = InternalUefiDisk[DriveNumber - FIRST_BIOS_DISK].UefiRootNumber;
|
||||||
GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber], &bioGuid, (void**)&bio);
|
GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber], &bioGuid, (void**)&bio);
|
||||||
Geometry->Cylinders = 1; // Not relevant for the UEFI BIO protocol
|
Geometry->Cylinders = 1; // Not relevant for the UEFI BIO protocol
|
||||||
Geometry->Heads = 1; // Not relevant for the UEFI BIO protocol
|
Geometry->Heads = 1; // Not relevant for the UEFI BIO protocol
|
||||||
Geometry->Sectors = bio->Media->LastBlock; // Number of sectors per track
|
Geometry->SectorsPerTrack = (bio->Media->LastBlock + 1);
|
||||||
Geometry->BytesPerSector = bio->Media->BlockSize; // Number of bytes per sector
|
Geometry->BytesPerSector = bio->Media->BlockSize;
|
||||||
|
Geometry->Sectors = (bio->Media->LastBlock + 1);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -592,5 +593,5 @@ UefiDiskGetCacheableBlockCount(UCHAR DriveNumber)
|
||||||
TRACE("UefiDiskGetCacheableBlockCount: DriveNumber: %d\n", UefiDriveNumber);
|
TRACE("UefiDiskGetCacheableBlockCount: DriveNumber: %d\n", UefiDriveNumber);
|
||||||
|
|
||||||
GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber], &bioGuid, (void**)&bio);
|
GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber], &bioGuid, (void**)&bio);
|
||||||
return bio->Media->LastBlock;
|
return (bio->Media->LastBlock + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,6 @@ extern ULONG FrldrBootPartition;
|
||||||
|
|
||||||
LONG DiskReportError(BOOLEAN bShowError);
|
LONG DiskReportError(BOOLEAN bShowError);
|
||||||
BOOLEAN DiskResetController(UCHAR DriveNumber);
|
BOOLEAN DiskResetController(UCHAR DriveNumber);
|
||||||
// BOOLEAN DiskGetExtendedDriveParameters(UCHAR DriveNumber, PVOID Buffer, USHORT BufferSize);
|
|
||||||
|
|
||||||
BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer);
|
BOOLEAN PcDiskReadLogicalSectors(UCHAR DriveNumber, ULONGLONG SectorNumber, ULONG SectorCount, PVOID Buffer);
|
||||||
BOOLEAN PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY DriveGeometry);
|
BOOLEAN PcDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY DriveGeometry);
|
||||||
|
|
|
@ -21,19 +21,22 @@
|
||||||
|
|
||||||
#include <reactos/rosioctl.h>
|
#include <reactos/rosioctl.h>
|
||||||
|
|
||||||
|
/* FreeLoader-specific disk geometry structure */
|
||||||
typedef struct _GEOMETRY
|
typedef struct _GEOMETRY
|
||||||
{
|
{
|
||||||
ULONG Cylinders; // Number of cylinders on the disk
|
ULONG Cylinders; ///< Number of cylinders on the disk
|
||||||
ULONG Heads; // Number of heads on the disk
|
ULONG Heads; ///< Number of heads on the disk
|
||||||
ULONG Sectors; // Number of sectors per track
|
ULONG SectorsPerTrack; ///< Number of sectors per track
|
||||||
ULONG BytesPerSector; // Number of bytes per sector
|
ULONG BytesPerSector; ///< Number of bytes per sector
|
||||||
|
ULONGLONG Sectors; ///< Total number of disk sectors/LBA blocks
|
||||||
} GEOMETRY, *PGEOMETRY;
|
} GEOMETRY, *PGEOMETRY;
|
||||||
|
|
||||||
/*
|
|
||||||
* Extended disk geometry (Int13 / ah=48h)
|
|
||||||
*/
|
|
||||||
#include <pshpack1.h>
|
#include <pshpack1.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extended disk geometry (Int13 / AH=48h)
|
||||||
|
* See also ntdddisk.h DISK_EX_INT13_INFO
|
||||||
|
*/
|
||||||
typedef struct _EXTENDED_GEOMETRY
|
typedef struct _EXTENDED_GEOMETRY
|
||||||
{
|
{
|
||||||
USHORT Size;
|
USHORT Size;
|
||||||
|
@ -44,7 +47,6 @@ typedef struct _EXTENDED_GEOMETRY
|
||||||
ULONGLONG Sectors;
|
ULONGLONG Sectors;
|
||||||
USHORT BytesPerSector;
|
USHORT BytesPerSector;
|
||||||
ULONG PDPTE;
|
ULONG PDPTE;
|
||||||
|
|
||||||
} EXTENDED_GEOMETRY, *PEXTENDED_GEOMETRY;
|
} EXTENDED_GEOMETRY, *PEXTENDED_GEOMETRY;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -63,7 +65,6 @@ typedef struct _PARTITION_TABLE_ENTRY
|
||||||
UCHAR EndCylinder; // Ending cylinder# (low order bits of cylinder #)
|
UCHAR EndCylinder; // Ending cylinder# (low order bits of cylinder #)
|
||||||
ULONG SectorCountBeforePartition; // Number of sectors preceding the partition
|
ULONG SectorCountBeforePartition; // Number of sectors preceding the partition
|
||||||
ULONG PartitionSectorCount; // Number of sectors in the partition
|
ULONG PartitionSectorCount; // Number of sectors in the partition
|
||||||
|
|
||||||
} PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
|
} PARTITION_TABLE_ENTRY, *PPARTITION_TABLE_ENTRY;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -76,8 +77,8 @@ typedef struct _MASTER_BOOT_RECORD
|
||||||
USHORT Reserved; /* 0x1BC */
|
USHORT Reserved; /* 0x1BC */
|
||||||
PARTITION_TABLE_ENTRY PartitionTable[4]; /* 0x1BE */
|
PARTITION_TABLE_ENTRY PartitionTable[4]; /* 0x1BE */
|
||||||
USHORT MasterBootRecordMagic; /* 0x1FE */
|
USHORT MasterBootRecordMagic; /* 0x1FE */
|
||||||
|
|
||||||
} MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD;
|
} MASTER_BOOT_RECORD, *PMASTER_BOOT_RECORD;
|
||||||
|
|
||||||
#include <poppack.h>
|
#include <poppack.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue