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

📄 usb.c

📁 usb2.0 驱动; 包括SYS目录
💻 C
📖 第 1 页 / 共 5 页
字号:
                                         NULL);


            ntStatus = USB_CallUSBD(DeviceObject, urb);

            USB_KdPrintCond( DBGLVL_DEFAULT, !NT_SUCCESS(ntStatus), ("USB_StartDevice() FAILED USB_CallUSBD(DeviceObject, urb)\n"));

            if (NT_SUCCESS(ntStatus)) {
                USB_KdPrint( DBGLVL_DEFAULT,("Device Descriptor = %x, len %x\n",
                                deviceDescriptor,
                                urb->UrbControlDescriptorRequest.TransferBufferLength));
				//USB_KdPrint( DBGLVL_DEFAULT, ("exit USB_StartDevice (%x)\n", ntStatus));
                USB_KdPrint( DBGLVL_DEFAULT,("I68001 Device Descriptor:\n"));
                USB_KdPrint( DBGLVL_DEFAULT,("-------------------------\n"));
                USB_KdPrint( DBGLVL_DEFAULT,("bLength %d\n", deviceDescriptor->bLength));
                USB_KdPrint( DBGLVL_DEFAULT,("bDescriptorType 0x%x\n", deviceDescriptor->bDescriptorType));
                USB_KdPrint( DBGLVL_DEFAULT,("bcdUSB 0x%x\n", deviceDescriptor->bcdUSB));
                USB_KdPrint( DBGLVL_DEFAULT,("bDeviceClass 0x%x\n", deviceDescriptor->bDeviceClass));
                USB_KdPrint( DBGLVL_DEFAULT,("bDeviceSubClass 0x%x\n", deviceDescriptor->bDeviceSubClass));
                USB_KdPrint( DBGLVL_DEFAULT,("bDeviceProtocol 0x%x\n", deviceDescriptor->bDeviceProtocol));
                USB_KdPrint( DBGLVL_DEFAULT,("bMaxPacketSize0 0x%x\n", deviceDescriptor->bMaxPacketSize0));
                USB_KdPrint( DBGLVL_DEFAULT,("idVendor 0x%x\n", deviceDescriptor->idVendor));
                USB_KdPrint( DBGLVL_DEFAULT,("idProduct 0x%x\n", deviceDescriptor->idProduct));
                USB_KdPrint( DBGLVL_DEFAULT,("bcdDevice 0x%x\n", deviceDescriptor->bcdDevice));
                USB_KdPrint( DBGLVL_DEFAULT,("iManufacturer 0x%x\n", deviceDescriptor->iManufacturer));
                USB_KdPrint( DBGLVL_DEFAULT,("iProduct 0x%x\n", deviceDescriptor->iProduct));
                USB_KdPrint( DBGLVL_DEFAULT,("iSerialNumber 0x%x\n", deviceDescriptor->iSerialNumber));
                USB_KdPrint( DBGLVL_DEFAULT,("bNumConfigurations 0x%x\n", deviceDescriptor->bNumConfigurations));
            }
        } else {
                        // if we got here we failed to allocate deviceDescriptor
            ntStatus = STATUS_INSUFFICIENT_RESOURCES;
        }

        if (NT_SUCCESS(ntStatus)) {
            deviceExtension->UsbDeviceDescriptor = deviceDescriptor;
        } else if (deviceDescriptor) {
            USB_ExFreePool(deviceDescriptor);
        }

        USB_ExFreePool(urb);

    } else {
                // if we got here we failed to allocate the urb
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }

    if (NT_SUCCESS(ntStatus)) {
        ntStatus = USB_ConfigureDevice(DeviceObject);

        USB_KdPrintCond( DBGLVL_DEFAULT,!NT_SUCCESS(ntStatus),("USB_StartDevice USB_ConfigureDevice() FAILURE (%x)\n", ntStatus));
    }


    if (NT_SUCCESS(ntStatus)) {
        deviceExtension->DeviceStarted = TRUE;
    }
    USB_KdPrint( DBGLVL_DEFAULT, ("exit USB_StartDevice (%x)\n", ntStatus));

    return ntStatus;
}


NTSTATUS
USB_RemoveDevice(
    IN  PDEVICE_OBJECT DeviceObject
    )

{
    PDEVICE_EXTENSION deviceExtension;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    UNICODE_STRING deviceLinkUnicodeString;

    USB_KdPrint( DBGLVL_DEFAULT,("enter USB_RemoveDevice\n"));

    deviceExtension = DeviceObject->DeviceExtension;

    RtlInitUnicodeString (&deviceLinkUnicodeString,
                          deviceExtension->DeviceLinkNameBuffer);

    // remove the GUID-based symbolic link
    ntStatus = IoSetDeviceInterfaceState(&deviceLinkUnicodeString, FALSE);
    USB_ASSERT( NT_SUCCESS( ntStatus ) );

    //
    // Free device descriptor structure
    //

    if (deviceExtension->UsbDeviceDescriptor) {
        USB_ExFreePool(deviceExtension->UsbDeviceDescriptor);
        deviceExtension->UsbDeviceDescriptor = NULL;
    }

    //
    // Free pipe info structs
    //
    if( deviceExtension->PipeInfo ) {

        USB_ExFreePool( deviceExtension->PipeInfo );
        deviceExtension->PipeInfo = NULL;
    }


    //
    // Free up the UsbInterface structure
    //
    if (deviceExtension->UsbInterface) {
        USB_ExFreePool(deviceExtension->UsbInterface);
        deviceExtension->UsbInterface = NULL;
    }

        // free up the USB config discriptor
    if (deviceExtension->UsbConfigurationDescriptor) {
        USB_ExFreePool(deviceExtension->UsbConfigurationDescriptor);
        deviceExtension->UsbConfigurationDescriptor = NULL;
    }


    // free the pending irp list
    if ( deviceExtension->PendingIoIrps ) {
        USB_ExFreePool(deviceExtension->PendingIoIrps );
        deviceExtension->PendingIoIrps = NULL;
    }

        USB_ASSERT( gExAllocCount == 0 );
    USB_KdPrint( DBGLVL_HIGH,("exit USB_RemoveDevice() gExAllocCount = dec %d\n", gExAllocCount ));

    USB_KdPrint( DBGLVL_DEFAULT,("exit USB_RemoveDevice() status = 0x%x\n", ntStatus ));

    return ntStatus;
}




NTSTATUS
USB_StopDevice(
    IN  PDEVICE_OBJECT DeviceObject
    )

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

    USB_KdPrint( DBGLVL_DEFAULT,("enter USB_StopDevice\n"));

    deviceExtension = DeviceObject->DeviceExtension;

    //
    // Send the select configuration urb with a NULL pointer for the configuration
    // handle. This closes the configuration and puts the device in the 'unconfigured'
    // state.
    //

    siz = sizeof(struct _URB_SELECT_CONFIGURATION);

    urb = USB_ExAllocatePool(NonPagedPool,
                         siz);

    if (urb) {
        UsbBuildSelectConfigurationRequest(urb,
                                          (USHORT) siz,
                                          NULL);

        ntStatus = USB_CallUSBD(DeviceObject, urb);

        USB_KdPrintCond( DBGLVL_DEFAULT,!NT_SUCCESS(ntStatus),("USB_StopDevice() FAILURE Configuration Closed status = %x usb status = %x.\n", ntStatus, urb->UrbHeader.Status));

        USB_ExFreePool(urb);
    } else {
        ntStatus = STATUS_INSUFFICIENT_RESOURCES;
    }


    if (NT_SUCCESS(ntStatus)) {
        deviceExtension->DeviceStarted = FALSE;
    }

    deviceExtension->StopDeviceRequested = FALSE;

    USB_KdPrint( DBGLVL_DEFAULT,("exit USB_StopDevice() (%x)\n", ntStatus));

    return ntStatus;
}



NTSTATUS
USB_IrpCompletionRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PVOID Context
    )

{
    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.

    return STATUS_MORE_PROCESSING_REQUIRED;

}

//////////////////////////////////////////////////

NTSTATUS
USB_ProcessPowerIrp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )

{

    PIO_STACK_LOCATION irpStack;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    PDEVICE_EXTENSION deviceExtension;
    BOOLEAN fGoingToD0 = FALSE;
    POWER_STATE sysPowerState, desiredDevicePowerState;
    KEVENT event;

    USB_KdPrint( DBGLVL_MEDIUM,(" USB_ProcessPowerIrp() IRP_MJ_POWER\n"));

    deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    irpStack = IoGetCurrentIrpStackLocation (Irp);
    USB_IncrementIoCount(DeviceObject);

    switch (irpStack->MinorFunction) {
    case IRP_MN_WAIT_WAKE:
        USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Enter IRP_MN_WAIT_WAKE\n"));

        deviceExtension->PowerDownLevel = deviceExtension->DeviceCapabilities.DeviceWake;


        if  ( ( PowerDeviceD0 == deviceExtension->CurrentDevicePowerState )  ||
              ( deviceExtension->DeviceCapabilities.DeviceWake > deviceExtension->CurrentDevicePowerState ) ) {

            ntStatus = STATUS_INVALID_DEVICE_STATE;
            Irp->IoStatus.Status = ntStatus;
            IoCompleteRequest (Irp,IO_NO_INCREMENT );
            USB_KdPrint( DBGLVL_HIGH, ( "Exit USB_ProcessPowerIrp(), ntStatus STATUS_INVALID_DEVICE_STATE\n" ) );
            USB_DecrementIoCount(DeviceObject);
            return ntStatus;
        }

        // flag we're enabled for wakeup
        deviceExtension->EnabledForWakeup = TRUE;

        // init an event for our completion routine to signal when PDO is done with this Irp
        KeInitializeEvent(&event, NotificationEvent, FALSE);

       // If not failing outright, pass this on to our PDO for further handling
        IoCopyCurrentIrpStackLocationToNext(Irp);

        // Set a completion routine so it can signal our event when
        //  the PDO is done with the Irp
        IoSetCompletionRoutine(Irp,
                               USB_IrpCompletionRoutine,
                               &event,  // pass the event to the completion routine as the Context
                               TRUE,    // invoke on success
                               TRUE,    // invoke on error
                               TRUE);   // invoke on cancellation

        PoStartNextPowerIrp(Irp);
        ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
                                Irp);

         // if PDO is not done yet, wait for the event to be set in our completion routine
        if (ntStatus == STATUS_PENDING) {
             // wait for irp to complete

            NTSTATUS waitStatus = KeWaitForSingleObject(
                &event,
                Suspended,
                KernelMode,
                FALSE,
                NULL);

            USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() done waiting for PDO to finish IRP_MN_WAIT_WAKE\n"));
        }

                // now tell the device to actually wake up
          //=====USB_SelfSuspendOrActivate( DeviceObject, FALSE );

        // flag we're done with wakeup irp
        deviceExtension->EnabledForWakeup = FALSE;

        USB_DecrementIoCount(DeviceObject);

        USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Exit IRP_MN_WAIT_WAKE\n"));
        break;

    case IRP_MN_SET_POWER:
        {

                // The system power policy manager sends this IRP to set the system power state.
                // A device power policy manager sends this IRP to set the device power state for a device.

        USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Enter IRP_MN_SET_POWER\n"));

        // Set Irp->IoStatus.Status to STATUS_SUCCESS to indicate that the device
        // has entered the requested state. Drivers cannot fail this IRP.

        switch (irpStack->Parameters.Power.Type) {
            case SystemPowerState:

                // Get input system power state
                sysPowerState.SystemState = irpStack->Parameters.Power.State.SystemState;

                USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Set Power, type SystemPowerState = %s\n",
                    USB_StringForSysState( sysPowerState.SystemState ) ));

                // If system is in working state always set our device to D0
                //  regardless of the wait state or system-to-device state power map
                if ( sysPowerState.SystemState ==  PowerSystemWorking) {
                    desiredDevicePowerState.DeviceState = PowerDeviceD0;

                     USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() PowerSystemWorking, will set D0, not use state map\n"));


                } else {
                     // set to corresponding system state if IRP_MN_WAIT_WAKE pending
                    if ( deviceExtension->EnabledForWakeup ) { // got a WAIT_WAKE IRP pending?

                        // Find the device power state equivalent to the given system state.
                        // We get this info from the DEVICE_CAPABILITIES struct in our device
                        // extension (initialized in USB_PnPAddDevice() )
                        desiredDevicePowerState.DeviceState =
                            deviceExtension->DeviceCapabilities.DeviceState[ sysPowerState.SystemState ];

                        USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() IRP_MN_WAIT_WAKE pending, will use state map\n"));

                    } else {
                        // if no wait pending and the system's not in working state, just turn off
                        desiredDevicePowerState.DeviceState = PowerDeviceD3;

                        USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Not EnabledForWakeup and the system's not in working state,\n  settting PowerDeviceD3 (off )\n"));
                    }
                }

                //
                // We've determined the desired device state; are we already in this state?
                //

                USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Set Power, desiredDevicePowerState = %s\n",
                    USB_StringForDevState( desiredDevicePowerState.DeviceState ) ));

                if (desiredDevicePowerState.DeviceState !=
                    deviceExtension->CurrentDevicePowerState) {

                    // USB_IncrementIoCount(DeviceObject);

                    // No, request that we be put into this state
                                        // by requesting a new Power Irp from the Pnp manager
                    deviceExtension->PowerIrp = Irp;
                    ntStatus = PoRequestPowerIrp(deviceExtension->PhysicalDeviceObject,
                                               IRP_MN_SET_POWER,
                                               desiredDevicePowerState,
                                                                                           // completion routine will pass the Irp down to the PDO
                                               USB_PoRequestCompletion,
                                               DeviceObject,
                                               NULL);

                } else {
                    // Yes, just pass it on to PDO (Physical Device Object)
                    IoCopyCurrentIrpStackLocationToNext(Irp);
                    PoStartNextPowerIrp(Irp);
                    ntStatus = PoCallDriver(deviceExtension->TopOfStackDeviceObject,
                                            Irp);

                    USB_DecrementIoCount(DeviceObject);
                    USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Exit IRP_MN_SET_POWER\n"));

                }
                break;

            case DevicePowerState:

                USB_KdPrint( DBGLVL_MEDIUM,("USB_ProcessPowerIrp() Set Power, type DevicePowerState = %s\n",
                    USB_StringForDevState( irpStack->Parameters.Power.State.DeviceState ) ));

                fGoingToD0 = USB_SetDevicePowerState(DeviceObject,
                                                      irpStack->Parameters.Power.State.DeviceState

⌨️ 快捷键说明

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