- 浏览: 970762 次
- 性别:
- 来自: 珠海
文章分类
最新评论
-
Yunjey:
Yunjey 写道这样子的话、grid中的editable如何 ...
Flex创建可编辑以及分页的DataGrid -
Yunjey:
这样子的话、grid中的editable如何设置啊?!
Flex创建可编辑以及分页的DataGrid -
di1984HIT:
写的很好~~
JCalendar组件 -
sanny81:
此文真棒!感谢一路风尘的奉献!
但我有一疑 ...
Filter发送自定义数据详解 -
umgsai:
求完整demo umgsai@126.com
Flex和Jsp创建用户登入系统
在很多时候,某些用户需要与底层驱动有一个交互式的操作,所以需要寻找一个架构能够做到应用程程序和驱动程序进行有效的沟通,而Microsoft Windows 家族操作系统通过发送 I/O 请求数据包 (IRP) 与驱动程序通信。所以今天我们介绍Windows如何使用DeviceIoControl以及IRP进行User层和Kernel层的数据交流。
首先,为了比较完整的介绍这个部分,我们先看看一些准备工作。要访问底层驱动,我们应该先得到该驱可访问的句柄(Handle)。这里我们使用到了函数CreateFile。
HANDLE CreateFile( LPCTSTR lpFileName, // 文件名 DWORD dwDesiredAccess, // 访问方式 DWORD dwShareMode, // 共享模式 LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 设为NULL DWORD dwCreationDisposition, /// 创建方式 DWORD dwFlagsAndAttributes, // 属性 HANDLE hTemplateFile );
之后,我们在简单介绍下IOCTL,IOCTL通常用于驱动和应用程序的交流,其功能不限于读写数据。更多的时候,驱动都会定义一些列的IOCTL和数据结构来满足通信需求。简单来说,我们可把处于User Level的与IOCIL相关的东西看成一个Windows 信息,该信息通知驱动完成用户预先定义的某种请求。接下来先看看如何顶一个IOCTL. IOCTL是一个32未的数字,头两位的那个一了传输类型(METHOD_OUT_DIRECT,METHOD_IN_DIRECT
, METHOD_BUFFERED
or
METHOD_NEITHER
). 2-13bits定义了Function Code,其实你大可不需要在意这么多,用一个宏可以简单帮你完成任务。这个宏就是CTL_CODE.举例:我们定义一个IOCTL,用来查询MiniPort的版本号(5.1,6.0,6.20(Win7))。
#define _NDIS_CONTROL_CODE(request,method) \ CTL_CODE(FILE_DEVICE_PHYSICAL_NETCARD, request, method, FILE_ANY_ACCESS) #define IOCTL_FILTER_QUERY_DRIVER_VERSION _NDIS_CONTROL_CODE(18, METHOD_BUFFERED)
当然我们可能还需要预定义一些数据,比如分配输入和输出的缓冲区。输入缓冲区用于传输数据给底层驱动,输出缓冲区用于保存由底层返回的数据。而这些数据(包括IOCTL Code等)都必须由函数DeviceIoControl传递传递到底层驱动。有兴趣更深入了解的可以看看IRP。因为底层驱动是从IRP的数据结构中找到用户预先定义的数据,然后由驱动调度执行,完成用户的请求。
/** Rturns Ndis version of the current driver uses @return - TRUE - success, FALSE - failure */ BOOL FilterWrapper::QueryNdisVersion() { BOOL result = FALSE; LPVOID versionfoBuffer = NULL; DWORD bytesWritten = 0; //allocate new buffer to store mac info DWORD versionLengthBuffer = (DWORD)sizeof(USHORT); versionfoBuffer = new BYTE[versionLengthBuffer]; if(versionfoBuffer == NULL) { goto Exit; } // pass a new io control to underlying driver to create a new mac if(!DeviceIoControl( m_hFilter, IOCTL_FILTER_QUERY_DRIVER_VERSION, "Request from user mode to ger ndis version.\n", sizeof("Request from user mode to ger ndis version.\n"), versionfoBuffer, versionLengthBuffer, &bytesWritten, NULL)) { printf("Can't get version\n"); goto Exit; } printf("Successfylly get ndis version! And Version Info:\n"); if(!ParseVersionBuffer(versionfoBuffer, bytesWritten)) goto Exit; result = TRUE; Exit: delete[] versionfoBuffer; return result;; }
接下来,我们看看底层驱动是如何调度执行的。刚才说过了,所有的数据都会保存在一个叫做IRP的数据结构里,并且完成状态也是保存在IRP结构中。
NTSTATUS FilterDeviceIoControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PIO_STACK_LOCATION IrpSp; NTSTATUS Status = STATUS_SUCCESS; PFILTER_DEVICE_EXTENSION FilterDeviceExtension; PUCHAR InputBuffer; PUCHAR OutputBuffer; ULONG InputBufferLength, OutputBufferLength; PLIST_ENTRY Link; PUCHAR pInfo; ULONG InfoLength = 0; PMS_FILTER pFilter = NULL; UINT iCnt = 0, iPCnt = 0; PUCHAR temp; //Following variables are add by leyond NDIS_OID Oid; USHORT VersionBuffer = 0;//USHORT for getting version ULONG MethodId = 0; ULONG BytesProcessed = 0; UNREFERENCED_PARAMETER(DeviceObject); DEBUGP(DL_TEST,("==>Filter IO Control dispatch\n")); IrpSp = IoGetCurrentIrpStackLocation(Irp); if (IrpSp->FileObject == NULL) { return(STATUS_UNSUCCESSFUL); } FilterDeviceExtension = (PFILTER_DEVICE_EXTENSION)NdisGetDeviceReservedExtension(DeviceObject); ASSERT(FilterDeviceExtension->Signature == 'FTDR'); Irp->IoStatus.Information = 0; switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_FILTER_QUERY_DRIVER_VERSION://get ndsi version InputBuffer = OutputBuffer = (PUCHAR)Irp->AssociatedIrp.SystemBuffer; InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength; OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength; //pInfo = OutputBuffer; DEBUGP(DL_TEST,("The input length is %u, and inputdata is %s ",InputBufferLength,InputBuffer)); InfoLength = sizeof(USHORT); NdisZeroMemory(OutputBuffer, OutputBufferLength); Link = FilterModuleList.Flink; pFilter = CONTAINING_RECORD(Link, MS_FILTER, FilterModuleLink); /*Check Version */ Oid = OID_GEN_DRIVER_VERSION; Status = filterDoInternalRequest(pFilter, NdisRequestQueryInformation, Oid, &VersionBuffer, sizeof(VersionBuffer), sizeof(VersionBuffer), MethodId, &BytesProcessed); if(Status == NDIS_STATUS_SUCCESS) { DEBUGP(DL_TEST,("Get Ndis Version successfully!\n")); VersionHighByte = (VersionBuffer & 0xFF00) >> 8; VersionLowByte = (VersionBuffer & 0x00FF); DEBUGP(DL_TEST,("Ndis version:High %d, and Low: %d\n",VersionHighByte,VersionLowByte)); if(InfoLength <= OutputBufferLength) { temp = OutputBuffer; *(PUSHORT)OutputBuffer += VersionBuffer; OutputBuffer += sizeof(USHORT); OutputBuffer = temp; }else { Status = STATUS_BUFFER_TOO_SMALL; } Irp->IoStatus.Information = InfoLength; }else{ DEBUGP(DL_TEST,("Get Version Fail\n")); } break; default: break; } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = InfoLength; IoCompleteRequest(Irp, IO_NO_INCREMENT); DEBUGP(DL_TEST,("Filter IO Control dispatch<====\n")); return Status; }
总会调用IoCompleteRequest来结束IRP,返回执行结果给用户。
大概就是这样一个简单的介绍~
评论
发表评论
-
Filter驱动:过滤(修改)接受数据包
2010-04-20 16:18 9310Filter驱动可以实现简单的防火墙功能。它可以过滤所有接收到 ... -
Ndis过滤驱动:拷贝NetBufferList数据
2010-04-19 22:40 9557今天我们来看看如何拷贝NBL中的数据。有时候需要更改数据包中的 ... -
在Filter驱动内核中获取IP地址
2010-04-18 01:48 3893项目开发中有时候需要在Filter驱动中获取有效地Unic ... -
如何在内核中获得当前系统时间
2010-04-16 15:08 2719在 Windows NT 内核中你是无法使用 tim ... -
Filter发送自定义数据详解
2010-04-16 10:30 5756... -
DebugPrint 格式说明符
2010-04-13 19:46 17641) 直接打印字符串。 DbgPrint(“Hello ... -
WDK+Visual Studio 2008配置编译驱动
2010-04-12 23:36 5561Introduction As it is known, ... -
疑问:关于内存释放
2010-04-12 21:33 1453今天碰到一个比较棘手的内存处理问题。 首先来看一个数据结构: ... -
Windows NT 驱动程序开发人员提示 -- 应注意避免的事项
2010-04-10 11:32 2322原讨论链接: http://community.cs ... -
关于DeviceIoControl实现异步的笔记【2】
2010-04-09 23:17 5101前面我们谈到了关于异步I/O的实现:关于DeviceIoCon ... -
关于DeviceIoControl实现异步的笔记【1】
2010-04-08 22:26 11743一直所做的都是同步实现的。当然很多情况这并不是很好的解决问题。 ... -
驱动和应用层的异步通信
2010-04-08 20:55 5405作 者: sislcb时 间: 2008-01-28,11:1 ... -
Windows系统编程之异步I/O和完成端口
2010-04-08 19:40 2317一、 同步I/O和异步I/O ... -
纵横捭阖C++之从异步谈起
2010-04-08 19:31 3217一般来说,简单的异步(Asynchronous)调用是这样一种 ... -
在驱动中使用链表
2010-04-03 14:06 3291文章作者:grayfox 作 ... -
疑问:数据包Length增大的原因
2010-04-01 14:35 1366现象: 自己定义一个仅含有Ethernet Header的数 ... -
疑问:为何无线网卡无法发送数据?
2010-03-30 22:42 4563所有的测试流程表明,程序已经成功的创建新的数据包,然后调用Nd ... -
InsertHeadList和CONTAINING_RECORD
2010-03-29 16:36 3753LIST_ENTRY定义一个双向链表的数据结构: typed ... -
如何区分不同的Filter Module Instance
2010-03-29 14:50 1537前文 说到如何区分不同Filter Module Inst ... -
大数据是否需要封装在多个MDL中发送
2010-03-27 21:40 2516前段时间,我们已经解决如何发送自定义的网络数据。那么接下来要做 ...
相关推荐
本文将详细探讨如何使用`DeviceIoControl`进行直接方式的通信,以及在WDM(Windows Driver Model)驱动程序中的应用。 首先,我们需要理解WDM驱动模型。WDM是微软为Windows操作系统设计的一种驱动程序模型,它支持...
在Windows操作系统中,DeviceIoControl是一个非常重要的API,它提供了应用程序与设备驱动程序之间通信的桥梁。本实战教程将深入探讨如何使用DeviceIoControl来直接操控设备,从而实现对硬件的高级控制。以下是对这个...
在Windows驱动程序开发中,`passthru`是一种常见的技术,用于实现高层应用程序与底层硬件驱动之间的通信。本文将深入探讨`passthru`技术,以及如何利用`DeviceIoControl`函数来实现这种交互,同时关注`NDIS`(网络...
在Windows操作系统中,DeviceIoControl是一个非常重要的API函数,它为用户模式的应用程序提供了一种与设备驱动程序进行通信的方法。这个函数允许应用程序发送特定的I/O控制代码(IOCTLs)到设备,从而实现对硬件的...
DeviceIoControl的使用涉及到三个关键元素:控制代码、输入缓冲区和输出缓冲区。 1. 控制代码(IOCTL): IOCTL是Input/Output Control的缩写,它是DeviceIoControl中的关键参数。每个IOCTL代码都对应一个特定的...
使用DeviceIoControl通信 - **DeviceIoControl**:用于与设备驱动程序进行交互。 - **通信方式**:通过发送IOCTL命令来实现驱动与应用程序之间的通信。 #### 37. 纵横捭阖C++之从异步谈起 - **异步编程**:一种...
DeviceIoControl是一个广泛使用的API函数,用于应用程序与设备驱动程序之间的通信。它为应用程序提供了一种向驱动程序发送控制码的方式,从而实现了应用程序对硬件设备的直接控制。 ##### 3.2 使用场景 ...
DeviceIoControl函数是Windows API提供的一种通信方式,允许应用程序与设备驱动程序进行通信,执行特定的设备控制操作。其基本语法如下: ```c BOOL DeviceIoControl( HANDLE DeviceHandle, DWORD IoControlCode,...
在Windows操作系统中,`DeviceIoControl`函数是进行设备控制的主要接口,它允许应用程序与驱动程序之间进行低级别通信,执行各种设备特定的操作。本文将深入探讨`DeviceIoControl`函数的原理、参数、使用方法,并...
通过实战演示,我们可以更好地理解和掌握DeviceIOControl的使用技巧,了解如何与各种硬件设备进行有效的通信。在分析提供的源代码时,我们可以学习到如何构建正确的请求结构,以及如何正确处理设备返回的信息。这...
DeviceIoControl是Windows API提供的一种高级机制,允许应用程序与设备驱动程序进行通信,执行特定的设备操作,如配置硬件、读取硬件状态、控制设备功能等。在Windows系统开发中,熟练掌握DeviceIoControl对于驱动...
在Windows操作系统中,`DeviceIoControl`函数是一个非常重要的API,用于与设备驱动程序进行通信。这个函数允许用户模式的应用程序向设备发送控制代码,从而实现对硬件的直接操作。在本实例中,我们将深入探讨如何...
在驱动开发领域,`DeviceIoControl`函数是一个非常重要的API,它主要用于实现用户模式应用程序与内核模式驱动程序之间的通信。通过这个函数,用户空间的应用程序可以向驱动程序发送控制代码,并接收相应的数据。下面...
3. 在应用层使用DeviceIoControl函数,传入设备句柄和控制代码,以及可能的数据缓冲区。 4. 驱动处理控制请求后,通过IoCompleteRequest或WdfRequestComplete返回结果。 总之,Windows驱动程序开发是一个复杂而重要...
【设备驱动接口函数DeviceIoControl使用实例】 在Windows操作系统中,设备驱动接口函数DeviceIoControl是应用程序与设备驱动程序通信的重要途径。这个函数允许应用程序发送特定的控制代码到设备驱动,从而执行各种...