📄 plugplay.cpp
字号:
{
KdPrint((DRIVERNAME " - Failing removal query due to open handles\n"));
return CompleteRequest(Irp, STATUS_DEVICE_BUSY);
}
#endif
KdPrint((DRIVERNAME " - To PENDINGREMOVE from %s\n", statenames[pdx->state]));
} // currently working
// Save current state for restoration if the query gets cancelled.
// (We can now be stopped or working)
pdx->prevstate = pdx->state;
pdx->state = PENDINGREMOVE;
return DefaultPnpHandler(fdo, Irp);
} // HandleQueryRemove
///////////////////////////////////////////////////////////////////////////////
NTSTATUS HandleQueryStop(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // HandleQueryStop
ASSERT(IoGetCurrentIrpStackLocation(Irp)->MinorFunction == IRP_MN_QUERY_STOP_DEVICE);
Irp->IoStatus.Status = STATUS_SUCCESS; // flag that we handled this IRP
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
// Boot devices may get this query before they even start, so check to see
// if we're in the WORKING state before doing anything.
if (pdx->state != WORKING)
return DefaultPnpHandler(fdo, Irp);
KdPrint((DRIVERNAME " - To PENDINGSTOP from %s\n", statenames[pdx->state]));
pdx->state = PENDINGSTOP;
return DefaultPnpHandler(fdo, Irp);
} // HandleQueryStop
///////////////////////////////////////////////////////////////////////////////
NTSTATUS HandleRemoveDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // HandleRemoveDevice
ASSERT(IoGetCurrentIrpStackLocation(Irp)->MinorFunction == IRP_MN_REMOVE_DEVICE);
Irp->IoStatus.Status = STATUS_SUCCESS; // flag that we handled this IRP
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
// Cancel any queued IRPs and start rejecting new ones
AbortPendingIoctls(pdx, STATUS_DELETE_PENDING);
// Disable all device interfaces. This triggers PnP notifications that will
// allow apps to close their handles.
DeregisterAllInterfaces(pdx);
// Release our I/O resources
StopDevice(fdo, pdx->state == WORKING);
KdPrint((DRIVERNAME " - To REMOVED from %s\n", statenames[pdx->state]));
pdx->state = REMOVED;
// Let lower-level drivers handle this request. Ignore whatever
// result eventuates.
NTSTATUS status = DefaultPnpHandler(fdo, Irp);
// Wait for all claims against this device to vanish before removing
// the device object.
IoReleaseRemoveLockAndWait(&pdx->RemoveLock, Irp);
// Remove the device object
RemoveDevice(fdo);
return status; // lower-level completed IoStatus already
} // HandleRemoveDevice
///////////////////////////////////////////////////////////////////////////////
NTSTATUS HandleStartDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // HandleStartDevice
ASSERT(IoGetCurrentIrpStackLocation(Irp)->MinorFunction == IRP_MN_START_DEVICE);
Irp->IoStatus.Status = STATUS_SUCCESS; // flag that we handled this IRP
NTSTATUS status = ForwardAndWait(fdo, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status);
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
PCM_PARTIAL_RESOURCE_LIST raw;
if (stack->Parameters.StartDevice.AllocatedResources)
raw = &stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
else
raw = NULL;
PCM_PARTIAL_RESOURCE_LIST translated;
if (stack->Parameters.StartDevice.AllocatedResourcesTranslated)
translated = &stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
else
translated = NULL;
#if DBG
if (raw)
{
KdPrint((DRIVERNAME " - Resources:\n"));
ShowResources(raw);
}
if (translated)
{
KdPrint((DRIVERNAME " - Translated Resources:\n"));
ShowResources(translated);
}
#endif // DBG
status = StartDevice(fdo, raw, translated);
// While we were in the stopped state, we were stalling incoming requests.
// Now we can release any pending IRPs and start processing new ones
if (NT_SUCCESS(status))
{ // started okay
// Enable all registered device interfaces.
EnableAllInterfaces(pdx, TRUE);
KdPrint((DRIVERNAME " - To WORKING from %s\n", statenames[pdx->state]));
pdx->state = WORKING;
} // started okay
return CompleteRequest(Irp, status);
} // HandleStartDevice
///////////////////////////////////////////////////////////////////////////////
NTSTATUS HandleStopDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // HandleStopDevice
ASSERT(IoGetCurrentIrpStackLocation(Irp)->MinorFunction == IRP_MN_STOP_DEVICE);
Irp->IoStatus.Status = STATUS_SUCCESS; // flag that we handled this IRP
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
// We're supposed to always get a query before we're stopped, so
// we should already be in the PENDINGSTOP state. There's a Win98 bug that
// can sometimes cause us to get a STOP instead of a REMOVE, in which case
// we should start rejecting IRPs
if (pdx->state != PENDINGSTOP)
{ // no previous query
KdPrint((DRIVERNAME " - STOP with no previous QUERY_STOP!\n"));
AbortPendingIoctls(pdx, STATUS_DELETE_PENDING);
} // no previous query
StopDevice(fdo, pdx->state == WORKING);
KdPrint((DRIVERNAME " - To STOPPED from %s\n", statenames[pdx->state]));
pdx->state = STOPPED;
return DefaultPnpHandler(fdo, Irp);
} // HandleStopDevice
///////////////////////////////////////////////////////////////////////////////
NTSTATUS HandleSurpriseRemoval(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // HandleSurpriseRemoval
ASSERT(IoGetCurrentIrpStackLocation(Irp)->MinorFunction == IRP_MN_SURPRISE_REMOVAL);
Irp->IoStatus.Status = STATUS_SUCCESS; // flag that we handled this IRP
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
// Cancel any queued IRPs and start rejecting new ones
AbortPendingIoctls(pdx, STATUS_DELETE_PENDING);
DeregisterAllInterfaces(pdx);
KdPrint((DRIVERNAME " - To SURPRISEREMOVED from %s\n", statenames[pdx->state]));
BOOLEAN oktouch = pdx->state == WORKING;
pdx->state = SURPRISEREMOVED;
StopDevice(fdo, oktouch);
return DefaultPnpHandler(fdo, Irp);
} // HandleSurpriseRemoval
///////////////////////////////////////////////////////////////////////////////
#if DBG
VOID ShowResources(IN PCM_PARTIAL_RESOURCE_LIST list)
{ // ShowResources
PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = list->PartialDescriptors;
ULONG nres = list->Count;
ULONG i;
for (i = 0; i < nres; ++i, ++resource)
{ // for each resource
ULONG type = resource->Type;
static char* name[] = {
"CmResourceTypeNull",
"CmResourceTypePort",
"CmResourceTypeInterrupt",
"CmResourceTypeMemory",
"CmResourceTypeDma",
"CmResourceTypeDeviceSpecific",
"CmResourceTypeBusNumber",
"CmResourceTypeDevicePrivate",
"CmResourceTypeAssignedResource",
"CmResourceTypeSubAllocateFrom",
};
KdPrint((" type %s", type < arraysize(name) ? name[type] : "unknown"));
switch (type)
{ // select on resource type
case CmResourceTypePort:
case CmResourceTypeMemory:
KdPrint((" start %8X%8.8lX length %X\n",
resource->u.Port.Start.HighPart, resource->u.Port.Start.LowPart,
resource->u.Port.Length));
break;
case CmResourceTypeInterrupt:
KdPrint((" level %X, vector %X, affinity %X\n",
resource->u.Interrupt.Level, resource->u.Interrupt.Vector,
resource->u.Interrupt.Affinity));
break;
case CmResourceTypeDma:
KdPrint((" channel %d, port %X\n",
resource->u.Dma.Channel, resource->u.Dma.Port));
} // select on resource type
} // for each resource
} // ShowResources
#endif // DBG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -