📄 hardware.c
字号:
FullResourceDescriptor->PartialResourceList.Revision = 1;
FullResourceDescriptor->PartialResourceList.Count = 1;
FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type =
CmResourceTypeDeviceSpecific;
// FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
// FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize =
sizeof(CM_DISK_GEOMETRY_DEVICE_DATA);
/* Get pointer to geometry data */
DiskGeometry = (PVOID)(((ULONG_PTR)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
/* Get the disk geometry */
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 if(MachDiskGetDriveGeometry(DriveNumber, &Geometry))
{
DiskGeometry->BytesPerSector = Geometry.BytesPerSector;
DiskGeometry->NumberOfCylinders = Geometry.Cylinders;
DiskGeometry->SectorsPerTrack = Geometry.Sectors;
DiskGeometry->NumberOfHeads = Geometry.Heads;
}
else
{
DbgPrint((DPRINT_HWDETECT, "Reading disk geometry failed\n"));
MmFreeMemory(FullResourceDescriptor);
return;
}
DbgPrint((DPRINT_HWDETECT,
"Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
DriveNumber,
DiskGeometry->NumberOfCylinders,
DiskGeometry->NumberOfHeads,
DiskGeometry->SectorsPerTrack,
DiskGeometry->BytesPerSector));
Error = RegSetValue(DiskKey,
L"Configuration Data",
REG_FULL_RESOURCE_DESCRIPTOR,
(PCHAR) FullResourceDescriptor,
Size);
MmFreeMemory(FullResourceDescriptor);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue(Configuration Data) failed (Error %u)\n",
(int)Error));
}
}
static VOID
SetHarddiskIdentifier(FRLDRHKEY DiskKey,
ULONG DriveNumber)
{
PMASTER_BOOT_RECORD Mbr;
ULONG *Buffer;
ULONG i;
ULONG Checksum;
ULONG Signature;
WCHAR Identifier[20];
CHAR ArcName[256];
LONG Error;
/* Read the MBR */
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
{
DbgPrint((DPRINT_HWDETECT, "Reading MBR failed\n"));
return;
}
Buffer = (ULONG*)DISKREADBUFFER;
Mbr = (PMASTER_BOOT_RECORD)DISKREADBUFFER;
Signature = Mbr->Signature;
DbgPrint((DPRINT_HWDETECT, "Signature: %x\n", Signature));
/* Calculate the MBR checksum */
Checksum = 0;
for (i = 0; i < 128; i++)
{
Checksum += Buffer[i];
}
Checksum = ~Checksum + 1;
DbgPrint((DPRINT_HWDETECT, "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++;
/* 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] = L'-';
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] = L'-';
Identifier[18] = L'A';
Identifier[19] = 0;
DbgPrint((DPRINT_HWDETECT, "Identifier: %S\n", Identifier));
/* Set identifier */
Error = RegSetValue(DiskKey,
L"Identifier",
REG_SZ,
(PCHAR)Identifier,
sizeof(Identifier));
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue(Identifier) failed (Error %u)\n",
(int)Error));
}
}
static VOID
DetectBiosDisks(FRLDRHKEY SystemKey,
FRLDRHKEY BusKey)
{
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_INT13_DRIVE_PARAMETER Int13Drives;
GEOMETRY Geometry;
WCHAR Buffer[80];
FRLDRHKEY DiskKey;
ULONG DiskCount;
ULONG Size;
ULONG i;
LONG Error;
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)
{
DbgPrint((DPRINT_HWDETECT, "BIOS reports success for disk %d but data didn't change\n",
(int)DiskCount));
break;
}
DiskCount++;
memset((PVOID) DISKREADBUFFER, 0xcd, 512);
}
DiskReportError(TRUE);
DbgPrint((DPRINT_HWDETECT, "BIOS reports %d harddisk%s\n",
(int)DiskCount, (DiskCount == 1) ? "": "s"));
/* Allocate resource descriptor */
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
FullResourceDescriptor = MmAllocateMemory(Size);
if (FullResourceDescriptor == NULL)
{
DbgPrint((DPRINT_HWDETECT,
"Failed to allocate resource descriptor\n"));
return;
}
/* Initialize resource descriptor */
memset(FullResourceDescriptor, 0, Size);
FullResourceDescriptor->InterfaceType = InterfaceTypeUndefined;
FullResourceDescriptor->BusNumber = -1;
FullResourceDescriptor->PartialResourceList.Version = 1;
FullResourceDescriptor->PartialResourceList.Revision = 1;
FullResourceDescriptor->PartialResourceList.Count = 1;
FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type =
CmResourceTypeDeviceSpecific;
// FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition =
// FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags =
FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize =
sizeof(CM_INT13_DRIVE_PARAMETER) * DiskCount;
/* Get harddisk Int13 geometry data */
Int13Drives = (PVOID)(((ULONG_PTR)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
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 = Geometry.Sectors;
Int13Drives[i].MaxHeads = Geometry.Heads - 1;
Int13Drives[i].NumberDrives = DiskCount;
DbgPrint((DPRINT_HWDETECT,
"Disk %x: %u Cylinders %u Heads %u Sectors %u Bytes\n",
0x80 + i,
Geometry.Cylinders - 1,
Geometry.Heads -1,
Geometry.Sectors,
Geometry.BytesPerSector));
}
}
/* Set 'Configuration Data' value */
Error = RegSetValue(SystemKey,
L"Configuration Data",
REG_FULL_RESOURCE_DESCRIPTOR,
(PCHAR) FullResourceDescriptor,
Size);
MmFreeMemory(FullResourceDescriptor);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue(Configuration Data) failed (Error %u)\n",
(int)Error));
return;
}
/* Create and fill subkey for each harddisk */
for (i = 0; i < DiskCount; i++)
{
/* Create disk key */
swprintf (Buffer,
L"DiskController\\0\\DiskPeripheral\\%u",
i);
Error = RegCreateKey(BusKey,
Buffer,
&DiskKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "Failed to create drive key\n"));
continue;
}
DbgPrint((DPRINT_HWDETECT, "Created key: %S\n", Buffer));
/* Set disk values */
SetHarddiskConfigurationData(DiskKey, 0x80 + i);
SetHarddiskIdentifier(DiskKey, 0x80 + i);
}
}
static ULONG
GetFloppyCount(VOID)
{
UCHAR Data;
WRITE_PORT_UCHAR((PUCHAR)0x70, 0x10);
Data = READ_PORT_UCHAR((PUCHAR)0x71);
return ((Data & 0xF0) ? 1 : 0) + ((Data & 0x0F) ? 1 : 0);
}
static UCHAR
GetFloppyType(UCHAR DriveNumber)
{
UCHAR Data;
WRITE_PORT_UCHAR((PUCHAR)0x70, 0x10);
Data = READ_PORT_UCHAR((PUCHAR)0x71);
if (DriveNumber == 0)
return Data >> 4;
else if (DriveNumber == 1)
return Data & 0x0F;
return 0;
}
static PVOID
GetInt1eTable(VOID)
{
PUSHORT SegPtr = (PUSHORT)0x7A;
PUSHORT OfsPtr = (PUSHORT)0x78;
return (PVOID)((ULONG_PTR)(((ULONG)(*SegPtr)) << 4) + (ULONG)(*OfsPtr));
}
static VOID
DetectBiosFloppyPeripheral(FRLDRHKEY ControllerKey)
{
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
PCM_FLOPPY_DEVICE_DATA FloppyData;
WCHAR KeyName[32];
WCHAR Identifier[20];
FRLDRHKEY PeripheralKey;
ULONG Size;
LONG Error;
ULONG FloppyNumber;
UCHAR FloppyType;
ULONG MaxDensity[6] = {0, 360, 1200, 720, 1440, 2880};
PUCHAR Ptr;
for (FloppyNumber = 0; FloppyNumber < 2; FloppyNumber++)
{
FloppyType = GetFloppyType(FloppyNumber);
if ((FloppyType > 5) || (FloppyType == 0))
continue;
DiskResetController(FloppyNumber);
Ptr = GetInt1eTable();
swprintf(KeyName, L"FloppyDiskPeripheral\\%u", FloppyNumber);
Error = RegCreateKey(ControllerKey,
KeyName,
&PeripheralKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "Failed to create peripheral key\n"));
return;
}
DbgPrint((DPRINT_HWDETECT, "Created key: %S\n", KeyName));
/* Set 'ComponentInformation' value */
SetComponentInformation(PeripheralKey,
0x0,
FloppyNumber,
0xFFFFFFFF);
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
sizeof(CM_FLOPPY_DEVICE_DATA);
FullResourceDescriptor = MmAllocateMemory(Size);
if (FullResourceDescriptor == NULL)
{
DbgPrint((DPRINT_HWDETECT,
"Failed to allocate resource descriptor\n"));
return;
}
memset(FullResourceDescriptor, 0, Size);
FullResourceDescriptor->InterfaceType = Isa;
FullResourceDescriptor->BusNumber = 0;
FullResourceDescriptor->PartialResourceList.Version = 1;
FullResourceDescriptor->PartialResourceList.Revision = 1;
FullResourceDescriptor->PartialResourceList.Count = 1;
PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
PartialDescriptor->u.DeviceSpecificData.DataSize = sizeof(CM_FLOPPY_DEVICE_DATA);
FloppyData = (PVOID)(((ULONG_PTR)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
FloppyData->Version = 2;
FloppyData->Revision = 0;
FloppyData->MaxDensity = MaxDensity[FloppyType];
FloppyData->MountDensity = 0;
RtlCopyMemory(&FloppyData->StepRateHeadUnloadTime,
Ptr,
11);
FloppyData->MaximumTrackValue = (FloppyType == 1) ? 39 : 79;
FloppyData->DataTransferRate = 0;
/* Set 'Configuration Data' value */
Error = RegSetValue(PeripheralKey,
L"Configuration Data",
REG_FULL_RESOURCE_DESCRIPTOR,
(PCHAR) FullResourceDescriptor,
Size);
MmFreeMemory(FullResourceDescriptor);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue(Configuration Data) failed (Error %u)\n",
(int)Error));
return;
}
/* Set 'Identifier' value */
swprintf(Identifier, L"FLOPPY%u", FloppyNumber + 1);
Error = RegSetValue(PeripheralKey,
L"Identifier",
REG_SZ,
(PCHAR)Identifier,
(wcslen(Identifier) + 1) * sizeof(WCHAR));
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue() failed (Error %u)\n",
(int)Error));
}
}
}
static VOID
DetectBiosFloppyController(FRLDRHKEY SystemKey,
FRLDRHKEY BusKey)
{
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
FRLDRHKEY ControllerKey;
ULONG Size;
LONG Error;
ULONG FloppyCount;
FloppyCount = GetFloppyCount();
DbgPrint((DPRINT_HWDETECT,
"Floppy count: %u\n",
FloppyCount));
if (FloppyCount == 0)
return;
Error = RegCreateKey(BusKey,
L"DiskController\\0",
&ControllerKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "Failed to create controller key\n"));
return;
}
DbgPrint((DPRINT_HWDETECT, "Created key: DiskController\\0\n"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -