博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Windows 驱动开发 - 7
阅读量:5770 次
发布时间:2019-06-18

本文共 16226 字,大约阅读时间需要 54 分钟。

    在《》我们所说的读写操作在本篇实现。

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

 

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

ioQueueConfig.EvtIoRead = EvtIoRead;ioQueueConfig.EvtIoWrite = EvtIoWrite;

然后。在EvtDevicePrepareHardware中获取WDFUSBPIPE并測试他。

pDeviceContext->BulkReadPipe = WdfUsbInterfaceGetConfiguredPipe(                                                  pDeviceContext->UsbInterface,                                                  BULK_IN_ENDPOINT_INDEX,                                                  NULL);// pipeInfo    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDeviceContext->BulkReadPipe);        pDeviceContext->BulkWritePipe = WdfUsbInterfaceGetConfiguredPipe(                                                  pDeviceContext->UsbInterface,                                                  BULK_OUT_ENDPOINT_INDEX,                                                  NULL);// pipeInfo

(1)获取WDFUSBPIPE

使用方法。

WDFUSBPIPE WdfUsbInterfaceGetConfiguredPipe(  [in]            WDFUSBINTERFACE           UsbInterface,  [in]            UCHAR                     PipeIndex,  [out, optional] PWDF_USB_PIPE_INFORMATION PipeInfo);

(2) 測试WDFUSBPIPE

使用方法.

VOID WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(  [in] WDFUSBPIPE Pipe);

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

1. 获得传输缓存

读:

NTSTATUS WdfRequestRetrieveOutputMemory(  [in]  WDFREQUEST Request,  [out] WDFMEMORY  *Memory);

写:

NTSTATUS WdfRequestRetrieveInputMemory(  [in]  WDFREQUEST Request,  [out] WDFMEMORY  *Memory);

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

读:

NTSTATUS WdfUsbTargetPipeFormatRequestForRead(  [in]           WDFUSBPIPE        Pipe,  [in]           WDFREQUEST        Request,  [in, optional] WDFMEMORY         ReadMemory,  [in, optional] PWDFMEMORY_OFFSET ReadOffset);

写:

NTSTATUS WdfUsbTargetPipeFormatRequestForWrite(  [in]           WDFUSBPIPE        Pipe,  [in]           WDFREQUEST        Request,  [in, optional] WDFMEMORY         WriteMemory,  [in, optional] PWDFMEMORY_OFFSET WriteOffset);

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

(1) 设置完毕例程

使用方法。

VOID WdfRequestSetCompletionRoutine(  [in]           WDFREQUEST                         Request,  [in, optional] PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine,  [in, optional] WDFCONTEXT                         CompletionContext);

(2)完毕例程

1).检查请求状态

status = CompletionParams->IoStatus.Status;

2). 检查传输的字节数

读完:

bytesRead =  usbCompletionParams->Parameters.PipeRead.Length;

写完:

bytesWritten =  usbCompletionParams->Parameters.PipeWrite.Length;

3). 检查USBD状态

首先。赋值

usbCompletionParams = CompletionParams->Parameters.Usb.Completion;

最后,获取

usbCompletionParams->UsbdStatus;
注:

读:EvtIoRead

写:EvtIoWrite

读完:EvtRequestReadCompletionRoutine

写完:EvtRequestWriteCompletionRoutine

附:

step4.c

