📄 hardware.c
字号:
/* Set 'ComponentInformation' value */
SetComponentInformation(ControllerKey,
0x64,
0,
0xFFFFFFFF);
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;
}
memset(FullResourceDescriptor, 0, Size);
/* Initialize resource descriptor */
FullResourceDescriptor->InterfaceType = Isa;
FullResourceDescriptor->BusNumber = 0;
FullResourceDescriptor->PartialResourceList.Version = 1;
FullResourceDescriptor->PartialResourceList.Revision = 1;
FullResourceDescriptor->PartialResourceList.Count = 3;
/* Set IO Port */
PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[0];
PartialDescriptor->Type = CmResourceTypePort;
PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
PartialDescriptor->Flags = CM_RESOURCE_PORT_IO;
PartialDescriptor->u.Port.Start.LowPart = 0x03F0;
PartialDescriptor->u.Port.Start.HighPart = 0x0;
PartialDescriptor->u.Port.Length = 8;
/* Set Interrupt */
PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[1];
PartialDescriptor->Type = CmResourceTypeInterrupt;
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
PartialDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
PartialDescriptor->u.Interrupt.Level = 6;
PartialDescriptor->u.Interrupt.Vector = 0;
PartialDescriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
/* Set DMA channel */
PartialDescriptor = &FullResourceDescriptor->PartialResourceList.PartialDescriptors[2];
PartialDescriptor->Type = CmResourceTypeDma;
PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
PartialDescriptor->Flags = 0;
PartialDescriptor->u.Dma.Channel = 2;
PartialDescriptor->u.Dma.Port = 0;
/* 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;
}
DetectBiosFloppyPeripheral(ControllerKey);
}
static VOID
InitializeSerialPort(ULONG Port,
ULONG LineControl)
{
WRITE_PORT_UCHAR((PUCHAR)Port + 3, 0x80); /* set DLAB on */
WRITE_PORT_UCHAR((PUCHAR)Port, 0x60); /* speed LO byte */
WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0); /* speed HI byte */
WRITE_PORT_UCHAR((PUCHAR)Port + 3, LineControl);
WRITE_PORT_UCHAR((PUCHAR)Port + 1, 0); /* set comm and DLAB to 0 */
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x09); /* DR int enable */
READ_PORT_UCHAR((PUCHAR)Port + 5); /* clear error bits */
}
static ULONG
DetectSerialMouse(ULONG Port)
{
CHAR Buffer[4];
ULONG i;
ULONG TimeOut;
UCHAR LineControl;
/* Shutdown mouse or something like that */
LineControl = READ_PORT_UCHAR((PUCHAR)Port + 4);
WRITE_PORT_UCHAR((PUCHAR)Port + 4, (LineControl & ~0x02) | 0x01);
StallExecutionProcessor(100000);
/*
* Clear buffer
* Maybe there is no serial port although BIOS reported one (this
* is the case on Apple hardware), or the serial port is misbehaving,
* therefore we must give up after some time.
*/
TimeOut = 200;
while (READ_PORT_UCHAR((PUCHAR)Port + 5) & 0x01)
{
if (--TimeOut == 0)
return MOUSE_TYPE_NONE;
READ_PORT_UCHAR((PUCHAR)Port);
}
/*
* Send modem control with 'Data Terminal Ready', 'Request To Send' and
* 'Output Line 2' message. This enables mouse to identify.
*/
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x0b);
/* Wait 10 milliseconds for the mouse getting ready */
StallExecutionProcessor(10000);
/* Read first four bytes, which contains Microsoft Mouse signs */
TimeOut = 200;
for (i = 0; i < 4; i++)
{
while (((READ_PORT_UCHAR((PUCHAR)Port + 5) & 1) == 0) && (TimeOut > 0))
{
StallExecutionProcessor(1000);
--TimeOut;
if (TimeOut == 0)
return MOUSE_TYPE_NONE;
}
Buffer[i] = READ_PORT_UCHAR((PUCHAR)Port);
}
DbgPrint((DPRINT_HWDETECT,
"Mouse data: %x %x %x %x\n",
Buffer[0],Buffer[1],Buffer[2],Buffer[3]));
/* Check that four bytes for signs */
for (i = 0; i < 4; ++i)
{
if (Buffer[i] == 'B')
{
/* Sign for Microsoft Ballpoint */
// DbgPrint("Microsoft Ballpoint device detected\n");
// DbgPrint("THIS DEVICE IS NOT SUPPORTED, YET\n");
return MOUSE_TYPE_NONE;
}
else if (Buffer[i] == 'M')
{
/* Sign for Microsoft Mouse protocol followed by button specifier */
if (i == 3)
{
/* Overflow Error */
return MOUSE_TYPE_NONE;
}
switch (Buffer[i + 1])
{
case '3':
DbgPrint((DPRINT_HWDETECT,
"Microsoft Mouse with 3-buttons detected\n"));
return MOUSE_TYPE_LOGITECH;
case 'Z':
DbgPrint((DPRINT_HWDETECT,
"Microsoft Wheel Mouse detected\n"));
return MOUSE_TYPE_WHEELZ;
/* case '2': */
default:
DbgPrint((DPRINT_HWDETECT,
"Microsoft Mouse with 2-buttons detected\n"));
return MOUSE_TYPE_MICROSOFT;
}
}
}
return MOUSE_TYPE_NONE;
}
static ULONG
GetSerialMousePnpId(ULONG Port, char *Buffer)
{
ULONG TimeOut;
ULONG i = 0;
char c;
char x;
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x09);
/* Wait 10 milliseconds for the mouse getting ready */
StallExecutionProcessor(10000);
WRITE_PORT_UCHAR((PUCHAR)Port + 4, 0x0b);
StallExecutionProcessor(10000);
for (;;)
{
TimeOut = 200;
while (((READ_PORT_UCHAR((PUCHAR)Port + 5) & 1) == 0) && (TimeOut > 0))
{
StallExecutionProcessor(1000);
--TimeOut;
if (TimeOut == 0)
{
return 0;
}
}
c = READ_PORT_UCHAR((PUCHAR)Port);
if (c == 0x08 || c == 0x28)
break;
}
Buffer[i++] = c;
x = c + 1;
for (;;)
{
TimeOut = 200;
while (((READ_PORT_UCHAR((PUCHAR)Port + 5) & 1) == 0) && (TimeOut > 0))
{
StallExecutionProcessor(1000);
--TimeOut;
if (TimeOut == 0)
return 0;
}
c = READ_PORT_UCHAR((PUCHAR)Port);
Buffer[i++] = c;
if (c == x)
break;
if (i >= 256)
break;
}
return i;
}
static VOID
DetectSerialPointerPeripheral(FRLDRHKEY ControllerKey,
ULONG Base)
{
CM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
char Buffer[256];
WCHAR Identifier[256];
FRLDRHKEY PeripheralKey;
ULONG MouseType;
ULONG Length;
ULONG i;
ULONG j;
ULONG k;
LONG Error;
DbgPrint((DPRINT_HWDETECT,
"DetectSerialPointerPeripheral()\n"));
Identifier[0] = 0;
InitializeSerialPort(Base, 2);
MouseType = DetectSerialMouse(Base);
if (MouseType != MOUSE_TYPE_NONE)
{
Length = GetSerialMousePnpId(Base, Buffer);
DbgPrint((DPRINT_HWDETECT,
"PnP ID length: %u\n",
Length));
if (Length != 0)
{
/* Convert PnP sting to ASCII */
if (Buffer[0] == 0x08)
{
for (i = 0; i < Length; i++)
Buffer[i] += 0x20;
}
Buffer[Length] = 0;
DbgPrint((DPRINT_HWDETECT,
"PnP ID string: %s\n",
Buffer));
/* Copy PnpId string */
for (i = 0; i < 7; i++)
{
Identifier[i] = Buffer[3+i];
}
memcpy(&Identifier[7],
L" - ",
3 * sizeof(WCHAR));
/* Skip device serial number */
i = 10;
if (Buffer[i] == '\\')
{
for (j = ++i; i < Length; ++i)
{
if (Buffer[i] == '\\')
break;
}
if (i >= Length)
i -= 3;
}
/* Skip PnP class */
if (Buffer[i] == '\\')
{
for (j = ++i; i < Length; ++i)
{
if (Buffer[i] == '\\')
break;
}
if (i >= Length)
i -= 3;
}
/* Skip compatible PnP Id */
if (Buffer[i] == '\\')
{
for (j = ++i; i < Length; ++i)
{
if (Buffer[i] == '\\')
break;
}
if (Buffer[j] == '*')
++j;
if (i >= Length)
i -= 3;
}
/* Get product description */
if (Buffer[i] == '\\')
{
for (j = ++i; i < Length; ++i)
{
if (Buffer[i] == ';')
break;
}
if (i >= Length)
i -= 3;
if (i > j + 1)
{
for (k = 0; k < i - j; k++)
{
Identifier[k + 10] = Buffer[k + j];
}
Identifier[10 + (i-j)] = 0;
}
}
DbgPrint((DPRINT_HWDETECT,
"Identifier string: %S\n",
Identifier));
}
if (Length == 0 || wcslen(Identifier) < 11)
{
switch (MouseType)
{
case MOUSE_TYPE_LOGITECH:
wcscpy (Identifier,
L"LOGITECH SERIAL MOUSE");
break;
case MOUSE_TYPE_WHEELZ:
wcscpy (Identifier,
L"MICROSOFT SERIAL MOUSE WITH WHEEL");
break;
case MOUSE_TYPE_MICROSOFT:
default:
wcscpy (Identifier,
L"MICROSOFT SERIAL MOUSE");
break;
}
}
/* Create 'PointerPeripheral' 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);
/* Set 'Configuration Data' value */
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;
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));
}
/* Set 'Identifier' value */
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
DetectSerialPorts(FRLDRHKEY BusKey)
{
PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
PCM_SERIAL_DEVICE_DATA SerialDeviceData;
ULONG Irq[4] = {4, 3, 4, 3};
ULONG Base;
WCHAR Buffer[80];
PUSHORT BasePtr;
ULONG ControllerNumber = 0;
FRLDRHKEY ControllerKey;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -