Организация ввода-вывода. Драйверы WDM. Рощин А.В. - 60 стр.

UptoLike

Составители: 

60
}
После этого пишутся две простые функции для постановки IRP в очередь
VOID NativeStartPacket(PDEVICE_EXTENSION pdx, PIRP Irp)
{
if (pdx->DeviceBusy)
InsertTailList(&pdx->IrpQueue,&Irp->Tail.Overlay.ListEntry);
else
{
pdx->DeviceBusy = TRUE;
StartIo(pdx->DeviceObject, Irp);
}
}
и извлечения его из очереди
VOID NativeStartNextPacket(PDEVICE_EXTENSION pdx, PIRP Irp)
{
if (IsListEmpty(&pdx->IrpQueue))
pdx->DeviceBusy = FALSE;
else
{
PLIST_ENTRY foo = RemoveHeadList(&pdx->IrpQueue);
PIRP Irp = CONTAINING_RECORD(foo,IRP, Tail.Overlay.ListEntry);
StartIo(pdx->DeviceObject, Irp);
}
}
В коде извлечения IRP из очереди используется оригинальный макрос,
определенный в ntdef.h:
#define CONTAINING_RECORD(address, type, field) \
((type *)((PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))
Этот макрос восстанавливает по известному адресу поля структуры адрес
самой структуры.
Рассмотренный метод неудобен тем, что дополнительно необходим
механизм приостановки очереди на время некоторых состояний PnP и управления
питанием [3]. При этом пакеты запроса ввода-вывода накапливаются в
          }
         После этого пишутся две простые функции для постановки IRP в очередь
VOID NativeStartPacket(PDEVICE_EXTENSION pdx, PIRP Irp)
 {
 if (pdx->DeviceBusy)
     InsertTailList(&pdx->IrpQueue,&Irp->Tail.Overlay.ListEntry);
 else
     {
     pdx->DeviceBusy = TRUE;
     StartIo(pdx->DeviceObject, Irp);
     }
 }
и извлечения его из очереди
VOID NativeStartNextPacket(PDEVICE_EXTENSION pdx, PIRP Irp)
{
if (IsListEmpty(&pdx->IrpQueue))
    pdx->DeviceBusy = FALSE;
else
 {
 PLIST_ENTRY foo = RemoveHeadList(&pdx->IrpQueue);
 PIRP Irp = CONTAINING_RECORD(foo,IRP, Tail.Overlay.ListEntry);
 StartIo(pdx->DeviceObject, Irp);
 }
}
         В коде извлечения IRP из очереди используется оригинальный макрос,
определенный в ntdef.h:
#define CONTAINING_RECORD(address, type, field) \
          ((type *)((PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))
         Этот макрос восстанавливает по известному адресу поля структуры адрес
самой структуры.
         Рассмотренный метод неудобен тем, что дополнительно необходим
механизм приостановки очереди на время некоторых состояний PnP и управления
питанием [3]. При этом пакеты запроса ввода-вывода накапливаются в


                                        60