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

全部博文(51)

文章存档

2020年(2)

2018年(49)

我的朋友

分类: Windows平台

2018-08-26 02:12:59

上篇《Windows 驱动开发 - 5》我们设置了回调事件,我们在此篇来实现他。

    我们知道在进行读写之前我们要进行一定约定,比如同步。

    在WDF中控制同步约定的方法为:


  1. NTSTATUS WdfUsbTargetDeviceSendControlTransferSynchronously(
  2.   [in] WDFUSBDEVICE UsbDevice,
  3.   [in, optional] WDFREQUEST Request,
  4.   [in, optional] PWDF_REQUEST_SEND_OPTIONS RequestOptions,
  5.   [in] PWDF_USB_CONTROL_SETUP_PACKET SetupPacket,
  6.   [in, optional] PWDF_MEMORY_DESCRIPTOR MemoryDescriptor,
  7.   [out, optional] PULONG BytesTransferred
  8. );

(1) 选项请求


          对结构的设置。


  1. typedef struct _WDF_REQUEST_SEND_OPTIONS {
  2.   ULONG Size;
  3.   ULONG Flags;
  4.   LONGLONG Timeout;
  5. } WDF_REQUEST_SEND_OPTIONS, *PWDF_REQUEST_SEND_OPTIONS;

1). 初始化


            使用方法进行初始化.


  1. VOID WDF_REQUEST_SEND_OPTIONS_INIT(
  2.   _Out_ PWDF_REQUEST_SEND_OPTIONS Options,
  3.   _In_ ULONG Flags
  4. );
2). 设置超时
            使用方法进行超时设置。

  1. VOID WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(
  2.   _Inout_ PWDF_REQUEST_SEND_OPTIONS Options,
  3.   _In_ LONGLONG Timeout
  4. );

  (2) 包设置

          使用方法进行包设置。


  1. VOID WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(
  2.   _Out_ PWDF_USB_CONTROL_SETUP_PACKET Packet,
  3.   _In_ WDF_USB_BMREQUEST_DIRECTION Direction,
  4.   _In_ WDF_USB_BMREQUEST_RECIPIENT Recipient,
  5.   _In_ BYTE Request,
  6.   _In_ USHORT Value,
  7.   _In_ USHORT Index
  8. );

    (3) 内存描述

        1). 内存请求

             使用方法进行请求。


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

        2). 初始化内存句柄

             使用方法进行内存句柄的初始化。


  1. VOID WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(
  2.   _Out_ PWDF_MEMORY_DESCRIPTOR Descriptor,
  3.   _In_ WDFMEMORY Memory,
  4.   _In_opt_ PWDFMEMORY_OFFSET Offsets
  5. );

代码:


step3.c


  1. /*++

  2. Step3: This steps shows:
  3.        1) How to create a default parallel queue to receive a IOCTL requests to
  4.           set bar graph display.
  5.        2) How to retreive memory handle from the requests and use that to send
  6.           a vendor command to the USB device.
  7. --*/

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

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

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

  34. WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext)


  35. NTSTATUS
  36. DriverEntry(
  37.     IN PDRIVER_OBJECT DriverObject,
  38.     IN PUNICODE_STRING RegistryPath
  39.     )
  40. {
  41.     WDF_DRIVER_CONFIG config;
  42.     NTSTATUS status;

  43.     KdPrint(("DriverEntry of Step3\n"));

  44.     WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd);

  45.     status = WdfDriverCreate(DriverObject,
  46.                         RegistryPath,
  47.                         WDF_NO_OBJECT_ATTRIBUTES,
  48.                         &config,
  49.                         WDF_NO_HANDLE
  50.                         );

  51.     if (!NT_SUCCESS(status)) {
  52.         KdPrint(("WdfDriverCreate failed 0x%x\n", status));
  53.     }

  54.     return status;
  55. }

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

  70.     WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
  71.     pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware;
  72.     WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);

  73.     WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);

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

  79.     pDevContext = GetDeviceContext(device);

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

  87.     WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,
  88.                                     WdfIoQueueDispatchParallel);

  89.     ioQueueConfig.EvtIoDeviceControl = EvtIoDeviceControl;

  90.     status = WdfIoQueueCreate(device,
  91.                          &ioQueueConfig,
  92.                          WDF_NO_OBJECT_ATTRIBUTES,
  93.                          WDF_NO_HANDLE);
  94.     if (!NT_SUCCESS(status)) {
  95.         KdPrint(("WdfIoQueueCreate failed %!STATUS!\n", status));
  96.         return status;
  97.     }

  98.     return status;
  99. }


  100. NTSTATUS
  101. EvtDevicePrepareHardware(
  102.     IN WDFDEVICE Device,
  103.     IN WDFCMRESLIST ResourceList,
  104.     IN WDFCMRESLIST ResourceListTranslated
  105.     )
  106. {
  107.     NTSTATUS status;
  108.     PDEVICE_CONTEXT pDeviceContext;
  109.     WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
  110.  
  111.     UNREFERENCED_PARAMETER(ResourceList);
  112.     UNREFERENCED_PARAMETER(ResourceListTranslated);

  113.     pDeviceContext = GetDeviceContext(Device);

  114.     //
  115.     // Create the USB device if it is not already created.
  116.     //
  117.     if (pDeviceContext->UsbDevice == NULL) {

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

  126.     WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);

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

  134.     pDeviceContext->UsbInterface =
  135.                 configParams.Types.SingleInterface.ConfiguredUsbInterface;
  136.     return status;
  137. }

  138. VOID
  139. EvtIoDeviceControl(
  140.     IN WDFQUEUE Queue,
  141.     IN WDFREQUEST Request,
  142.     IN size_t OutputBufferLength,
  143.     IN size_t InputBufferLength,
  144.     IN ULONG IoControlCode
  145.     )
  146. {
  147.     WDFDEVICE device;
  148.     PDEVICE_CONTEXT pDevContext;
  149.     size_t bytesTransferred = 0;
  150.     NTSTATUS status;
  151.     WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket;
  152.     WDF_MEMORY_DESCRIPTOR memDesc;
  153.     WDFMEMORY memory;
  154.     WDF_REQUEST_SEND_OPTIONS sendOptions;
  155.      
  156.     UNREFERENCED_PARAMETER(InputBufferLength);
  157.     UNREFERENCED_PARAMETER(OutputBufferLength);
  158.     
  159.     device = WdfIoQueueGetDevice(Queue);
  160.     pDevContext = GetDeviceContext(device);

  161.     switch(IoControlCode) {

  162.     case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY:

  163.         if(InputBufferLength < sizeof(UCHAR)) {
  164.             status = STATUS_BUFFER_OVERFLOW;
  165.             bytesTransferred = sizeof(UCHAR);
  166.             break;
  167.         }

  168.         status = WdfRequestRetrieveInputMemory(Request, &memory);
  169.         if (!NT_SUCCESS(status)) {
  170.             KdPrint(("WdfRequestRetrieveMemory failed 0x%x", status));
  171.             break;
  172.         }

  173.         WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,
  174.                                         BmRequestHostToDevice,
  175.                                         BmRequestToDevice,
  176.                                         USBFX2LK_SET_BARGRAPH_DISPLAY, // Request
  177.                                         0, // Value
  178.                                         0); // Index

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

  180.        //
  181.        // Send the I/O with a timeout to avoid hanging the calling
  182.        // thread indefinitely.
  183.        //
  184.         WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions,
  185.                                   WDF_REQUEST_SEND_OPTION_TIMEOUT);

  186.         WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions,
  187.                                          WDF_REL_TIMEOUT_IN_MS(100));
  188.         status = WdfUsbTargetDeviceSendControlTransferSynchronously(
  189.                                         pDevContext->UsbDevice,
  190.                                         NULL, // Optional WDFREQUEST
  191.                                         &sendOptions, // PWDF_REQUEST_SEND_OPTIONS
  192.                                         &controlSetupPacket,
  193.                                         &memDesc,
  194.                                         (PULONG)&bytesTransferred);
  195.         if (!NT_SUCCESS(status)) {
  196.             KdPrint(("SendControlTransfer failed 0x%x", status));
  197.             break;
  198.         }
  199.         break;

  200.     default:
  201.         status = STATUS_INVALID_DEVICE_REQUEST;
  202.         break;
  203.     }

  204.     WdfRequestCompleteWithInformation(Request, status, bytesTransferred);

  205.     return;
  206. }








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