StartIo или Как заставить драйвер вернуть STATUS_PENDING

Тема в разделе "WASM.WIN32", создана пользователем wish3, 16 май 2005.

  1. wish3

    wish3 New Member

    Публикаций:
    0
    Регистрация:
    31 янв 2005
    Сообщения:
    29
    Адрес:
    Ukraine
    1. Если с процедуры StartIo выйти не делая ни IoStartNextPacket, ни IoCompleteRequest, то останется ли текущий IRP в очереди необработаных пакетов? И вызовит ли диспечер ввода/вывода StartIo с этим IRP при следующим вызове IoStartNextPacket?



    2. Если даже отработчик IRP_MJ_READ всегда помещает пакет в очередь необработаных пакетом(IoStartPacket) и возвращает STATUS_PENDING, то насамом деле на этот вызов ВЫШЕлежащего драйвера(IoCallDriver) может прийти STATUS_SUCCESS, если очередь необработаных пакетов пуста и IoStartPacket сразу породжает StartIo.

    Подскажите как это обходиться? В двух словах - дальше я догадаюсь.



    3. Я делаю это так:
    Код (Text):
    1.  
    2. NTSTATUS
    3. MouDrv_Read (
    4.     IN PDEVICE_OBJECT DeviceObject,
    5.     IN PIRP pIrp
    6.     )
    7. {
    8.     ...
    9.     status = STATUS_PENDING;
    10.     ...
    11.     pIrp->IoStatus.Status = status;
    12.     pIrp->IoStatus.Information = 0;
    13.        
    14.     if(status == STATUS_PENDING) {
    15.        
    16.         IoStartPacket(DeviceObject, pIrp, (PULONG)NULL, NULL);
    17.     } else {
    18.         IoCompleteRequest(pIrp, IO_NO_INCREMENT);
    19.     }
    20.    
    21.     return status;
    22. }
    23.  
    24. VOID
    25. MouDrv_StartIo (
    26.     IN PDEVICE_OBJECT pDeviceObject,
    27.     IN PIRP pIrp
    28.     )
    29. {
    30.   ..............
    31.         //Если запрос к нам в первый раз то, сигнализируем
    32.         //поток о том, чтобы через некоторое время он нам
    33.         //напомнил что его нужно обработать
    34.     if(!pIrp->IoStatus.Information) {
    35.         pIrp->IoStatus.Information = 1;
    36.         KeSetEvent( &delayEvent, IO_NO_INCREMENT, FALSE );
    37.         return;
    38.     }
    39.    
    40.     ....
    41.       Обработка запроса
    42.     ....
    43.  
    44.     pIrp->IoStatus.Status      = STATUS_SUCCESS;    
    45.     pIrp->IoStatus.Information = sizeof( MOUSE_INPUT_DATA );  
    46.     IoStartNextPacket( pDeviceObject, FALSE );    
    47.     IoCompleteRequest( pIrp, IO_NO_INCREMENT );
    48.     return ;   
    49. }
    50.  
    51. // Процедура-напоминалка, она в другом потоке
    52. void delayRoutine (PVOID pContext)
    53. {
    54.     do {
    55.         KeWaitForSingleObject(&delayEvent, Executive, KernelMode, FALSE, NULL);
    56.        
    57.                 ....
    58.                 Задержка
    59.                 ....
    60.                 //Этот IoStartNextPacket ни к чему не приводит
    61.         IoStartNextPacket( pDeviceObject, FALSE );
    62.     } while (!devExt->Removed);
    63. }
    64.  


    Проблема в том что последний IoStartNextPacket не приводит к вызову StartIo. В чем я прокололся?
     
  2. wish3

    wish3 New Member

    Публикаций:
    0
    Регистрация:
    31 янв 2005
    Сообщения:
    29
    Адрес:
    Ukraine
    Я заменил в последней процедуре IoStartNextPacket на прямой вызов StartIo:

    pDeviceObject->DriverObject->DriverStartIo( pDeviceObject, devExt->PendingRequest );

    Предварительно сохраняя нужный IRP.

    Вобшем логика какаято в этом есть: если сам не соизволил обработать IRP, то сам и дорабатывай:)))

    <font color="red]Для драйвера мыши важно делать возможность отмены IRP?</font><!--color-->

    Что скажете верно я сделал?