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

📄 isopnp.c

📁 WINDDK开发代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    // 2.  reset the cancel routine
    // 3.  process them
    // 3a. if the device is active, send them down
    // 3b. else complete with STATUS_DELETE_PENDING
    //

    while(1) {

        KeAcquireSpinLock(&DeviceExtension->QueueLock, &oldIrql);

        if(IsListEmpty(&DeviceExtension->NewRequestsQueue)) {

            KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql);
            break;
        }
    
        //
        // Remove a request from the queue
        //

        listEntry = RemoveHeadList(&DeviceExtension->NewRequestsQueue);
        nextIrp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry);

        //
        // set the cancel routine to NULL
        //

        cancelRoutine = IoSetCancelRoutine(nextIrp, NULL);

        //
        // check if its already cancelled
        //

        if(nextIrp->Cancel) {
            if(cancelRoutine) {

                //
                // the cancel routine for this IRP hasnt been called yet
                // so queue the IRP in the cancelledIrp list and complete
                // after releasing the lock
                //
                
                InsertTailList(&cancelledIrpList, listEntry);
            }
            else {

                //
                // the cancel routine has run
                // it must be waiting to hold the queue lock
                // so initialize the IRPs listEntry
                //

                InitializeListHead(listEntry);
            }

            KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql);
        }
        else {

            KeReleaseSpinLock(&DeviceExtension->QueueLock, oldIrql);

            if(FailRequests == DeviceExtension->QueueState) {

                nextIrp->IoStatus.Information = 0;
                nextIrp->IoStatus.Status = STATUS_DELETE_PENDING;
                IoCompleteRequest(nextIrp, IO_NO_INCREMENT);
            }
            else {

                PIO_STACK_LOCATION irpStack;

                IsoUsb_DbgPrint(3, ("ProcessQueuedRequests::"));
                IsoUsb_IoIncrement(DeviceExtension);

                IoSkipCurrentIrpStackLocation(nextIrp);
                IoCallDriver(DeviceExtension->TopOfStackDeviceObject, nextIrp);
               
                IsoUsb_DbgPrint(3, ("ProcessQueuedRequests::"));
                IsoUsb_IoDecrement(DeviceExtension);
            }
        }
    } // while loop

    //
    // walk through the cancelledIrp list and cancel them
    //

    while(!IsListEmpty(&cancelledIrpList)) {

        PLIST_ENTRY listEntry = RemoveHeadList(&cancelledIrpList);
        
        cancelledIrp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry);

        cancelledIrp->IoStatus.Status = STATUS_CANCELLED;
        cancelledIrp->IoStatus.Information = 0;

        IoCompleteRequest(cancelledIrp, IO_NO_INCREMENT);
    }

    IsoUsb_DbgPrint(3, ("ProcessQueuedRequests - ends\n"));

    return;
}

VOID
GetBusInterfaceVersion(
    IN PDEVICE_OBJECT DeviceObject
    )
/*++
 
Routine Description:

    This routine queries the bus interface version

Arguments:

    DeviceExtension

Return Value:

    VOID

--*/
{
    PIRP                       irp;
    KEVENT                     event;
    NTSTATUS                   ntStatus;
    PDEVICE_EXTENSION          deviceExtension;
    PIO_STACK_LOCATION         nextStack;
    USB_BUS_INTERFACE_USBDI_V1 busInterfaceVer1;

    //
    // initialize vars
    //
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

    IsoUsb_DbgPrint(3, ("GetBusInterfaceVersion - begins\n"));

    irp = IoAllocateIrp(deviceExtension->TopOfStackDeviceObject->StackSize,
                        FALSE);

    if(NULL == irp) {

        IsoUsb_DbgPrint(1, ("Failed to alloc irp in GetBusInterfaceVersion\n"));
        return;
    }

    //
    // All pnp Irp's need the status field initialized to
    // STATUS_NOT_SUPPORTED
    //
    irp->IoStatus.Status = STATUS_NOT_SUPPORTED;

    KeInitializeEvent(&event, NotificationEvent, FALSE);

    IoSetCompletionRoutine(irp,
                           (PIO_COMPLETION_ROUTINE) IrpCompletionRoutine,
                           &event,
                           TRUE,
                           TRUE,
                           TRUE);

    nextStack = IoGetNextIrpStackLocation(irp);
    ASSERT(nextStack);
    nextStack->MajorFunction = IRP_MJ_PNP;
    nextStack->MinorFunction = IRP_MN_QUERY_INTERFACE;

    //
    // Allocate memory for an interface of type
    // USB_BUS_INTERFACE_USBDI_V0 and have the IRP point to it:
    //
    nextStack->Parameters.QueryInterface.Interface = 
                                (PINTERFACE) &busInterfaceVer1;

    //
    // Assign the InterfaceSpecificData member of the IRP to be NULL
    //
    nextStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;

    //
    // Set the interface type to the appropriate GUID
    //
    nextStack->Parameters.QueryInterface.InterfaceType = 
                                        &USB_BUS_INTERFACE_USBDI_GUID;

    //
    // Set the size and version of interface in the IRP
    // Currently, there is only one valid version of 
    // this interface available to clients.
    //
    nextStack->Parameters.QueryInterface.Size = 
                                    sizeof(USB_BUS_INTERFACE_USBDI_V1);

    nextStack->Parameters.QueryInterface.Version = USB_BUSIF_USBDI_VERSION_1;
    
    IsoUsb_IoIncrement(deviceExtension);

    ntStatus = IoCallDriver(DeviceObject,
                            irp);

    if(STATUS_PENDING == ntStatus) {

        KeWaitForSingleObject(&event,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);

        ntStatus = irp->IoStatus.Status;
    }

    if(NT_SUCCESS(ntStatus)) {

        deviceExtension->IsDeviceHighSpeed = 
                busInterfaceVer1.IsDeviceHighSpeed(
                                       busInterfaceVer1.BusContext);

        IsoUsb_DbgPrint(1, ("IsDeviceHighSpeed = %x\n", 
                            deviceExtension->IsDeviceHighSpeed));
    }

    IoFreeIrp(irp);

    IsoUsb_DbgPrint(3, ("GetBusInterfaceVersion::"));
    IsoUsb_IoDecrement(deviceExtension);

    IsoUsb_DbgPrint(3, ("GetBusInterfaceVersion - ends\n"));
}

NTSTATUS
IrpCompletionRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp,
    IN PVOID          Context
    )
/*++
 
Routine Description:

    This routine is a completion routine.
    In this routine we set an event.

    Since the completion routine returns 
    STATUS_MORE_PROCESSING_REQUIRED, the Irps,
    which set this routine as the completion routine,
    should be marked pending.

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet
    Context - 

Return Value:

    NT status value

--*/
{
    PKEVENT event = Context;

    KeSetEvent(event, 0, FALSE);

    return STATUS_MORE_PROCESSING_REQUIRED;
}


NTSTATUS
IsoUsb_GetRegistryDword(
    IN     PWCHAR RegPath,
    IN     PWCHAR ValueName,
    IN OUT PULONG Value
    )
/*++
 
Routine Description:

    This routine reads the specified reqistry value.

Arguments:

    RegPath - registry path
    ValueName - property to be fetched from the registry
    Value - corresponding value read from the registry.

Return Value:

    NT status value

--*/
{
    ULONG                    defaultData;
    WCHAR                    buffer[MAXIMUM_FILENAME_LENGTH];
    NTSTATUS                 ntStatus;
    UNICODE_STRING           regPath;
    RTL_QUERY_REGISTRY_TABLE paramTable[2];

    IsoUsb_DbgPrint(3, ("IsoUsb_GetRegistryDword - begins\n"));

    regPath.Length = 0;
    regPath.MaximumLength = MAXIMUM_FILENAME_LENGTH * sizeof(WCHAR);
    regPath.Buffer = buffer;

    RtlZeroMemory(regPath.Buffer, regPath.MaximumLength);
    RtlMoveMemory(regPath.Buffer,
                  RegPath,
                  wcslen(RegPath) * sizeof(WCHAR));

    RtlZeroMemory(paramTable, sizeof(paramTable));

    paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
    paramTable[0].Name = ValueName;
    paramTable[0].EntryContext = Value;
    paramTable[0].DefaultType = REG_DWORD;
    paramTable[0].DefaultData = &defaultData;
    paramTable[0].DefaultLength = sizeof(ULONG);

    ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE |
                                      RTL_REGISTRY_OPTIONAL,
                                      regPath.Buffer,
                                      paramTable,
                                      NULL,
                                      NULL);

    if(NT_SUCCESS(ntStatus)) {

        IsoUsb_DbgPrint(3, ("success Value = %X\n", *Value));
        return STATUS_SUCCESS;
    }
    else {

        *Value = 0;
        return STATUS_UNSUCCESSFUL;
    }
}

NTSTATUS
IsoUsb_AbortPipes(
    IN PDEVICE_OBJECT DeviceObject
    )
/*++
 
Routine Description:

    This routine sends an irp/urb pair with
    URB_FUNCTION_ABORT_PIPE request down the stack

Arguments:

    DeviceObject - pointer to device object

Return Value:

    NT status value

--*/
{
    PURB                        urb;
    ULONG                       i;
    NTSTATUS                    ntStatus;
    PDEVICE_EXTENSION           deviceExtension;
    PUSBD_PIPE_INFORMATION      pipeInformation;
    PUSBD_INTERFACE_INFORMATION interfaceInfo;

    //
    // initialize variables
    //
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    interfaceInfo = deviceExtension->UsbInterface;
    
    IsoUsb_DbgPrint(3, ("IsoUsb_AbortPipes - begins\n"));
    
    if(interfaceInfo == NULL) {

        return STATUS_SUCCESS;
    }

    for(i = 0; i < interfaceInfo->NumberOfPipes; i++) {

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

        if(urb) {

            urb->UrbHeader.Length = sizeof(struct _URB_PIPE_REQUEST);
            urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
            urb->UrbPipeRequest.PipeHandle = 
                            interfaceInfo->Pipes[i].PipeHandle;

            ntStatus = CallUSBD(DeviceObject, urb);

            ExFreePool(urb);
        }
        else {

            IsoUsb_DbgPrint(1, ("Failed to alloc memory for urb for input pipe\n"));

            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
            return ntStatus;
        }
    }

    IsoUsb_DbgPrint(3, ("IsoUsb_AbortPipes - ends\n"));

    return STATUS_SUCCESS;
}

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

    Dispatch routine for IRP_MJ_CLEANUP

Arguments:

    DeviceObject - pointer to device object
    Irp - I/O request packet sent by the pnp manager

Return Value:

    NT status value

--*/
{
    PDEVICE_EXTENSION     deviceExtension;
    KIRQL                 oldIrql;
    LIST_ENTRY            cleanupList;
    PLIST_ENTRY           thisEntry, 
                          nextEntry, 
                          listHead;
    PIRP                  pendingIrp;
    PIO_STACK_LOCATION    pendingIrpStack, 
                          irpStack;
    NTSTATUS              ntStatus;
    PFILE_OBJECT          fileObject;
    PFILE_OBJECT_CONTENT  fileObjectContent;
    PISOUSB_STREAM_OBJECT tempStreamObject;

    //
    // initialize variables
    //
    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation(Irp);
    fileObject = irpStack->FileObject;

    IsoUsb_DbgPrint(3, ("IsoUsb_DispatchClean::"));
    IsoUsb_IoIncrement(deviceExtension);

    //
    // check if any stream objects need to be cleaned
    //

    if(fileObject && fileObject->FsContext) {

        fileObjectContent = (PFILE_OBJECT_CONTENT)
                            fileObject->FsContext;

        if(fileObjectContent->StreamInformation) {

            tempStreamObject = (PISOUSB_STREAM_OBJECT)
                               InterlockedExchangePointer(
                                    &fileObjectContent->StreamInformation,
                                    NULL);
        
            if(tempStreamObject && 
               (tempStreamObject->DeviceObject == DeviceObject)) {
        
                IsoUsb_DbgPrint(3, ("clean dispatch routine"
                                    " found a stream object match\n"));
                IsoUsb_StreamObjectCleanup(tempStreamObject, deviceExtension);
            }
        }
    }

    InitializeListHead(&cleanupList);

    //
    // acquire queue lock
    //
    KeAcquireSpinLock(&deviceExtension->QueueLock, &oldIrql);

    //
    // remove all Irp's that belong to input Irp's fileobject
    //

    listHead = &deviceExtension->NewRequestsQueue;

    for(thisEntry = listHead->Flin

⌨️ 快捷键说明

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