阅读:1785回复:11
DeviceIoControl是怎么实现数据传入驱动程序的?
我刚刚开始学习驱动程序的开发2天,现在刚学会用DRIVERSTUDIO向导创建驱动工程.我对驱动程序开发的知识基本为0,但对VC比较熟悉。
BOOL DeviceIoControl( HANDLE hDevice, // handle to device DWORD dwIoControlCode, // operation LPVOID lpInBuffer, // input data buffer DWORD nInBufferSize, // size of input data buffer LPVOID lpOutBuffer, // output data buffer DWORD nOutBufferSize, // size of output data buffer LPDWORD lpBytesReturned, // byte count LPOVERLAPPED lpOverlapped // overlapped information ); 这是MSDN上对DeviceIoControl的申明。 void Test_TESTSYS_IOCTL_800(void) { // Note that Input and Output are named from the point of view // of the DEVICE: // bufInput supplies data to the device // bufOutput is written by the device to return data to this application CHAR bufInput[IOCTL_INBUF_SIZE]; // Input to device CHAR bufOutput[IOCTL_OUTBUF_SIZE]; // Output from device ULONG nOutput; // Count written to bufOutput memcpy(bufInput,"testdata",8); // Call device IO Control interface (TESTSYS_IOCTL_800) in driver printf("Issuing Ioctl to device - "); if (!DeviceIoControl(hDevice, TESTSYS_IOCTL_800, bufInput, IOCTL_INBUF_SIZE, bufOutput, IOCTL_OUTBUF_SIZE, &nOutput, NULL) ) { printf("ERROR: DeviceIoControl returns %0x.", GetLastError()); Exit(1); } printf("return:%s\n",bufOutput); } 这是我用DRIVERSTUDIO自动生成的测试程序中的一个函数。 bufInput应该是传入驱动程序的数据内容。 bufOutput应该是驱动程序返回给执行程序的数据内容。 但我想知道的是调用DeviceIoControl把数据传入驱动后驱动是在哪个函数中对这个事件进行处理的?传入的数据又是被保存在哪个变量中的。 在自动生成的驱动程序代码中有 NTSTATUS TestsysDevice::TESTSYS_IOCTL_800_Handler(KIrp I) { NTSTATUS status = STATUS_SUCCESS; t << "Entering TestsysDevice::TESTSYS_IOCTL_800_Handler, " << I << EOL; // TODO: Verify that the input parameters are correct // If not, return STATUS_INVALID_PARAMETER // TODO: Handle the the TESTSYS_IOCTL_800 request, or // defer the processing of the IRP (i.e. by queuing) and set // status to STATUS_PENDING. // TODO: Assuming that the request was handled here. Set I.Information // to indicate how much data to copy back to the user. I.Information() = 0; return status; } 这个是不是用来响应上面执行程序中的Test_TESTSYS_IOCTL_800(void) 函数的。如果是的话那么传入的数据是被保存到I中了吗? 如果是的话如何把它分离出来?而返回给执行程序的bufOutput又是如何传出的? 小弟初学驱动,请大家赐教。 |
|
沙发#
发布于:2004-08-27 13:31
DeviceIOControl将数据发送到IO管理器,IO管理对数据进行包装成IO请求(存放在一个KIRP中),然后再发给PNP管理器,再发给驱动程序,驱动程序处理好之后再按相反的顺序返回,你可以在DS帮助文件中查找KIRP的对应内容就OK了
|
|
板凳#
发布于:2004-08-27 13:33
建议你使用DDK里面的例子,DRIVERSTUDIO等你对WIN和DDK都很熟练了再去使用,如果你和我水平一样烂的话,还是先从简单的DDK开始,嘿嘿。。。。。
|
|
|
地板#
发布于:2004-08-27 14:46
1.调用DeviceIoControl把数据传入驱动后驱动是在以下函数中对这个事件进行处理:
NTSTATUS ELITEDevice::DeviceControl(KIrp I) { switch (I.IoctlCode()) { ... case TESTSYS_IOCTL_800: status = TESTSYS_IOCTL_800_Handler(I); break; ... } } 然后就转到 NTSTATUS TestsysDevice::TESTSYS_IOCTL_800_Handler(KIrp I) { ..... } 2.I/O管理器把用户模式程序发送给驱动程序的数据复制到数据缓冲区中;对于读请求,设备驱动程序把读出的数据填到这个缓冲区中,然后I/O管理器再把缓冲区的内容复制到用户模式缓冲区。 3.Test_TESTSYS_IOCTL_800(void)是应用程序,它可以调用一个或多个驱动程序(看你怎么用);你的例子只调用了一个驱动程序 请看以下模型 |
|
地下室#
发布于:2004-08-27 14:58
模型打不开?
能再发一次吗? |
|
5楼#
发布于:2004-08-27 15:05
好的
|
|
6楼#
发布于:2004-08-27 15:09
不好意思,再来一次
|
|
|
7楼#
发布于:2004-08-27 15:16
还是打不开
:( I.Information()是表示数据长度吗? 还有我在 memcpy(bufInput,"testdata",8); // Call device IO Control interface (TESTSYS_IOCTL_800) in driver printf("Issuing Ioctl to device - "); if (!DeviceIoControl(hDevice, TESTSYS_IOCTL_800, bufInput, IOCTL_INBUF_SIZE, bufOutput, IOCTL_OUTBUF_SIZE, &nOutput, NULL) ) 将"testdata"这个字符串作为传入参数传入的,现在应该如果才能取出? |
|
8楼#
发布于:2004-08-27 15:19
我也想看,怎么打不开附件呢?
|
|
|
9楼#
发布于:2004-08-27 16:00
wowocock 老兄:
你总说先学ddk,ddk那么难,初学者怎么能学呢?我觉得还是先学ds熟悉了驱动之后再精学ddk :( |
|
|
10楼#
发布于:2004-08-27 16:55
I.Information()是表示数据长度,
参考:Field IoStatus.Information informs the I/O manager how many bytes of data the driver is returning. This is critical for buffered I/O operations where the I/O manager must know how much data to copy from the I/O buffer to the application buffer. |
|
11楼#
发布于:2004-08-27 17:29
建议学习DDK呀,这是基础.
|
|