⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umsspnp.c

📁 usb海量存储的驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/*++
Routine Description:

    Dispatch table routine for IRP_MJ_PNP.
    Process the Plug and Play IRPs sent to our PDO.

Arguments:

    DeviceObject - pointer to our child PDO
    Irp          - pointer to an I/O Request Packet

Return Value:

    NT status code

--*/

{
    PIO_STACK_LOCATION irpStack;
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PDEVICE_OBJECT stackDeviceObject;

    //
    // Get a pointer to the current location in the Irp. This is where
    //     the function codes and parameters are located.
    //
    
    ENTER(UMSS_PdoProcessPnPIrp);

    irpStack = IoGetCurrentIrpStackLocation (Irp);

    //
    // Get a pointer to the device extension
    //

    deviceExtension = DeviceObject->DeviceExtension;
    stackDeviceObject = deviceExtension->TopOfStackDeviceObject;

    UMSS_KdPrint( DBGLVL_MEDIUM, ( "enter UMSS_ProcessPnPIrp() IRP_MJ_PNP, minor %s\n",
    UMSS_StringForPnpMnFunc( irpStack->MinorFunction ) ));

    // inc the FDO device extension's pending IO count for this Irp
    //UMSS_IncrementIoCount(DeviceObject);

    UMSS_ASSERT( IRP_MJ_PNP == irpStack->MajorFunction );

    switch (irpStack->MinorFunction)
    {
        case IRP_MN_QUERY_DEVICE_RELATIONS:
            ntStatus = UMSS_PdoDeviceQuery(DeviceObject, Irp);
            break;


	case IRP_MN_QUERY_ID:
            ntStatus = UMSS_PdoQueryID(DeviceObject, Irp);
            break;


	case IRP_MN_REMOVE_DEVICE:
            IoDeleteDevice(DeviceObject);
            break;


	case IRP_MN_QUERY_BUS_INFORMATION:
            ntStatus = UMSS_QueryBusInfo(DeviceObject, Irp);
            break;
    }

    RETURN(ntStatus, UMSS_PdoProcessPnPIrp);
}


NTSTATUS
UMSS_QueryBusInfo(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++
Routine Description:

    Handler for IRP_MN_QUERY_BUS_INFO.  Returns info about our virtual bus.

Arguments:

    DeviceObject - pointer to our child PDO
    Irp          - pointer to an I/O Request Packet

Return Value:

    NT status code

--*/

{
    NTSTATUS ntStatus;
    PIO_STACK_LOCATION irpStack;
    PPNP_BUS_INFORMATION BusInfo;
        	
    ENTER(UMSS_QueryBusInfo);

    irpStack = IoGetCurrentIrpStackLocation(Irp);

    BusInfo = ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));

    // If we can't allocate BusInfo structure, bail
    if (!BusInfo)
    {
        Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }
    else
    {
        BusInfo->BusTypeGuid = GUID_BUS_UMSS;
        BusInfo->LegacyBusType = PNPBus;
        BusInfo->BusNumber = 0;
			
        Irp->IoStatus.Information = (ULONG)BusInfo;
        ntStatus = Irp->IoStatus.Status = STATUS_SUCCESS;
    }

    RETURN(ntStatus, UMSS_QueryBusInfo);
}										



NTSTATUS
UMSS_PdoDeviceQuery(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
/*++
Routine Description:

    Handler for IRP_MN_QUERY_DEVICE_RELATIONS for our virtual child device.
    
Arguments:

    DeviceObject - pointer to our child PDO
    Irp          - pointer to an I/O Request Packet

Return Value:

    NT status code

--*/

{
    NTSTATUS ntStatus;
    PIO_STACK_LOCATION irpStack;
    PDEVICE_RELATIONS DeviceRelations;
    PDEVICE_EXTENSION DeviceExtension;
        	
    ENTER(UMSS_PdoDeviceQuery);

    irpStack = IoGetCurrentIrpStackLocation(Irp);
    DeviceExtension = DeviceObject->DeviceExtension;

    switch (irpStack->Parameters.QueryDeviceRelations.Type)
    {
	case TargetDeviceRelation:

            // Allocate space for 1 child device
            DeviceRelations = UMSS_ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));

            // If we can't allocate DeviceRelations structure, bail
            if (!DeviceRelations)
            {
                Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
            }
            else
            {
                ObReferenceObject(DeviceObject);
			
                DeviceRelations->Count = 1;
                DeviceRelations->Objects[0] = DeviceObject;
			
                Irp->IoStatus.Information = (ULONG)DeviceRelations;
                ntStatus = Irp->IoStatus.Status = STATUS_SUCCESS;
            }
		
            break;

	default:
            ntStatus = Irp->IoStatus.Status;
    }

    RETURN(ntStatus, UMSS_PdoDeviceQuery);
}										



