• Windows 驱动开发


        最后的一点开发工作:跟踪驱动。


    一、驱动跟踪

        1. 包括TMH头文件

    #include "step5.tmh"

        

        2. 初始化跟踪

                在DriverEntry中初始化。

        WPP_INIT_TRACING( DriverObject, RegistryPath );
    
        WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    
        attributes.EvtCleanupCallback = EvtDriverContextCleanup;


            (1) WPP跟踪初始化

                     WPP_INIT_TRACING

    VOID
      WPP_INIT_TRACING(
        IN PDRIVER_OBJECT  DriverObject,
        IN OPT PUNICODE_STRING  RegistryPath
        );

            (2) WDF对象属性初始化

                     WDF_OBJECT_ATTRIBUTES_INIT

    VOID WDF_OBJECT_ATTRIBUTES_INIT(
      _Out_ PWDF_OBJECT_ATTRIBUTES Attributes
    );

            (3) 设置回调事件 

                  EvtDriverContextCleanup

    EVT_WDF_OBJECT_CONTEXT_CLEANUP EvtCleanupCallback;
    
    VOID EvtCleanupCallback(
      _In_ WDFOBJECT Object
    )
    { ... }



        3. 清理跟踪

            使用WPP_CLEANUP宏。

    VOID 
    WPP_CLEANUP(
        IN PDRIVER_OBJECT  DriverObject
    );

            (1) 清理WDM驱动对象

                   WdfDriverWdmGetDriverObject

    PDRIVER_OBJECT WdfDriverWdmGetDriverObject(
      [in] WDFDRIVER Driver
    );




        Windows 驱动开发编后话:

            我们的开发工作到此已经完毕了。可是。这不是工作状态的驱动程序。

            后继还要进行IRQL、EvtIoStop、电源的细化处理、IOTarget(包含EvtIoDeviceControl)以及inf文件等等。


    附:

    step5.c

    /*++
    
    Step5: This steps shows:
           1) How to map KdPrint function to do WPP tracing
    --*/
    
    #include <stdarg.h> // To avoid build errors on Win2K due to WPP
    #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"
    
    #include "step5.tmh"
    
    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)
    
    
    NTSTATUS
    DriverEntry(
        IN PDRIVER_OBJECT  DriverObject,
        IN PUNICODE_STRING RegistryPath
        )
    {
        WDF_DRIVER_CONFIG       config;
        NTSTATUS                status;
        WDF_OBJECT_ATTRIBUTES   attributes;
    
        WPP_INIT_TRACING( DriverObject, RegistryPath );
    
        KdPrint(("DriverEntry of Step5
    "));
    
        WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd);
    
        //
        // Register a cleanup callback so that we can call WPP_CLEANUP when
        // the framework driver object is deleted during driver unload.
        //
        WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
        attributes.EvtCleanupCallback = EvtDriverContextCleanup;
    
        status = WdfDriverCreate(DriverObject,
                            RegistryPath,
                            &attributes,
                            &config,
                            WDF_NO_HANDLE
                            );
    
        if (!NT_SUCCESS(status)) {
            KdPrint(("WdfDriverCreate failed %!STATUS!
    ", status));
            //
            // Cleanup tracing here because DriverContextCleanup will not be called
            // as we have failed to create WDFDRIVER object itself.
            // Please note that if your return failure from DriverEntry after the
            // WDFDRIVER object is created successfully, you don't have to
            // call WPP cleanup because in those cases DriverContextCleanup
            // will be executed when the framework deletes the DriverObject.
            //
            WPP_CLEANUP(DriverObject);
        }
    
        return status;
    }
    
    VOID
    EvtDriverContextCleanup(
        IN WDFDRIVER Driver
        )
    {
        WPP_CLEANUP( WdfDriverWdmGetDriverObject( Driver ));
    }
    
    NTSTATUS
    EvtDeviceAdd(
        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 %!STATUS!
    ", status));
            return status;
        }
    
        pDevContext = GetDeviceContext(device);
    
        status = WdfDeviceCreateDeviceInterface(device,
                                    (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2,
                                    NULL);// Reference String
        if (!NT_SUCCESS(status)) {
            KdPrint(("WdfDeviceCreateDeviceInterface failed %!STATUS!
    ", 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!
    ", status));
            return status;
        }
    
        return status;
    }
    
    
    NTSTATUS
    EvtDevicePrepareHardware(
        IN WDFDEVICE    Device,
        IN WDFCMRESLIST ResourceList,
        IN WDFCMRESLIST ResourceListTranslated
        )
    {
        NTSTATUS                            status;
        PDEVICE_CONTEXT                     pDeviceContext;
        WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
        WDFUSBPIPE                          pipe;
    
        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 %!STATUS!
    ", 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 %!STATUS!
    ", status));
            return status;
        }
    
        pDeviceContext->UsbInterface =
                    configParams.Types.SingleInterface.ConfiguredUsbInterface;
    
        pipe = WdfUsbInterfaceGetConfiguredPipe(pDeviceContext->UsbInterface,
                                           2, //PipeIndex,
                                           NULL);// pipeInfo
    
        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;
    }
    
    VOID
    EvtIoDeviceControl(
        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 %!STATUS!", 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 %!STATUS!", 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;
    }
    
    VOID
    EvtRequestReadCompletionRoutine(
        IN WDFREQUEST                  Request,
        IN WDFIOTARGET                 Target,
        PWDF_PEQUEST_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
    ", (INT64)bytesRead));
        } else {
            KdPrint(("Read failed - request status %!STATUS! UsbdStatus %!STATUS!
    ",
                    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;
    }
    
    VOID
    EvtRequestWriteCompletionRoutine(
        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
    ", (INT64)bytesWritten));
        } else {
            KdPrint(("Write failed: request Status %!STATUS! UsbdStatus %!STATUS!
    ",
                    status, usbCompletionParams->UsbdStatus));
        }
    
        WdfRequestCompleteWithInformation(Request, status, bytesWritten);
    
        return;
    }
    


  • 相关阅读:
    wikioi 1002 旁路
    OS X升级到10.10使用后pod故障解决方案出现
    Python challenge 3
    maven 编
    独立博客网站FansUnion.cn操作2多年的经验和教训以及未来计划
    Wakelock API详解
    智遥工作流——会签与多人审批区别
    mysql 参数optimizer_switch
    OpenRisc-31-关于在设计具有DMA功能的ipcore时的虚实地址转换问题的分析与解决
    TROUBLE SHOOTING: FRM-30425
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7106751.html
Copyright © 2020-2023  润新知