【驱动笔记11】使用DeviceIoControl通信
文章作者: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;
}
最后的演示结果如下图所示:
【驱动笔记11】使用DeviceIoControl通信的更多相关文章
- 嵌入式Linux驱动笔记(十八)------浅析V4L2框架之ioctl【转】
转自:https://blog.csdn.net/Guet_Kite/article/details/78574781 权声明:本文为 风筝 博主原创文章,未经博主允许不得转载!!!!!!谢谢合作 h ...
- linux 2.6 驱动笔记(一)
本文作为linux 2.6 驱动笔记,记录环境搭建及linux基本内核模块编译加载. 环境搭建: 硬件:OK6410开发板 目标板操作系统:linux 2.6 交叉编译环境:windows 7 + v ...
- 机器学习实战 - 读书笔记(11) - 使用Apriori算法进行关联分析
前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第11章 - 使用Apriori算法进行关联分析. 基本概念 关联分析(associat ...
- Ext.Net学习笔记11:Ext.Net GridPanel的用法
Ext.Net学习笔记11:Ext.Net GridPanel的用法 GridPanel是用来显示数据的表格,与ASP.NET中的GridView类似. GridPanel用法 直接看代码: < ...
- SQL反模式学习笔记11 限定列的有效值
目标:限定列的有效值,将一列的有效字段值约束在一个固定的集合中.类似于数据字典. 反模式:在列定义上指定可选值 1. 对某一列定义一个检查约束项,这个约束不允许往列中插入或者更新任何会导致约束失败的值 ...
- JAVA自学笔记11
JAVA自学笔记11 1:Eclipse的安装 2:用Eclipse写一个HelloWorld案例,最终在控制台输出你的名字 A:创建项目 B:在src目录下创建包.cn.itcast C:在cn.i ...
- golang学习笔记11 golang要用jetbrain的golang这个IDE工具开发才好
golang学习笔记11 golang要用jetbrain的golang这个IDE工具开发才好 jetbrain家的全套ide都很好用,一定要dark背景风格才装B 从File-->s ...
- Spring MVC 学习笔记11 —— 后端返回json格式数据
Spring MVC 学习笔记11 -- 后端返回json格式数据 我们常常听说json数据,首先,什么是json数据,总结起来,有以下几点: 1. JSON的全称是"JavaScript ...
- Python标准库笔记(11) — Operator模块
Operator--标准功能性操作符接口. 代码中使用迭代器时,有时必须要为一个简单表达式创建函数.有些情况这些函数可以用一个lambda函数实现,但是对于某些操作,根本没必要去写一个新的函数.因此o ...
随机推荐
- Java 与 JavaScript 对websocket的使用
ebsocket,HTML5中新一代全双工通信协议.其底层仍然是http协议. 传统 HTTP 请求响应客户端服务器交互图 WebSocket 请求响应客户端服务器交互图 WebSocket 客户端支 ...
- $.jsonp()的简单使用
// jsonp 获取 json 数据: $.jsonp({ url: GLOBAL.baseUrl + '/company/mobi_getposter.action', callback: 'ca ...
- libsvm svmtrain函数运行出错问题
我安装的是matlab R2013a 安装上libsvm后需要设置set path 为libsvm的所有文件夹加载上,但是发现每次重新打开之后,之前加载的又不见了,所有导致出现,使用svmsrai ...
- C语言:strcpy()和memcpy()
一.strcpy和memcpy都是标准C库函数,它们有下面的特点: 1.strcpy提供了字符串的复制.即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符. ...
- php平滑升级
php平滑升级 1.既然是平滑升级,是不需要宕机,也不需要停止服务,是不存在关闭网站的说法 2.而升级最后的重启,重启的是PHP加载的配置文件,不影响你当前运行的网站 3.php-fpm是属于Fast ...
- 整数划分问题--DFS
单点时限:1000ms 内存限制:256MB 描写叙述 Given two positive integers N and M, please divide N into several intege ...
- ZH奶酪:PHP上传图片三个步骤
1. 上传图片三步骤 第一步:首先判断文件类型是否为图片格式,若是则上传文件; 第二步:然后重命名文件(一般都是避免上传文件重名,现在基本上都是以为时间来命名); 第三步:最后把文件上传到指定目录,成 ...
- IO习题
1.Java实现将九九乘法表输入到文本文件 public class Test1 { public static void main(String[] args) throws FileNotFoun ...
- mysqld: unrecognized service
为了快速搭建了测试环境yum安装了MySQL. 执行 [root@localhost bin]#mysql ERROR 2002 (HY000): Can't connect to local MyS ...
- EXCEL 列与列怎么交换?
选中A列数据,按先SHIFT键的同时按住鼠标左键,向右拖动鼠标,在拖动的过程中,会出现一条虚线,当拖动到B列的右边缘时,屏幕上会出现 C:C 的提示,这时送开SHIFT键及鼠标左键,就完成了A B两列 ...