Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Ошибка при вызове completion routine нижележащего драйвера  (Прочитано 7497 раз)
0 Пользователей и 1 Гость смотрят эту тему.
prus
Гость
« : 18-03-2008 19:43 » 

Всем привет!
Помогите решить проблему.
Имею свой драйвер, который аттачу к \Device\Tcp.
В TDI_CONNECT хочу узнать статус завершения данной процедуры нижележащим драйвером, для чего регистрирую свою completion routine и передаю ей контекст с сохраненными старой функцией завершения и старым контекстом. При вызове в моей completion routine старой функции происходит бсод с ошибкой BAD_POOL_CALLER.

Вот место где заполняю контекст:

...
...
                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:

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;

}

Крэш дамп:

*******************************************************************************
* *
* 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
---------
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 19-03-2008 09:42 » 

pTdiConnCompletionRoutineContext кто и как размещает?
PS а там всегда irpStack->CompletionRoutine и irpStack->Context не нулевые?
« Последнее редактирование: 19-03-2008 09:49 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
prus
Гость
« Ответ #2 : 19-03-2008 13:05 » 

Сама структура вот такая:

typedef struct _TDI_CONNECT_COMPLETION_ROUTINE_CONTEXT {
   PIO_COMPLETION_ROUTINE  CompletionRoutine;
   PVOID Context;
   PCLIENT_CONNECTION_TO_SERVER_INFO pClientConnToSrvInfo;
} TDI_CONNECT_COMPLETION_ROUTINE_CONTEXT, *PTDI_CONNECT_COMPLETION_ROUTINE_CONTEXT;

Память выделяю так:

pTdiConnCompletionRoutineContext = (PTDI_CONNECT_COMPLETION_ROUTINE_CONTEXT)ExAllocatePool(NonPagedPool, sizeof(TDI_CONNECT_COMPLETION_ROUTINE_CONTEXT));

Сам указатель старой функции и старого контекста не нулевой. Бсод происходит через небольшой промежуток времени после вхождения в мою completion routine.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 19-03-2008 15:24 » 

хм... я конечно плохо c этим делом...
а кто сказал что надо чужую CompletionRoutine вызывать самому??)
« Последнее редактирование: 19-03-2008 15:30 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
prus
Гость
« Ответ #4 : 19-03-2008 18:16 » 

Вот это кто-то сказал, а делать этого не стоит точно Улыбаюсь
Теперь немного другаю проблема...
Не понимаю, почему в моей completion routine регистрирую cancel routine, а сама cancel routine не вызывается?
Вот так это выглядит:

VOID TdiConnectCancelRoutine(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) {

   DbgPrint("In TdiConnectCancelRoutine");
   pIrp->IoStatus.Status = STATUS_CANCELLED;
   IoCompleteRequest(pIrp, IO_NO_INCREMENT);

}

NTSTATUS TdiConnectCompletionRoutine(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp, IN PVOID pContext) {

   PTDI_CONNECT_COMPLETION_ROUTINE_CONTEXT pTdiConnCompletionRoutineContext = (PTDI_CONNECT_COMPLETION_ROUTINE_CONTEXT)pContext;

   ExFreePool(pTdiConnCompletionRoutineContext->pClientConnToSrvInfo);
   ExFreePool(pTdiConnCompletionRoutineContext);

   if( pIrp->IoStatus.Status != STATUS_SUCCESS ) {
      //DbgPrint("In TdiConnectCompletionRoutine STATUS = 0x%08X", (ULONG)pIrp->IoStatus.Status);
      IoSetCancelRoutine(pIrp, TdiConnectCancelRoutine);
   }
   
   return STATUS_SUCCESS;

}
Записан
prus
Гость
« Ответ #5 : 19-03-2008 19:57 » 

Реализация не правильная... Вопрос снимаю.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 20-03-2008 12:56 » 

)))))
ну да, CancelRoutine в CompletionRoutine регистрировать - это круто!))))))
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines