DeviceIoControl这个api我们用的不多,但是很重要,有时会帮助我们实现一些特别的需求, 如获取硬件设备信息、与硬件设备通信(读写数据)等,对照msdn,下面我们详细解释一下这个api的用法...DeviceIoControl是用来控制我们指定设备的输入输出操作,使设备按照我们发的指令去工作。...DeviceIoControl是kernel32中的函数,需要包含的头文件是winbase.h,先看函数原型 BOOL DeviceIoControl( HANDLE hDevice, DWORD dwIoControlCode...Method) ) 可以看到,这个宏四个参数,自然是一个32位分成了4部分,高16位存储设备类型( 这里不列举了,看msdn哦),14~15位访问权限,2~13位操作功能,最后一个就是确定缓冲区(别忘记上面DeviceIOControl
A 在NT/2000/XP中,应用程序可以通过API函数DeviceIoControl来实现对设备的访问—获取信息,发送命令,交换数据等。...DeviceIoControl的函数原型为 BOOL DeviceIoControl( HANDLE hDevice, // 设备句柄 DWORD dwIoControlCode, // 控制码 LPVOID...Q 请举一个简单的例子说明如何通过DeviceIoControl访问设备驱动程序。...现在我们总结一下通过DeviceIoControl访问设备驱动程序的“三步曲”:首先用CreateFile取得设备句柄,然后用DeviceIoControl与设备进行I/O,最后别忘记用CloseHandle...A DeviceIoControl使用这两个控制码时,都不需要输入数据。
* filename, DISK_GEOMETRY * pdg) { HANDLE hDevice; // 设备句柄 BOOL bResult; // DeviceIoControl...bResult) { pmt = (GET_MEDIA_TYPES *)new BYTE[MEDIA_INFO_SIZE]; bResult = ::DeviceIoControl(...好麻烦阿,好多看不懂,慢慢来 先看DISK_GEOMETRY 这个结构体 其中的MEDIA_TYPE是个枚举类型 好多阿 具体就不列出来了,可以到msdn上察看到所有的 这里有一个很重要的函数,就是::DeviceIoControl.../C : 关于::DeviceIoControl这个函数的用法,我不多说了,可以参考 http://dev.csdn.net/article/55/55510.shtm 这个系列,我也是参考这个的...关于这个,确实还有很多值得我们去学习~~~~ 4.区分移动硬盘和硬盘 我说了,移动硬盘也是DRIVE_FIXED ,真够bt的,这个没做过的话,很难想像的,太bt了 那怎么区分 用DeviceIoControl
A 在NT/2000/XP中,应用程序可以通过API函数DeviceIoControl来实现对设备的访问—获取信息,发送命令,交换数据等。...DeviceIoControl的函数原型为 BOOL DeviceIoControl( HANDLE hDevice, // 设备句柄 DWORD dwIoControlCode
lcb0281@163点com MSDN原文地址:DeviceIoControl function DeviceIoControl 将控制代码直接发送到指定的设备驱动程序,使相应的设备执行相应的操作...即使操作没有返回输出数据并且lpOutBuffer为NULL,DeviceIoControl也会使用lpBytesReturned。...对于重叠操作,DeviceIoControl会立即返回,并在操作完成时通知事件对象。 否则,该功能在操作完成或发生错误之前不会返回。...返回值: 如果操作成功完成,DeviceIoControl将返回一个非零值。 如果操作失败或正在等待,则DeviceIoControl返回零。...的示例,请参阅调用DeviceIoControl。
与驱动程序通信的函数,除了ReadFile和WriteFile函数还有DeviceIoControl函数,而且DeviceIoControl函数那是相当的彪悍。...DeviceIoControl的第二个参数就是控制码,控制码是一个32为无符号整型,需要符合DDK的规定。...操作系统会将AssociatedIrp.SystemBuffer的数据再次复制到DeviceIoControl提供的输出缓冲区,复制的字节数有pIrp->IoStatus.Information指定,DeviceIoControl...往驱动中Input数据:通过I/O堆栈的Parameters.DeviceIoControl.Type3InputBuffer得到DeviceIoControl提供的输入缓冲区地址,Parameters.DeviceIoControl.InputBufferLength...从驱动中Output数据:通过pIrp->UserBuffer得到DeviceIoControl函数提供的输出缓冲区地址,再通过Parameters.DeviceIoControl.OutputBufferLength
驱动开发之 用DeviceIoControl实现应用程序与驱动程序通信 1. readfile和writefile可以实现应用程序与驱动程序通信,另外一个Win32 API 是DeviceIoControl...首先介绍一下DeviceIoControl函数 BOOL WINAPI DeviceIoControl( _In_ HANDLE hDevice, //已经打开的设备句柄...直接内存模式中,操作系统会将DeviceIoControl指定的输出缓冲区锁定,然后在内核模式地址下重新映射一段地址。...派遣函数中IRP中的pIrp->MdlAddress记录DeviceIoControl指定的输出缓冲区。...使用用户模式地址必须保证调用DeviceIoControl 的线程与派遣函数运行在同一个线程上下文中。
之前写过一篇关于通过DeviceIoControl函数来使应用程序与驱动程序通信的博客,这次再通过这个完整的代码来简要疏通总结一下。 ...这种通信方式,就是驱动程序和应用程序自定义一种IO控制码,然后调用DeviceIoControl函数,IO管理器会产生一个MajorFunction 为IRP_MJ_DEVICE_CONTROL(DeviceIoControl...驱动程序铺垫打理好之后,应用程序就可以由符号链接名通过CreateFile函数获取到设备句柄DeviceHandle,再用本场的主角,DeviceIoControl通过这个DeviceHandle发送控制码了...先看看这两个函数: BOOL WINAPI DeviceIoControl( _In_ HANDLE hDevice, //CreateFile函数打开的设备句柄...; OutputDataLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength; switch
这种通信方式,就是驱动程序和应用程序自定义一种IO控制码,然后调用DeviceIoControl函数,IO管理器会产生一个MajorFunction 为IRP_MJ_DEVICE_CONTROL(DeviceIoControl...METHOD_ NEITHER方式是不进行缓冲的,在驱动中可以直接使用Ring3的输入输出内存地址, 驱动程序可以通过pIrpStack->Parameters.DeviceIoControl.Type3InputBuffer...驱动程序铺垫打理好之后,应用程序就可以由符号链接名通过CreateFile函数获取到设备句柄DeviceHandle,再用本场的主角,DeviceIoControl通过这个DeviceHandle发送控制码了...先看看这两个函数: 1234567891011121314151617181920212223242526 BOOL WINAPI DeviceIoControl( _In_ HANDLE...; OutputDataLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength; switch (IoControlCode
Ring3层的CreateFile函数获取了设备句柄后,将使用DeviceIoControl函数向指定的设备驱动发送一个IO控制码,驱动程序通过这个控制码来完成特定的工作。...该函数原型如下: BOOL WINAPI DeviceIoControl( _In_ HANDLE hDevice, //CreateFile函数打开的设备句柄 _In...在驱动层,IoStackLocation->Parameters.DeviceIoControl.IoControlCode表示了这个控制码。发送不同的控制码,可以调用设备驱动程序的不同类型的功能。...在驱动层,这个值是IoStackLocation->Parameters.DeviceIoControl.InputBufferLength。...在驱动层,这个值是IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength。
驱动层与应用层通信是通过DeviceIoControl, 符号定义 #define DEVICE_NAME L"\\Device\\myDriver" // Driver Name...直接内存模式中,操作系统会将DeviceIoControl指定的输出缓冲区锁定,然后在内核模式地址下重新映射一段地址。...派遣函数中IRP中的pIrp->MdlAddress记录DeviceIoControl指定的输出缓冲区。...使用用户模式地址必须保证调用DeviceIoControl 的线程与派遣函数运行在同一个线程上下文中。...派遣函数得到输入缓冲区的方式与前两种不同,此模式是通过IO堆栈的stack->Parameters.DeviceIoControl.Type3InputBuffer;得到输入缓冲区。
A 在NT/2000/XP中,应用程序能够通过API函数DeviceIoControl来实现对设备的訪问—获取信息,发送命令,交换数据等。...DeviceIoControl的函数原型为 BOOL DeviceIoControl( HANDLE hDevice, // 设备句柄 DWORD dwIoControlCode...Q 请举一个简单的样例说明怎样通过DeviceIoControl訪问设备驱动程序。...A 这里有一个从MSDN上摘抄来的demo程序,演示在NT/2000/XP中怎样通过DeviceIoControl获取硬盘的基本參数。...如今我们总结一下通过DeviceIoControl訪问设备驱动程序的“三步曲”:首先用CreateFile取得设备句柄,然后用DeviceIoControl与设备进行I/O,最后别忘记用CloseHandle
内核中执行代码后需要将结果动态显示给应用层的用户,DeviceIoControl 是直接发送控制代码到指定的设备驱动程序,使相应的移动设备以执行相应的操作的函数,如下代码是一个经典的驱动开发模板框架,在开发经典驱动时会用到的一个通用案例...;// 输入和输出的缓冲区(DeviceIoControl的InBuffer和OutBuffer都是它)pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;// EXE...发送传入数据的BUFFER长度(DeviceIoControl的nInBufferSize)uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength...;// EXE接收传出数据的BUFFER长度(DeviceIoControl的nOutBufferSize)uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength...;pIrp->IoStatus.Information = uOutSize;IoCompleteRequest(pIrp, IO_NO_INCREMENT);return status;}// 设定DeviceIoControl
内核中执行代码后需要将结果动态显示给应用层的用户,DeviceIoControl 是直接发送控制代码到指定的设备驱动程序,使相应的移动设备以执行相应的操作的函数,如下代码是一个经典的驱动开发模板框架,在开发经典驱动时会用到的一个通用案例...; // 输入和输出的缓冲区(DeviceIoControl的InBuffer和OutBuffer都是它) pIoBuffer = pIrp->AssociatedIrp.SystemBuffer...; // EXE发送传入数据的BUFFER长度(DeviceIoControl的nInBufferSize) uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength...; // EXE接收传出数据的BUFFER长度(DeviceIoControl的nOutBufferSize) uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength...发送控制信号 // input = 发送数据 output = 接受数据 ref_len = 数据长度 DWORD input = 100, output = 0, ref_len = 0; DeviceIoControl
当时我推测可能是句柄为NULL,或者DeviceIoControl中哪个缓冲区不能为NULL,为了知道是哪的问题,我在调用DeviceIoControl之前加了一条输出语句,我发现这条语句输出的句柄值是正常的...,那就肯定是DeviceIoControl的问题,我先试着吧所有的输入输出缓冲区都给定了一个值,通过排查最后发现是倒数第二个参数不能为NULL,这个参数表示的是驱动层实际返回的缓冲区的大小。...这就要说到DeviceIoControl与驱动通信的方式,DeviceIoControl的定义如下: BOOL DeviceIoControl( HANDLE hDevice, DWORD dwIoControlCode...通过dwIoControlCode向驱动下发控制码,这个控制码在驱动中可以通过IO_STACK_LOCATION 结构中的Parameters.DeviceIoControl.IoControlCode...DeviceIoControl函数,如果不需要跟驱动层进行交互,那么他的输入输出缓冲区是可以给NULL的,但是由于I/O管理器会像它返回驱动层实际返回的数据的大小,所以这个真实大小的缓冲区一定不能为NULL
hProcessEvent, INFINITE)一直在等待事件,一旦内核驱动KeSetEvent(pDeviceExten->pkProcessEvent, 0, FALSE)设置为有信号状态,则应用层会通过DeviceIoControl...pBuffer = (PPROCESS_PTR)pUserOutPutBuffer;uIoControl = pIrpStack->Parameters.DeviceIoControl.IoControlCode...;uReadLen = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;uWriteLen = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength...;uReadLen = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;uWriteLen = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength...hProcessEvent){return 0;}while (TRUE){// 等待事件WaitForSingleObject(hProcessEvent, INFINITE);// 发送控制信号bRet = DeviceIoControl
KeSetEvent(&g_Event, 0, FALSE); } } } 此时若有新进程创建全局的 g_Event 会被设置为有信号状态,接下来就到我们处理应用层使用 DeviceIoControl...; ULONG ulOutputlength = pIrpsp->Parameters.DeviceIoControl.OutputBufferLength; do {...switch (pIrpsp->Parameters.DeviceIoControl.IoControlCode) { case CWK_DVC_SEND_STR...通过 CreateFile 打开设备,并调用 DeviceIoControl 函数向驱动发送一个接收数据的请求。...此时如果驱动链表中没有数据,那么会停在 KeWaitForSingleObject 函数,同时应用层也阻塞在 DeviceIoControl 函数上。
缓存方式派遣函数中的使用例子 三丶MDL方式(直接IO方式) 3.1 直接IO方式 3.2Mdl结构 3.3 直接IO通信例子 四丶其它方式读写 4.1 其它方式 五丶IO控制设备通讯方式 5.1 DeviceIoControl...它里面记录着 Read Write DeviceIoControl Create 等结构。 当我们 IRP类型为Read的时候。派遣函数 则可以从 Read域中获取读取的长度 偏移等信息。...BOOL DeviceIoControl( [in] HANDLE hDevice, [in] DWORD...函数,并且通信方式指明为 METHOD_BUFFERED 那么DeviceIoControl 传递的 InBuffer OutBuffer 都会转化为IRP中的 SystemBuffer 我们直接从...DeviceIoControl->Type3InputBuffer 记录着输入缓冲区 Irp->UserBuffer 记录着输出缓冲区 其中输入输出缓冲区的长度还是在 DeviceIoControl
AssociatedIrp.SystemBuffer; // 输出堆栈 InputDataLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength...; // 输入数据大小 OutputDataLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength;...// 输出数据大小 ULONG Code = IoStackLocation->Parameters.DeviceIoControl.IoControlCode; // 控制码...symLinkName; status = IoCreateSymbolicLink(&symLinkName, &devName); return STATUS_SUCCESS; } 客户端代码中只需要通过DeviceIoControl...buf.Flage = 2; buf.Addr = 0x401234; buf.WriteBufferAddr = 1024; buf.Size = 100; buf.Pid = 2566; DeviceIoControl
hProcessEvent, INFINITE)一直在等待事件,一旦内核驱动KeSetEvent(pDeviceExten->pkProcessEvent, 0, FALSE)设置为有信号状态,则应用层会通过DeviceIoControl...pBuffer = (PPROCESS_PTR)pUserOutPutBuffer; uIoControl = pIrpStack->Parameters.DeviceIoControl.IoControlCode...; uReadLen = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; uWriteLen = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength...; uReadLen = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; uWriteLen = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength...} while (TRUE) { // 等待事件 WaitForSingleObject(hProcessEvent, INFINITE); // 发送控制信号 bRet = DeviceIoControl
领取专属 10元无门槛券
手把手带您无忧上云