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

一、驱动跟踪

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. 在mac上快捷找到nodejs的安装路径

    打开控制台输入 which node ,得到的输出结果就是node安装路径

  2. JS——tab切换

    排它思想: 1.先让所有的元素恢复默认值 2.再让选中的元素赋专有的值 3.干掉所有人,剩下我一个 <!DOCTYPE html> <html> <head lang=& ...

  3. java攻城狮之路--复习JDBC(利用BeanUtils、JDBC元数据编写通用的查询方法;元数据;Blob;事务;批量处理)

    1.利用BeanUtils的前提得要加入以下两个jar包: commons-beanutils-1.8.0.jar commons-logging-1.1.1.jar package com.shel ...

  4. Java_Web三大框架之Hibernate+jsp+selvect+HQL登入验证

    刚开始接触Hibernate有些举手无措,觉得配置信息太多.经过一个星期的适应,Hibernate比sql简单方便多了.下面做一下Hibernate+jsp+selvect+HQL登入验证. 第一步: ...

  5. javascript常用功能函数

    特殊字符转义:将<, >, &, “进行转义 function escape(str){ return str.replace(/[<>"&]/g,f ...

  6. Html5 WebSocket详细介绍

    什么是WebSocket?看过html5的同学都知道,WebSocket protocol 是HTML5一种新的协议.它是实现了浏览器与服务器全双工通信(full-duplex).HTML5定义了We ...

  7. poj3176-Cow Bowling【dp】

    The cows don't use actual bowling balls when they go bowling. They each take a number (in the range ...

  8. uva 1587(Box UVA - 1587)

    题目大意是给定6个数对,每个数对代表一个面的长和宽,判断这6个面是否能构成一个长方体. 这种题一看很复杂,但是只要不想多了实际上这就是一个水题... 首先说明一下判断的思路: 1.长方体是有三个对面的 ...

  9. PHP服务搭建

    一.PHP二进制安装(下载路径http://cn2.php.net/get/php-5.5.32.tar.gz/from/a/mirror) 1.解压: tar xf php-5.5.32.tar.g ...

  10. STM32学习笔记:读写内部Flash(介绍+附代码)

    一.介绍 首先我们需要了解一个内存映射: stm32的flash地址起始于0x0800 0000,结束地址是0x0800 0000加上芯片实际的flash大小,不同的芯片flash大小不同. RAM起 ...