`
tomhibolu
  • 浏览: 1385367 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

本文首先发表于:http://bbs.driverdevelop.com/htm_data/10/0703/100349.html

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

参照了开源代码,现修正如下:
/*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);
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics