📄 hardware.c
字号:
/* Set 'ComponentInformation' value */
SetComponentInformation(ControllerKey,
0x28,
0,
0xFFFFFFFF);
/* Set 'Configuration Data' value */
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
2 * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
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 = Isa;
FullResourceDescriptor->BusNumber = 0;
FullResourceDescriptor->PartialResourceList.Version = 1;
FullResourceDescriptor->PartialResourceList.Revision = 1;
FullResourceDescriptor->PartialResourceList.Count = 3;
/* Set Interrupt */
PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
PartialDescriptor->Type = CmResourceTypeInterrupt;
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
PartialDescriptor->u.Interrupt.Level = 1;
PartialDescriptor->u.Interrupt.Vector = 0;
PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
/* Set IO Port 0x60 */
PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[1];
PartialDescriptor->Type = CmResourceTypePort;
PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
PartialDescriptor->u.Port.Start.LowPart = 0x60;
PartialDescriptor->u.Port.Start.HighPart = 0x0;
PartialDescriptor->u.Port.Length = 1;
/* Set IO Port 0x64 */
PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[2];
PartialDescriptor->Type = CmResourceTypePort;
PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
PartialDescriptor->u.Port.Start.LowPart = 0x64;
PartialDescriptor->u.Port.Start.HighPart = 0x0;
PartialDescriptor->u.Port.Length = 1;
/* Set 'Configuration Data' value */
Error = RegSetValue(ControllerKey,
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;
}
DetectKeyboardPeripheral(ControllerKey);
}
static VOID
PS2ControllerWait(VOID)
{
ULONG Timeout;
UCHAR Status;
for (Timeout = 0; Timeout < CONTROLLER_TIMEOUT; Timeout++)
{
Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
if ((Status & CONTROLLER_STATUS_INPUT_BUFFER_FULL) == 0)
return;
/* Sleep for one millisecond */
StallExecutionProcessor(1000);
}
}
static BOOLEAN
DetectPS2AuxPort(VOID)
{
#if 1
/* Current detection is too unreliable. Just do as if
* the PS/2 aux port is always present
*/
return TRUE;
#else
ULONG Loops;
UCHAR Status;
/* Put the value 0x5A in the output buffer using the
* "WriteAuxiliary Device Output Buffer" command (0xD3).
* Poll the Status Register for a while to see if the value really turns up
* in the Data Register. If the KEYBOARD_STATUS_MOUSE_OBF bit is also set
* to 1 in the Status Register, we assume this controller has an
* Auxiliary Port (a.k.a. Mouse Port).
*/
PS2ControllerWait();
WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER);
PS2ControllerWait();
/* 0x5A is a random dummy value */
WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
0x5A);
for (Loops = 0; Loops < 10; Loops++)
{
StallExecutionProcessor(10000);
Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
break;
}
READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
return (Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL);
#endif
}
static BOOLEAN
DetectPS2AuxDevice(VOID)
{
UCHAR Scancode;
UCHAR Status;
ULONG Loops;
BOOLEAN Result = TRUE;
PS2ControllerWait();
WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_CONTROL,
CONTROLLER_COMMAND_WRITE_MOUSE);
PS2ControllerWait();
/* Identify device */
WRITE_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA,
0xF2);
/* Wait for reply */
for (Loops = 0; Loops < 100; Loops++)
{
StallExecutionProcessor(10000);
Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
if ((Status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
break;
}
Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
Result = FALSE;
Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
if (Scancode != 0xFA)
Result = FALSE;
StallExecutionProcessor(10000);
Status = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_STATUS);
if ((Status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0)
Result = FALSE;
Scancode = READ_PORT_UCHAR((PUCHAR)CONTROLLER_REGISTER_DATA);
if (Scancode != 0x00)
Result = FALSE;
return Result;
}
static VOID
DetectPS2Mouse(FRLDRHKEY BusKey)
{
CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
FRLDRHKEY ControllerKey;
FRLDRHKEY PeripheralKey;
LONG Error;
if (DetectPS2AuxPort())
{
DbgPrint((DPRINT_HWDETECT, "Detected PS2 port\n"));
/* Create controller key */
Error = RegCreateKey(BusKey,
L"PointerController\\0",
&ControllerKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "Failed to create controller key\n"));
return;
}
DbgPrint((DPRINT_HWDETECT, "Created key: PointerController\\0\n"));
/* Set 'ComponentInformation' value */
SetComponentInformation(ControllerKey,
0x20,
0,
0xFFFFFFFF);
memset(&FullResourceDescriptor, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
/* Initialize resource descriptor */
FullResourceDescriptor.InterfaceType = Isa;
FullResourceDescriptor.BusNumber = 0;
FullResourceDescriptor.PartialResourceList.Version = 1;
FullResourceDescriptor.PartialResourceList.Revision = 1;
FullResourceDescriptor.PartialResourceList.Count = 1;
/* Set Interrupt */
FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].Type = CmResourceTypeInterrupt;
FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].ShareDisposition = CmResourceShareUndetermined;
FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].Flags = CM_RESOURCE_INTERRUPT_LATCHED;
FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Level = 12;
FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Vector = 0;
FullResourceDescriptor.PartialResourceList.PartialDescriptors[0].u.Interrupt.Affinity = 0xFFFFFFFF;
/* Set 'Configuration Data' value */
Error = RegSetValue(ControllerKey,
L"Configuration Data",
REG_FULL_RESOURCE_DESCRIPTOR,
(PCHAR)&FullResourceDescriptor,
sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue(Configuration Data) failed (Error %u)\n",
(int)Error));
return;
}
if (DetectPS2AuxDevice())
{
DbgPrint((DPRINT_HWDETECT, "Detected PS2 mouse\n"));
/* Create peripheral key */
Error = RegCreateKey(ControllerKey,
L"PointerPeripheral\\0",
&PeripheralKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "Failed to create peripheral key\n"));
return;
}
DbgPrint((DPRINT_HWDETECT, "Created key: PointerPeripheral\\0\n"));
/* Set 'ComponentInformation' value */
SetComponentInformation(PeripheralKey,
0x20,
0,
0xFFFFFFFF);
/* Initialize resource descriptor */
memset(&FullResourceDescriptor, 0, sizeof(CM_FULL_RESOURCE_DESCRIPTOR));
FullResourceDescriptor.InterfaceType = Isa;
FullResourceDescriptor.BusNumber = 0;
FullResourceDescriptor.PartialResourceList.Version = 1;
FullResourceDescriptor.PartialResourceList.Revision = 1;
FullResourceDescriptor.PartialResourceList.Count = 0;
/* Set 'Configuration Data' value */
Error = RegSetValue(PeripheralKey,
L"Configuration Data",
REG_FULL_RESOURCE_DESCRIPTOR,
(PCHAR)&FullResourceDescriptor,
sizeof(CM_FULL_RESOURCE_DESCRIPTOR) -
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue(Configuration Data) failed (Error %u)\n",
(int)Error));
return;
}
/* Set 'Identifier' value */
Error = RegSetValue(PeripheralKey,
L"Identifier",
REG_SZ,
(PCHAR)L"MICROSOFT PS2 MOUSE",
20 * sizeof(WCHAR));
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue() failed (Error %u)\n",
(int)Error));
return;
}
}
}
}
static VOID
DetectDisplayController(FRLDRHKEY BusKey)
{
WCHAR Buffer[80];
FRLDRHKEY ControllerKey;
USHORT VesaVersion;
LONG Error;
Error = RegCreateKey(BusKey,
L"DisplayController\\0",
&ControllerKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "Failed to create controller key\n"));
return;
}
DbgPrint((DPRINT_HWDETECT, "Created key: DisplayController\\0\n"));
/* Set 'ComponentInformation' value */
SetComponentInformation(ControllerKey,
0x00,
0,
0xFFFFFFFF);
/* FIXME: Set 'ComponentInformation' value */
VesaVersion = BiosIsVesaSupported();
if (VesaVersion != 0)
{
DbgPrint((DPRINT_HWDETECT,
"VESA version %c.%c\n",
(VesaVersion >> 8) + '0',
(VesaVersion & 0xFF) + '0'));
}
else
{
DbgPrint((DPRINT_HWDETECT,
"VESA not supported\n"));
}
if (VesaVersion >= 0x0200)
{
wcscpy(Buffer,
L"VBE Display");
}
else
{
wcscpy(Buffer,
L"VGA Display");
}
/* Set 'Identifier' value */
Error = RegSetValue(ControllerKey,
L"Identifier",
REG_SZ,
(PCHAR)Buffer,
(wcslen(Buffer) + 1) * sizeof(WCHAR));
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT,
"RegSetValue() failed (Error %u)\n",
(int)Error));
return;
}
/* FIXME: Add display peripheral (monitor) data */
}
static VOID
DetectIsaBios(FRLDRHKEY SystemKey, ULONG *BusNumber)
{
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
WCHAR Buffer[80];
FRLDRHKEY BusKey;
ULONG Size;
LONG Error;
/* Create new bus key */
swprintf(Buffer,
L"MultifunctionAdapter\\%u", *BusNumber);
Error = RegCreateKey(SystemKey,
Buffer,
&BusKey);
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error));
return;
}
/* Set 'Component Information' value similar to my NT4 box */
SetComponentInformation(BusKey,
0x0,
0x0,
0xFFFFFFFF);
/* Increment bus number */
(*BusNumber)++;
/* Set 'Identifier' value */
Error = RegSetValue(BusKey,
L"Identifier",
REG_SZ,
(PCHAR)L"ISA",
4 * sizeof(WCHAR));
if (Error != ERROR_SUCCESS)
{
DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error));
return;
}
/* Set 'Configuration Data' value */
Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) -
sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
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 = Isa;
FullResourceDescriptor->BusNumber = 0;
FullResourceDescriptor->PartialResourceList.Version = 1;
FullResourceDescriptor->PartialResourceList.Revision = 1;
FullResourceDescriptor->PartialResourceList.Count = 0;
/* Set 'Configuration Data' value */
Error = RegSetValue(BusKey,
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;
}
/* Detect ISA/BIOS devices */
DetectBiosDisks(S
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -