📄 enum.c
字号:
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE, ("Setting DTR...\n"));
status = Serenum_IoSyncIoctl(IOCTL_SERIAL_SET_DTR, FALSE,
FdoData->TopOfStack, &event, &IoStatusBlock);
if (!NT_SUCCESS(status)) {
goto EnumerationDone;
}
//
// First iteration is for modems
// Therefore wait for 200 ms as per protocol for getting PNP string out
//
if (!i) {
status = Serenum_Wait(&timer, defaultTime);
if (!NT_SUCCESS(status)) {
Serenum_KdPrint (FdoData, SER_DBG_SS_ERROR,
("Timer failed with status %x\n", status ));
goto EnumerationDone;
}
}
//
// set RTS
//
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE, ("Setting RTS...\n"));
status = Serenum_IoSyncIoctl(IOCTL_SERIAL_SET_RTS, FALSE,
FdoData->TopOfStack, &event, &IoStatusBlock);
if (!NT_SUCCESS(status)) {
goto EnumerationDone;
}
//
// Read from the serial port
//
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
("Reading the serial port...\n"));
Serenum_KdPrint(FdoData, SER_DBG_SS_INFO, ("Address: %x\n", ReadBuffer));
nActual = 0;
#if DBG
RtlFillMemory(ReadBuffer, MAX_DEVNODE_NAME, 0xff);
#endif
//
// Flush the input buffer
//
status = Serenum_ReadSerialPort(ReadBuffer, MAX_DEVNODE_NAME,
defaultSerialTime, &nActual,
&IoStatusBlock, FdoData);
switch (status) {
case STATUS_TIMEOUT:
if (nActual == 0) {
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
("Timeout with no bytes read; continuing\n"));
continue;
}
break;
case STATUS_SUCCESS:
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
("Read succeeded\n"));
goto EnumerationDone;
break;
default:
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
("Read failed with 0x%x\n", status));
goto EnumerationDone;
break;
}
//
// If anything was read from the serial port, we're done!
//
if (nActual) {
break;
}
}
//
// If DSR wasn't set, then a jump will be made here, and any existing
// pdos will be eliminated
//
EnumerationDone:;
if (basicSettingsDone) {
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
("Restoring basic settings\n"));
Serenum_IoSyncIoctlEx(IOCTL_SERIAL_INTERNAL_RESTORE_SETTINGS, TRUE,
FdoData->TopOfStack, &event, &IoStatusBlock,
&basicSettings, sizeof(basicSettings), NULL, 0);
} else {
Serenum_IoSyncIoctlEx(IOCTL_SERIAL_SET_TIMEOUTS, FALSE,
FdoData->TopOfStack, &event, &IoStatusBlock,
&timeouts, sizeof(timeouts), NULL, 0);
}
//
// Cleanup and then Close
//
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
("Cleanup on the serial port...\n"));
status = Serenum_IoSyncReqWithIrp(Irp, IRP_MJ_CLEANUP, &event,
FdoData->TopOfStack);
#if DBG
if (!NT_SUCCESS(status)) {
Serenum_KdPrint(FdoData, SER_DBG_SS_ERROR,
("Failed to cleanup the serial port...\n"));
// don't return because we want to attempt to close!
}
#endif
//
// Close the Serial port after everything is done
//
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
("Closing the serial port...\n"));
status = Serenum_IoSyncReqWithIrp(Irp, IRP_MJ_CLOSE, &event,
FdoData->TopOfStack);
if (!NT_SUCCESS(status)) {
Serenum_KdPrint(FdoData, SER_DBG_SS_ERROR,
("Failed to close the serial port...\n"));
Irp->AssociatedIrp.SystemBuffer = stack->Parameters.Others.Argument1;
return status;
}
//
// Check if anything was read, and if not, we're done
//
if (nActual == 0) {
if (ReadBuffer != NULL) {
ExFreePool(ReadBuffer);
}
if (pdo != NULL) {
//
// Something was there. The device must have been unplugged.
// Remove the PDO.
//
Serenum_PDO_EnumMarkMissing(FdoData, pdo->DeviceExtension);
pdo = NULL;
}
goto ExitReenumerate;
}
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
("Something was read from the serial port...\n"));
#if DBG
if (FdoData->DebugLevel & SER_DBG_PNP_DUMP_PACKET) {
ULONG dmpi;
ULONG col;
DbgPrint("SERENUM: Raw Data Packet on probe\n");
for (dmpi = 0; dmpi < ((ULONG)nActual / 20); dmpi++) {
DbgPrint("-------: ");
for (col = 0; col < 20; col++) {
DbgPrint("%02x ", (unsigned char)ReadBuffer[dmpi * 20 + col]);
}
DbgPrint(" ");
for (col = 0; col < 20; col++) {
if (__isascii(ReadBuffer[dmpi * 20 + col])
&& (ReadBuffer[dmpi * 20 + col] > ' ')) {
DbgPrint("%c", ReadBuffer[dmpi * 20 + col]);
} else {
DbgPrint(".");
}
}
DbgPrint("\n");
}
if (nActual % 20) {
DbgPrint("-------: ");
for (col = 0; col < ((ULONG)nActual % 20); col++) {
DbgPrint("%02x ", (unsigned char)ReadBuffer[dmpi * 20 + col]);
}
for (col = 0; col < (20 - ((ULONG)nActual % 20)); col++) {
DbgPrint(" ");
}
for (col = 0; col < ((ULONG)nActual % 20); col++) {
if (__isascii(ReadBuffer[dmpi * 20 + col])
&& (ReadBuffer[dmpi * 20 + col] > ' ')) {
DbgPrint("%c", ReadBuffer[dmpi * 20 + col]);
} else {
DbgPrint(".");
}
}
DbgPrint("\n");
}
}
#endif
//
// Determine from the result whether the current pdo (if we have one),
// should be deleted. If it's the same device, then keep it. If it's a
// different device or if the device is a legacy device, then create a
// new pdo.
//
if (legacyPotential) {
PCHAR mouseId = ReadBuffer;
ULONG charCnt;
SerenumScanOtherIdForMouse(ReadBuffer, nActual, &mouseId);
if (mouseId != NULL) {
//
// A legacy device is attached to the serial port, since DSR was
// not set when RTS was set.
// If we find a mouse from the readbuffer, copy the appropriate
// strings into the hardwareIDs and CompIDs manually.
//
if (*mouseId == 'M') {
if ((mouseId - ReadBuffer) > 1 && mouseId[1] == '3') {
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE, ("*PNP0F08 mouse\n"));
Serenum_InitMultiString(FdoData, &HardwareIDs, "*PNP0F08",
NULL);
Serenum_InitMultiString(FdoData, &CompIDs, "SERIAL_MOUSE",
NULL);
//
// ADRIAO CIMEXCIMEX 04/28/1999 -
// Device ID's should be unique, at least as unique as the
// hardware ID's. This ID should really be Serenum\\PNP0F08
//
Serenum_InitMultiString(FdoData, &DeviceIDs, "Serenum\\Mouse",
NULL);
legacyFound = TRUE;
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
("Buffers at 0x%x 0x%x 0x%x\n",
HardwareIDs.Buffer, CompIDs.Buffer,
DeviceIDs.Buffer));
} else {
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE, ("*PNP0F01 mouse\n"));
Serenum_InitMultiString(FdoData, &HardwareIDs, "*PNP0F01", NULL);
Serenum_InitMultiString(FdoData, &CompIDs, "SERIAL_MOUSE", NULL);
//
// ADRIAO CIMEXCIMEX 04/28/1999 -
// Device ID's should be unique, at least as unique as the
// hardware ID's. This ID should really be Serenum\\PNP0F01
//
Serenum_InitMultiString(FdoData, &DeviceIDs, "Serenum\\Mouse",
NULL);
legacyFound = TRUE;
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
("Buffers at 0x%x 0x%x 0x%x\n",
HardwareIDs.Buffer, CompIDs.Buffer,
DeviceIDs.Buffer));
}
} else if (*mouseId == 'B') {
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE, ("*PNP0F09 mouse\n"));
Serenum_InitMultiString(FdoData, &HardwareIDs, "*PNP0F09", NULL);
Serenum_InitMultiString(FdoData, &CompIDs, "*PNP0F0F",
"SERIAL_MOUSE", NULL);
//
// ADRIAO CIMEXCIMEX 04/28/1999 -
// Device ID's should be unique, at least as unique as the
// hardware ID's. This ID should really be Serenum\\PNP0F09
//
Serenum_InitMultiString(FdoData, &DeviceIDs, "Serenum\\BallPoint",
NULL);
legacyFound = TRUE;
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
("Buffers at 0x%x 0x%x 0x%x\n",
HardwareIDs.Buffer, CompIDs.Buffer,
DeviceIDs.Buffer));
}
}
}
if (!legacyFound) {
//
// A legacy device wasn't found. Even if DSR wasn't set, it could
// just be a broken PNP device, so check here by parsing the
// PNP COM ID
//
if (!NT_SUCCESS(Serenum_ParseData(FdoData, ReadBuffer, nActual,
&HardwareIDs, &CompIDs, &DeviceIDs,
&DevDesc))) {
Serenum_KdPrint(FdoData, SER_DBG_SS_ERROR,
("Failed to parse the data for the new device\n"));
//
// Legacy device. Remove the current pdo and make a new one
// so that always pops up message asking for new device driver.
//
if (pdo) {
Serenum_PDO_EnumMarkMissing(FdoData, pdo->DeviceExtension);
pdo = NULL;
}
ExFreePool(ReadBuffer);
goto ExitReenumerate;
}
}
//
// We're now finally able to free this read buffer.
//
if (ReadBuffer != NULL) {
ExFreePool(ReadBuffer);
}
//
// Check if the current device is the same as the one that we're
// enumerating. If so, we'll just keep the current pdo.
//
if (pdo) {
pdoData = pdo->DeviceExtension;
//
// ADRIAO CIMEXCIMEX 04/28/1999 -
// We should be comparing device ID's here, but the above mentioned
// bug must be fixed first. Note that even this code is broken as it
// doesn't take into account that hardware/compID's are multiSz.
//
if (!(RtlEqualUnicodeString(&pdoData->HardwareIDs, &HardwareIDs, FALSE)
&& RtlEqualUnicodeString(&pdoData->CompIDs, &CompIDs, FALSE))) {
//
// The ids are not the same, so get rid of this pdo and create a
// new one so that the PNP system will query the ids and find a
// new driver
//
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE, ("Different device."
" Removing PDO %x\n",
pdo));
Serenum_PDO_EnumMarkMissing(FdoData, pdoData);
pdo = NULL;
} else {
Serenum_KdPrint(FdoData, SER_DBG_SS_TRACE,
("Same device. Keeping current Pdo %x\n", pdo));
}
}
//
// If there isn't a pdo, then create one!
//
if (!pdo) {
//
// Allocate a pdo
//
status = IoCreateDevice(FdoData->Self->DriverObject,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -