jackxin
驱动牛犊
驱动牛犊
  • 注册日期2002-07-29
  • 最后登录2009-06-16
  • 粉丝0
  • 关注0
  • 积分40分
  • 威望5点
  • 贡献值0点
  • 好评度3点
  • 原创分1分
  • 专家分0分
阅读:2596回复:1

有关费尔防火墙一书TDI代码“网上邻居”不能访问功能的修复

楼主#
更多 发布于:2007-03-29 13:33
  参照了开源代码,现修正如下:
/*if (Irp->CurrentLocation == 1)
    {
        ULONG ReturnedInformation = 0;

        DBGPRINT(("PacketDispatch encountered bogus current location\n"));

        RC = STATUS_INVALID_DEVICE_REQUEST;
        Irp->IoStatus.Status = RC;
        Irp->IoStatus.Information = ReturnedInformation;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        return( RC );
    }*/

修正如下:
sequenceNumber = 0;
    seq = InterlockedIncrement(&sequenceNumber);
    if (Irp->CurrentLocation < DeviceObject->StackSize)
    {
        return PassThroughWithNewIrp(DeviceObject, Irp, seq);
    }
    else
    {
        NextIrpStack    = IoGetNextIrpStackLocation(Irp);
        *NextIrpStack    = *IrpStack;
        IoSetCompletionRoutine(Irp,PacketCompletion,NULL,TRUE,TRUE,TRUE);
        return IoCallDriver(pTDIH_DeviceExtension->LowerDeviceObject,Irp);
    }

上面用到的子函数体内容如下:
NTSTATUS NetPassOnNormally (PDEVICE_OBJECT HookDevice, IN PIRP Irp)
{
    PTDIH_DeviceExtension hookExt = HookDevice->DeviceExtension;
    
    // Back the stack up one
    IoSkipCurrentIrpStackLocation(Irp);
    
    // Call the next lower driver
    return IoCallDriver(hookExt->LowerDeviceObject, Irp);
}

NTSTATUS NetOtherIRPCompletionRoutine (PDEVICE_OBJECT DeviceObject,
                                           PIRP Irp, PVOID Context)
{
  PIRP origIrp = (PIRP) Context;
  ULONG seq;
  KIRQL oldirql;
  PCHAR eventBuffer;
    
  // Extract the sequence number from the original IRP's UserEvent field,
  // then restore that field's proper value from the new IRP's field

  seq = (ULONG) origIrp->UserEvent;
  origIrp->UserEvent = Irp->UserEvent;
        
  // Copy important possibly returned fields in this IRP to the original IRP
  origIrp->IoStatus = Irp->IoStatus;
  origIrp->PendingReturned = Irp->PendingReturned;
  origIrp->MdlAddress = Irp->MdlAddress;

  // If this IRP was pending, mark the new and original IRP's pending
  if (Irp->PendingReturned) {
    IoMarkIrpPending(Irp);
    IoMarkIrpPending(origIrp);
  }

  // Free the IRP we created
  IoFreeIrp(Irp);

  // Complete the original IRP

  IoCompleteRequest(origIrp, IO_NO_INCREMENT);

  // Return STATUS_MORE_PROCESSING_REQUIRED to indicate that we're going
  // to take control of our IRP and finish handling it.  Actually, we've
  // already handled it by freeing it.  If we didn't take control of it,
  // the I/O Manager might try to process our IRP further, which would
  // we bad since it's been freed.
  return STATUS_MORE_PROCESSING_REQUIRED;
}

NTSTATUS PassThroughWithNewIrp(PDEVICE_OBJECT HookDevice, IN PIRP Irp, ULONG seq)
{
    PTDIH_DeviceExtension    hookExt = HookDevice->DeviceExtension;
    PIRP                    newIrp;
    PIO_STACK_LOCATION        currentIrpStackLocation;
    PIO_STACK_LOCATION        newIrpFirstStackLocation;
    
    // Allocate a new IRP with stack size sufficient for the next lower device
    newIrp = IoAllocateIrp(hookExt->LowerDeviceObject->StackSize, FALSE);
    DbgPrint("FilterTdiDriver.sys, lower stack, %d, current stack, %d",
        hookExt->LowerDeviceObject->StackSize, hookExt->TargetDeviceObject->StackSize);
    if (newIrp == NULL){
        return NetPassOnNormally(HookDevice, Irp);
    }
    
    // Fill in important fields of new IRP with those of original IRP
    newIrp->MdlAddress = Irp->MdlAddress;
    newIrp->Flags = Irp->Flags;
    newIrp->AssociatedIrp = Irp->AssociatedIrp;
    newIrp->RequestorMode = Irp->RequestorMode;
    newIrp->UserIosb = Irp->UserIosb;
    newIrp->UserEvent = Irp->UserEvent;
    newIrp->Overlay = Irp->Overlay;
    newIrp->UserBuffer = Irp->UserBuffer;
    newIrp->Tail.Overlay.AuxiliaryBuffer = Irp->Tail.Overlay.AuxiliaryBuffer;
    newIrp->Tail.Overlay.OriginalFileObject = Irp->Tail.Overlay.OriginalFileObject;
    newIrp->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
    
    // Copy current stack location to the first stack location in the new IRP
    currentIrpStackLocation = IoGetCurrentIrpStackLocation(Irp);
    newIrpFirstStackLocation = IoGetNextIrpStackLocation(newIrp);
    *newIrpFirstStackLocation = *currentIrpStackLocation;
    
    // Set the completion routine to VTrcNetOtherIRPCompletionRoutine, with
    // the original IRP as context.  Save the sequence number in the UserEvent
    // field so that it can be used in the completion routine.  (The completion
    // routine will restore the original UserEvent field from the new IRP.)
    Irp->UserEvent = (PKEVENT) seq;
    IoSetCompletionRoutine(newIrp, NetOtherIRPCompletionRoutine, (PVOID) Irp, TRUE, TRUE, TRUE);
    
    // Send the new IRP to the lower-level device
    return IoCallDriver(hookExt->LowerDeviceObject, newIrp);
}
burgess
驱动牛犊
驱动牛犊
  • 注册日期2007-03-18
  • 最后登录2008-04-26
  • 粉丝0
  • 关注0
  • 积分310分
  • 威望32点
  • 贡献值0点
  • 好评度31点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-03-29 15:12
置顶帖《TDI 过滤驱动开发指南 by 楚狂人 》中最后几页写的应该也可以吧
游客

返回顶部