文章作者: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通信的更多相关文章

  1. 嵌入式Linux驱动笔记(十八)------浅析V4L2框架之ioctl【转】

    转自:https://blog.csdn.net/Guet_Kite/article/details/78574781 权声明:本文为 风筝 博主原创文章,未经博主允许不得转载!!!!!!谢谢合作 h ...

  2. linux 2.6 驱动笔记(一)

    本文作为linux 2.6 驱动笔记,记录环境搭建及linux基本内核模块编译加载. 环境搭建: 硬件:OK6410开发板 目标板操作系统:linux 2.6 交叉编译环境:windows 7 + v ...

  3. 机器学习实战 - 读书笔记(11) - 使用Apriori算法进行关联分析

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第11章 - 使用Apriori算法进行关联分析. 基本概念 关联分析(associat ...

  4. Ext.Net学习笔记11:Ext.Net GridPanel的用法

    Ext.Net学习笔记11:Ext.Net GridPanel的用法 GridPanel是用来显示数据的表格,与ASP.NET中的GridView类似. GridPanel用法 直接看代码: < ...

  5. SQL反模式学习笔记11 限定列的有效值

    目标:限定列的有效值,将一列的有效字段值约束在一个固定的集合中.类似于数据字典. 反模式:在列定义上指定可选值 1. 对某一列定义一个检查约束项,这个约束不允许往列中插入或者更新任何会导致约束失败的值 ...

  6. JAVA自学笔记11

    JAVA自学笔记11 1:Eclipse的安装 2:用Eclipse写一个HelloWorld案例,最终在控制台输出你的名字 A:创建项目 B:在src目录下创建包.cn.itcast C:在cn.i ...

  7. golang学习笔记11 golang要用jetbrain的golang这个IDE工具开发才好

    golang学习笔记11   golang要用jetbrain的golang这个IDE工具开发才好  jetbrain家的全套ide都很好用,一定要dark背景风格才装B   从File-->s ...

  8. Spring MVC 学习笔记11 —— 后端返回json格式数据

    Spring MVC 学习笔记11 -- 后端返回json格式数据 我们常常听说json数据,首先,什么是json数据,总结起来,有以下几点: 1. JSON的全称是"JavaScript ...

  9. Python标准库笔记(11) — Operator模块

    Operator--标准功能性操作符接口. 代码中使用迭代器时,有时必须要为一个简单表达式创建函数.有些情况这些函数可以用一个lambda函数实现,但是对于某些操作,根本没必要去写一个新的函数.因此o ...

随机推荐

  1. IOS info.plist配置文件

    创建ios程序时,系统会自动生成一个info.plist文件,它是一个必不可少的文件,因为在这个文件中,存放是应用程序的配置信息,比如本地化语言.版本号.软件名称等,当然,我们也可以在项目的属性中进行 ...

  2. GeSHi——通用语法高亮显示

    Examples Category Examples Views ActionScript 2 46173 Ada 3 27881 Apache configuration 2 40029 Apple ...

  3. [NPM] Execute npx commands with $npm_ Environment Variables

    We will incorporate npm specific environment variables when executing various npx commands. In our e ...

  4. [Node.js]29. Level 6: Socket.io: Setting up Socket.io server-side & Client socket.io setup

    Below we've already created an express server, but we want to start building a real-time Q&A mod ...

  5. Andriod中的依赖注入

    Web后端开发者应该对依赖注入都比较熟悉,至于Android又是如何进行依赖注入的呢?在这篇文章中,让我们一起通过一个例子了解一下在Android中进行依赖注入的好处. AndroidAnnotati ...

  6. java 反射获取属性值 方法

    public static void main(String[] args) throws SecurityException, ClassNotFoundException, IllegalArgu ...

  7. spring mvc返回jsonp内容

    代码如下: import com.alibaba.fastjson.JSONPObject; @RequestMapping(value = "/method1") @Respon ...

  8. Java从零开始学十九(异常)

    一.什么是异常 从字面上讲,就是不正常的现实就是异常. 程序中的异常也是要在程序运行中才会偶尔发生.如果程序还没有运行,编译就报错,这种不叫异常,这种叫编译错误,通常是语法上的错误 二.java中异常 ...

  9. 选择合适的Linux版本

    以下纯属个人想法:欢迎指正 1.Linux桌面系统,首选Ubuntu.当然Ubuntu也有服务器版本,不建议使用 2.服务端的Linux稳定的服务器系统,在企业中从事运维工作Redhat或者CentO ...

  10. 【转】Spring中IoC的优点与缺点

    1. 优点 我们知道,在Java基本教程中有一个定律告诉我们:所有的对象都必须创建:或者说:使用对象之前必须创建,但是现在我们可以不必一定遵循这个定律了,我们可以从Ioc容器中直接获得一个对象然后直接 ...