Всем привет! Помогите решить проблему. Имею свой драйвер, который аттачу к \Device\Tcp. В TDI_CONNECT хочу узнать статус завершения данной процедуры нижележащим драйвером, для чего регистрирую свою completion routine и передаю ей контекст с сохраненными старой функцией завершения и старым контекстом. При вызове в моей completion routine старой функции происходит бсод с ошибкой BAD_POOL_CALLER. Вот реализация: Код (Text): ... ... pTdiConnCompletionRoutineContext->CompletionRoutine = irpStack->CompletionRoutine; pTdiConnCompletionRoutineContext->Context = irpStack->Context; pTdiConnCompletionRoutineContext->pClientConnToSrvInfo = pClientConnToSrvInfo; IoCopyCurrentIrpStackLocationToNext(pIrp); IoSetCompletionRoutine(pIrp, (PIO_COMPLETION_ROUTINE)TdiConnectCompletionRoutine, (PTDI_CONNECT_COMPLETION_ROUTINE_CONTEXT)pTdiConnCompletionRoutineContext, TRUE, TRUE, TRUE); return IoCallDriver(pDevExt->pDeviceObject, pIrp); ... ... Моя completion routine: Код (Text): NTSTATUS TdiConnectCompletionRoutine(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID pContext) { NTSTATUS ntResStatus = STATUS_SUCCESS; PTDI_CONNECT_COMPLETION_ROUTINE_CONTEXT pTdiConnCompletionRoutineContext; PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension; pTdiConnCompletionRoutineContext = (PTDI_CONNECT_COMPLETION_ROUTINE_CONTEXT)pContext; ntResStatus = pTdiConnCompletionRoutineContext->CompletionRoutine(pDeviceObject, pIrp, pTdiConnCompletionRoutineContext->Context); DbgPrint("In TdiConnectCompletionRoutine... Context: 0x%08X", (ULONG)pTdiConnCompletionRoutineContext->Context); ExFreePool(pTdiConnCompletionRoutineContext->pClientConnToSrvInfo); return ntResStatus; } Крэш дамп: Код (Text): ******************************************************************************* * * * Bugcheck Analysis * * * ******************************************************************************* BAD_POOL_CALLER (c2) The current thread is making a bad pool request. Typically this is at a bad IRQL level or double freeing the same allocation, etc. Arguments: Arg1: 00000040, Attempt to free usermode address to kernel pool Arg2: 00000000, Starting address Arg3: 80000000, Start of system address space Arg4: 00000000, 0 Debugging Details: ------------------ FAULTING_IP: afd!AfdRestartConnect+100 f6d6f2e1 83660c00 and dword ptr [esi+0Ch],0 BUGCHECK_STR: 0xc2_40 DEFAULT_BUCKET_ID: INTEL_CPU_MICROCODE_ZERO PROCESS_NAME: System LAST_CONTROL_TRANSFER: from 8054a509 to 805339ae STACK_TEXT: f88dc974 8054a509 000000c2 00000040 00000000 nt!KeBugCheckEx+0x1b f88dc9b0 8054b28b 00000000 81acd008 81822008 nt!MiFreePoolPages+0x94 f88dc9f0 f6d6f2e1 00000000 c9646641 818220c3 nt!ExFreePoolWithTag+0x1b7 f88dca18 804e42cc 81a0cd80 00000000 819f4008 afd!AfdRestartConnect+0x100 f88dca48 f6db181c 81987540 81970008 00000002 nt!IopfCompleteRequest+0xa2 f88dca60 f6dc9a67 81822008 c0000236 00000000 tcpip!TCPDataRequestComplete+0xa6 f88dca74 f6db508d 81822008 c0000236 00000000 tcpip!TCPRequestComplete+0x12 f88dca94 f6db996b 81970008 f88dcc54 c0000236 tcpip!CompleteConnReq+0x87 f88dcb18 f6daeef9 81aa5c60 0100007f 0100007f tcpip!TCPRcv+0xc7f f88dcb78 f6daeb19 00000020 81aa5c60 f6db1076 tcpip!DeliverToUser+0x18e f88dcbf4 f6dae836 f6dee210 81aa5c60 f88dcd10 tcpip!DeliverToUserEx+0x95f f88dccac f6db86e6 81aa5c60 f88dcd24 00000014 tcpip!IPRcvPacket+0x6cb f88dcd58 f87653e4 f6dee020 81aa5c60 f6dee030 tcpip!LoopXmitRtn+0x195 f88dcd74 804e47fe 81aa5c60 00000000 81bc9640 TDI!CTEpEventHandler+0x32 f88dcdac 8057dfed f6dee020 00000000 00000000 nt!ExpWorkerThread+0x100 f88dcddc 804fa477 804e4729 00000001 00000000 nt!PspSystemThreadStartup+0x34 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16 STACK_COMMAND: kb FOLLOWUP_IP: TDI!CTEpEventHandler+32 f87653e4 5f pop edi SYMBOL_STACK_INDEX: d SYMBOL_NAME: TDI!CTEpEventHandler+32 FOLLOWUP_NAME: MachineOwner MODULE_NAME: TDI IMAGE_NAME: TDI.SYS DEBUG_FLR_IMAGE_TIMESTAMP: 41107d33 FAILURE_BUCKET_ID: 0xc2_40_TDI!CTEpEventHandler+32 BUCKET_ID: 0xc2_40_TDI!CTEpEventHandler+32 Followup: MachineOwner --------- Заранее спасибо!
ExFreePool(pTdiConnCompletionRoutineContext->pClientConnToSrvInfo); Эта строка смущает... попробуй закомментировать и без нее запустить.
ну ведь тогда competionroutine нижнего дрова вызовется дважды - один раз из твоей completion routine, а второй раз нормально при проходе стека сверху вниз в IopfCompleteRequest. так что надо тогда сделать что-то, чтобы нижний драйвер не ставил completion routine, а ты вызывать ее будешь сам
Спасиб. Вопрос решен. Вызывать старую completion routine не к чему было. Так все ок: Код (Text): NTSTATUS TdiConnectCompletionRoutine(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID pContext) { PCLIENT_CONNECTION_TO_SERVER_INFO pClientConnToSrvInfo = (PCLIENT_CONNECTION_TO_SERVER_INFO)pContext; if( pIrp->StackCount >= pIrp->CurrentLocation ) { if( pIrp->PendingReturned ) IoMarkIrpPending(pIrp); } if( pClientConnToSrvInfo != NULL ) ExFreePool(pClientConnToSrvInfo); return STATUS_SUCCESS; }