{
PFDO_DEVICE_EXTENSION DeviceExtension;
PCI_COMMON_CONFIG PciConfig;
- PLIST_ENTRY CurrentEntry;
PPCI_DEVICE Device;
PCI_SLOT_NUMBER SlotNumber;
ULONG DeviceNumber;
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- /* Mark all devices to be removed. If we don't discover them again during
- enumeration, assume that they have been surprise removed */
- CurrentEntry = DeviceExtension->DeviceListHead.Flink;
- while (CurrentEntry != &DeviceExtension->DeviceListHead) {
- Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
- Device->RemovePending = TRUE;
- CurrentEntry = CurrentEntry->Flink;
- }
-
DeviceExtension->DeviceListCount = 0;
/* Enumerate devices on the PCI bus */
&DeviceExtension->DeviceListLock);
}
- /* Don't remove this device */
- Device->RemovePending = FALSE;
-
DeviceExtension->DeviceListCount++;
/* Skip to next device if the current one is not a multifunction device */
case IRP_MN_STOP_DEVICE:
case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_CANCEL_REMOVE_DEVICE:
- case IRP_MN_REMOVE_DEVICE:
case IRP_MN_SURPRISE_REMOVAL:
Status = STATUS_SUCCESS;
break;
+ case IRP_MN_REMOVE_DEVICE:
+ {
+ PPDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+ PFDO_DEVICE_EXTENSION FdoDeviceExtension = DeviceExtension->Fdo->DeviceExtension;
+ KIRQL OldIrql;
+
+ /* Remove it from the device list */
+ KeAcquireSpinLock(&FdoDeviceExtension->DeviceListLock, &OldIrql);
+ RemoveEntryList(&DeviceExtension->PciDevice->ListEntry);
+ FdoDeviceExtension->DeviceListCount--;
+ KeReleaseSpinLock(&FdoDeviceExtension->DeviceListLock, OldIrql);
+
+ /* Free the device */
+ ExFreePool(DeviceExtension->PciDevice);
+
+ /* Complete the IRP */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ /* Delete the DO */
+ IoDeleteDevice(DeviceObject);
+ return STATUS_SUCCESS;
+ }
+
case IRP_MN_QUERY_INTERFACE:
DPRINT("IRP_MN_QUERY_INTERFACE received\n");
Status = PdoQueryInterface(DeviceObject, Irp, IrpSp);
{
return HidClassFDO_RemoveDevice(DeviceObject, Irp);
}
+ case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_QUERY_STOP_DEVICE:
{
//
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
}
+ case IRP_MN_CANCEL_REMOVE_DEVICE:
case IRP_MN_CANCEL_STOP_DEVICE:
{
//
}
//
- // done
+ // delete and detach device
//
+ IoDetachDevice(DeviceExtension->NextDeviceObject);
+ IoDeleteDevice(DeviceObject);
+
return Status;
}
case IRP_MN_QUERY_PNP_DEVICE_STATE:
//
return Status;
}
+ case IRP_MN_QUERY_STOP_DEVICE:
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ {
+ //
+ // we're fine with it
+ //
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ //
+ // pass request to next driver
+ //
+ IoSkipCurrentIrpStackLocation(Irp);
+ Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+
+ //
+ // done
+ //
+ return Status;
+ }
case IRP_MN_STOP_DEVICE:
{
//
IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT1("[KBDHID] IRP_MJ_PNP Request: %x\n", IoStack->MinorFunction);
- if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE || IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE)
+ if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE ||
+ IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE ||
+ IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE ||
+ IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE ||
+ IoStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE)
{
/* indicate success */
Irp->IoStatus.Status = STATUS_SUCCESS;
IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT1("[MOUHID] IRP_MJ_PNP Request: %x\n", IoStack->MinorFunction);
- if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE || IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE)
+ if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE ||
+ IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE ||
+ IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE ||
+ IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE ||
+ IoStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE)
{
/* indicate success */
Irp->IoStatus.Status = STATUS_SUCCESS;
}
break;
}
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ case IRP_MN_QUERY_STOP_DEVICE:
+ {
+ //
+ // sure
+ //
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ //
+ // forward irp to next device object
+ //
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
+ }
default:
{
//
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ case IRP_MN_QUERY_STOP_DEVICE:
+ {
+ //
+ // sure
+ //
+ Status = STATUS_SUCCESS;
+ break;
+ }
case IRP_MN_START_DEVICE:
{
//
// do nothing
//
Status = Irp->IoStatus.Status;
+ break;
}
}
Status = SetDeviceInterface(TRUE);
break;
}
+ case IRP_MN_QUERY_STOP_DEVICE:
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ {
+ //
+ // sure
+ //
+ Status = STATUS_SUCCESS;
+ break;
+ }
case IRP_MN_QUERY_ID:
{
DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_ID Type %x\n", IoStack->Parameters.QueryId.IdType);
}
break;
}
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ case IRP_MN_QUERY_STOP_DEVICE:
+ {
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ return ForwardIrpAndForget(DeviceObject, Irp);
+ }
+ case IRP_MN_REMOVE_DEVICE:
+ {
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ IoDetachDevice(HubDeviceExtension->LowerDeviceObject);
+ IoDeleteDevice(DeviceObject);
+
+ return STATUS_SUCCESS;
+ }
case IRP_MN_QUERY_BUS_INFORMATION:
{
DPRINT1("IRP_MN_QUERY_BUS_INFORMATION\n");
IoDeleteDevice(DeviceObject);
return STATUS_SUCCESS;
}
+ case IRP_MN_QUERY_STOP_DEVICE:
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ {
+ /* Sure, no problem */
+ Status = STATUS_SUCCESS;
+ Information = 0;
+ break;
+ }
default:
{
DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
Status = SetDeviceInterface(TRUE);
break;
}
+ case IRP_MN_QUERY_STOP_DEVICE:
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ {
+ //
+ // sure
+ //
+ Status = STATUS_SUCCESS;
+ break;
+ }
case IRP_MN_QUERY_ID:
{
DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_ID Type %x\n", IoStack->Parameters.QueryId.IdType);
break;
}
case IRP_MN_STOP_DEVICE:
+ {
DPRINT1("USBSTOR_FdoHandlePnp: IRP_MN_STOP_DEVICE unimplemented\n");
Status = STATUS_NOT_SUPPORTED;
break;
+ }
case IRP_MN_REMOVE_DEVICE:
{
DPRINT1("IRP_MN_REMOVE_DEVICE\n");
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
}
+ case IRP_MN_QUERY_STOP_DEVICE:
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ {
+ //
+ // we can if nothing is pending
+ //
+ if (DeviceExtension->IrpPendingCount != 0 ||
+ DeviceExtension->ActiveSrb != NULL)
+ {
+ /* We have pending requests */
+ DPRINT1("Failing removal/stop request due to pending requests present\n");
+ Status = STATUS_UNSUCCESSFUL;
+ }
+ else
+ {
+ /* We're all clear */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ IoSkipCurrentIrpStackLocation(Irp);
+ return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
+ }
+ break;
+ }
case IRP_MN_START_DEVICE:
{
Status = USBSTOR_FdoHandleStartDevice(DeviceObject, DeviceExtension, Irp);
}
break;
}
+ case IRP_MN_QUERY_REMOVE_DEVICE:
+ case IRP_MN_QUERY_STOP_DEVICE:
+ {
+ //
+ // if we're not claimed it's ok
+ //
+ if (DeviceExtension->Claimed)
+ Status = STATUS_UNSUCCESSFUL;
+ else
+ Status = STATUS_SUCCESS;
+ break;
+ }
case IRP_MN_START_DEVICE:
{
//