drive
驱动牛犊
驱动牛犊
  • 注册日期2005-02-01
  • 最后登录2005-05-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1375回复:6

求助:关于DeviceIoControl()函数

楼主#
更多 发布于:2005-03-03 15:06
请问应用程序在利用DeviceIoControl()函数调用驱动程序时,如果一开始驱动程序没有完成本次操作,然后应用程序将该函数所在的线程悬挂。
我的理解是:这虽然应用程序悬挂了,但是驱动程序还在处理本次的IRP中,所以在执行一段时间后,驱动程序在条件具备后就能完成本次IRP操作。
不知道我的理解是否正确?还有若驱动程序完成了本次IRP操作,是否能在应用程序端线程还处在悬挂状态时就自动将交互的数据放到DeviceIoControl()函数所指定的内存中?

做了很久的程序,就一直被卡在这里,大侠们帮忙啊
bow
谢谢

最新喜欢:

wolfwangwolfwa... hanwlhanwl
bmyyyud
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2010-01-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望130点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-03-03 15:46
看你的DeviceIoControl 中LPOVERLAPPED lpOverlapped指定的是同步还是异步,同步,调用DeviceIoControl,驱动必须完成返回,应用程序才能继续,如果是异步,调用DeviceIoControl,应用程序立即返回,驱动自己处理IRP,应用程序需要回头来查询是否完成

还有若驱动程序完成了本次IRP操作,是否能在应用程序端线程还处在悬挂状态时就自动将交互的数据放到DeviceIoControl()函数所指定的内存中?
任何时候驱动完成就放数据到用户缓冲,其实不是驱动放的,是I/O Manager放的,它的IRQL比应用程序高,所以那时应用程序是停止的
滚滚长江东逝水 浪花淘尽英雄 是非成败转头空 青山依旧在 几度夕阳红 白发渔樵江渚上 惯看秋月春风 一壶浊酒喜相逢 古今多少事 尽付笑谈中
drive
驱动牛犊
驱动牛犊
  • 注册日期2005-02-01
  • 最后登录2005-05-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-03-03 18:47
非常感谢bmyyyud的回答。
不过我还是有不明白的:
我的程序中DeviceIoControl用的是同步,我把数据的传输做成一个线程,然后用WaitForSingleObject(..,100)来判断数据传送是否完成。如果100ms后数据没有传送成功应用程序停止等待。那之后驱动完成了IRP并自动将数据存放到用户缓冲后,应用程序怎么知道什么时候数据放进去了呢?
看你的DeviceIoControl 中LPOVERLAPPED lpOverlapped指定的是同步还是异步,同步,调用DeviceIoControl,驱动必须完成返回,应用程序才能继续,如果是异步,调用DeviceIoControl,应用程序立即返回,驱动自己处理IRP,应用程序需要回头来查询是否完成

还有若驱动程序完成了本次IRP操作,是否能在应用程序端线程还处在悬挂状态时就自动将交互的数据放到DeviceIoControl()函数所指定的内存中?
任何时候驱动完成就放数据到用户缓冲,其实不是驱动放的,是I/O Manager放的,它的IRQL比应用程序高,所以那时应用程序是停止的
 
bmyyyud
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2010-01-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望130点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-03-04 09:02
非常感谢bmyyyud的回答。
不过我还是有不明白的:
我的程序中DeviceIoControl用的是同步,我把数据的传输做成一个线程,然后用WaitForSingleObject(..,100)来判断数据传送是否完成。如果100ms后数据没有传送成功应用程序停止等待。那之后驱动完成了IRP并自动将数据存放到用户缓冲后,应用程序怎么知道什么时候数据放进去了呢?
[quote]看你的DeviceIoControl 中LPOVERLAPPED lpOverlapped指定的是同步还是异步,同步,调用DeviceIoControl,驱动必须完成返回,应用程序才能继续,如果是异步,调用DeviceIoControl,应用程序立即返回,驱动自己处理IRP,应用程序需要回头来查询是否完成

还有若驱动程序完成了本次IRP操作,是否能在应用程序端线程还处在悬挂状态时就自动将交互的数据放到DeviceIoControl()函数所指定的内存中?
任何时候驱动完成就放数据到用户缓冲,其实不是驱动放的,是I/O Manager放的,它的IRQL比应用程序高,所以那时应用程序是停止的
 
[/quote]
你是在新创建线程中调用DeviceIoControl吗?在主线程中用WaitForSingleObject(..,100)等待新创建线程的什么对象?请进一步说明
滚滚长江东逝水 浪花淘尽英雄 是非成败转头空 青山依旧在 几度夕阳红 白发渔樵江渚上 惯看秋月春风 一壶浊酒喜相逢 古今多少事 尽付笑谈中
drive
驱动牛犊
驱动牛犊
  • 注册日期2005-02-01
  • 最后登录2005-05-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-03-04 10:18
你是在新创建线程中调用DeviceIoControl吗?在主线程中用WaitForSingleObject(..,100)等待新创建线程的什么对象?请进一步说明 [/quote]

 下面是辅助线程函数:
UINT WINAPI ReadProc(
   LPVOID threadParameter2
)
{
// perform the bulk transfer
   PTHREAD_CONTROL threadControl=(PTHREAD_CONTROL)
                                  threadParameter2;
   threadControl->status = DeviceIoControl
                      (threadControl->hDevice,
                        threadControl->Ioctl,
                        threadControl->InBuffer,
                        threadControl->InBufferSize,
                        threadControl->OutBuffer,
                        threadControl->OutBufferSize,
                        &threadControl->BytesReturned,
                       NULL);

   // if an event exists, set it
    if (threadControl->completionEvent)
       SetEvent(threadControl->completionEvent);
    return 1;
}

在主线程中创建新线程时调用DeviceIoControl函数,并利用WaitForSingleObject进行等待:
...
ReadCompleteEvent = CreateEvent(0,FALSE,FALSE,NULL);
InThreadControl.completionEvent = ReadCompleteEvent;
hReadex=_beginthreadex(NULL,
             0,
   ReadProc,
   &InThreadControl,
   0,
   NULL);
DWORD ReadReturnValue=WaitForSingleObject(InThreadControl.completionEvent,100);
CloseHandle(InThreadControl.completionEvent);
在后面根据ReadWReturnValue的值,如果调用成功就将缓存中的数据读取出来。但如果100ms以内调用不成功,而在后面驱动程序又自动将数据放入用户缓存;我怎么者能把这个数据从用户缓存中读取出来呢?
非常感谢!
bmyyyud
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2010-01-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望130点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-03-04 11:26

 下面是辅助线程函数:
UINT WINAPI ReadProc(
LPVOID threadParameter2
)
{
// perform the bulk transfer
PTHREAD_CONTROL threadControl=(PTHREAD_CONTROL)
threadParameter2;
threadControl->status = DeviceIoControl
(threadControl->hDevice,
threadControl->Ioctl,
threadControl->InBuffer,
threadControl->InBufferSize,
threadControl->OutBuffer,
threadControl->OutBufferSize,
&threadControl->BytesReturned,
NULL);

// if an event exists, set it
if (threadControl->completionEvent)
SetEvent(threadControl->completionEvent);
//设置另外一个新Event
return 1;
}
然后在主线程要数据时检查这个新Event状态,如果数据已到,取就可以了
滚滚长江东逝水 浪花淘尽英雄 是非成败转头空 青山依旧在 几度夕阳红 白发渔樵江渚上 惯看秋月春风 一壶浊酒喜相逢 古今多少事 尽付笑谈中
drive
驱动牛犊
驱动牛犊
  • 注册日期2005-02-01
  • 最后登录2005-05-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-03-04 12:50
非常感谢bmyyyud
我再考虑一政你的这个方法,有不懂的地方再向你请教!
先送分!
游客

返回顶部