/*++Step4: This steps shows:       1) How to register Read and Write events on the default queue.       2) Retrieve memory from read and write request, format the          requests and send it to USB target.--*/#include "ntddk.h"#include "wdf.h"#include "prototypes.h"#pragma warning(disable:4200)  // suppress nameless struct/union warning#pragma warning(disable:4201)  // suppress nameless struct/union warning#pragma warning(disable:4214)  // suppress bit field types other than int warning#include "usbdi.h"#pragma warning(default:4200)#pragma warning(default:4201)#pragma warning(default:4214)#include "wdfusb.h"#include "initguid.h"DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, // Generated using guidgen.exe   0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84);// {573E8C73-0CB4-4471-A1BF-FAB26C31D384}#define IOCTL_INDEX                     0x800#define FILE_DEVICE_OSRUSBFX2          0x65500#define USBFX2LK_SET_BARGRAPH_DISPLAY 0xD8#define BULK_OUT_ENDPOINT_INDEX        1#define BULK_IN_ENDPOINT_INDEX         2#define IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY CTL_CODE(FILE_DEVICE_OSRUSBFX2,\                                                    IOCTL_INDEX + 5, \                                                    METHOD_BUFFERED, \                                                    FILE_WRITE_ACCESS)typedef struct _DEVICE_CONTEXT {  WDFUSBDEVICE      UsbDevice;  WDFUSBINTERFACE   UsbInterface;  WDFUSBPIPE        BulkReadPipe;  WDFUSBPIPE        BulkWritePipe;} DEVICE_CONTEXT, *PDEVICE_CONTEXT;WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext)NTSTATUSDriverEntry(    IN PDRIVER_OBJECT  DriverObject,    IN PUNICODE_STRING RegistryPath    ){    WDF_DRIVER_CONFIG       config;    NTSTATUS                status;    KdPrint(("DriverEntry of Step4\n"));    WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd);    status = WdfDriverCreate(DriverObject,                        RegistryPath,                        WDF_NO_OBJECT_ATTRIBUTES,                         &config,                             WDF_NO_HANDLE                         );    if (!NT_SUCCESS(status)) {        KdPrint(("WdfDriverCreate failed 0x%x\n", status));    }    return status;}NTSTATUSEvtDeviceAdd(    IN WDFDRIVER        Driver,    IN PWDFDEVICE_INIT  DeviceInit    ){    WDF_OBJECT_ATTRIBUTES               attributes;    NTSTATUS                            status;    WDFDEVICE                           device;    PDEVICE_CONTEXT                     pDevContext;    WDF_PNPPOWER_EVENT_CALLBACKS        pnpPowerCallbacks;    WDF_IO_QUEUE_CONFIG                 ioQueueConfig;        UNREFERENCED_PARAMETER(Driver);    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);    pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware;    WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);    status = WdfDeviceCreate(&DeviceInit, &attributes, &device);    if (!NT_SUCCESS(status)) {        KdPrint(("WdfDeviceCreate failed 0x%x\n", status));        return status;    }    pDevContext = GetDeviceContext(device);    status = WdfDeviceCreateDeviceInterface(device,                                (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2,                                NULL);// Reference String    if (!NT_SUCCESS(status)) {        KdPrint(("WdfDeviceCreateDeviceInterface failed 0x%x\n", status));        return status;    }    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,                                    WdfIoQueueDispatchParallel);    ioQueueConfig.EvtIoDeviceControl = EvtIoDeviceControl;    ioQueueConfig.EvtIoRead = EvtIoRead;    ioQueueConfig.EvtIoWrite = EvtIoWrite;    status = WdfIoQueueCreate(device,                         &ioQueueConfig,                         WDF_NO_OBJECT_ATTRIBUTES,                         WDF_NO_HANDLE);    if (!NT_SUCCESS(status)) {        KdPrint(("WdfIoQueueCreate failed  %!STATUS!\n", status));        return status;    }    return status;}NTSTATUSEvtDevicePrepareHardware(    IN WDFDEVICE    Device,    IN WDFCMRESLIST ResourceList,    IN WDFCMRESLIST ResourceListTranslated    ){    NTSTATUS                            status;    PDEVICE_CONTEXT                     pDeviceContext;    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;    UNREFERENCED_PARAMETER(ResourceList);    UNREFERENCED_PARAMETER(ResourceListTranslated);    pDeviceContext = GetDeviceContext(Device);    //    // Create the USB device if it is not already created.    //    if (pDeviceContext->UsbDevice == NULL) {        status = WdfUsbTargetDeviceCreate(Device,                                    WDF_NO_OBJECT_ATTRIBUTES,                                    &pDeviceContext->UsbDevice);        if (!NT_SUCCESS(status)) {            KdPrint(("WdfUsbTargetDeviceCreate failed 0x%x\n", status));                    return status;        }    }    WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);    status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,                                        WDF_NO_OBJECT_ATTRIBUTES,                                        &configParams);    if(!NT_SUCCESS(status)) {        KdPrint(("WdfUsbTargetDeviceSelectConfig failed 0x%x\n", status));        return status;    }    pDeviceContext->UsbInterface =                  configParams.Types.SingleInterface.ConfiguredUsbInterface;        pDeviceContext->BulkReadPipe = WdfUsbInterfaceGetConfiguredPipe(                                                  pDeviceContext->UsbInterface,                                                  BULK_IN_ENDPOINT_INDEX,                                                  NULL);// pipeInfo    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDeviceContext->BulkReadPipe);        pDeviceContext->BulkWritePipe = WdfUsbInterfaceGetConfiguredPipe(                                                  pDeviceContext->UsbInterface,                                                  BULK_OUT_ENDPOINT_INDEX,                                                  NULL);// pipeInfo    WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pDeviceContext->BulkWritePipe);            return status;}VOIDEvtIoDeviceControl(    IN WDFQUEUE   Queue,    IN WDFREQUEST Request,    IN size_t     OutputBufferLength,    IN size_t     InputBufferLength,    IN ULONG      IoControlCode        ){    WDFDEVICE                           device;    PDEVICE_CONTEXT                     pDevContext;    size_t                              bytesTransferred = 0;    NTSTATUS                            status;    WDF_USB_CONTROL_SETUP_PACKET        controlSetupPacket;    WDF_MEMORY_DESCRIPTOR               memDesc;    WDFMEMORY                           memory;    WDF_REQUEST_SEND_OPTIONS            sendOptions;         UNREFERENCED_PARAMETER(InputBufferLength);    UNREFERENCED_PARAMETER(OutputBufferLength);        device = WdfIoQueueGetDevice(Queue);    pDevContext = GetDeviceContext(device);    switch(IoControlCode) {    case IOCTL_OSRUSBFX2_SET_BAR_GRAPH_DISPLAY:        if(InputBufferLength < sizeof(UCHAR)) {            status = STATUS_BUFFER_OVERFLOW;            bytesTransferred = sizeof(UCHAR);            break;        }         status = WdfRequestRetrieveInputMemory(Request, &memory);        if (!NT_SUCCESS(status)) {            KdPrint(("WdfRequestRetrieveMemory failed 0x%x", status));            break;        }        WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket,                                        BmRequestHostToDevice,                                        BmRequestToDevice,                                        USBFX2LK_SET_BARGRAPH_DISPLAY, // Request                                        0, // Value                                        0); // Index                                                                WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&memDesc, memory, NULL);       //       // Send the I/O with a timeout to avoid hanging the calling        // thread indefinitely.       //        WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions,                                  WDF_REQUEST_SEND_OPTION_TIMEOUT);        WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions,                                         WDF_REL_TIMEOUT_IN_MS(100));            status = WdfUsbTargetDeviceSendControlTransferSynchronously(                                        pDevContext->UsbDevice,                                         NULL, // Optional WDFREQUEST                                        &sendOptions, // PWDF_REQUEST_SEND_OPTIONS                                        &controlSetupPacket,                                        &memDesc,                                        (PULONG)&bytesTransferred);        if (!NT_SUCCESS(status)) {            KdPrint(("SendControlTransfer failed 0x%x", status));            break;        }        break;    default:        status = STATUS_INVALID_DEVICE_REQUEST;        break;    }    WdfRequestCompleteWithInformation(Request, status, bytesTransferred);    return;}VOID EvtIoRead(    IN WDFQUEUE         Queue,    IN WDFREQUEST       Request,    IN size_t           Length    )   {    WDFUSBPIPE                  pipe;    NTSTATUS                    status;    WDFMEMORY                   reqMemory;    PDEVICE_CONTEXT             pDeviceContext;    BOOLEAN                     ret;        UNREFERENCED_PARAMETER(Length);    pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));        pipe = pDeviceContext->BulkReadPipe;        status = WdfRequestRetrieveOutputMemory(Request, &reqMemory);    if(!NT_SUCCESS(status)){        goto Exit;    }       status = WdfUsbTargetPipeFormatRequestForRead(pipe,                                        Request,                                        reqMemory,                                        NULL // Offsets                                        );     if (!NT_SUCCESS(status)) {        goto Exit;    }    WdfRequestSetCompletionRoutine(Request,                            EvtRequestReadCompletionRoutine,                            pipe);    ret = WdfRequestSend(Request,                     WdfUsbTargetPipeGetIoTarget(pipe),                     WDF_NO_SEND_OPTIONS);        if (ret == FALSE) {        status = WdfRequestGetStatus(Request);        goto Exit;    } else {        return;    }   Exit:    WdfRequestCompleteWithInformation(Request, status, 0);    return;}VOIDEvtRequestReadCompletionRoutine(    IN WDFREQUEST                  Request,    IN WDFIOTARGET                 Target,    PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,    IN WDFCONTEXT                  Context    ){        NTSTATUS    status;    size_t      bytesRead = 0;    PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams;    UNREFERENCED_PARAMETER(Target);    UNREFERENCED_PARAMETER(Context);    status = CompletionParams->IoStatus.Status;        usbCompletionParams = CompletionParams->Parameters.Usb.Completion;        bytesRead =  usbCompletionParams->Parameters.PipeRead.Length;        if (NT_SUCCESS(status)){        KdPrint(("Number of bytes read: %I64d\n", (INT64)bytesRead));      } else {        KdPrint(("Read failed - request status 0x%x UsbdStatus 0x%x\n",                status, usbCompletionParams->UsbdStatus));    }    WdfRequestCompleteWithInformation(Request, status, bytesRead);    return;}VOID EvtIoWrite(    IN WDFQUEUE         Queue,    IN WDFREQUEST       Request,    IN size_t           Length    )   {    NTSTATUS                    status;    WDFUSBPIPE                  pipe;    WDFMEMORY                   reqMemory;    PDEVICE_CONTEXT             pDeviceContext;    BOOLEAN                     ret;        UNREFERENCED_PARAMETER(Length);    pDeviceContext = GetDeviceContext(WdfIoQueueGetDevice(Queue));        pipe = pDeviceContext->BulkWritePipe;    status = WdfRequestRetrieveInputMemory(Request, &reqMemory);    if(!NT_SUCCESS(status)){        goto Exit;    }    status = WdfUsbTargetPipeFormatRequestForWrite(pipe,                                              Request,                                              reqMemory,                                              NULL); // Offset    if (!NT_SUCCESS(status)) {        goto Exit;    }    WdfRequestSetCompletionRoutine(                            Request,                            EvtRequestWriteCompletionRoutine,                            pipe);    ret = WdfRequestSend(Request,                     WdfUsbTargetPipeGetIoTarget(pipe),                     WDF_NO_SEND_OPTIONS);    if (ret == FALSE) {        status = WdfRequestGetStatus(Request);        goto Exit;    } else {        return;    }Exit:        WdfRequestCompleteWithInformation(Request, status, 0);    return;}VOIDEvtRequestWriteCompletionRoutine(    IN WDFREQUEST                  Request,    IN WDFIOTARGET                 Target,    PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,    IN WDFCONTEXT                  Context    ){    NTSTATUS    status;    size_t      bytesWritten = 0;    PWDF_USB_REQUEST_COMPLETION_PARAMS usbCompletionParams;    UNREFERENCED_PARAMETER(Target);    UNREFERENCED_PARAMETER(Context);    status = CompletionParams->IoStatus.Status;    usbCompletionParams = CompletionParams->Parameters.Usb.Completion;        bytesWritten =  usbCompletionParams->Parameters.PipeWrite.Length;        if (NT_SUCCESS(status)){        KdPrint(("Number of bytes written: %I64d\n", (INT64)bytesWritten));            } else {        KdPrint(("Write failed: request Status 0x%x UsbdStatus 0x%x\n",                 status, usbCompletionParams->UsbdStatus));    }    WdfRequestCompleteWithInformation(Request, status, bytesWritten);    return;}

參考文章:

    1. 《》 

    2. 《》

转载地址:http://ojiux.baihongyu.com/

你可能感兴趣的文章
微信公众平台开发(96) 多个功能整合
查看>>
[转]MVC4项目中验证用户登录一个特性就搞定
查看>>
用Perl编写Apache模块续二 - SVN动态鉴权实现SVNAuth 禅道版
查看>>
Android 阴影,圆形的Button
查看>>
C++概述
查看>>
卡特兰数
查看>>
006_mac osx 应用跨屏幕
查看>>
nginx中配置文件的讲解
查看>>
MindNode使用
查看>>
SQL Server 2016 Alwayson新增功能
查看>>
HTTP库Axios
查看>>
CentOS7下安装python-pip
查看>>
认知计算 Cognitive Computing
查看>>
左手坐标系和右手坐标系 ZZ
查看>>
陀螺仪主要性能指标
查看>>
Java 架构师眼中的 HTTP 协议
查看>>
Linux 目录结构和常用命令
查看>>
Linux内存管理之mmap详解 (可用于android底层内存调试)
查看>>
利润表(年末)未分配利润公式备份
查看>>
Android开发中ViewStub的应用方法
查看>>