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

📄 usblspnp.c

📁 usb驱动源代码。98的
💻 C
📖 第 1 页 / 共 3 页
字号:
NTSTATUS
USBLS120_IrpCompletionRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    )
/*++

Routine Description:

    Used as a  general purpose completion routine so it can signal an event,
    passed as the Context, when the next lower driver is done with the input Irp.
    This routine is used by both PnP and Power Management logic.

    Even though this routine does nothing but set an event, it must be defined and
    prototyped as a completetion routine for use as such


Arguments:

    DeviceObject - Pointer to the device object for the class device.

    Irp - Irp completed.

    Context - Driver defined context, in this case a pointer to an event.

Return Value:

    The function value is the final status from the operation.

--*/
{
    PKEVENT event = Context;

    // Set the input event
    KeSetEvent(
        event,
        1,       // Priority increment  for waiting thread.
        FALSE);  // Flag this call is not immediately followed by wait.

    // This routine must return STATUS_MORE_PROCESSING_REQUIRED because we have not yet called
    // IoFreeIrp() on this IRP.
    return STATUS_MORE_PROCESSING_REQUIRED;

}


NTSTATUS
USBLS120_FdoDeviceQuery(
    IN PDEVICE_OBJECT pDeviceObject,
    IN PIRP pIrp)
/*++

Routine Description:

    Handler for IRP_MN_QUERY_DEVICE_RELATIONS.
    Enumerates our child PDO.

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;
    PDEVICE_EXTENSION PdoExtension;
    UNICODE_STRING PdoUniName;
    static UCHAR PdoCount=0;

    //NOTE: This name be unique to each hardware vendor
    //      to avoid name collision between different
    //      drivers based on this code
    WCHAR PdoName[] = CHILD_PDO_NAME;

    irpStack = IoGetCurrentIrpStackLocation(pIrp);
    DeviceExtension = pDeviceObject->DeviceExtension;

    switch (irpStack->Parameters.QueryDeviceRelations.Type)
    {
        case BusRelations:
 
            // Allocate space for 1 child PDO
            DeviceRelations = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS));

            // If we can't allocate DeviceRelations structure, bail
            if (!DeviceRelations) {
                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
            }
            else {
                DeviceRelations->Count = 0;
			
                if ((!DeviceExtension->ChildPdo) && (PdoCount<9)) {
                    RtlInitUnicodeString (&PdoUniName, PdoName);
                    PdoName [((sizeof(PdoName)/sizeof(WCHAR)) - 2)] = L'0' + PdoCount++;

                    ntStatus = IoCreateDevice(
                        USBLS120DriverObject,
                        sizeof(DEVICE_EXTENSION),
                        &PdoUniName,
                        FILE_DEVICE_MASS_STORAGE,
                        0,
                        FALSE,
                        &DeviceExtension->ChildPdo
                        );

                    if(NT_SUCCESS(ntStatus))
                    {
                        PdoExtension = DeviceExtension->ChildPdo->DeviceExtension;

                        // Mark the device object as our child PDO
                        PdoExtension->DeviceObjectType = DO_PDO;

                        DeviceExtension->ChildPdo->Flags &= ~DO_DEVICE_INITIALIZING;
		
                        DeviceRelations->Objects[DeviceRelations->Count++] = DeviceExtension->ChildPdo;
                        ObReferenceObject(DeviceExtension->ChildPdo);
                    }
                }
                else {
                    // Child PDO already exists, just return it
                    DeviceRelations->Objects[DeviceRelations->Count++] = DeviceExtension->ChildPdo;
                    ObReferenceObject(DeviceExtension->ChildPdo);
                }
		
                pIrp->IoStatus.Information = (ULONG)DeviceRelations;
                ntStatus = pIrp->IoStatus.Status = STATUS_SUCCESS;
            }
		
            break;

	default:
            // We pass on any non-BusRelations IRP
            IoSkipCurrentIrpStackLocation (pIrp);
            ntStatus = IoCallDriver (DeviceExtension->TopOfStackDeviceObject, pIrp);

    }

    return ntStatus;
}
		


NTSTATUS
USBLS120_PdoProcessPnPIrp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
/*++

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.
    //
    
    USBLS120_KdPrint( DBGLVL_MEDIUM, ( "enter USBLS120_PdoProcessPnPIrp()\n"));

    irpStack = IoGetCurrentIrpStackLocation (Irp);

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

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

    USBLS120_KdPrint( DBGLVL_MEDIUM, ( "enter USBLS120_ProcessPnPIrp() IRP_MJ_PNP, minor %s\n",
    USBLS120_StringForPnpMnFunc( irpStack->MinorFunction ) ));

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

    USBLS120_ASSERT( IRP_MJ_PNP == irpStack->MajorFunction );

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


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


	case IRP_MN_REMOVE_DEVICE:
            IoDeleteDevice(DeviceObject);
            break;


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

    return (ntStatus);
}


NTSTATUS
USBLS120_QueryBusInfo(
    IN PDEVICE_OBJECT pDeviceObject,
    IN PIRP pIrp
    )
{
    NTSTATUS ntStatus;
    PIO_STACK_LOCATION irpStack;
    PPNP_BUS_INFORMATION BusInfo;
        	
    USBLS120_KdPrint( DBGLVL_MEDIUM, ( "enter USBLS120_QueryBusInfo()\n"));

    irpStack = IoGetCurrentIrpStackLocation(pIrp);

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

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

    return ntStatus;
}										



NTSTATUS
USBLS120_PdoDeviceQuery(
    IN PDEVICE_OBJECT pDeviceObject,
    IN PIRP pIrp
    )
{
    NTSTATUS ntStatus;
    PIO_STACK_LOCATION irpStack;
    PDEVICE_RELATIONS DeviceRelations;
    PDEVICE_EXTENSION DeviceExtension;
        	
    USBLS120_KdPrint( DBGLVL_DEFAULT, ( "enter USBLS120_PdoDeviceQuery()\n"));

    irpStack = IoGetCurrentIrpStackLocation(pIrp);
    DeviceExtension = pDeviceObject->DeviceExtension;

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

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

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

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

	return ntStatus;
}										



NTSTATUS
USBLS120_PdoQueryID(
    IN PDEVICE_OBJECT pDeviceObject,
    IN PIRP pIrp)
{
    PIO_STACK_LOCATION ioStack;
    PWCHAR buffer;
    WCHAR IDString[] = CHILD_DEVICE_ID;
    WCHAR InstanceIDString[] = L"0000";
    ULONG length;

    USBLS120_KdPrint( DBGLVL_MEDIUM, ( "enter USBLS120_PdoQueryID()\n"));

    ioStack = IoGetCurrentIrpStackLocation(pIrp);

    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);
            }

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


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

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

            pIrp->IoStatus.Information = (ULONG) buffer;
            break;
    }
    return STATUS_SUCCESS;
}


NTSTATUS
USBLS120_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;

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

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

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

            urb = USBLS120_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 = USBLS120_CallUSBD(DeviceObject, urb);

                USBLS120_ExFreePool(urb);

            }
            else {
                ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                USBLS120_KdPrint( DBGLVL_HIGH,("USBLS120_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;
}


⌨️ 快捷键说明

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