wahaha2000
驱动牛犊
驱动牛犊
  • 注册日期2003-08-05
  • 最后登录2004-12-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1713回复:11

DeviceIoControl是怎么实现数据传入驱动程序的?

楼主#
更多 发布于:2004-08-27 10:31
    我刚刚开始学习驱动程序的开发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又是如何传出的?
   小弟初学驱动,请大家赐教。
zhiyuan19840428
驱动小牛
驱动小牛
  • 注册日期2004-05-11
  • 最后登录2005-06-17
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-08-27 13:31
DeviceIOControl将数据发送到IO管理器,IO管理对数据进行包装成IO请求(存放在一个KIRP中),然后再发给PNP管理器,再发给驱动程序,驱动程序处理好之后再按相反的顺序返回,你可以在DS帮助文件中查找KIRP的对应内容就OK了
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2004-08-27 13:33
建议你使用DDK里面的例子,DRIVERSTUDIO等你对WIN和DDK都很熟练了再去使用,如果你和我水平一样烂的话,还是先从简单的DDK开始,嘿嘿。。。。。
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
colinyou
驱动牛犊
驱动牛犊
  • 注册日期2003-11-03
  • 最后登录2006-03-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于: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)是应用程序,它可以调用一个或多个驱动程序(看你怎么用);你的例子只调用了一个驱动程序

请看以下模型
wahaha2000
驱动牛犊
驱动牛犊
  • 注册日期2003-08-05
  • 最后登录2004-12-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-08-27 14:58
模型打不开?
能再发一次吗?
colinyou
驱动牛犊
驱动牛犊
  • 注册日期2003-11-03
  • 最后登录2006-03-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-08-27 15:05
好的
colinyou
驱动牛犊
驱动牛犊
  • 注册日期2003-11-03
  • 最后登录2006-03-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-08-27 15:09
不好意思,再来一次
附件名称/大小 下载次数 最后更新
2004-08-27_IRP处理的“标准模型”.rar (4KB)  25
wahaha2000
驱动牛犊
驱动牛犊
  • 注册日期2003-08-05
  • 最后登录2004-12-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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"这个字符串作为传入参数传入的,现在应该如果才能取出?
relaxs
驱动牛犊
驱动牛犊
  • 注册日期2003-03-21
  • 最后登录2005-03-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-08-27 15:19
我也想看,怎么打不开附件呢?
想做就做
chencheng
驱动小牛
驱动小牛
  • 注册日期2003-06-27
  • 最后登录2007-08-30
  • 粉丝0
  • 关注0
  • 积分28分
  • 威望5点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-08-27 16:00
wowocock 老兄:
你总说先学ddk,ddk那么难,初学者怎么能学呢?我觉得还是先学ds熟悉了驱动之后再精学ddk
 :(
好好学习,天天向上
colinyou
驱动牛犊
驱动牛犊
  • 注册日期2003-11-03
  • 最后登录2006-03-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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.
  
Sundsea
驱动老牛
驱动老牛
  • 注册日期2003-05-06
  • 最后登录2012-06-05
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望35点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-08-27 17:29
建议学习DDK呀,这是基础.
游客

返回顶部