📄 serenum.c
字号:
// This IOCTL is used by the modem cpl.
//
status = IoOpenDeviceRegistryKey(fdoData->UnderlyingPDO,
PLUGPLAY_REGKEY_DEVICE,
STANDARD_RIGHTS_READ,
&keyHandle);
if (!NT_SUCCESS(status)) {
//
// This is a fatal error. If we can't get to our registry key,
// we are sunk.
//
Serenum_KdPrint_Def (SER_DBG_PNP_ERROR,
("IoOpenDeviceRegistryKey failed - %x \n", status));
} else {
status = Serenum_GetRegistryKeyValue(
keyHandle,
L"PortName",
sizeof(L"PortName"),
Irp->AssociatedIrp.SystemBuffer,
irpStack->Parameters.DeviceIoControl.OutputBufferLength,
&actualLength);
if ( STATUS_OBJECT_NAME_NOT_FOUND == status ||
STATUS_INVALID_PARAMETER == status ) {
status = Serenum_GetRegistryKeyValue(
keyHandle,
L"Identifier",
sizeof(L"Identifier"),
Irp->AssociatedIrp.SystemBuffer,
irpStack->Parameters.DeviceIoControl.OutputBufferLength,
&actualLength);
}
Irp->IoStatus.Information = actualLength;
ZwClose (keyHandle);
}
break;
default:
//
// This is not intended for us - fire and forget!
//
Serenum_DecIoCount (fdoData);
return Serenum_DispatchPassThrough(
DeviceObject,
Irp);
}
Serenum_DecIoCount (fdoData);
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
NTSTATUS
Serenum_InternIoCtl (
PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
--*/
{
PIO_STACK_LOCATION irpStack;
NTSTATUS status;
PCOMMON_DEVICE_DATA commonData;
PPDO_DEVICE_DATA pdoData;
PVOID buffer;
// PAGED_CODE();
status = STATUS_SUCCESS;
irpStack = IoGetCurrentIrpStackLocation (Irp);
ASSERT (IRP_MJ_INTERNAL_DEVICE_CONTROL == irpStack->MajorFunction);
commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension;
pdoData = (PPDO_DEVICE_DATA) DeviceObject->DeviceExtension;
//
// We only take Internal Device Control requests for the PDO.
// That is the objects on the bus (representing the serial ports)
//
// We do pass on the irp if this comes into the fdo, but not if it comes
// into the pdo.
//
if (commonData->IsFDO) {
return Serenum_DispatchPassThrough(
DeviceObject,
Irp);
} else if (pdoData->Removed) {
//
// This bus has received the PlugPlay remove IRP. It will no longer
// respond to external requests.
//
status = STATUS_DELETE_PENDING;
} else {
buffer = Irp->UserBuffer;
switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_INTERNAL_SERENUM_REMOVE_SELF:
Serenum_KdPrint(pdoData, SER_DBG_SS_TRACE, ("Remove self\n"));
((PFDO_DEVICE_DATA) pdoData->ParentFdo->DeviceExtension)->
PDOForcedRemove = TRUE;
IoInvalidateDeviceRelations(
((PFDO_DEVICE_DATA) pdoData->ParentFdo->DeviceExtension)->
UnderlyingPDO,
BusRelations );
status = STATUS_SUCCESS;
break;
default:
//
// Pass it through
//
return Serenum_DispatchPassThrough(DeviceObject, Irp);
}
}
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
VOID
Serenum_DriverUnload (
IN PDRIVER_OBJECT Driver
)
/*++
Routine Description:
Clean up everything we did in driver entry.
--*/
{
UNREFERENCED_PARAMETER (Driver);
PAGED_CODE();
//
// All the device objects should be gone.
//
ASSERT (NULL == Driver->DeviceObject);
//
// Here we free any resources allocated in DriverEntry
//
return;
}
NTSTATUS
Serenum_IncIoCount (
PFDO_DEVICE_DATA Data
)
{
InterlockedIncrement (&Data->OutstandingIO);
if (Data->Removed) {
if (0 == InterlockedDecrement (&Data->OutstandingIO)) {
KeSetEvent (&Data->RemoveEvent, 0, FALSE);
}
return STATUS_DELETE_PENDING;
}
return STATUS_SUCCESS;
}
VOID
Serenum_DecIoCount (
PFDO_DEVICE_DATA Data
)
{
if (0 == InterlockedDecrement (&Data->OutstandingIO)) {
KeSetEvent (&Data->RemoveEvent, 0, FALSE);
}
}
NTSTATUS
Serenum_DispatchPassThrough(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Passes a request on to the lower driver.
--*/
{
PIO_STACK_LOCATION IrpStack =
IoGetCurrentIrpStackLocation( Irp );
#if 0
Serenum_KdPrint_Def (SER_DBG_SS_TRACE, (
"[Serenum_DispatchPassThrough] "
"IRP: %8x; "
"MajorFunction: %d\n",
Irp,
IrpStack->MajorFunction ));
#endif
//
// Pass the IRP to the target
//
IoSkipCurrentIrpStackLocation (Irp);
// CIMEXCIMEX: VERIFY THIS FUNCTIONS CORRECTLY!!!
if (((PPDO_DEVICE_DATA) DeviceObject->DeviceExtension)->IsFDO) {
return IoCallDriver(
((PFDO_DEVICE_DATA) DeviceObject->DeviceExtension)->TopOfStack,
Irp );
} else {
return IoCallDriver(
((PFDO_DEVICE_DATA) ((PPDO_DEVICE_DATA) DeviceObject->
DeviceExtension)->ParentFdo->DeviceExtension)->TopOfStack,
Irp );
}
}
void
Serenum_InitPDO (
PDEVICE_OBJECT Pdo,
PFDO_DEVICE_DATA FdoData
)
/*
Description:
Common code to initialize a newly created serenum pdo.
Called either when the control panel exposes a device or when Serenum senses
a new device was attached.
Parameters:
Pdo - The pdo
FdoData - The fdo's device extension
*/
{
ULONG FdoFlags = FdoData->Self->Flags;
PPDO_DEVICE_DATA pdoData = Pdo->DeviceExtension;
//
// Check the IO style
//
if (FdoFlags & DO_BUFFERED_IO) {
Pdo->Flags |= DO_BUFFERED_IO;
} else if (FdoFlags & DO_DIRECT_IO) {
Pdo->Flags |= DO_DIRECT_IO;
}
//
// Increment the pdo's stacksize so that it can pass irps through
//
Pdo->StackSize += FdoData->Self->StackSize;
//
// Initialize the rest of the device extension
//
pdoData->IsFDO = FALSE;
pdoData->Self = Pdo;
pdoData->ParentFdo = FdoData->Self;
pdoData->Started = FALSE; // irp_mn_start has yet to be received
pdoData->Attached = TRUE; // attached to the bus
pdoData->Removed = FALSE; // no irp_mn_remove as of yet
pdoData->DebugLevel = FdoData->DebugLevel; // Copy the debug level
pdoData->DeviceState = PowerDeviceD0;
pdoData->SystemState = PowerSystemWorking;
//
// Add the pdo to serenum's list
//
ASSERT(FdoData->AttachedPDO == NULL);
ASSERT(FdoData->PdoData == NULL);
ASSERT(FdoData->NumPDOs == 0);
FdoData->AttachedPDO = Pdo;
FdoData->PdoData = pdoData;
FdoData->NumPDOs = 1;
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
Pdo->Flags |= DO_POWER_PAGABLE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -