Example #1
0
File: pnp.c Project: GYGit/reactos
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #6
0
///////////////////////////////////////////////////////////////////////////////////////////////////
//  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));
    }
}
Example #7
0
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;
}
Example #8
0
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";
    }
}