NTSTATUS
UMSS_PdoQueryID(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
/*++
Routine Description:

    Handler for IRP_MN_QUERY_ID.  Returns hardware, device, and instance
    IDs for our virtual child PDO.

Arguments:

    DeviceObject - pointer to our child PDO
    Irp          - pointer to an I/O Request Packet

Return Value:

    NT status code

--*/

{
    PIO_STACK_LOCATION ioStack;
    PWCHAR buffer;
    WCHAR IDString[] = CHILD_DEVICE_ID;
    WCHAR InstanceIDString[] = L"0000";
    ULONG length;

    ENTER(UMSS_PdoQueryID);

    ioStack = IoGetCurrentIrpStackLocation(Irp);

    switch (ioStack->Parameters.QueryId.IdType)
    {
        case BusQueryHardwareIDs:
            // return a multi WCHAR (null terminated) string (null terminated)
            // array for use in matching hardare ids in inf files;


        case BusQueryDeviceID:
            // return a WCHAR (null terminated) string describing the device
            // For symplicity we make it exactly the same as the Hardware ID.
       
            length = sizeof (IDString) * sizeof(WCHAR);
            buffer = ExAllocatePool (PagedPool, length);

            if (buffer)
            {
                RtlCopyMemory (buffer, IDString, length);
            }

            Irp->IoStatus.Information = (ULONG) buffer;
            break;


        case BusQueryInstanceID:
            length = sizeof (InstanceIDString) * sizeof(WCHAR);
            buffer = ExAllocatePool (PagedPool, length);

            if (buffer)
            {
                RtlCopyMemory (buffer, InstanceIDString, length);
            }

            Irp->IoStatus.Information = (ULONG) buffer;
            break;
    }

    RETURN(STATUS_SUCCESS, UMSS_PdoQueryID);
}


NTSTATUS
UMSS_AbortPipes(
    IN PDEVICE_OBJECT DeviceObject
    )
/*++

Routine Description:

    Called as part of sudden device removal handling.
    Cancels any pending transfers for all open pipes. 
    If any pipes are still open, call USBD with URB_FUNCTION_ABORT_PIPE
    Also marks the pipe 'closed' in our saved  configuration info.

Arguments:

    Ptrs to our FDO

Return Value:

    NT status code

--*/

{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PURB urb;
    PDEVICE_EXTENSION deviceExtension;
    ULONG i;

    PUSBD_INTERFACE_INFORMATION interface;
    PUSBD_PIPE_INFORMATION PipeInfo;

    ENTER(UMSS_AbortPipes);

    deviceExtension = DeviceObject->DeviceExtension;
    interface = deviceExtension->UsbInterface;

    for (i=0; i<interface->NumberOfPipes; i++)
    {
        PipeInfo =  &interface->Pipes[i]; // PUSBD_PIPE_INFORMATION  PipeInfo;

        if ( PipeInfo->PipeFlags )
        {
            UMSS_KdPrint( DBGLVL_HIGH,("UMSS_AbortPipes() Aborting open  Pipe %d\n", i));

            urb = UMSS_ExAllocatePool(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));

            if (urb)
            {
                urb->UrbHeader.Length = (USHORT) sizeof (struct _URB_PIPE_REQUEST);
                urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
                urb->UrbPipeRequest.PipeHandle = PipeInfo->PipeHandle;

                ntStatus = UMSS_CallUSBD(DeviceObject, urb);

                UMSS_ExFreePool(urb);

            }
            else
            {
                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                UMSS_KdPrint( DBGLVL_HIGH,("UMSS_AbortPipes() FAILED urb alloc\n" ));
                break;
            }


            if (!(NT_SUCCESS(ntStatus)))
            {
                // if we failed, dump out
#if DBG
                if ( gpDbg )
                    gpDbg->PipeErrorCount++;
#endif
                break;
            }
            else
            {
                PipeInfo->PipeFlags = FALSE; // mark the pipe 'closed'
                deviceExtension->OpenPipeCount--;
#if DBG
                if ( gpDbg )
                    gpDbg->AbortPipeCount++;
#endif
            }

        } // end, if pipe open
    } // end, for all pipes

    RETURN(ntStatus, UMSS_AbortPipes);
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -