doganddog
驱动牛犊
驱动牛犊
  • 注册日期2004-05-20
  • 最后登录2004-07-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1362回复:5

过滤文件驱动中进程切换的问题

楼主#
更多 发布于:2004-06-03 21:33
想做一个文件的读写过滤驱动程序,现在的问题是:在IRP_MJ_READ中通过IoSetCompletionRoutine函数来设定低层读操作完成以后调用自己的函数完成一些和读取内容相关的操作。但是因为可能会有阻塞的情况发生,所以当读操作完成并将控制权转交给自己编写的处理函数时,很可能进程已经做了切换,而Irp->UserBuffer地址是读请求发生时的进程的用户空间地址,所以不能直接访问或修改其内容。
我现在的想法是手工进程切换,即在我的函数内部先切换到读请求发生时的进程空间,相应操作完成后再切换回来。不知道关于存储叶面表的操作涉及到那些?目前我能通过pFileThread=Irp->Tail.Overlay.Thread;      pFileProcess=pFileThread->ThreadsProcess;     FileCr3=pFileProcess->Pcb.DirectoryTableBase[0];得到CR3的内容,但是好像还是没有很完整的完成切换,请各位大侠指点进程空间的切换都需要做那些操作和更改那些寄存器的内容,谢谢大家
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2004-06-03 23:13
KeStackAttachProcess
[This is preliminary documentation and subject to change.]

KeStackAttachProcess attaches the current thread to the address space of the target process. Use this routine with extreme caution. (See the following Comments section.)

VOID
  KeStackAttachProcess (
    IN PKPROCESS  Process,
    OUT PRKAPC_STATE  ApcState
    );
Parameters
Process
Pointer to the target process object. This parameter can be a PEPROCESS pointer returned by IoGetCurrentProcess or PsGetCurrentProcess.
ApcState
Pointer to a variable that receives an opaque pointer to a KAPC_STATE structure for which the caller must allocate storage either from nonpaged pool or from the caller\'s own thread stack.
Comments
KeStackAttachProcess attaches the current thread to the address space of the process pointed to by the Process parameter. If the current thread was already attached to another process, the ApcState parameter receives the current APC state before KeStackAttachProcess attaches to the new process.

Every successful call to KeStackAttachProcess must be matched by a subsequent call to KeUnstackDetachProcess.

Note that attaching a thread to a different process can prevent asynchronous I/O operations from completing and can potentially cause deadlocks. In general, the lines of code between the call to KeStackAttachProcess and the call to KeUnstackDetachProcess should be very simple and not call complex routines or send IRPs to other drivers.

For more information on using system threads and managing synchronization within a non-arbitrary thread context, see \"Driver Threads, Dispatcher Objects, and Resources\" in the DDK Kernel-Mode Driver Architecture Reference.

Callers of KeStackAttachProcess must be running at IRQL < DISPATCH_LEVEL.

花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-06-03 23:37
我的建议是直接在IRP_MJ_READ派遣例程中等待。

Status = IoCallDriver(....);

if(Status == STATUS_PENDING)
{
  Status = KeWaitForSingleObject(...);

  if(Status == STATUS_SUCCESS)
  {
    Status = Irp->IoStatus.Status;
  }
}

if(Status == STATUS_SUCCESS)
{
  // Do Something here    
}

我就这样做,到目前为止还没有发现什么问题。
doganddog
驱动牛犊
驱动牛犊
  • 注册日期2004-05-20
  • 最后登录2004-07-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-06-04 09:20
多谢wowocock和slwqw的回复,我会去试验一下的,再次谢过二位的指点
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-06-05 15:28
我的建议是直接在IRP_MJ_READ派遣例程中等待。

Status = IoCallDriver(....);

if(Status == STATUS_PENDING)
{
  Status = KeWaitForSingleObject(...);

  if(Status == STATUS_SUCCESS)
  {
    Status = Irp->IoStatus.Status;
  }
}

if(Status == STATUS_SUCCESS)
{
  // Do Something here    
}

我就这样做,到目前为止还没有发现什么问题。

这样效率势必降低
能否有更好的办法呢?
是不是可通过在读时保留线程相关信息,比如PRKTHREAD,然后在完成例程中检查,当然我并没有测试过
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
idaxsy
驱动大牛
驱动大牛
  • 注册日期2004-12-09
  • 最后登录2006-03-17
  • 粉丝0
  • 关注0
  • 积分386分
  • 威望54点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-05-17 15:27
 
我的建议是直接在IRP_MJ_READ派遣例程中等待。

Status = IoCallDriver(....);

if(Status == STATUS_PENDING)
{
  Status = KeWaitForSingleObject(...);

  if(Status == STATUS_SUCCESS)
  {
    Status = Irp->IoStatus.Status;
  }
}

if(Status == STATUS_SUCCESS)
{
  // Do Something here
}

我就这样做,到目前为止还没有发现什么问题。


很多代码就是这么处理的。
[b]万水千山总是情,回个帖子行不行?[/b]
游客

返回顶部