文章作者:grayfox
作者主页:http://nokyo.blogbus.com
原始出处:http://www.blogbus.com/nokyo-logs/34018521.html

在我昨日发布的《驱动学习笔记系列文章汇总(PDF)》第11.2节中,我没有给出使用DeviceIoControl通信的演示源码,附录中附带的程序是我尚未调试好的,因此没有达到通信的目的。

今天又认真阅读了下张帆的《Windows驱动开发技术详解》第7章的内容,并对它给出的示例程序多次调试,总算把这个通信过程给理解了,下面我们先来看看应用层程序的代码:

#include <windows.h>

#include <stdio.h>

#include <winioctl.h>

#include "..\Ioctls.h"

#define SYMBOL_LINK "\\\\.\\Test"

int main()

{

HANDLE hDevice = ::CreateFile(SYMBOL_LINK,

GENERIC_READ | GENERIC_WRITE,

0,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL );

if (hDevice == INVALID_HANDLE_VALUE)

{

printf("Failed to Open Device : %d\n", ::GetLastError());

return -1;

}

UCHAR InputBuffer[10];

UCHAR OutputBuffer[10];

DWORD dwOutput;

memset(InputBuffer, 0xAA, 10);

BOOL bRet = ::DeviceIoControl(hDevice, IOCTL_TEST, InputBuffer, 10, &OutputBuffer, 10, &dwOutput, NULL);

if (bRet)

{

printf("Output buffer:%d bytes\n",dwOutput);

for (int i=0;i<(int)dwOutput;i++)

{

printf("%02X ",OutputBuffer[i]);

}

printf("\n");

}

CloseHandle(hDevice);

return 0;

}

其中Ioctls.h这个头文件没有实质作用,它是为了在驱动程序和应用层程序之间共享IOCTL定义而设立的,内容很简单,如下所示:

#ifndef IOCTLS_H

#define IOCTLS_H

#ifndef CTL_CODE

#pragma message("CTL_CODE undefined. Include winioctl.h or wdm.h")

#endif

#define IOCTL_TEST \

CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)

#endif

我们再来看驱动程序,这里的xxxxDispatchDeviceControl函数需要作适当修改,如下所示:

NTSTATUS

TestDispatchDeviceControl(

IN PDEVICE_OBJECT        DeviceObject,

IN PIRP                    Irp

)

{

NTSTATUS            Status = STATUS_SUCCESS;

PIO_STACK_LOCATION    irpStack;

ULONG                inBufLength, outBufLength;

ULONG                i = 0;

ULONG                ioControlCode;

UCHAR                *InputBuffer, *OutputBuffer;

irpStack = IoGetCurrentIrpStackLocation(Irp);

inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;

outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;

ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;

if (ioControlCode == IOCTL_TEST)

{

KdPrint(("[Test] IOCTL_TEST : 0x%X", ioControlCode));

// 读取数据

InputBuffer = (UCHAR *)Irp->AssociatedIrp.SystemBuffer;

for (i = 0; i < inBufLength; i++)

{

KdPrint(("[Test] %X\n", InputBuffer[i]));

}

// 写入数据

OutputBuffer = (UCHAR *)Irp->AssociatedIrp.SystemBuffer;

memset(OutputBuffer, 0xBB, outBufLength);

Irp->IoStatus.Information = outBufLength;

}

else

{

KdPrint(("[Test] Unknown IOCTL: 0x%X (%04X,%04X)", \

ioControlCode, DEVICE_TYPE_FROM_CTL_CODE(ioControlCode), IoGetFunctionCodeFromCtlCode(ioControlCode)));

Status = STATUS_INVALID_PARAMETER;

Irp->IoStatus.Information = 0;

}

// 完成IRP

Irp->IoStatus.Status = Status;

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return Status;

}

最后的演示结果如下图所示:

最新文章

  1. FreeSwitch安装配置记录
  2. 直接运行可执行文件linux终端一闪而过
  3. 让android webView使用系统默认浏览器内核直接解析,不弹出选择浏览器选项
  4. 【下有对策】verycd没有的资源有很多方法下载
  5. jquery如何通过name名称获取当前name的value值
  6. nginx笔记---http配置
  7. 《ASP.NET 本质论》HttpApplication的处理管道 ,HttpMoudle,HttpHandler
  8. ActiveMQ内存设置和流控
  9. C#语法糖之第二篇: 参数默认值和命名参数 对象初始化器与集合初始化器
  10. [Mugeda HTML5技术教程之6]添加元素
  11. repeater一个简单的用法例子
  12. git stash用法
  13. pscs6
  14. Problem 2. number题解
  15. 图片缓存:浏览器刷新 和 304 Not Modified 与 If-Modified-Since 及 Cache-Control
  16. kafka 消息系统
  17. create a plugin for PowerShell ISE
  18. java json与map互相转换(二)
  19. [转]你所不知的 CSS ::before 和 ::after 伪元素用法
  20. Codeforces 429B Working out(递推DP)

热门文章

  1. Loadrunner视频教程汇总
  2. report studio 交叉表占比
  3. [Node.js]28. Level 5: Express Server
  4. unity3d插件Daikon Forge GUI 中文教程-3-基础控件Button和Sprite的使用
  5. 【iOS】网络操作与AFNetworking
  6. C#.NET常见问题(FAQ)-如何给Listbox添加右键菜单
  7. ThinkPHP的A方法,R方法,M方法,D方法区别
  8. mixin
  9. 图说十大数据挖掘算法(一)K最近邻算法
  10. getattr和setattr