NTSTATUS NTAPI Bus_PnP ( PDEVICE_OBJECT DeviceObject, PIRP Irp ) { PIO_STACK_LOCATION irpStack; NTSTATUS status; PCOMMON_DEVICE_DATA commonData; PAGED_CODE (); irpStack = IoGetCurrentIrpStackLocation (Irp); ASSERT (IRP_MJ_PNP == irpStack->MajorFunction); commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension; if (commonData->IsFDO) { DPRINT("FDO %s IRP:0x%p\n", PnPMinorFunctionString(irpStack->MinorFunction), Irp); // // Request is for the bus FDO // status = Bus_FDO_PnP ( DeviceObject, Irp, irpStack, (PFDO_DEVICE_DATA) commonData); } else { DPRINT("PDO %s IRP: 0x%p\n", PnPMinorFunctionString(irpStack->MinorFunction), Irp); // // Request is for the child PDO. // status = Bus_PDO_PnP ( DeviceObject, Irp, irpStack, (PPDO_DEVICE_DATA) commonData); } return status; }
NTSTATUS Bus_PnP(PDEVICE_OBJECT DeviceObject, PIRP Irp) { PIO_STACK_LOCATION irpStack; NTSTATUS status; PCOMMON_DEVICE_DATA commonData; PAGED_CODE(); irpStack = IoGetCurrentIrpStackLocation(Irp); ASSERT(IRP_MJ_PNP == irpStack->MajorFunction); commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension; if (commonData->DevicePnPState == Deleted) { Irp->IoStatus.Status = status = STATUS_NO_SUCH_DEVICE ; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } if (commonData->IsFDO) { Bus_KdPrint(("FDO %s IRP:0x%p\n", PnPMinorFunctionString(irpStack->MinorFunction), Irp)); status = Bus_FDO_PnP(DeviceObject, Irp, irpStack, (PFDO_DEVICE_DATA) commonData); } else { Bus_KdPrint(("PDO %s IRP: 0x%p\n", PnPMinorFunctionString(irpStack->MinorFunction), Irp)); status = Bus_PDO_PnP(DeviceObject, Irp, irpStack, (PPDO_DEVICE_DATA) commonData); } return status; }
NTSTATUS Bus_PnP ( __in PDEVICE_OBJECT DeviceObject, __in PIRP Irp ) /*++ Routine Description: Handles PnP Irps sent to both FDO and child PDOs. Arguments: DeviceObject - Pointer to deviceobject Irp - Pointer to a PnP Irp. Return Value: NT Status is returned. --*/ { PIO_STACK_LOCATION irpStack; NTSTATUS status; PCOMMON_DEVICE_DATA commonData; PAGED_CODE (); KdPrint(("Bus_PnP\r\n")); irpStack = IoGetCurrentIrpStackLocation (Irp); ASSERT (IRP_MJ_PNP == irpStack->MajorFunction); commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension; // // If the device has been removed, the driver should // not pass the IRP down to the next lower driver. // if (commonData->DevicePnPState == Deleted) { Irp->IoStatus.Status = status = STATUS_NO_SUCH_DEVICE ; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } if (commonData->IsFDO) { Bus_KdPrint (commonData, BUS_DBG_PNP_TRACE, ("FDO %s IRP:0x%p\n", PnPMinorFunctionString(irpStack->MinorFunction), Irp)); // // Request is for the bus FDO // status = Bus_FDO_PnP ( DeviceObject, Irp, irpStack, (PFDO_DEVICE_DATA) commonData); } else { Bus_KdPrint (commonData, BUS_DBG_PNP_TRACE, ("PDO %s IRP: 0x%p\n", PnPMinorFunctionString(irpStack->MinorFunction), Irp)); // // Request is for the child PDO. // status = Bus_PDO_PnP ( DeviceObject, Irp, irpStack, (PPDO_DEVICE_DATA) commonData); } return status; }
NTSTATUS PPJoyBus_PnP_Joy (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS ntStatus; PIO_STACK_LOCATION IrpStack; PJOY_DEVICE_DATA JoyDeviceData; WCHAR LinkNameBuffer[128]; UNICODE_STRING LinkName; PAGED_CODE(); PPJOY_DBGPRINT (FILE_PNP|PPJOY_FENTRY,("PPJoyBus_PnP_Joy(DeviceObject=0x%p,Irp=0x%p)",DeviceObject,Irp) ); IrpStack = IoGetCurrentIrpStackLocation (Irp); JoyDeviceData= (PJOY_DEVICE_DATA)DeviceObject->DeviceExtension; switch(IrpStack->MinorFunction) { case IRP_MN_START_DEVICE: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_START_DEVICE") ); ntStatus= PPJoyBus_JoyStartDevice (JoyDeviceData,Irp); goto CompleteIRP; case IRP_MN_STOP_DEVICE: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_STOP_DEVICE") ); PPJoyBus_JoyStopDevice (JoyDeviceData,Irp); /* This routine must always return success. */ ntStatus= STATUS_SUCCESS; goto CompleteIRP; case IRP_MN_QUERY_STOP_DEVICE: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_QUERY_STOP_DEVICE") ); /* Always accept stop device request */ ntStatus= STATUS_SUCCESS; goto CompleteIRP; case IRP_MN_CANCEL_STOP_DEVICE: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_CANCEL_STOP_DEVICE") ); /* Canceling stop requests always successful */ ntStatus= STATUS_SUCCESS; goto CompleteIRP; case IRP_MN_QUERY_REMOVE_DEVICE: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_QUERY_REMOVE_DEVICE") ); /* Always accept remove requests */ ntStatus= STATUS_SUCCESS; goto CompleteIRP; case IRP_MN_CANCEL_REMOVE_DEVICE: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_CANCEL_REMOVE_DEVICE") ); /* Cancelling remove requests always successful */ ntStatus= STATUS_SUCCESS; goto CompleteIRP; case IRP_MN_QUERY_CAPABILITIES: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_QUERY_CAPABILITIES") ); ntStatus= PPJoyBus_JoyQueryCaps (JoyDeviceData,Irp); goto CompleteIRP; case IRP_MN_QUERY_DEVICE_RELATIONS: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_QUERY_DEVICE_RELATIONS type %s",DbgDeviceRelationString(IrpStack->Parameters.QueryDeviceRelations.Type)) ); ntStatus= PPJoyBus_JoyDevRelations (JoyDeviceData,Irp); goto CompleteIRP; case IRP_MN_QUERY_RESOURCES: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_QUERY_RESOURCES") ); /* Simply copy the status of the incoming IRP to return back */ ntStatus= Irp->IoStatus.Status; goto CompleteIRP; #if 0 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_QUERY_RESOURCE_REQUIREMENTS") ); ntStatus= PPJoyBus_JoyQueryResourceRequirements (JoyDeviceData,Irp); goto CompleteIRP; #endif case IRP_MN_DEVICE_USAGE_NOTIFICATION: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_DEVICE_USAGE_NOTIFICATION") ); ntStatus= STATUS_UNSUCCESSFUL; goto CompleteIRP; case IRP_MN_SURPRISE_REMOVAL: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_SURPRISE_REMOVAL") ); /* Simply say request was successful */ ntStatus= STATUS_SUCCESS; goto CompleteIRP; case IRP_MN_REMOVE_DEVICE: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_REMOVE_DEVICE") ); /* We stop the device if it wasn't done before the remove */ if (JoyDeviceData->Flags&PPJFLAGS_STARTED) PPJoyBus_JoyStopDevice (JoyDeviceData,Irp); /* Set the DeviceExtension flag to say that our device is removed */ JoyDeviceData->Flags|= PPJFLAGS_REMOVED; /* Leave request to decrease requests counter. Event should be */ /* signaled when last request leaves. Then we will return a */ /* successful status. */ PPJoyBus_LeaveRequest((PCOMMON_DATA)JoyDeviceData); KeWaitForSingleObject (&JoyDeviceData->RemoveEvent,Executive,KernelMode,FALSE,NULL); PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE2, ("KeWaitForSingleObject on RemoveEvent completed.") ); /* If our Joystick is unplugged (via control panel applet) then we */ /* delete the device object for it as well. Else we only mark it */ /* as being removed. (Can later be AddDevice and START'ed again) */ if (JoyDeviceData->Flags&PPJFLAGS_UNPLUGGED) { /* Remove the PDO from joystick list. */ ExAcquireFastMutex (&Globals.Mutex); RemoveEntryList (&JoyDeviceData->ListEntry); ExReleaseFastMutex (&Globals.Mutex); PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE2, ("Device unplugged so we will delete the PDO.") ); /* Then nuke the PDO out of existance */ IoDeleteDevice (JoyDeviceData->Self); } /* The hardware is still physically present. We are ready to be */ /* started again - so clear the REMOVED flag. Should work. */ JoyDeviceData->Flags&= ~PPJFLAGS_REMOVED; /* After all that indicate that the request was successful */ ntStatus= STATUS_SUCCESS; goto CompleteIRP; case IRP_MN_QUERY_ID: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_QUERY_ID type %s",DbgDeviceIDString(IrpStack->Parameters.QueryId.IdType)) ); ntStatus= PPJoyBus_JoyQueryIDs (JoyDeviceData,Irp); goto CompleteIRP; case IRP_MN_QUERY_DEVICE_TEXT: PPJOY_DBGPRINT (FILE_PNP|PPJOY_BABBLE, ("PPJoyBus_PnP_Joy: IRP_MN_QUERY_DEVICE_TEXT") ); ntStatus= PPJoyBus_JoyQueryDevText (JoyDeviceData,Irp); goto CompleteIRP; default: PPJOY_DBGPRINT (FILE_PNP|PPJOY_WARN,("PPJoyBus_PnP_Joy: IrpStack->MinorFunction Not handled %s (0x%x)",PnPMinorFunctionString (IrpStack->MinorFunction),IrpStack->MinorFunction) ); /* Simply copy the status of the incoming IRP to return back */ ntStatus= Irp->IoStatus.Status; goto CompleteIRP; } CompleteIRP: Irp->IoStatus.Status = ntStatus; IoCompleteRequest (Irp, IO_NO_INCREMENT); goto Exit; Exit: PPJOY_EXITPROC (FILE_PNP|PPJOY_FEXIT, "PPJoyBus_PnP_Joy",ntStatus ); return ntStatus; }
//======================================================================================== // Function: DispatchPnp // Purpose: // Return Value: // NT status code //======================================================================================== NTSTATUS DispatchPnp ( IN PDEVICE_OBJECT fido, // fido - pointer to a device object. IN PIRP irp // Irp - pointer to an I/O Request Packet. ) { PDEVICE_EXTENSION dx; PIO_STACK_LOCATION irpStack; NTSTATUS ntStatus = STATUS_SUCCESS; PAGED_CODE(); dx = (PDEVICE_EXTENSION)fido->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(irp); //acquire remove lock ntStatus = IoAcquireRemoveLock(&dx->rmLock, irp); if (!NT_SUCCESS(ntStatus)) { //complete irp if cannot acquire remove lock irp->IoStatus.Status=ntStatus; irp->IoStatus.Information=0; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } PnPMinorFunctionString(irpStack->MinorFunction); switch (irpStack->MinorFunction) { case IRP_MN_START_DEVICE: //The device is starting. //We cannot touch the device (send it any non pnp irps) until a //start device has been passed down to the lower drivers. IoCopyCurrentIrpStackLocationToNext(irp); IoSetCompletionRoutine(irp, (PIO_COMPLETION_ROUTINE)CompletionRoutineStartDevice, NULL, TRUE, TRUE, TRUE); return IoCallDriver(dx->lowerdo, irp); case IRP_MN_REMOVE_DEVICE: IoSkipCurrentIrpStackLocation(irp); ntStatus = IoCallDriver(dx->lowerdo, irp); IoReleaseRemoveLockAndWait(&dx->rmLock, irp); SET_NEW_PNP_STATE(dx, Deleted); IoDetachDevice(dx->lowerdo); IoDeleteDevice(fido); return ntStatus; case IRP_MN_QUERY_STOP_DEVICE: SET_NEW_PNP_STATE(dx, StopPending); break; case IRP_MN_CANCEL_STOP_DEVICE: //Check to see whether you have received cancel-stop //without first receiving a query-stop. This could happen if someone //above us fails a query-stop and passes down the subsequent //cancel-stop. if(dx->DevicePnPState == StopPending) { //We did receive a query-stop, so restore. RESTORE_PREVIOUS_PNP_STATE(dx); } //We must not fail this IRP. break; case IRP_MN_STOP_DEVICE: SET_NEW_PNP_STATE(dx, Stopped); break; case IRP_MN_QUERY_REMOVE_DEVICE: SET_NEW_PNP_STATE(dx, RemovePending); break; case IRP_MN_SURPRISE_REMOVAL: SET_NEW_PNP_STATE(dx, SurpriseRemovePending); break; case IRP_MN_CANCEL_REMOVE_DEVICE: //Check to see whether you have received cancel-remove //without first receiving a query-remove. This could happen if //someone above us fails a query-remove and passes down the //subsequent cancel-remove. if(dx->DevicePnPState == RemovePending) { //We did receive a query-remove, so restore. RESTORE_PREVIOUS_PNP_STATE(dx); } //We must not fail this IRP. break; case IRP_MN_DEVICE_USAGE_NOTIFICATION: //On the way down, pagable might become set. Mimic the driver //above us. If no one is above us, just set pagable. if ((fido->AttachedDevice == NULL) || (fido->AttachedDevice->Flags & DO_POWER_PAGABLE)) { fido->Flags |= DO_POWER_PAGABLE; } IoCopyCurrentIrpStackLocationToNext(irp); IoSetCompletionRoutine(irp, CompletionRoutineDevUsgNotify, NULL, TRUE, TRUE, TRUE); return IoCallDriver(dx->lowerdo, irp); default: break; } IoSkipCurrentIrpStackLocation(irp); ntStatus = IoCallDriver(dx->lowerdo, irp); IoReleaseRemoveLock(&dx->rmLock, irp); return ntStatus; }
/////////////////////////////////////////////////////////////////////////////////////////////////// // testdrvDumpIrp // Dump Irp fields to the debugger. // // Arguments: // IN Irp // Irp to display // // Return Value: // None. // VOID testdrvDumpIrp( IN PIRP Irp ) { ULONG debugArea; PIO_STACK_LOCATION irpStack; // Get our current IRP stack location irpStack = IoGetCurrentIrpStackLocation(Irp); // determine debug area switch (irpStack->MajorFunction) { case IRP_MJ_PNP: debugArea = DBG_PNP; break; case IRP_MJ_POWER: debugArea = DBG_POWER; break; case IRP_MJ_CREATE: case IRP_MJ_CLOSE: case IRP_MJ_CLEANUP: debugArea = DBG_CREATECLOSE; break; case IRP_MJ_SYSTEM_CONTROL: debugArea = DBG_WMI; break; case IRP_MJ_READ: case IRP_MJ_WRITE: case IRP_MJ_DEVICE_CONTROL: case IRP_MJ_INTERNAL_DEVICE_CONTROL: debugArea = DBG_IO; break; default: debugArea = DBG_GENERAL; break; } testdrvDebugPrint(debugArea, DBG_INFO, "IRP %p %s", Irp, IrpMajorFunctionString(irpStack->MajorFunction)); if (irpStack->MajorFunction == IRP_MJ_PNP) { testdrvDebugPrint(debugArea, DBG_INFO, "%s", PnPMinorFunctionString(irpStack->MinorFunction)); } else if (irpStack->MajorFunction == IRP_MJ_POWER) { testdrvDebugPrint(debugArea, DBG_INFO, "%s", PowerMinorFunctionString(irpStack->MinorFunction)); if (irpStack->Parameters.Power.Type == SystemPowerState) { testdrvDebugPrint(debugArea, DBG_INFO, "%s", SystemPowerStateString(irpStack->Parameters.Power.State.SystemState)); } else { testdrvDebugPrint(debugArea, DBG_INFO, "%s", DevicePowerStateString(irpStack->Parameters.Power.State.DeviceState)); } } else if (irpStack->MajorFunction == IRP_MJ_SYSTEM_CONTROL) { testdrvDebugPrint(debugArea, DBG_INFO, "%s", WMIMinorFunctionString(irpStack->MinorFunction)); } }
NTSTATUS FilterDispatchPnp ( PDEVICE_OBJECT DeviceObject, PIRP Irp ) /*++ Routine Description: The plug and play dispatch routines. Most of these the driver will completely ignore. In all cases it must pass on the IRP to the lower driver. Arguments: DeviceObject - pointer to a device object. Irp - pointer to an I/O Request Packet. Return Value: NT status code --*/ { PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION irpStack; NTSTATUS status; KEVENT event; PAGED_CODE(); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); DebugPrint(("FilterDO %s IRP:0x%p \n", PnPMinorFunctionString(irpStack->MinorFunction), Irp)); status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp); if (!NT_SUCCESS (status)) { Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } switch (irpStack->MinorFunction) { case IRP_MN_START_DEVICE: // // The device is starting. // We cannot touch the device (send it any non pnp irps) until a // start device has been passed down to the lower drivers. // KeInitializeEvent(&event, NotificationEvent, FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, FilterStartCompletionRoutine, &event, TRUE, TRUE, TRUE); status = IoCallDriver(deviceExtension->NextLowerDriver, Irp); // // Wait for lower drivers to be done with the Irp. Important thing to // note here is when you allocate memory for an event in the stack // you must do a KernelMode wait instead of UserMode to prevent // the stack from getting paged out. // if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = Irp->IoStatus.Status; } if (NT_SUCCESS (status)) { // // As we are successfully now back, we will // first set our state to Started. // SET_NEW_PNP_STATE(deviceExtension, Started); // // On the way up inherit FILE_REMOVABLE_MEDIA during Start. // This characteristic is available only after the driver stack is started!. // if (deviceExtension->NextLowerDriver->Characteristics & FILE_REMOVABLE_MEDIA) { DeviceObject->Characteristics |= FILE_REMOVABLE_MEDIA; } #ifdef IOCTL_INTERFACE // // If the PreviousPnPState is stopped then we are being stopped temporarily // and restarted for resource rebalance. // if (Stopped != deviceExtension->PreviousPnPState) { // // Device is started for the first time. // FilterCreateControlObject(DeviceObject); } #endif } Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); return status; case IRP_MN_REMOVE_DEVICE: // // Wait for all outstanding requests to complete // DebugPrint(("Waiting for outstanding requests\n")); IoReleaseRemoveLockAndWait(&deviceExtension->RemoveLock, Irp); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver, Irp); SET_NEW_PNP_STATE(deviceExtension, Deleted); #ifdef IOCTL_INTERFACE FilterDeleteControlObject(); #endif IoDetachDevice(deviceExtension->NextLowerDriver); IoDeleteDevice(DeviceObject); return status; case IRP_MN_QUERY_STOP_DEVICE: SET_NEW_PNP_STATE(deviceExtension, StopPending); status = STATUS_SUCCESS; break; case IRP_MN_CANCEL_STOP_DEVICE: // // Check to see whether you have received cancel-stop // without first receiving a query-stop. This could happen if someone // above us fails a query-stop and passes down the subsequent // cancel-stop. // if (StopPending == deviceExtension->DevicePnPState) { // // We did receive a query-stop, so restore. // RESTORE_PREVIOUS_PNP_STATE(deviceExtension); } status = STATUS_SUCCESS; // We must not fail this IRP. break; case IRP_MN_STOP_DEVICE: SET_NEW_PNP_STATE(deviceExtension, Stopped); status = STATUS_SUCCESS; break; case IRP_MN_QUERY_REMOVE_DEVICE: SET_NEW_PNP_STATE(deviceExtension, RemovePending); status = STATUS_SUCCESS; break; case IRP_MN_SURPRISE_REMOVAL: SET_NEW_PNP_STATE(deviceExtension, SurpriseRemovePending); status = STATUS_SUCCESS; break; case IRP_MN_CANCEL_REMOVE_DEVICE: // // Check to see whether you have received cancel-remove // without first receiving a query-remove. This could happen if // someone above us fails a query-remove and passes down the // subsequent cancel-remove. // if (RemovePending == deviceExtension->DevicePnPState) { // // We did receive a query-remove, so restore. // RESTORE_PREVIOUS_PNP_STATE(deviceExtension); } status = STATUS_SUCCESS; // We must not fail this IRP. break; case IRP_MN_DEVICE_USAGE_NOTIFICATION: // // On the way down, pagable might become set. Mimic the driver // above us. If no one is above us, just set pagable. // #pragma prefast(suppress:__WARNING_INACCESSIBLE_MEMBER) if ((DeviceObject->AttachedDevice == NULL) || (DeviceObject->AttachedDevice->Flags & DO_POWER_PAGABLE)) { DeviceObject->Flags |= DO_POWER_PAGABLE; } IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine( Irp, FilterDeviceUsageNotificationCompletionRoutine, NULL, TRUE, TRUE, TRUE ); return IoCallDriver(deviceExtension->NextLowerDriver, Irp); default: // // If you don't handle any IRP you must leave the // status as is. // status = Irp->IoStatus.Status; break; } // // Pass the IRP down and forget it. // Irp->IoStatus.Status = status; IoSkipCurrentIrpStackLocation (Irp); status = IoCallDriver (deviceExtension->NextLowerDriver, Irp); IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); return status; }
PCHAR MajorFunctionString(UCHAR MajorFunction, LONG MinorFunction) { switch (MajorFunction) { case IRP_MJ_CREATE: return "IRP_MJ_CREATE"; case IRP_MJ_CREATE_NAMED_PIPE: return "IRP_MJ_CREATE_NAMED_PIPE"; case IRP_MJ_CLOSE: return "IRP_MJ_CLOSE"; case IRP_MJ_READ: return "IRP_MJ_READ"; case IRP_MJ_WRITE: return "IRP_MJ_WRITE"; case IRP_MJ_QUERY_INFORMATION: return "IRP_MJ_QUERY_INFORMATION"; case IRP_MJ_SET_INFORMATION: return "IRP_MJ_SET_INFORMATION"; case IRP_MJ_QUERY_EA: return "IRP_MJ_QUERY_EA"; case IRP_MJ_SET_EA: return "IRP_MJ_SET_EA"; case IRP_MJ_FLUSH_BUFFERS: return "IRP_MJ_FLUSH_BUFFERS"; case IRP_MJ_QUERY_VOLUME_INFORMATION: return "IRP_MJ_QUERY_VOLUME_INFORMATION"; case IRP_MJ_SET_VOLUME_INFORMATION: return "IRP_MJ_SET_VOLUME_INFORMATION"; case IRP_MJ_DIRECTORY_CONTROL: return "IRP_MJ_DIRECTORY_CONTROL"; case IRP_MJ_FILE_SYSTEM_CONTROL: return "IRP_MJ_FILE_SYSTEM_CONTROL"; case IRP_MJ_DEVICE_CONTROL: return "IRP_MJ_DEVICE_CONTROL"; case IRP_MJ_INTERNAL_DEVICE_CONTROL: return "IRP_MJ_INTERNAL_DEVICE_CONTROL"; case IRP_MJ_SHUTDOWN: return "IRP_MJ_SHUTDOWN"; case IRP_MJ_LOCK_CONTROL: return "IRP_MJ_LOCK_CONTROL"; case IRP_MJ_CLEANUP: return "IRP_MJ_CLEANUP"; case IRP_MJ_CREATE_MAILSLOT: return "IRP_MJ_CREATE_MAILSLOT"; case IRP_MJ_QUERY_SECURITY: return "IRP_MJ_QUERY_SECURITY"; case IRP_MJ_SET_SECURITY: return "IRP_MJ_SET_SECURITY"; case IRP_MJ_POWER: return "IRP_MJ_POWER"; case IRP_MJ_SYSTEM_CONTROL: return "IRP_MJ_SYSTEM_CONTROL"; case IRP_MJ_DEVICE_CHANGE: return "IRP_MJ_DEVICE_CHANGE"; case IRP_MJ_QUERY_QUOTA: return "IRP_MJ_QUERY_QUOTA"; case IRP_MJ_SET_QUOTA: return "IRP_MJ_SET_QUOTA"; case IRP_MJ_PNP: return PnPMinorFunctionString(MinorFunction); default: return "unknown_pnp_irp"; } }