Chris Cant - Writing Windows WDM Device Drivers

Здесь есть возможность читать онлайн «Chris Cant - Writing Windows WDM Device Drivers» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: Lawrence, Kansas 66046, ISBN: , Издательство: R & D Books, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Writing Windows WDM Device Drivers: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Writing Windows WDM Device Drivers»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Writing Windows WDM Device Drivers — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Writing Windows WDM Device Drivers», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Thread and process contexts are not normally a problem for most device drivers. When you process a normal user request, the IRP has all the information you need. The fact that you may be running in an arbitrary thread context does not effect the job you have to do. The Zw… file access functions are one case when the process context is significant. If you use "neither" Buffered I/O nor Direct I/O or use METHOD_NEITHER IOCTLs, the thread context is also important.

System Threads

The solution to both these problems is to use a system thread. A driver can create a system thread (or threads) that runs in kernel mode. This thread runs at PASSIVE_LEVEL IRQL. If the DebugPrint system thread makes all the Zw… calls, the "same process" problem is fixed. A doubly-linked list is used to store the events for processing by the system thread. Inserting events into this list can be done safely at IRQL levels up to and including DISPATCH_LEVEL This means that most types of driver code can generate DebugPrint trace output.

The DebugPrintInit routine calls PsCreateSystemThread (at PASSIVE_LEVEL IRQL) to create its system thread as shown in the partial code in Listing 14.1. PsCreateSystemThread is passed the name of the function to run and a context to pass to it. The DebugPrint system thread function is defined as follows.

void DebugPrintSystemThread(IN PVOID Context)

DebugPrintInit passes just a NULL context to the thread function. Some drivers may wish to create one thread per device, and so will usually pass a pointer to the device extension as the context. A DebugPrint test driver has just one system thread for all its devices.

The DebugPrint system thread does not need a high priority. Therefore, DebugPrintSystemThread calls KeSetPriorityThread straightaway to set its priority to the lowest real-time priority. It uses KeGetCurrentThread to get a pointer to its own thread object.

If PsCreateSystemThread succeeds, it returns a handle to the thread. Later, I shall show that a driver can wait for certain objects to be set. It can wait for the completion of a system thread if it has a pointer to the system thread object, not a handle. Use ObReferenceObjectByHandle to retrieve the thread object pointer. If this succeeds, call ZwClose to close the thread handle. Technically speaking, the call to ZwClose reduces the reference count to the thread handle. When the thread completes, its handle reference count will be decremented to zero.

A system thread must terminate itself using PsTerminateSystemThread . I am not sure what happens if a system thread function simply returns without calling PsTerminateSystemThread . The main driver code cannot force a system thread to terminate. For this reason, a global Boolean variable called ExitNow is used. This is set true when the driver wants the system thread to exit.

DebugPrintClose waits for the ThreadExiting event to be set into the signalled state by the thread as it exits. This ensures that the thread has completed by the time DebugPrintClose exits. DebugPrintClose is commonly called from a driver unload routine. All driver code must have stopped running when the unload routine exits, as the driver address space may soon be deleted. Make sure that any other call-backs are disabled, e.g., interrupt handlers, Deferred Procedure Calls, and timers.

Listing 14.1 DebugPrint test driver thread and event handling

KEVENT ThreadEvent;

KEVENT ThreadExiting;

PVOID ThreadObjectPointer=NULL;

void DebugPrintInit(char* _DriverName) {

// …

ExitNow = false;

KeInitializeEvent(&ThreadEvent, SynchronizationEvent, FALSE);

KeInitia1izeEvent(&ThreadExiting, SynchronizationEvent, FALSE);

HANDLE threadHandle;

status = PsCreateSystemThread(&threadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, DebugPrintSystemThread, NULL);

if (!NT_SUCCESS(status)) return;

status = ObReferenceObjectByHandle(threadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, &ThreadObjectPointer, NULL);

if (NT_SUCCESS(status)) ZwClose(threadHandle);

// …

}

void DebugPrintClose() {

// …

ExitNow = true;

KeSetEvent(&ThreadEvent, 0, FALSE);

KeWaitForSingleObject(&ThreadExiting, Executive, KernelMode, FALSE, NULL);

// …

}

void DebugPrintSystemThread(IN PVOID Context) {

// Lower thread priority

KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);

// Make One second relative timeout

LARGE_INTEGER OneSecondTimeout;

OneSecondTimeout.QuadPart = –1i64 * 1000000i64 * 10i64;

// Loop waiting for events or ExitNow

while (true) {

KeWaitForSingleObject(&ThreadEvent, Executive, KernelMode, FALSE, &0neSecondTimeout);

// Process events

// …

if (ExitNow) break;

}

// Tidy up

if (ThreadObjectPointer!=NULL) {

ObDereferenceObject(&ThreadObjectPointer);

ThreadObjectPointer = NULL;

}

DebugPrintStarted = FALSE;

ClearEvents();

KeSetEvent(&ThreadExiting, 0, FALSE);

PsTerminateSystemThread(STATUS_SUCCESS);

}

System Worker Threads

An alternative technique is available if you want to perform occasional short tasks at PASSIVE_LEVEL IRQL. However, this system worker thread method was not suitable for the DebugPrint software because the thread context may change between calls.

To use the system worker thread method, first allocate a WORK_QUEUE_ITEM structure from nonpaged memory. Call ExInitializeWorkItem passing this pointer, a callback routine, and a context for it. When you want your function to be run, call ExQueueWorkItem . In due course, your callback routine is called at PASSIVE_LEVEL in the context of a system thread. Do not forget to free the WORK_QUEUE_ITEM structure memory when finished with it. System worker threads have a lower priority than system threads running at the lowest real time priority, but higher than most user mode threads.

The WdmIo and PHDIo drivers, described in Chapters 15-18, show how to use a system worker thread.

In W2000, it is recommended that you use the IoAllocateWorkItem, IoQueueWorkItem, IoFreeWorkItem functions instead.

Events

The main DebugPrint test driver code sets the ExitNow Boolean to true when it wants its system thread to terminate. However, it is not a good idea for the system thread to spin continuously waiting for this value to become true.

Instead, a kernel event called ThreadEvent signals when to check ExitNow. A KEVENT must be defined for the event in nonpaged memory. Kernel events are very similar to their user mode Win32 cousins.

Listing 14.1 shows how ThreadEvent is initialized using KeInitializeEvent , at PASSIVE_LEVEL IRQL. Two types of events are supported, SynchronizationEvent and NotificationEvent. The last parameter sets the initial state of the event, which is nonsignalled in this case.

When set, a Synchronization event only releases one waiting thread before reverting to the nonsignalled state. A Notification event stays signalled until explicitly reset.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Writing Windows WDM Device Drivers»

Представляем Вашему вниманию похожие книги на «Writing Windows WDM Device Drivers» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Writing Windows WDM Device Drivers»

Обсуждение, отзывы о книге «Writing Windows WDM Device Drivers» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x