📄 genport.c.bak
字号:
Irp->IoStatus.Status = status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break;
case IRP_MN_QUERY_REMOVE_DEVICE:
//
// The device can be removed without disrupting the machine.
//
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);
break;
case IRP_MN_SURPRISE_REMOVAL:
//
// The device has been unexpectedly removed from the machine
// and is no longer available for I/O. Stop all access to the device.
// Release any resources associated with the device, but leave the
// device object attached to the device stack until the PnP Manager
// sends a subsequent IRP_MN_REMOVE_DEVICE request.
// You should fail any outstanding I/O to the device. You will
// not get a remove until all the handles open to the device
// have been closed.
//
deviceInfo->Removed = TRUE;
deviceInfo->Started = FALSE;
//
// Wait for all outstanding requests to complete
//
DebugPrint(("Waiting for outstanding requests\n"));
IoReleaseRemoveLockAndWait(&deviceInfo->RemoveLock, Irp);
if (deviceInfo->PortWasMapped)
{
MmUnmapIoSpace(deviceInfo->PortBase, deviceInfo->PortCount);
deviceInfo->PortWasMapped = FALSE;
}
RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&win32DeviceName);
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);
break;
case IRP_MN_REMOVE_DEVICE:
//
// Relinquish all resources here.
// Detach and delete the device object so that
// your driver can be unloaded. You get remove
// either after query_remove or surprise_remove.
//
if(!deviceInfo->Removed)
{
deviceInfo->Removed = TRUE;
deviceInfo->Started = FALSE;
//
// Wait for all outstanding requests to complete
//
DebugPrint(("Waiting for outstanding requests\n"));
IoReleaseRemoveLockAndWait(&deviceInfo->RemoveLock, Irp);
if (deviceInfo->PortWasMapped)
{
MmUnmapIoSpace(deviceInfo->PortBase, deviceInfo->PortCount);
deviceInfo->PortWasMapped = FALSE;
}
RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&win32DeviceName);
}
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);
IoDetachDevice(deviceInfo->NextLowerDriver);
IoDeleteDevice(DeviceObject);
return status;
case IRP_MN_STOP_DEVICE:
// Since you failed query stop, you will not get this request.
case IRP_MN_CANCEL_REMOVE_DEVICE:
// No action required in this case. Just pass it down.
case IRP_MN_CANCEL_STOP_DEVICE:
//No action required in this case.
default:
//
// Please see PnP documentation for use of these IRPs.
//
IoSkipCurrentIrpStackLocation (Irp);
status = IoCallDriver(deviceInfo->NextLowerDriver, Irp);
break;
}
IoReleaseRemoveLock(&deviceInfo->RemoveLock, NULL);
return status;
}
NTSTATUS
GpdStartDevice (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
Get the resources, map the resources if required
and initialize the device.
Arguments:
DeviceObject - pointer to a device object.
Irp - pointer to an I/O Request Packet.
Return Value:
NT status code
--*/
{
NTSTATUS status = STATUS_SUCCESS;
PCM_PARTIAL_RESOURCE_DESCRIPTOR resource;
PCM_PARTIAL_RESOURCE_DESCRIPTOR resourceTrans;
PCM_PARTIAL_RESOURCE_LIST partialResourceList;
PCM_PARTIAL_RESOURCE_LIST partialResourceListTranslated;
PIO_STACK_LOCATION stack;
ULONG i;
PLOCAL_DEVICE_INFO deviceInfo;
deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject->DeviceExtension;
stack = IoGetCurrentIrpStackLocation (Irp);
PAGED_CODE();
//
// We need to check that we haven't received a surprise removal
//
if (deviceInfo->Removed) {
//
// Some kind of surprise removal arrived. We will fail the IRP
// The dispatch routine that called us will take care of
// completing the IRP.
//
return STATUS_DELETE_PENDING;
}
//
// Do whatever initialization needed when starting the device:
// gather information about it, update the registry, etc.
//
if ((NULL == stack->Parameters.StartDevice.AllocatedResources) &&
(NULL == stack->Parameters.StartDevice.AllocatedResourcesTranslated)) {
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// Parameters.StartDevice.AllocatedResources points to a
// CM_RESOURCE_LIST describing the hardware resources that
// the PnP Manager assigned to the device. This list contains
// the resources in raw form. Use the raw resources to program
// the device.
//
partialResourceList =
&stack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
resource = &partialResourceList->PartialDescriptors[0];
//
// Parameters.StartDevice.AllocatedResourcesTranslated points
// to a CM_RESOURCE_LIST describing the hardware resources that
// the PnP Manager assigned to the device. This list contains
// the resources in translated form. Use the translated resources
// to connect the interrupt vector, map I/O space, and map memory.
//
partialResourceListTranslated =
&stack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
resourceTrans = &partialResourceListTranslated->PartialDescriptors[0];
for (i = 0;
i < partialResourceList->Count; i++, resource++, resourceTrans++) {
switch (resource->Type) {
case CmResourceTypePort:
switch (resourceTrans->Type) {
case CmResourceTypePort:
deviceInfo->PortWasMapped = FALSE;
deviceInfo->PortBase = (PVOID)resourceTrans->u.Port.Start.LowPart;
deviceInfo->PortCount = resourceTrans->u.Port.Length;
DebugPrint(("Resource Translated Port: (%x) Length: (%d)\n",
resourceTrans->u.Port.Start.LowPart,
resourceTrans->u.Port.Length));
break;
case CmResourceTypeMemory:
//
// We need to map the memory
//
deviceInfo->PortBase = (PVOID)
MmMapIoSpace (resourceTrans->u.Memory.Start,
resourceTrans->u.Memory.Length,
MmNonCached);
deviceInfo->PortCount = resourceTrans->u.Memory.Length;
deviceInfo->PortWasMapped = TRUE;
DebugPrint(("Resource Translated Memory: (%x) Length: (%d)\n",
resourceTrans->u.Memory.Start.LowPart,
resourceTrans->u.Memory.Length));
break;
default:
DebugPrint(("Unhandled resource_type (0x%x)\n", resourceTrans->Type));
status = STATUS_UNSUCCESSFUL;
TRAP ();
}
break;
case CmResourceTypeMemory:
deviceInfo->PortBase = (PVOID)
MmMapIoSpace (resourceTrans->u.Memory.Start,
resourceTrans->u.Memory.Length,
MmNonCached);
deviceInfo->PortCount = resourceTrans->u.Memory.Length;
deviceInfo->PortWasMapped = TRUE;
DebugPrint(("Resource Translated Memory: (%x) Length: (%d)\n",
resourceTrans->u.Memory.Start.LowPart,
resourceTrans->u.Memory.Length));
break;
case CmResourceTypeInterrupt:
default:
DebugPrint(("Unhandled resource type (0x%x)\n", resource->Type));
status = STATUS_UNSUCCESSFUL;
break;
} // end of switch
} // end of for
return status;
}
NTSTATUS
GpdDispatchPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is the dispatch routine for power irps.
Does nothing except forwarding the IRP to the next device
in the stack.
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
NT Status code
--*/
{
PLOCAL_DEVICE_INFO deviceInfo;
deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject->DeviceExtension;
//
// If the device has been removed, the driver should not pass
// the IRP down to the next lower driver.
//
if (deviceInfo->Removed) {
PoStartNextPowerIrp(Irp);
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
IoCompleteRequest(Irp, IO_NO_INCREMENT );
return STATUS_DELETE_PENDING;
}
PoStartNextPowerIrp(Irp);
IoSkipCurrentIrpStackLocation(Irp);
return PoCallDriver(deviceInfo->NextLowerDriver, Irp);
}
NTSTATUS
GpdDispatchSystemControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
This routine is the dispatch routine for WMI irps.
Does nothing except forwarding the IRP to the next device
in the stack.
Arguments:
DeviceObject - Pointer to the device object.
Irp - Pointer to the request packet.
Return Value:
NT Status code
--*/
{
PLOCAL_DEVICE_INFO deviceInfo;
PAGED_CODE();
deviceInfo = (PLOCAL_DEVICE_INFO) DeviceObject->DeviceExtension;
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(deviceInfo->NextLowerDriver, Irp);
}
VOID
GpdUnload(
IN PDRIVER_OBJECT DriverObject
)
/*++
Routine Description:
Free all the allocated resources, etc.
Arguments:
DriverObject - pointer to a driver object.
Return Value:
VOID.
--*/
{
PAGED_CODE ();
//
// The device object(s) should be NULL now
// (since we unload, all the devices objects associated with this
// driver must have been deleted.
//
ASSERT(DriverObject->DeviceObject == NULL);
DebugPrint (("unload\n"));
return;
}
NTSTATUS
GpdDispatch(
IN PDEVICE_OBJECT pDO,
IN PIRP pIrp
)
/*++
Routine Description:
This routine is the dispatch handler for the driver. It is responsible
for processing the IRPs.
Arguments:
pDO - Pointer to device object.
pIrp - Pointer to the current IRP.
Return Value:
STATUS_SUCCESS if the IRP was processed successfully, otherwise an error
indicating the reason for failure.
--*/
{
PLOCAL_DEVICE_INFO pLDI;
PIO_STACK_LOCATION pIrpStack;
NTSTATUS Status;
PAGED_CODE();
pIrp->IoStatus.Information = 0;
pLDI = (PLOCAL_DEVICE_INFO)pDO->DeviceExtension; // Get local info struct
DebugPrint (("Entered GpdDispatch\n"));
Status = IoAcquireRemoveLock (&pLDI->RemoveLock, NULL);
if (!NT_SUCCESS (Status)) {
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = Status;
IoCompleteRequest (pIrp, IO_NO_INCREMENT);
return Status;
}
if (!pLDI->Started) {
//
// We fail all the IRPs that arrive before the device is started.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -