AllocateIRP vs BSOD

Тема в разделе "WASM.NT.KERNEL", создана пользователем dmk, 27 сен 2006.

  1. dmk

    dmk New Member

    Публикаций:
    0
    Регистрация:
    25 мар 2006
    Сообщения:
    20
    Адрес:
    Russia
    Привет всем!

    столкнулся с такой проблемой:
    взял SFilter из из примеров DDK, и хочу теперь в IRP_MJ_READ dispatch routine сделать редирект запросов нижестоящему драйверу...однако получаю BSOD...

    код обработчика IRP_MJ_READ:
    Код (Text):
    1.         hProcess = PsGetCurrentProcessId();
    2.  
    3.     if( (KeGetCurrentIrql() >= APC_LEVEL)||(hAttachedProcessID != hProcess)||(hAttachedProcessID == 0) || (Irp->Flags & IRP_PAGING_IO) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) )
    4.     {
    5.            IoSkipCurrentIrpStackLocation( Irp );
    6.            return IoCallDriver( ((PDRIVER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
    7.     }
    8.     else
    9.     {
    10.            tIrpRead = IoAllocateIrp( ((PRBDRIVER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject->StackSize, FALSE );
    11.             // заполнение tIrpRead
    12.     }
    так вот, может кто-нибудь подсказать, как правильно заполнять tIrpRead (или примерчик кода), чтобы операция чтения прошла без BSOD...

    заранее благодарен за помощь!
     
  2. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    В общем случае примерно так. С IoAllocateIrp больно много руками заполнять придется. Ну и код выше очень странный...

    Код (Text):
    1. NTSTATUS        status;
    2. PIRP            pIrp;
    3. KEVENT          event;
    4. IO_STATUS_BLOCK iosb;
    5. LARGE_INTEGER   offset;
    6. UCHAR           buffer[ 512 ];   //  you'd better allocate it from the pool
    7.  
    8. offset.QuadPart = 0;
    9.  
    10. pIrp = IoBuildSynchronousFsdRequest( IRP_MJ_READ,
    11.                                      pDeviceObject,
    12.                                      buffer,
    13.                                      sizeof(buffer),
    14.                                      &offset,
    15.                                      &event,
    16.                                      &iosb);
    17. if ( pIrp ) {
    18.  
    19.     KeInitializeEvent( &event, NotificationEvent, FALSE );
    20.  
    21.     status = IoCallDriver( pDeviceObject, pIrp );
    22.  
    23.     if ( STATUS_PENDING == status  ) {
    24.  
    25.         KeWaitForSingleObject( &event,
    26.                                Executive,
    27.                                KernelMode,
    28.                                FALSE,
    29.                                NULL );
    30.  
    31.          status = iosb.Status;
    32.     }
    33.  
    34.     if ( NT_SUCCESS( status ) ) {
    35.  
    36.     }
    37. }
     
  3. dmk

    dmk New Member

    Публикаций:
    0
    Регистрация:
    25 мар 2006
    Сообщения:
    20
    Адрес:
    Russia
    Four-F, спасибо за код!

    а что такого странного в моем коде? пропускаю все запросы не от моей тестовой проги, а так же пропускаю все PAGING_IO...

    а вот мне что-то не совсем понятно насчет offset... используя этот код смещение будет получаться относительно чего? относительно начала диска (раздела)?
    т.е. обрабатывая IRP_MJ_READ, я могу получить смещение относительно начала файла:
    IrpSp = IoGetCurrentIrpStackLocation(Irp);
    IrpSp->Parameters.Read.ByteOffset;

    т.е. основной вопрос как прочитать содержимое файла используя IoBuildSynchronousFsdRequest.

    или я чего-то недопонимаю?
     
  4. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Странно то, что ты зачем-то создаешь новый IRP. Ты говоришь, что "хочу теперь в IRP_MJ_READ dispatch routine сделать редирект запросов нижестоящему драйверу". Ну так и редиректь. Зачем новый-то делать? И что делать с тем, что пришел в твою "IRP_MJ_READ dispatch routine"?

    Стандартно ставится процедура завершения (completion routine), которая будет вызвана при завершинии IRP. В ней и можно посмотреть, что прочитано, если тебе это надо. Например, вот так (опять же примерно):

    Код (Text):
    1. NTSTATUS
    2.   ReadCompletion (
    3.     IN PDEVICE_OBJECT pDeviceObject,
    4.     IN PIRP           pIrp,
    5.     IN PVOID          pContext
    6.     )
    7. {
    8.  
    9.     if ( NT_SUCCESS(pIrp->IoStatus.Status) ) {
    10.  
    11.         DebugPrint( "Bytes transferred 0x%X \n", pIrp->IoStatus.Information );
    12.     }
    13.  
    14.     if ( pIrp->PendingReturned ) {
    15.  
    16.         IoMarkIrpPending( pIrp );
    17.     }
    18.  
    19.     return STATUS_SUCCESS;
    20. }
    21.  
    22.  
    23.  
    24.     . . .
    25.  
    26.     } else {
    27.  
    28.         IoCopyCurrentIrpStackLocationToNext( pIrp );
    29.  
    30.         IoSetCompletionRoutine(
    31.                           pIrp,
    32.                           ReadCompletion,
    33.                           NULL,
    34.                           TRUE,
    35.                           TRUE,
    36.                           TRUE );
    37.  
    38.         return IoCallDriver( ((PDRIVER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, pIrp );
    39.     }
    40. }
    Если запрос к девайсу, управляющему разделом, то от начала раздела. Я, кстати, не имел в виду именно запрос к диску. Это смещение драйвер получит в pIoStack->Parameters.Read.ByteOffset, а относительно чего, уже его дело. Например я могу создать драйвер, который выделит буфер и будет в него что-то писАть, лог какой-нибудь. Если клиент захочет получить лог с самого начала через ReadFile, то определит офсет равным нулю, а если с какого-нибудь другого места, то определит нужное смещение в буфере.

    Напрямую, видимо, никак. Если говорить о чтении диска, то можно зная размер сектора, читать его посекторно.

    Из исходного поста не понятно зачем вообще всё это нужно, и чего ты в итоге хочешь добиться, поэтому я тоже не совсем понимаю и, кстати, в драйверах файловых систем не силён - могу попутать что-нибудь.
     
  5. dmk

    dmk New Member

    Публикаций:
    0
    Регистрация:
    25 мар 2006
    Сообщения:
    20
    Адрес:
    Russia
    начсет записи лога, и чтения его по ReadFile - это хорошая мысль! мне как-то это раньше в голову не приходило... :dntknw:

    все это я начал делать, т.к. просто интересно прочитать из драйвера файл, для которого было выполнено FAST_IO_LOCK. простым перенаправлением чтения нижестоящему драйверу я получаю STATUS_LOCK_CONFLICT, а хочется все-равно прочитать файл...не писать же для этого дела кэш залоченых файлов :)

    эт ничего...я сам напостой что-нить путаю :) главное понять где и что я не так делаю :)

    кстати, а если после IoBuildSynchronousFsdRequest сделать IoGetNextIrpStackLocation, и туда прописать валидный FILE_OBJECT, то вроде все должно встать на "свои" места...так ведь?
     
  6. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Понятно. К сожалению, это не моя тема. Сходи http://www.osronline.com/page.cfm?name=search - одна из самых дельных конф по дровам. Там есть спец раздел по драйверам файловых систем.

    Не знаю, но не думаю, что всё так просто. В любом случае гадание на кофейной гуще, в данном случае, плохой метод.
     
  7. dmk

    dmk New Member

    Публикаций:
    0
    Регистрация:
    25 мар 2006
    Сообщения:
    20
    Адрес:
    Russia
    спасибо за помощь, буду дальше шариться по osr...