shineast
驱动牛犊
驱动牛犊
  • 注册日期2008-01-11
  • 最后登录2011-05-03
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望32点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2763回复:0

tdifw-1.4.4在TDI Hook模式下的问题及修正

楼主#
更多 发布于:2009-01-06 10:23
之前把tdifw-1.4.4源码看了一边,老外的代码确实看着舒服。。。注释很丰富。。。
我的程序中需要获取程序的网络行为,甚至需要拦截,以及用户交互。。。
遂copy了tdifw-1.4.4的源码,幸好是开源免费的。。。
tdifw-1.4.4 支持两种模式:设备过滤模式 和 TDI Hook模式
开始没有考虑那么多,直接用了设备过滤模式。
后来发现一个问题——在驱动卸载的时候,偶尔会蓝屏。。。
原因就在于,如果卸载时有网络活动的话,刚一卸载驱动,IRP就过来了。。。
因此这种蓝屏似乎很难避免,也许还有一些巧妙的办法,但是我还没怎么思考。。。
然而使用TDI Hook模式的话,就不存在这个问题了,于是改了工作模式。。。
后面问题又来了,虽然不蓝屏了,但是tdi_dispatch_complete函数有问题。。。
处理完IRP_MJ_CREATE时,在tdi_dispatch_complete中设置的完成例程,根本不执行。。。
为什么一定需要完成例程被调用呢,主要是为了在完成例程中解析IP地址。。。
下面是几个代码片段:
//分析 MajorFunction
switch (irps->MajorFunction)
{
case IRP_MJ_CREATE:   /* create fileobject */
  
   result = tdi_create(irp, irps, &completion);
  
   status = tdi_dispatch_complete(DeviceObject, irp, result,
    completion.routine, completion.context);
  
   break;


NTSTATUS
tdi_dispatch_complete(PDEVICE_OBJECT devobj, PIRP irp, int filter,
       PIO_COMPLETION_ROUTINE cr, PVOID context)
{

。。。。。。
   if (cr != NULL) {
     /*
     * set completion routine (this way is slow)
     */

    // save old completion routine and context
     TDI_SKIP_CTX *ctx = (TDI_SKIP_CTX *)malloc_np(sizeof(*ctx));
     if (ctx == NULL) {
      KdPrint(("[tdi_fw] tdi_send_irp_to_old_driver: malloc_np\n"));
    
      status = irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
      IoCompleteRequest(irp, IO_NO_INCREMENT);
    
      return status;
     }

    ctx->old_cr = irps->CompletionRoutine;
     ctx->old_context = irps->Context;
     ctx->new_cr = cr;
     ctx->new_context = context;
     ctx->fileobj = irps->FileObject;
     ctx->new_devobj = devobj;

    ctx->old_control = irps->Control;
   IoSetCompletionRoutine(irp, tdi_skip_complete, ctx, TRUE, TRUE, TRUE);
    }

。。。。。。
return status;
}

[size=+0]事实上,上面的红色代码是有问题的,IoSetCompletionRoutine设置的是下一层驱动的完成例程,根本没有调用,应该设置本层的完成例程。经过我修改的代码如下:
    ctx->old_cr = irps->CompletionRoutine;
     ctx->old_context = irps->Context;
     ctx->old_control = irps->Control;

    ctx->new_cr = cr;
     ctx->new_context = context;
     ctx->new_devobj = devobj;

    ctx->fileobj = irps->FileObject;
    //设置本层驱动的完成例程
     irps->Context = ctx;
     irps->CompletionRoutine = (PIO_COMPLETION_ROUTINE) tdi_skip_complete;
     irps->Control=SL_INVOKE_ON_ERROR|SL_INVOKE_ON_SUCCESS|SL_INVOKE_ON_CANCEL;

[size=+0]发现也有朋友遇到和我一样的问题,http://bbs.pediy.com/showthread.php?t=76149
[size=+0]不过tdifw-1.4.4自从2005年已经不更新了,希望其他朋友注意这个地方!
游客

返回顶部