📄 legacy.c
字号:
0,
65,
STATUS_SUCCESS,
SERIAL_INVALID_USER_CONFIG,
UserSubKey->NameLength+sizeof(WCHAR),
&UserSubKey->Name[0],
(wcslen(Parameters[2].Name)*sizeof(WCHAR))
+ sizeof(WCHAR),
Parameters[2].Name
);
SerialDbgPrintEx(SERERRORS, "Bogus vector %ws\n", Parameters[2].Name);
rval = FALSE;
goto SerialIsUserDataValidError;
}
if (!PUserData->UserSymbolicLink.Length) {
//
// Ehhhh! Lose Game.
//
SerialLogError(DriverObject, NULL, PUserData->UserPort,
SerialPhysicalZero, 0, 0, 0, 66, STATUS_SUCCESS,
SERIAL_INVALID_USER_CONFIG,
UserSubKey->NameLength + sizeof(WCHAR),
&UserSubKey->Name[0],
(wcslen(Parameters[3].Name) * sizeof(WCHAR))
+ sizeof(WCHAR),
Parameters[3].Name);
SerialDbgPrintEx(SERERRORS, "bogus value for %ws\n", Parameters[3].Name);
rval = FALSE;
goto SerialIsUserDataValidError;
}
if (PUserData->UserInterruptStatus.LowPart != 0) {
if (PUserData->UserPortIndex == MAXULONG) {
//
// Ehhhh! Lose Game.
//
SerialLogError(
DriverObject,
NULL,
PUserData->UserPort,
SerialPhysicalZero,
0,
0,
0,
67,
STATUS_SUCCESS,
SERIAL_INVALID_PORT_INDEX,
PUserData->UserSymbolicLink.Length+sizeof(WCHAR),
PUserData->UserSymbolicLink.Buffer,
0,
NULL
);
SerialDbgPrintEx(SERERRORS, "Bogus port index %ws\n",
Parameters[0].Name);
rval = FALSE;
goto SerialIsUserDataValidError;
} else if (!PUserData->UserPortIndex) {
//
// So sorry, you must have a non-zero port index.
//
SerialLogError(
DriverObject,
NULL,
PUserData->UserPort,
SerialPhysicalZero,
0,
0,
0,
68,
STATUS_SUCCESS,
SERIAL_INVALID_PORT_INDEX,
PUserData->UserSymbolicLink.Length+sizeof(WCHAR),
PUserData->UserSymbolicLink.Buffer,
0,
NULL
);
SerialDbgPrintEx(SERERRORS, "Port index must be > 0 for any\n"
"port on a multiport card: %ws\n",
Parameters[0].Name);
rval = FALSE;
goto SerialIsUserDataValidError;
} else {
if (PUserData->UserIndexed) {
if (PUserData->UserPortIndex > SERIAL_MAX_PORTS_INDEXED) {
SerialLogError(
DriverObject,
NULL,
PUserData->UserPort,
SerialPhysicalZero,
0,
0,
0,
69,
STATUS_SUCCESS,
SERIAL_PORT_INDEX_TOO_HIGH,
PUserData->UserSymbolicLink.Length+sizeof(WCHAR),
PUserData->UserSymbolicLink.Buffer,
0,
NULL
);
SerialDbgPrintEx(SERERRORS, "port index to large %ws\n",
Parameters[0].Name);
rval = FALSE;
goto SerialIsUserDataValidError;
}
} else {
if (PUserData->UserPortIndex > SERIAL_MAX_PORTS_NONINDEXED) {
SerialLogError(
DriverObject,
NULL,
PUserData->UserPort,
SerialPhysicalZero,
0,
0,
0,
70,
STATUS_SUCCESS,
SERIAL_PORT_INDEX_TOO_HIGH,
PUserData->UserSymbolicLink.Length+sizeof(WCHAR),
PUserData->UserSymbolicLink.Buffer,
0,
NULL
);
SerialDbgPrintEx(SERERRORS, "port index to large %ws\n",
Parameters[0].Name);
rval = FALSE;
goto SerialIsUserDataValidError;
}
}
}
}
//
// We don't want to cause the hal to have a bad day,
// so let's check the interface type and bus number.
//
// We only need to check the registry if they aren't
// equal to the defaults.
//
if ((PUserData->UserBusNumber != 0) ||
(PUserData->UserInterfaceType != DefaultInterfaceType)) {
BOOLEAN foundIt;
if (PUserData->UserInterfaceType >= MaximumInterfaceType) {
//
// Ehhhh! Lose Game.
//
SerialLogError(
DriverObject,
NULL,
PUserData->UserPort,
SerialPhysicalZero,
0,
0,
0,
71,
STATUS_SUCCESS,
SERIAL_UNKNOWN_BUS,
PUserData->UserSymbolicLink.Length+sizeof(WCHAR),
PUserData->UserSymbolicLink.Buffer,
0,
NULL
);
SerialDbgPrintEx(SERERRORS, "Invalid Bus type %ws\n",
Parameters[0].Name);
rval = FALSE;
goto SerialIsUserDataValidError;
}
IoQueryDeviceDescription(
(INTERFACE_TYPE *)&PUserData->UserInterfaceType,
&zero,
NULL,
NULL,
NULL,
NULL,
SerialItemCallBack,
&foundIt
);
if (!foundIt) {
SerialLogError(
DriverObject,
NULL,
PUserData->UserPort,
SerialPhysicalZero,
0,
0,
0,
72,
STATUS_SUCCESS,
SERIAL_BUS_NOT_PRESENT,
PUserData->UserSymbolicLink.Length+sizeof(WCHAR),
PUserData->UserSymbolicLink.Buffer,
0,
NULL
);
SerialDbgPrintEx(SERERRORS, "There aren't that many of those\n"
"busses on this system,%ws\n", Parameters[0].Name);
rval = FALSE;
goto SerialIsUserDataValidError;
}
}
if ((PUserData->UserInterfaceType == MicroChannel) &&
(PUserData->UserInterruptMode == CM_RESOURCE_INTERRUPT_LATCHED)) {
SerialLogError(
DriverObject,
NULL,
PUserData->UserPort,
SerialPhysicalZero,
0,
0,
0,
73,
STATUS_SUCCESS,
SERIAL_BUS_INTERRUPT_CONFLICT,
PUserData->UserSymbolicLink.Length+sizeof(WCHAR),
PUserData->UserSymbolicLink.Buffer,
0,
NULL
);
SerialDbgPrintEx(SERERRORS, "Latched interrupts and MicroChannel\n"
"busses don't mix,%ws\n", Parameters[0].Name);
rval = FALSE;
goto SerialIsUserDataValidError;
}
SerialDbgPrintEx(SERDIAG1, "'user registry info - userPort: %x\n",
PUserData->UserPort.LowPart);
SerialDbgPrintEx(SERDIAG1, "'user registry info - userInterruptStatus: %x\n",
PUserData->UserInterruptStatus.LowPart);
SerialDbgPrintEx(SERDIAG1, "'user registry info - userPortIndex: %d\n",
PUserData->UserPortIndex);
SerialDbgPrintEx(SERDIAG1, "'user registry info - userClockRate: %d\n",
PUserData->UserClockRate);
SerialDbgPrintEx(SERDIAG1, "'user registry info - userBusNumber: %d\n",
PUserData->UserBusNumber);
SerialDbgPrintEx(SERDIAG1, "'user registry info - userAddressSpace: %d\n",
PUserData->UserAddressSpace);
SerialDbgPrintEx(SERDIAG1, "'user registry info - userInterruptMode: %d\n",
PUserData->UserInterruptMode);
SerialDbgPrintEx(SERDIAG1, "'user registry info - userInterfaceType: %d\n",
PUserData->UserInterfaceType);
SerialDbgPrintEx(SERDIAG1, "'user registry info - userVector: %d\n",
PUserData->UserVector);
SerialDbgPrintEx(SERDIAG1, "'user registry info - userLevel: %d\n",
PUserData->UserLevel);
SerialDbgPrintEx(SERDIAG1, "'user registry info - userIndexed: %d\n",
PUserData->UserIndexed);
SerialDbgPrintEx(SERTRACECALLS, "Leave SerialIsUserDataValid\n");
SerialIsUserDataValidError:
return rval;
}
NTSTATUS
SerialEnumerateLegacy(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath,
IN PSERIAL_FIRMWARE_DATA DriverDefaultsPtr)
/*++
Routine Description:
This routine will enumerate and initialize all legacy serial ports that
have just been scribbled into the registry. These are usually non-
intelligent multiport boards, but can be any type of "standard" serial
port.
This is pageable INIT because it is only called from DriverEntry.
Arguments:
DriverObject - Used only for logging errors.
RegistryPath - Path to this drivers service node in
the current control set.
DriverDefaultsPtr - Pointer to structure of driver-wide defaults.
Return Value:
STATUS_SUCCESS if consistant configuration was found - otherwise.
returns STATUS_SERIAL_NO_DEVICE_INITED.
--*/
{
SERIAL_FIRMWARE_DATA firmware;
PRTL_QUERY_REGISTRY_TABLE parameters = NULL;
INTERFACE_TYPE interfaceType;
ULONG defaultInterfaceType;
PULONG countSoFar = &IoGetConfigurationInformation()->SerialCount;
//
// Default values for user data.
//
ULONG maxUlong = MAXULONG;
ULONG zero = 0;
ULONG nonzero = 1;
ULONG badValue = (ULONG)-1;
ULONG defaultInterruptMode;
ULONG defaultAddressSpace = CM_RESOURCE_PORT_IO;
//
// Where user data from the registry will be placed.
//
SERIAL_USER_DATA userData;
ULONG legacyDiscovered;
UNICODE_STRING PnPID;
UNICODE_STRING legacyKeys;
UNICODE_STRING parametersPath;
OBJECT_ATTRIBUTES parametersAttributes;
HANDLE parametersKey;
HANDLE pnpKey;
PKEY_BASIC_INFORMATION userSubKey = NULL;
ULONG i;
PCM_RESOURCE_LIST resourceList = NULL;
PCM_RESOURCE_LIST trResourceList = NULL;
PIO_RESOURCE_REQUIREMENTS_LIST pRequiredList = NULL;
ULONG countOfPartials;
PDEVICE_OBJECT newPdo;
ULONG brokenStatus;
PAGED_CODE();
SerialDbgPrintEx(SERTRACECALLS, "Enter SerialEnumerateLegacy\n");
PnPID.Buffer = NULL;
legacyKeys.Buffer = NULL;
userData.UserSymbolicLink.Buffer = NULL;
parametersPath.Buffer = NULL;
userData.ForceFIFOEnableDefault = DriverDefaultsPtr->ForceFifoEnableDefault;
userData.PermitShareDefault = DriverDefaultsPtr->PermitShareDefault;
userData.LogFIFODefault = DriverDefaultsPtr->LogFifoDefault;
userData.DefaultPermitSystemWideShare = FALSE;
userData.RxFIFODefault = DriverDefaultsPtr->RxFIFODefault;
userData.TxFIFODefault = DriverDefaultsPtr->TxFIFODefault;
//
// Start of normal configuration and detection.
//
//
// Query the registry one more time. This time we
// look for the first bus on the system (that isn't
// the internal bus - we assume that the firmware
// code knows about those ports). We will use that
// as the default bus if no bustype or bus number
// is specified in the "user" configuration records.
//
defaultInterfaceType = (ULONG)Isa;
defaultInterruptMode = CM_RESOURCE_INTERRUPT_LATCHED;
for (
interfaceType = 0;
interfaceType < MaximumInterfaceType;
interfaceType++
) {
ULONG busZero = 0;
BOOLEAN foundOne = FALSE;
if (interfaceType != Internal) {
IoQueryDeviceDescription(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -