Chinaunix首页 | 论坛 | 博客
  • 博客访问: 54889
  • 博文数量: 51
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 410
  • 用 户 组: 普通用户
  • 注册时间: 2018-08-26 01:30
文章分类

全部博文(51)

文章存档

2020年(2)

2018年(49)

我的朋友

分类: Windows平台

2018-08-26 02:08:48

在《Windows 驱动开发 - 5》我们所说的读写操作在本篇实现。

    在WDF中实现此功能主要为:EvtIoRead和EvtIoWrite。


首先,在EvtDeviceAdd设置以上两个回调事件。

  1. ioQueueConfig.EvtIoRead = EvtIoRead;
  2. ioQueueConfig.EvtIoWrite = EvtIoWrite;
然后,在EvtDevicePrepareHardware中获取WDFUSBPIPE并测试他。

  1. pDeviceContext->BulkReadPipe = WdfUsbInterfaceGetConfiguredPipe(
  2.                                                   pDeviceContext->UsbInterface,
  3.                                                   BULK_IN_ENDPOINT_INDEX,
  4.                                                   NULL);// pipeInfo

  5.     WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDeviceContext->BulkReadPipe);
  6.     
  7.     pDeviceContext->BulkWritePipe = WdfUsbInterfaceGetConfiguredPipe(
  8.                                                   pDeviceContext->UsbInterface,
  9.                                                   BULK_OUT_ENDPOINT_INDEX,
  10.                                                   NULL);// pipeInfo

(1)获取WDFUSBPIPE

使用方法。


  1. WDFUSBPIPE WdfUsbInterfaceGetConfiguredPipe(
  2.   [in] WDFUSBINTERFACE UsbInterface,
  3.   [in] UCHAR PipeIndex,
  4.   [out, optional] PWDF_USB_PIPE_INFORMATION PipeInfo
  5. );

(2) 测试WDFUSBPIPE

使用方法.


  1. VOID WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(
  2.   [in] WDFUSBPIPE Pipe
  3. );

最后,实现以上两个回调事件和他们的完成例程。

1. 获得传输缓存


读:


  1. NTSTATUS WdfRequestRetrieveOutputMemory(
  2.   [in] WDFREQUEST Request,
  3.   [out] WDFMEMORY *Memory
  4. );
写:

  1. NTSTATUS WdfRequestRetrieveInputMemory(
  2.   [in] WDFREQUEST Request,
  3.   [out] WDFMEMORY *Memory
  4. );

2. 格式化并发送一个请求对象到USB驱动程序堆栈


读:


  1. NTSTATUS WdfUsbTargetPipeFormatRequestForRead(
  2.   [in] WDFUSBPIPE Pipe,
  3.   [in] WDFREQUEST Request,
  4.   [in, optional] WDFMEMORY ReadMemory,
  5.   [in, optional] PWDFMEMORY_OFFSET ReadOffset
  6. );
写:

  1. NTSTATUS WdfUsbTargetPipeFormatRequestForWrite(
  2.   [in] WDFUSBPIPE Pipe,
  3.   [in] WDFREQUEST Request,
  4.   [in, optional] WDFMEMORY WriteMemory,
  5.   [in, optional] PWDFMEMORY_OFFSET WriteOffset
  6. );

3. 对请求实现一个完成例程


(1) 设置完成例程

使用方法。


  1. VOID WdfRequestSetCompletionRoutine(
  2.   [in] WDFREQUEST Request,
  3.   [in, optional] PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine,
  4.   [in, optional] WDFCONTEXT CompletionContext
  5. );

(2)完成例程

1).检查请求状态


  1. status = CompletionParams->IoStatus.Status;

2). 检查传输的字节数


读完:


  1. bytesRead = usbCompletionParams->Parameters.PipeRead.Length;
写完:

  1. bytesWritten = usbCompletionParams->Parameters.PipeWrite.Length;

3). 检查USBD状态

首先,赋值


  1. usbCompletionParams = CompletionParams->Parameters.Usb.Completion;
最后,获取

  1. usbCompletionParams->UsbdStatus;

注:


读:EvtIoRead

写:EvtIoWrite

读完:EvtRequestReadCompletionRoutine

写完:EvtRequestWriteCompletionRoutine



附:

step4.c


  1. /*++

  2. Step4: This steps shows:
  3.        1) How to register Read and Write events on the default queue.
  4.        2) Retrieve memory from read and write request, format the
  5.           requests and send it to USB target.
  6. --*/

  7. #include "ntddk.h"
  8. #include "wdf.h"
  9. #include "prototypes.h"
  10. #pragma warning(disable:4200) // suppress nameless struct/union warning
  11. #pragma warning(disable:4201) // suppress nameless struct/union warning
  12. #pragma warning(disable:4214) // suppress bit field types other than int warning
  13. #include "usbdi.h"
  14. #pragma warning(default:4200)
  15. #pragma warning(default:4201)
  16. #pragma warning(default:4214)
  17. #include "wdfusb.h"
  18. #include "initguid.h"

  19. DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, // Generated using guidgen.exe
  20.    0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84);
  21. // {573E8C73-0CB4-4471-A1BF-FAB26C31D384}

  22. #define IOCTL_INDEX 0x800
  23. #define FILE_DEVICE_OSRUSBFX2 0x65500
  24. #define USBFX2LK_SET_BARGRAPH_DISPLAY 0xD8
  25. #define BULK_OUT_ENDPOINT_INDEX 1
  26. #define BULK_IN_ENDPOINT_INDEX 2
  27. #define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\
  28.                                                     IOCTL_INDEX + 5, \
  29.                                                     METHOD_BUFFERED, \
  30.                                                     FILE_WRITE_ACCESS)
  31. typedef struct _DEVICE_CONTEXT {
  32.   WDFUSBDEVICE UsbDevice;
  33.   WDFUSBINTERFACE UsbInterface;
  34.   WDFUSBPIPE BulkReadPipe;
  35.   WDFUSBPIPE BulkWritePipe;
  36. } DEVICE_CONTEXT, *PDEVICE_CONTEXT;

  37. WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext)


  38. NTSTATUS
  39. DriverEntry(
  40.     IN PDRIVER_OBJECT DriverObject,
  41.     IN PUNICODE_STRING RegistryPath
  42.     )
  43. {
  44.     WDF_DRIVER_CONFIG config;
  45.     NTSTATUS status;

  46.     KdPrint(("DriverEntry of Step4\n"));

  47.     WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd);

  48.     status = WdfDriverCreate(DriverObject,
  49.                         RegistryPath,
  50.                         WDF_NO_OBJECT_ATTRIBUTES,
  51.                         &config,
  52.                         WDF_NO_HANDLE
  53.                         );

  54.     if (!NT_SUCCESS(status)) {
  55.         KdPrint(("WdfDriverCreate failed 0x%x\n", status));
  56.     }

  57.     return status;
  58. }

  59. NTSTATUS
  60. EvtDeviceAdd(
  61.     IN WDFDRIVER Driver,
  62.     IN PWDFDEVICE_INIT DeviceInit
  63.     )
  64. {
  65.     WDF_OBJECT_ATTRIBUTES attributes;
  66.     NTSTATUS status;
  67.     WDFDEVICE device;
  68.     PDEVICE_CONTEXT pDevContext;
  69.     WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
  70.     WDF_IO_QUEUE_CONFIG ioQueueConfig;
  71.     
  72.     UNREFERENCED_PARAMETER(Driver);

  73.     WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
  74.     pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware;
  75.     WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);

  76.     WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);

  77.     status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
  78.     if (!NT_SUCCESS(status)) {
  79.         KdPrint(("WdfDeviceCreate failed 0x%x\n", status));
  80.         return status;
  81.     }

  82.     pDevContext = GetDeviceContext(device);

  83.     status = WdfDeviceCreateDeviceInterface(device,
  84.                                 (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2,
  85.                                 NULL);// Reference String
  86.     if (!NT_SUCCESS(status)) {
  87.         KdPrint(("WdfDeviceCreateDeviceInterface failed 0x%x\n", status));
  88.         return status;
  89.     }

  90.     WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,
  91.                                     WdfIoQueueDispatchParallel);

  92.     ioQueueConfig.EvtIoDeviceControl = EvtIoDeviceControl;
  93.     ioQueueConfig.EvtIoRead = EvtIoRead;
  94.     ioQueueConfig.EvtIoWrite = EvtIoWrite;

  95.     status = WdfIoQueueCreate(device,
  96.                          &ioQueueConfig,
  97.                          WDF_NO_OBJECT_ATTRIBUTES,
  98.                          WDF_NO_HANDLE);
  99.     if (!NT_SUCCESS(status)) {
  100.         KdPrint(("WdfIoQueueCreate failed %!STATUS!\n", status));
  101.         return status;
  102.     }

  103.     return status;
  104. }


  105. NTSTATUS
  106. EvtDevicePrepareHardware(
  107.     IN WDFDEVICE Device,
  108.     IN WDFCMRESLIST ResourceList,
  109.     IN WDFCMRESLIST ResourceListTranslated
  110.     )
  111. {
  112.     NTSTATUS status;
  113.     PDEVICE_CONTEXT pDeviceContext;
  114.     WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;

  115.     UNREFERENCED_PARAMETER(ResourceList);
  116.     UNREFERENCED_PARAMETER(ResourceListTranslated);

  117.     pDeviceContext = GetDeviceContext(Device);

  118.     //
  119.     // Create the USB device if it is not already created.
  120.     //
  121.     if (pDeviceContext->UsbDevice == NULL) {

  122.         status = WdfUsbTargetDeviceCreate(Device,
  123.                                     WDF_NO_OBJECT_ATTRIBUTES,
  124.                                     &pDeviceContext->UsbDevice);
  125.         if (!NT_SUCCESS(status)) {
  126.             KdPrint(("WdfUsbTargetDeviceCreate failed 0x%x\n", status));
  127.             return status;
  128.         }
  129.     }

  130.     WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);

  131.     status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
  132.                                         WDF_NO_OBJECT_ATTRIBUTES,
  133.                                         &configParams);
  134.     if(!NT_SUCCESS(status)) {
  135.         KdPrint(("WdfUsbTargetDeviceSelectConfig failed 0x%x\n", status));
  136.         return status;
  137.     }

  138.     pDeviceContext->UsbInterface =
  139.                 configParams.Types.SingleInterface.ConfiguredUsbInterface;
  140.     
  141.     pDeviceContext->BulkReadPipe = WdfUsbInterfaceGetConfiguredPipe(
  142.                                                   pDeviceContext->UsbInterface,
  143.                                                   BULK_IN_ENDPOINT_INDEX,
  144.                                                   NULL);// pipeInfo

  145.     WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDeviceContext->BulkReadPipe);
  146.     
  147.     pDeviceContext->BulkWritePipe = WdfUsbInterfaceGetConfiguredPipe(
  148.                                                   pDeviceContext->UsbInterface,
  149.                                                   BULK_OUT_ENDPOINT_INDEX,
  150.                                                   NULL);// pipeInfo

  151.     WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDeviceContext->BulkWritePipe);
  152.         
  153.     return status;
  154. }

  155. VOID
  156. EvtIoDeviceControl(
  157.     IN WDFQUEUE Queue,
  158.     IN WDFREQUEST Request,
  159.     IN size_t OutputBufferLength,
  160.     IN size_t InputBufferLength,
  161.     IN ULONG IoControlCode
  162.     )
  163. {
  164.     WDFDEVICE device;
  165.     PDEVICE_CONTEXT pDevContext;
  166.     size_t bytesTransferred = 0;
  167.     NTSTATUS status;
  168.     WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket;
  169.     WDF_MEMORY_DESCRIPTOR memDesc;
  170.     WDFMEMORY memory;
  171.     WDF_REQUEST_SEND_OPTIONS sendOptions;
  172.      
  173.     UNREFERENCED_PARAMETER(InputBufferLength);
  174.     UNREFERENCED_PARAMETER(OutputBufferLength);
  175.     
  176.     device = WdfIoQueueGetDevice(Queue);
  177.     pDevContext = GetDeviceContext(device);

  178.     switch(IoControlCode) {

  179.     case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY:

  180.         if(InputBufferLength < sizeof(UCHAR)) {
  181.             status = STATUS_BUFFER_OVERFLOW;
  182.             bytesTransferred = sizeof(UCHAR);
  183.             break;
  184.         }

  185.         status = WdfRequestRetrieveInputMemory(Request, &memory);
  186.         if (!NT_SUCCESS(status)) {
  187.             KdPrint(("WdfRequestRetrieveMemory failed 0x%x", status));
  188.             break;
  189.         }

  190.         WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
  191.                                         BmRequestHostToDevice,
  192.                                         BmRequestToDevice,
  193.                                         USBFX2LK_SET_BARGRAPH_DISPLAY, // Request
  194.                                         0, // Value
  195.                                         0); // Index

  196.         WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDesc, memory, NULL);

  197.        //
  198.        // Send the I/O with a timeout to avoid hanging the calling
  199.        // thread indefinitely.
  200.        //
  201.         WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions,
  202.                                   WDF_REQUEST_SEND_OPTION_TIMEOUT);

  203.         WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions,
  204.                                          WDF_REL_TIMEOUT_IN_MS(100));
  205.     
  206.         status = WdfUsbTargetDeviceSendControlTransferSynchronously(
  207.                                         pDevContext->UsbDevice,
  208.                                         NULL, // Optional WDFREQUEST
  209.                                         &sendOptions, // PWDF_REQUEST_SEND_OPTIONS
  210.                                         &controlSetupPacket,
  211.                                         &memDesc,
  212.                                         (PULONG)&bytesTransferred);
  213.         if (!NT_SUCCESS(status)) {
  214.             KdPrint(("SendControlTransfer failed 0x%x", status));
  215.             break;
  216.         }
  217.         break;

  218.     default:
  219.         status = STATUS_INVALID_DEVICE_REQUEST;
  220.         break;
  221.     }

  222.     WdfRequestCompleteWithInformation(Request, status, bytesTransferred);

  223.     return;
  224. }

  225. VOID
  226. EvtIoRead(
  227.     IN WDFQUEUE Queue,
  228.     IN WDFREQUEST Request,
  229.     IN size_t Length
  230.     )
  231. {
  232.     WDFUSBPIPE pipe;
  233.     NTSTATUS status;
  234.     WDFMEMORY reqMemory;
  235.     PDEVICE_CONTEXT pDeviceContext;
  236.     BOOLEAN ret;
  237.     
  238.     UNREFERENCED_PARAMETER(Length);

  239.     pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
  240.     
  241.     pipe = pDeviceContext->BulkReadPipe;
  242.     
  243.     status = WdfRequestRetrieveOutputMemory(Request, &reqMemory);
  244.     if(!NT_SUCCESS(status)){
  245.         goto Exit;
  246.     }
  247.    
  248.     status = WdfUsbTargetPipeFormatRequestForRead(pipe,
  249.                                         Request,
  250.                                         reqMemory,
  251.                                         NULL // Offsets
  252.                                         );
  253.     if (!NT_SUCCESS(status)) {
  254.         goto Exit;
  255.     }

  256.     WdfRequestSetCompletionRoutine(Request,
  257.                             EvtRequestReadCompletionRoutine,
  258.                             pipe);
  259.     ret = WdfRequestSend(Request,
  260.                     WdfUsbTargetPipeGetIoTarget(pipe),
  261.                     WDF_NO_SEND_OPTIONS);
  262.     
  263.     if (ret == FALSE) {
  264.         status = WdfRequestGetStatus(Request);
  265.         goto Exit;
  266.     } else {
  267.         return;
  268.     }
  269.    
  270. Exit:
  271.     WdfRequestCompleteWithInformation(Request, status, 0);

  272.     return;
  273. }

  274. VOID
  275. EvtRequestReadCompletionRoutine(
  276.     IN WDFREQUEST Request,
  277.     IN WDFIOTARGET Target,
  278.     PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,
  279.     IN WDFCONTEXT Context
  280.     )
  281. {
  282.     NTSTATUS status;
  283.     size_t bytesRead = 0;
  284.     PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams;

  285.     UNREFERENCED_PARAMETER(Target);
  286.     UNREFERENCED_PARAMETER(Context);

  287.     status = CompletionParams->IoStatus.Status;
  288.     
  289.     usbCompletionParams = CompletionParams->Parameters.Usb.Completion;
  290.     
  291.     bytesRead = usbCompletionParams->Parameters.PipeRead.Length;
  292.     
  293.     if (NT_SUCCESS(status)){
  294.         KdPrint(("Number of bytes read: %I64d\n", (INT64)bytesRead));
  295.     } else {
  296.         KdPrint(("Read failed - request status 0x%x UsbdStatus 0x%x\n",
  297.                 status, usbCompletionParams->UsbdStatus));

  298.     }

  299.     WdfRequestCompleteWithInformation(Request, status, bytesRead);

  300.     return;
  301. }

  302. VOID
  303. EvtIoWrite(
  304.     IN WDFQUEUE Queue,
  305.     IN WDFREQUEST Request,
  306.     IN size_t Length
  307.     )
  308. {
  309.     NTSTATUS status;
  310.     WDFUSBPIPE pipe;
  311.     WDFMEMORY reqMemory;
  312.     PDEVICE_CONTEXT pDeviceContext;
  313.     BOOLEAN ret;
  314.     
  315.     UNREFERENCED_PARAMETER(Length);

  316.     pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));
  317.     
  318.     pipe = pDeviceContext->BulkWritePipe;

  319.     status = WdfRequestRetrieveInputMemory(Request, &reqMemory);
  320.     if(!NT_SUCCESS(status)){
  321.         goto Exit;
  322.     }

  323.     status = WdfUsbTargetPipeFormatRequestForWrite(pipe,
  324.                                               Request,
  325.                                               reqMemory,
  326.                                               NULL); // Offset
  327.     if (!NT_SUCCESS(status)) {
  328.         goto Exit;
  329.     }

  330.     WdfRequestSetCompletionRoutine(
  331.                             Request,
  332.                             EvtRequestWriteCompletionRoutine,
  333.                             pipe);
  334.     ret = WdfRequestSend(Request,
  335.                     WdfUsbTargetPipeGetIoTarget(pipe),
  336.                     WDF_NO_SEND_OPTIONS);
  337.     if (ret == FALSE) {
  338.         status = WdfRequestGetStatus(Request);
  339.         goto Exit;
  340.     } else {
  341.         return;
  342.     }

  343. Exit:
  344.     WdfRequestCompleteWithInformation(Request, status, 0);

  345.     return;
  346. }

  347. VOID
  348. EvtRequestWriteCompletionRoutine(
  349.     IN WDFREQUEST Request,
  350.     IN WDFIOTARGET Target,
  351.     PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,
  352.     IN WDFCONTEXT Context
  353.     )
  354. {
  355.     NTSTATUS status;
  356.     size_t bytesWritten = 0;
  357.     PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams;

  358.     UNREFERENCED_PARAMETER(Target);
  359.     UNREFERENCED_PARAMETER(Context);

  360.     status = CompletionParams->IoStatus.Status;

  361.     usbCompletionParams = CompletionParams->Parameters.Usb.Completion;
  362.     
  363.     bytesWritten = usbCompletionParams->Parameters.PipeWrite.Length;
  364.     
  365.     if (NT_SUCCESS(status)){
  366.         KdPrint(("Number of bytes written: %I64d\n", (INT64)bytesWritten));
  367.     } else {
  368.         KdPrint(("Write failed: request Status 0x%x UsbdStatus 0x%x\n",
  369.                 status, usbCompletionParams->UsbdStatus));
  370.     }

  371.     WdfRequestCompleteWithInformation(Request, status, bytesWritten);

  372.     return;
  373. }

参考文章:


    1. 《》 

    2. 《》











阅读(1972) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~