Ошибка при вызове completion routine нижележащего драйвера

Тема в разделе "WASM.NT.KERNEL", создана пользователем prus, 18 мар 2008.

  1. prus

    prus New Member

    Публикаций:
    0
    Регистрация:
    26 окт 2007
    Сообщения:
    92
    Всем привет!
    Помогите решить проблему.
    Имею свой драйвер, который аттачу к \Device\Tcp.
    В TDI_CONNECT хочу узнать статус завершения данной процедуры нижележащим драйвером, для чего регистрирую свою completion routine и передаю ей контекст с сохраненными старой функцией завершения и старым контекстом. При вызове в моей completion routine старой функции происходит бсод с ошибкой BAD_POOL_CALLER. Вот реализация:
    Код (Text):
    1. ...
    2. ...
    3.                 pTdiConnCompletionRoutineContext->CompletionRoutine = irpStack->CompletionRoutine;
    4.                 pTdiConnCompletionRoutineContext->Context = irpStack->Context;
    5.                 pTdiConnCompletionRoutineContext->pClientConnToSrvInfo = pClientConnToSrvInfo;
    6.  
    7.                 IoCopyCurrentIrpStackLocationToNext(pIrp);
    8.                 IoSetCompletionRoutine(pIrp, (PIO_COMPLETION_ROUTINE)TdiConnectCompletionRoutine, (PTDI_CONNECT_COMPLETION_ROUTINE_CONTEXT)pTdiConnCompletionRoutineContext, TRUE, TRUE, TRUE);
    9.                 return IoCallDriver(pDevExt->pDeviceObject, pIrp);
    10. ...
    11. ...
    Моя completion routine:
    Код (Text):
    1. NTSTATUS TdiConnectCompletionRoutine(IN PDEVICE_OBJECT  pDeviceObject, IN PIRP  pIrp, IN PVOID pContext) {
    2.  
    3.     NTSTATUS ntResStatus = STATUS_SUCCESS;
    4.     PTDI_CONNECT_COMPLETION_ROUTINE_CONTEXT pTdiConnCompletionRoutineContext;
    5.     PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;
    6.  
    7.     pTdiConnCompletionRoutineContext = (PTDI_CONNECT_COMPLETION_ROUTINE_CONTEXT)pContext;
    8.  
    9.     ntResStatus = pTdiConnCompletionRoutineContext->CompletionRoutine(pDeviceObject, pIrp, pTdiConnCompletionRoutineContext->Context);
    10.  
    11.     DbgPrint("In TdiConnectCompletionRoutine... Context: 0x%08X", (ULONG)pTdiConnCompletionRoutineContext->Context);
    12.  
    13.     ExFreePool(pTdiConnCompletionRoutineContext->pClientConnToSrvInfo);
    14.  
    15.     return ntResStatus;
    16.  
    17. }
    Крэш дамп:
    Код (Text):
    1. *******************************************************************************
    2. * *
    3. * Bugcheck Analysis *
    4. * *
    5. *******************************************************************************
    6.  
    7. BAD_POOL_CALLER (c2)
    8. The current thread is making a bad pool request. Typically this is at a bad IRQL level or double freeing the same allocation, etc.
    9. Arguments:
    10. Arg1: 00000040, Attempt to free usermode address to kernel pool
    11. Arg2: 00000000, Starting address
    12. Arg3: 80000000, Start of system address space
    13. Arg4: 00000000, 0
    14.  
    15. Debugging Details:
    16. ------------------
    17.  
    18. FAULTING_IP:
    19. afd!AfdRestartConnect+100
    20. f6d6f2e1 83660c00 and dword ptr [esi+0Ch],0
    21.  
    22. BUGCHECK_STR: 0xc2_40
    23.  
    24. DEFAULT_BUCKET_ID: INTEL_CPU_MICROCODE_ZERO
    25.  
    26. PROCESS_NAME: System
    27.  
    28. LAST_CONTROL_TRANSFER: from 8054a509 to 805339ae
    29.  
    30. STACK_TEXT:
    31. f88dc974 8054a509 000000c2 00000040 00000000 nt!KeBugCheckEx+0x1b
    32. f88dc9b0 8054b28b 00000000 81acd008 81822008 nt!MiFreePoolPages+0x94
    33. f88dc9f0 f6d6f2e1 00000000 c9646641 818220c3 nt!ExFreePoolWithTag+0x1b7
    34. f88dca18 804e42cc 81a0cd80 00000000 819f4008 afd!AfdRestartConnect+0x100
    35. f88dca48 f6db181c 81987540 81970008 00000002 nt!IopfCompleteRequest+0xa2
    36. f88dca60 f6dc9a67 81822008 c0000236 00000000 tcpip!TCPDataRequestComplete+0xa6
    37. f88dca74 f6db508d 81822008 c0000236 00000000 tcpip!TCPRequestComplete+0x12
    38. f88dca94 f6db996b 81970008 f88dcc54 c0000236 tcpip!CompleteConnReq+0x87
    39. f88dcb18 f6daeef9 81aa5c60 0100007f 0100007f tcpip!TCPRcv+0xc7f
    40. f88dcb78 f6daeb19 00000020 81aa5c60 f6db1076 tcpip!DeliverToUser+0x18e
    41. f88dcbf4 f6dae836 f6dee210 81aa5c60 f88dcd10 tcpip!DeliverToUserEx+0x95f
    42. f88dccac f6db86e6 81aa5c60 f88dcd24 00000014 tcpip!IPRcvPacket+0x6cb
    43. f88dcd58 f87653e4 f6dee020 81aa5c60 f6dee030 tcpip!LoopXmitRtn+0x195
    44. f88dcd74 804e47fe 81aa5c60 00000000 81bc9640 TDI!CTEpEventHandler+0x32
    45. f88dcdac 8057dfed f6dee020 00000000 00000000 nt!ExpWorkerThread+0x100
    46. f88dcddc 804fa477 804e4729 00000001 00000000 nt!PspSystemThreadStartup+0x34
    47. 00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16
    48.  
    49.  
    50. STACK_COMMAND: kb
    51.  
    52. FOLLOWUP_IP:
    53. TDI!CTEpEventHandler+32
    54. f87653e4 5f pop edi
    55.  
    56. SYMBOL_STACK_INDEX: d
    57.  
    58. SYMBOL_NAME: TDI!CTEpEventHandler+32
    59.  
    60. FOLLOWUP_NAME: MachineOwner
    61.  
    62. MODULE_NAME: TDI
    63.  
    64. IMAGE_NAME: TDI.SYS
    65.  
    66. DEBUG_FLR_IMAGE_TIMESTAMP: 41107d33
    67.  
    68. FAILURE_BUCKET_ID: 0xc2_40_TDI!CTEpEventHandler+32
    69.  
    70. BUCKET_ID: 0xc2_40_TDI!CTEpEventHandler+32
    71.  
    72. Followup: MachineOwner
    73. ---------
    Заранее спасибо!
     
  2. zoool

    zoool New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2007
    Сообщения:
    412
    ExFreePool(pTdiConnCompletionRoutineContext->pClientConnToSrvInfo);
    Эта строка смущает...
    попробуй закомментировать и без нее запустить.
     
  3. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    ну ведь тогда competionroutine нижнего дрова вызовется дважды - один раз из твоей completion routine, а второй раз нормально при проходе стека сверху вниз в IopfCompleteRequest.
    так что надо тогда сделать что-то, чтобы нижний драйвер не ставил completion routine, а ты вызывать ее будешь сам
     
  4. prus

    prus New Member

    Публикаций:
    0
    Регистрация:
    26 окт 2007
    Сообщения:
    92
    Спасиб. Вопрос решен. Вызывать старую completion routine не к чему было. Так все ок:
    Код (Text):
    1. NTSTATUS TdiConnectCompletionRoutine(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID pContext) {
    2.  
    3.     PCLIENT_CONNECTION_TO_SERVER_INFO pClientConnToSrvInfo = (PCLIENT_CONNECTION_TO_SERVER_INFO)pContext;
    4.  
    5.     if( pIrp->StackCount >= pIrp->CurrentLocation ) {
    6.         if( pIrp->PendingReturned )
    7.             IoMarkIrpPending(pIrp);
    8.     }
    9.  
    10.     if( pClientConnToSrvInfo != NULL )
    11.         ExFreePool(pClientConnToSrvInfo);
    12.  
    13.     return STATUS_SUCCESS;
    14.  
    15. }