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

一、驱动跟踪

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\n")); 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!\n", 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!\n", status));
return status;
} pDevContext = GetDeviceContext(device); status = WdfDeviceCreateDeviceInterface(device,
(LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2,
NULL);// Reference String
if (!NT_SUCCESS(status)) {
KdPrint(("WdfDeviceCreateDeviceInterface failed %!STATUS!\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;
} 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!\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 %!STATUS!\n", 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\n", (INT64)bytesRead));
} else {
KdPrint(("Read failed - request status %!STATUS! UsbdStatus %!STATUS!\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;
} 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\n", (INT64)bytesWritten));
} else {
KdPrint(("Write failed: request Status %!STATUS! UsbdStatus %!STATUS!\n",
status, usbCompletionParams->UsbdStatus));
} WdfRequestCompleteWithInformation(Request, status, bytesWritten); return;
}

Windows 驱动开发 - 8的更多相关文章

  1. Windows驱动开发(中间层)

    Windows驱动开发 一.前言 依据<Windows内核安全与驱动开发>及MSDN等网络质料进行学习开发. 二.初步环境 1.下载安装WDK7.1.0(WinDDK\7600.16385 ...

  2. [Windows驱动开发](一)序言

    笔者学习驱动编程是从两本书入门的.它们分别是<寒江独钓——内核安全编程>和<Windows驱动开发技术详解>.两本书分别从不同的角度介绍了驱动程序的制作方法. 在我理解,驱动程 ...

  3. windows驱动开发推荐书籍

    [作者] 猪头三 个人网站 :http://www.x86asm.com/ [序言] 很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都 ...

  4. Windows 驱动开发 - 5

    上篇<Windows 驱动开发 - 4>我们已经完毕了硬件准备. 可是我们还没有详细的数据操作,比如接收读写操作. 在WDF中进行此类操作前须要进行设备的IO控制,已保持数据的完整性. 我 ...

  5. windows 驱动开发入门——驱动中的数据结构

    最近在学习驱动编程方面的内容,在这将自己的一些心得分享出来,供大家参考,与大家共同进步,本人学习驱动主要是通过两本书--<独钓寒江 windows安全编程> 和 <windows驱动 ...

  6. Windows驱动——读书笔记《Windows驱动开发技术详解》

    =================================版权声明================================= 版权声明:原创文章 谢绝转载  请通过右侧公告中的“联系邮 ...

  7. Windows 驱动开发 - 7

    在<Windows 驱动开发 - 5>我们所说的读写操作在本篇实现. 在WDF中实现此功能主要为:EvtIoRead和EvtIoWrite. 首先,在EvtDeviceAdd设置以上两个回 ...

  8. Windows驱动开发-IRP的完成例程

    <Windows驱动开发技术详解 >331页, 在将IRP发送给底层驱动或其他驱动之前,可以对IRP设置一个完成例程,一旦底层驱动将IRP完成后,IRP完成例程立刻被处罚,通过设置完成例程 ...

  9. C++第三十八篇 -- 研究一下Windows驱动开发(二)--WDM式驱动的加载

    基于Windows驱动开发技术详解这本书 一.简单的INF文件剖析 INF文件是一个文本文件,由若干个节(Section)组成.每个节的名称用一个方括号指示,紧接着方括号后面的就是节内容.每一行就是一 ...

随机推荐

  1. drupal 8——图片组(list)在前台的显示顺序在登录状态和非登录状态不同

    问题描述:该页面是通过view来输出的,然而,登录状态下其页面中的图片组输出顺序是乱序的,而非登录状态下则根据id值升序输出. 原因:在原view配置页面中,没有配置默认的排序字段 解决方案:在vie ...

  2. mysql下载和安装Windows服务

    一.下载mysql:https://dev.mysql.com/downloads/mysql/,解压拷贝到D:\software\mysql-8.0.13-winx64 二.在D:\software ...

  3. 认识 java JVM虚拟机选项 Xms Xmx PermSize MaxPermSize 区别

    点击window---->preferences---->配置的tomcat---->JDK,在Optional Java VM arguments:中输入 -Xmx512M -Xm ...

  4. 【sqli-labs】 less48 GET -Error based -Blind -Numeric -Order By Clause(GET型基于盲注的整型Order By从句注入)

    图片还是47...访问的的确是48 这个是基于bool的盲注 http://192.168.136.128/sqli-labs-master/Less-48/?sort=1 and sleep(0.1 ...

  5. 初学JSP_内置对象

    out内置对象: 表单,表单常用的的提交方式

  6. cocos creator destroy方法

    node.destroy(),Node.destroyAllChildren并不会立即销毁,实际销毁操作会延迟到当前帧渲染前执行. 这段话可能不明白,但是在Node.destroyAllChildre ...

  7. -bash:whois:command not found

    在centOS 下,如果出现-bash:whois:command not found的问题, 则yum install 安装whois软件 yum install -y jwhois 包名是jwho ...

  8. docker和jenkins安装启动

    docker安装Jenkins 1.安装Docker 1.1 yum 包更新到最新 sudo yum update 1.2 安装需要的软件包, yum-util 提供yum-config-manage ...

  9. Ubuntu 18.04 nvidia driver 390.48 安装 TensorFlow 1.12.0 和 PyTorch 1.0.0 详细教程

    最近要在个人台式机上搭建TensorFlow和PyTorch运行环境,期间遇到了一些问题.这里就把解决的过程记录下来,同时也可以作为安装上述环境的过程记录. 如果没有遇到类似的问题,想直接从零安装上述 ...

  10. (C/C++学习)10.C++文件流

    说明:C++中的文件流分为三种:文件输入流.文件输出流.文件输入/输出流,其对应的类分别为 ifstream.ofstream 和 fstream .由这三个类创建类对象,完成对文件的操作.其中文件的 ...