ръководни функции опашка ниско - studopediya

За чакане с помощта на функции от ниско ниво, като се използва стандартната LIST_ENTRY структура.

typedef структура _LIST_ENTRY

Struct _LIST_ENTRY * летливи Flink; // указател към следващия елемент в списъка

Struct _LIST_ENTRY * летливи мигане; // указател към предишния елемент от списъка

Оказва се, както се вижда от определението за структурата, двупосочно.

Структурата обикновено се създаде DeviceExtension LIST_ENTRY структура Например което представлява главата опашка, която след това се инициализира използване функция InitializeListHead (). След това можете да добавяте или изтривате записи на опашката. За тази функция цел InsertHeadList (), InsertTailList (), RemoveHeadList (), RemoveTailList (), RemoveEntryList ().

IRP се добавя към опашката на функцията за контрол на стая, най-вероятно работи при IRQL = PASSIVE_LEVEL. В този случай, да бъдат отстранени от опашката, те могат да функционират, упражнения на всяко ниво на IRQL и функциите, избора на МКК от опашката, може да изместват функция МКК е поставен в режим на изчакване. Има проблем със синхронизацията. Ако не е решен, недовършена работа пространство МКК на опашката може да бъде отменена операция МКК за вземане на проби от опашката, която ще доведе до син екран.

Синхронизиране на достъп до споделения ресурс се извършва чрез завъртане заключване (механизми за синхронизиране ще бъдат обсъдени в следващата глава). Тъй като действието на добавяне и изтриване на записи в нивата на опашката IRQL PASSIVE_LEVEL и DISPATCH_LEVEL много често, за тяхното безопасно поведение при условие за специални функции: ExInterlocked ... Списък (). трябва да бъдат създадени и инициализират заключване спин За да използвате тези функции. Той обикновено се създава в едно и също място и завъртете главата (обикновено DeviceExtension) и инициализира след инициализация обръщат глави. Например:

typedef структура _DEVICE_EXTENSION

// В функция DriverEntry

// след това можете да добавяте и изтривате записи

PLIST_ENTRY pOldHead = ExInterlockedInsertHeadList (

Както може да се види от структурата на определение LIST_ENTRY, то съдържа полета за съхранение на действителните данни (например, указател към МКК на пакета). Ето защо, често срещаният начин за използване LIST_ENTRY структура - включването му в случая на по-обща структура.

За организирането на МКК пакети опашка, всеки в областта на МКК Tail.Overlay.ListEntry съдържа LIST_ENTRY инстанция на структурата. Това повдига въпроса за това как, знаейки LIST_ENTRY указател към структура, за да се получи указател към структурата на МКК, която включва LIST_ENTRY. За тази DDK предвижда специална макро CONTAINING_RECORD

#define CONTAINING_RECORD (адрес. тип. поле) \

((Тип *) ((PCHAR) (адрес) - (ULONG_PTR) (((тип *) 0) -> поле)))

По отношение на МКК, ние ще трябва да напиша нещо подобно

pIrp = CONTAINING_RECORD (pListEntry, IRP, Tail.Overlay.ListEntry);

// допълнително - обработка IRP

Организация IRP пакет опашка е показано на фигурата.

[10.2.2.2.2] високо ниво функции за управление на опашката - "Queue Devices" (опашка Устройство)

Опашката шофьора създава допълнителни устройства чрез разпределяне на памет от не-пейджъра памет под допълнителен опашка обекти KDEVICE_QUEUE устройства и инициализира тези обекти чрез KeInitializeDeviceQueue () функция. Добавянето МКК пакети в опашките се извършва от функцията KeInsertDeviceQueue () или KeInsertByKeyDeviceQueue (), и пакетите от проба от опашката - KeRemoveDeviceQueue (), KeRemoveByKeyDeviceQueue () или KeRemoveEntryDeviceQueue ().

За организирането на МКК пакет опашка използва тип KDEVICE_QUEUE_ENTRY структура, указател към която се съдържа в МКК в поле Tail.Overlay.DeviceQueueEntry.