阅读:1276回复:0
有一个问题,谁帮看看
下面是我写一段程序,可以截获发给\\DEVICE\\TCP的IRP请求,但我发现当使用网络邻居访问其他的机器的时候,IRP传到我的驱动时IRP->CurrentLocation已经等于1了,如果我再调用IoGetNextIrpStackLocation,IoCallDriver,就会出现NO_MORE_IRP_STACK_LOCATION的错误.谁能说说是怎么回事.
#include \"ntddk.h\" #include \"tdikrnl.h\" typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT pDevice; PDEVICE_OBJECT pTargetDevice; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; PDEVICE_OBJECT g_pDev; PDEVICE_OBJECT g_pTagDev; NTSTATUS PassDownPnP( IN PDEVICE_OBJECT pDO, IN PIRP pIrp ) { PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDO->DeviceExtension; IoSkipCurrentIrpStackLocation( pIrp ); return IoCallDriver(pDevExt->pTargetDevice, pIrp); } NTSTATUS DispPnp(IN PDEVICE_OBJECT pDO, IN PIRP pIrp ) { // obtain current IRP stack location PIO_STACK_LOCATION pIrpStack; pIrpStack = IoGetCurrentIrpStackLocation( pIrp ); DbgPrint(\"HIFILTER: Received PNP IRP: %d\\n\",pIrpStack->MinorFunction); if(pIrp->StackCount == 1) { DbgPrint(\"pIrp->StackCount == 1\\n\"); return STATUS_SUCCESS; } switch (pIrpStack->MinorFunction) { case IRP_MN_START_DEVICE: { DbgPrint(\"StartDevice\\n\"); return PassDownPnP(pDO, pIrp); } case IRP_MN_STOP_DEVICE: { DbgPrint(\"StopDevice\\n\"); return PassDownPnP(pDO, pIrp); } case IRP_MN_REMOVE_DEVICE: { DbgPrint(\"StopDevice\\n\"); // IoDeleteDevice(pDO); return PassDownPnP(pDO, pIrp); } default: // if not supported here, just pass it down return PassDownPnP(pDO, pIrp); } // all paths from the switch statement will \"return\" // the results of the handler invoked } NTSTATUS GenericCompletion( IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN PVOID pContext ) { if ( pIrp->PendingReturned ) IoMarkIrpPending( pIrp ); return STATUS_SUCCESS; } NTSTATUS DispatchPassThru( IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { PIO_STACK_LOCATION pIrpStack; PIO_STACK_LOCATION pNextIrpStack; PDEVICE_EXTENSION pFilterExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension; if(pIrp->CurrentLocation == 0x01) { pIrpStack = IoGetCurrentIrpStackLocation( pIrp ); DbgPrint(\"MJ = 0x%02x,MN = 0x%02x\\n\",pIrpStack->MajorFunction,pIrpStack->MinorFunction); IoSkipCurrentIrpStackLocation(pIrp); } else { pIrpStack = IoGetCurrentIrpStackLocation( pIrp ); pNextIrpStack = IoGetNextIrpStackLocation( pIrp ); //IoCopyCurrentIrpStackLocationToNext(pIrp); if(pNextIrpStack == NULL) { DbgPrint(\"pNextIrpStack == NULL\\n\"); return STATUS_SUCCESS; } *pNextIrpStack = *pIrpStack; // Set up a completion routine to handle the bubbling // of the \"pending\" mark of an IRP IoSetCompletionRoutine( pIrp, GenericCompletion, NULL, TRUE, TRUE, TRUE ); } // Pass the IRP to the target. return IoCallDriver( pFilterExt->pTargetDevice, pIrp ); } VOID Unload( IN PDRIVER_OBJECT DriverObject ) { DbgPrint(\"Unload\\n\"); IoDetachDevice(g_pTagDev); IoDeleteDevice(g_pDev); } NTSTATUS DriverEntry ( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath) { UNICODE_STRING TcpDeviceName; PDEVICE_OBJECT TcpDriver; PFILE_OBJECT FileDriver; PDEVICE_OBJECT FilterDev; PDEVICE_OBJECT TcpgetDevice; NTSTATUS status; PDEVICE_EXTENSION pDevExt; int i; RtlInitUnicodeString( &TcpDeviceName, L\"\\\\Device\\\\Tcp\"); pDriverObject->DriverUnload = Unload; for(i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++) { if(i != IRP_MJ_POWER) pDriverObject->MajorFunction = DispatchPassThru; } pDriverObject->MajorFunction[IRP_MJ_PNP] = DispPnp; status = IoGetDeviceObjectPointer(&TcpDeviceName, FILE_ALL_ACCESS, &FileDriver, &TcpDriver); if(!NT_SUCCESS(status)) { DbgPrint(\"IoGetDeviceObjectPointer Error\\n\"); return status; } DbgPrint(\"IoGetDeviceObjectPointer ok\\n\"); status = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_UNKNOWN, 0,TRUE, &FilterDev); if(!NT_SUCCESS(status)) { DbgPrint(\"IoCreateDevice Error\\n\"); return status; } else { g_pDev = FilterDev; } pDevExt = (PDEVICE_EXTENSION)FilterDev->DeviceExtension; pDevExt->pDevice = FilterDev; pDevExt->pTargetDevice = IoAttachDeviceToDeviceStack(FilterDev,TcpDriver); { DbgPrint(\"TargetStackSize = 0x%02x\\n\",pDevExt->pTargetDevice->StackSize); FilterDev->StackSize = pDevExt->pTargetDevice->StackSize + 1; } g_pTagDev = pDevExt->pTargetDevice; return STATUS_SUCCESS; } |
|