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

📄 testusb.c

📁 usb开发的资料!!USB标准
💻 C
字号:
// ===================================================================

//

//      testusb.c

//

//      rev 1.0 beta

//

//      this module handles USB IOCTL/IRP calls     

//

//      USB device driver for USB Device Example 

//      kernel mode driver 

//

//

// ===================================================================



#define DRIVER



// Include files needed for WDM driver support; from NT DDK

#include "wdm.h"

#include "stdarg.h"

#include "stdio.h"



// Include files needed for USB support; from USB DDK

#include "usbdi.h"

#include "usbdlib.h"

#include "usb.h"



#include "Testdrv.h"    // headers specified to this driver

#include "test98.h"



// ===================================================================

NTSTATUS

Test_CallUSBD(

    IN PDEVICE_OBJECT DeviceObject,

    IN PURB Urb

    )

/*

    Passes a Usb Request Block (URB) to the USB class driver (USBD)



    Note that we create our own IRP here and use it to send the request to

        the USB software subsystem.  This means that this routine is essentially

        independent of the IRP that caused this driver to be called in the first

        place.  The IRP for this transfer is created, used, and then destroyed

        in this routine.



    DiviceObject - pointer to the device object for this instance of a Test Device

    Urb          - pointer to Urb request block



    Return Value:

    STATUS_SUCCESS if successful,

    STATUS_UNSUCCESSFUL otherwise

*/

{

    NTSTATUS ntStatus, status = STATUS_SUCCESS;

    PFDO_DEVICE_DATA deviceData;

    PIRP irp;

    KEVENT event;

    IO_STATUS_BLOCK ioStatus;

    PIO_STACK_LOCATION nextStack;



    deviceData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;



    // issue a synchronous request (see notes above)

    KeInitializeEvent(&event, NotificationEvent, FALSE);



    irp = IoBuildDeviceIoControlRequest(

                IOCTL_INTERNAL_USB_SUBMIT_URB,

                deviceData->UnderlyingPDO,

                NULL,

                0,

                NULL,

                0,

                TRUE, /* INTERNAL */

                &event,

                &ioStatus);



    // Prepare for calling the USB driver stack

    nextStack = IoGetNextIrpStackLocation(irp);

    ASSERT(nextStack != NULL);



    // Set up the URB ptr to pass to the USB driver stack

    nextStack->Parameters.Others.Argument1 = Urb;



    // Call the USB class driver to perform the operation.  If the returned status

    // is PENDING, wait for the request to complete.

    ntStatus = IoCallDriver(deviceData->UnderlyingPDO,

                            irp);



    if (ntStatus == STATUS_PENDING) {

        

        status = KeWaitForSingleObject(

                       &event,

                       Suspended,

                       KernelMode,

                       FALSE,

                       NULL);



    } else {

        ioStatus.Status = ntStatus;

    }



    // USBD maps the error code for us.  USBD uses error codes in its URB

    // structure that are more insightful into USB behavior. To allow more insight into

    // the specific USB error that occurred, your driver may wish to examine the

    // URB's status code (Urb->UrbHeader.Status) as well.

    ntStatus = ioStatus.Status;



    return ntStatus;

}



// ===================================================================

NTSTATUS

Test_ProcessIOCTL(

    IN PDEVICE_OBJECT DeviceObject,

    IN PIRP Irp

    )

/*

    This where all the DeviceIoControl codes are handled.  You can expand and add more code

    here to handle IOCTL/IRP codes that are specific to your device driver.



    DeviceObject - pointer to the device object for this instance of the test device.



    Return Value: NT status 

*/

{

    PIO_STACK_LOCATION irpStack;

    PVOID ioBuffer;

    ULONG inputBufferLength;

    ULONG outputBufferLength;

    

    // PDEVICE_EXTENSION deviceExtension;

    PFDO_DEVICE_DATA deviceData;

    

    ULONG ioControlCode;

    NTSTATUS ntStatus;

    ULONG length;

    PUCHAR pch;



    

    // Get a pointer to the current location in the Irp. This is where

    //     the function codes and parameters are located.

    irpStack = IoGetCurrentIrpStackLocation (Irp);



    Irp->IoStatus.Status = STATUS_SUCCESS;

    Irp->IoStatus.Information = 0;



    // Get a pointer to the device extension

    deviceData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;



    // ***

    Test98_IncIoCount (deviceData);



    ioBuffer           = Irp->AssociatedIrp.SystemBuffer;

    inputBufferLength  = irpStack->Parameters.DeviceIoControl.InputBufferLength;

    outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;



    ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;



    // Handle Ioctls from User mode

    switch (ioControlCode) {



    case IRP_Test_GET_PIPE_INFO:

        // inputs  - none

        // outputs - we copy the interface information structure that we have

        //           stored in our device extension area to the output buffer which

        //           will be reflected to the user mode application by the IOS.

        length = 0;

        pch = (PUCHAR) ioBuffer;



        Irp->IoStatus.Information = length;

        Irp->IoStatus.Status = STATUS_SUCCESS;



        break;



       case IRP_Test_GET_DEVICE_DESCRIPTOR:

        // inputs  - pointer to a buffer in which to place descriptor data

        // outputs - we put the device descriptor data, if any is returned by the device

        //           in the system buffer and then we set the length inthe Information field

        //           in the Irp, which will then cause the system to copy the buffer back

        //           to the user's buffer

        

        length = Test_GetDeviceDescriptor (DeviceObject, ioBuffer);



        Irp->IoStatus.Information = length;

        Irp->IoStatus.Status = STATUS_SUCCESS;

      

        break;



    case IRP_Test_GET_CONFIGURATION_DESCRIPTOR:

        

        // inputs  - pointer to a buffer in which to place descriptor data

        // outputs - we put the configuration descriptor data, if any is returned by the device

        //           in the system buffer and then we set the length in the Information field

        //           in the Irp, which will then cause the system to copy the buffer back

        //           to the user's buffer

        

        length = Test_GetConfigDescriptor (DeviceObject, ioBuffer, outputBufferLength);



        Irp->IoStatus.Information = length;

        Irp->IoStatus.Status = STATUS_SUCCESS;

      

        break;





    default:



        Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

    }// switch on ioControlCode 



    ntStatus = Irp->IoStatus.Status;



    IoCompleteRequest (Irp,

                       IO_NO_INCREMENT

                       );



    Test98_DecIoCount (deviceData);



    return ntStatus;



}



// ===================================================================

ULONG

Test_GetDeviceDescriptor(

    IN PDEVICE_OBJECT DeviceObject,

    PVOID             pvOutputBuffer

    )

/*

    Gets a device descriptor from the given device object



    DeviceObject - pointer to the test device object



    Return Value: Number of valid bytes in data buffer  

*/

{

    PFDO_DEVICE_DATA deviceData = NULL;

    

    NTSTATUS            ntStatus        = STATUS_SUCCESS;

    PURB                urb             = NULL;

    ULONG               length          = 0;

    

    deviceData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;

    

    urb = ExAllocatePool(NonPagedPool, 

                         sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));

                         

    if (urb) {

        

        if (pvOutputBuffer) {    

        

            UsbBuildGetDescriptorRequest(urb,

                                         (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),

                                         USB_DEVICE_DESCRIPTOR_TYPE,    //descriptor type

                                         0,                             //index

                                         0,                             //language ID

                                         pvOutputBuffer,                //transfer buffer

                                         NULL,                          //MDL

                                         sizeof(USB_DEVICE_DESCRIPTOR), //buffer length

                                         NULL);                         //link

                                                                  

            ntStatus = Test_CallUSBD(DeviceObject, urb);



        } else {

            ntStatus = STATUS_NO_MEMORY;

        }    



        // Get the length from the Urb

        length = urb->UrbControlDescriptorRequest.TransferBufferLength;



        ExFreePool(urb);

        

    } else {

        ntStatus = STATUS_NO_MEMORY;        

    }        

   

    return length;



}    





// ===================================================================

/* not tested it yet

NTSTATUS    SetOne(IN PDEVICE_OBJECT pDeviceObject, PUSBTESTCTRLDESC pTestCtrlDesc)

 

//     perform a "set" setup packet 

//

//     Return Value: ntstatus



{

  NTSTATUS  ntStatus;

  PURB      pUrb;



  pTemp=ExAllocatePool(NonPagedPool, sizeof(USBDISPDESC));

  pUrb=ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));



  if (pUrb)  {



    RtlCopyMemory(pTemp, pTestCtrlDesc, sizeof(USBTESTDESC));



    UsbBuildVendorRequest(pUrb,

                          URB_FUNCTION_CLASS_DEVICE,   //Command

                          sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),

                          !(USBD_TRANSFER_DIRECTION_IN),// Direction Bit: OUT

                          0,                            // Reserved Bits !

                          0x04,                         // Request  (0xF1)

                          pTestCtrlDesc->usControlCode, // Value    (0xF0)

                          0x0,                          // Index    (0x00)

                          pTemp,                        // Transfer Buffer

                          NULL,                         // Transfer Buffer MDL

                          0x08,                         // Transfer buffer length: Size of display

                                                        // descriptor.

                          NULL) ;



    ntStatus=MakeUSBDCall(pDeviceObject, pUrb);



    ExFreePool(pUrb);

  }



  ExFreePool(pTemp);

  return ntStatus;

}

*/



// ===================================================================

ULONG

Test_GetConfigDescriptor(

    IN PDEVICE_OBJECT DeviceObject,

    PVOID             pvOutputBuffer,

    ULONG             ulLength

    )

/*

    Gets configuration descriptors from the given device object



    DeviceObject    - pointer to the test device object

    pvOutputBuffer  - pointer to the buffer where the data is to be placed

    ulLength        - length of the buffer



    Return Value: Number of valid bytes in data buffer  

*/

{

    PFDO_DEVICE_DATA deviceData = NULL;

    NTSTATUS            ntStatus        = STATUS_SUCCESS;

    PURB                urb             = NULL;

    ULONG               length          = 0;

    

    deviceData = (PFDO_DEVICE_DATA) DeviceObject->DeviceExtension;

    

    urb = ExAllocatePool(NonPagedPool, 

                         sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));

                         

    if (urb) {

        

        if (pvOutputBuffer) {    

        

            UsbBuildGetDescriptorRequest(urb,

                                         (USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),

                                         USB_CONFIGURATION_DESCRIPTOR_TYPE, //descriptor type

                                         0,                             //index

                                         0,                             //language ID

                                         pvOutputBuffer,                //transfer buffer

                                         NULL,                          //MDL

                                         ulLength,                      //buffer length

                                         NULL);                         //link

                                                                  

            ntStatus = Test_CallUSBD(DeviceObject, urb);



        } else {

            ntStatus = STATUS_NO_MEMORY;

        }    



        // Get the length from the Urb

        length = urb->UrbControlDescriptorRequest.TransferBufferLength;



        ExFreePool(urb);

        

    } else {

        ntStatus = STATUS_NO_MEMORY;        

    }        

    

    return length;

}    



// ===================================================================

NTSTATUS

Test_Read(

    IN PDEVICE_OBJECT DeviceObject,

    IN PIRP Irp

    )

/*

    This function is called for a IRP_MJ_READ.

    TODO:  Add functionality here for your device driver if it handles that IRP code.



    DeviceObject - pointer to the device object for this instance of the Test device.

    Irp          - pointer to IRP



    Return Value: NT status 

*/

{

        NTSTATUS ntStatus = STATUS_SUCCESS;

        UNREFERENCED_PARAMETER (DeviceObject);

        UNREFERENCED_PARAMETER (Irp);

        return (ntStatus);



}



// ===================================================================

NTSTATUS

Test_Write(

    IN PDEVICE_OBJECT DeviceObject,

    IN PIRP Irp

    )

/*

    This function is called for a IRP_MJ_WRITE.

    TODO:  Add functionality here for your device driver if it handles that IRP code.



    DeviceObject - pointer to the device object for this instance of the Test device.

    Irp                  - pointer to IRP



    Return Value: NT status 

*/

{



        NTSTATUS ntStatus = STATUS_SUCCESS;

        UNREFERENCED_PARAMETER (DeviceObject);

        UNREFERENCED_PARAMETER (Irp);

        return (ntStatus);



}



// ===================================================================

NTSTATUS

Test_Create(

    IN PDEVICE_OBJECT DeviceObject,

    IN PIRP Irp

    )

{

    NTSTATUS ntStatus;



    Irp->IoStatus.Status = STATUS_SUCCESS;

    Irp->IoStatus.Information = 0;



        // Create all the symbolic links here

    ntStatus = Irp->IoStatus.Status;



    IoCompleteRequest (Irp,IO_NO_INCREMENT);



    UNREFERENCED_PARAMETER (DeviceObject);



    return ntStatus;



}





⌨️ 快捷键说明

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