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», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

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

Интервал:

Закладка:

Сделать

There are kernel functions for singly-linked lists, which are really stacks. Declare a list head as a variable of type SINGLE_LIST_ENTRY. Initialize it by setting its Next field to NULL. PushEntryList puts an entry onto the front of the list, while PopEntryList removes an entry from the front of the list. You must use the same technique as before to get the correct pointer from a popped entry: include a SINGLE_LIST_ENTRY field in the structure you put on the list and use CONTAINING_RECORD.

There are also interlocked versions of these routines, using a spin lock as before to ensure accesses are carried out safely.

Device Queues

A device queue is an enhanced form of a doubly-linked list, usually used for storing IRPs. These are covered in glorious detail in Chapter 16.

Final Pieces

Let's draw together the final pieces of the DebugPrint code for test drivers.

DebugPrintInit makes a copy of the driver name passed to it. Why does it bother to do this? Well, initially it did not. However, the call to DebugPrintInit usually comes from a DriverEntry routine. DriverEntry code is often marked as being discardable once the driver has been initialized. This meant that the code with the driver name string might be discarded. I found that this did indeed happen and so the original pointer referred to invalid memory. Watch out for this problem in your drivers.

Listing 14.4 shows how the system thread opens a connection to the DebugPrint driver using ZwCreateFile . It opens a connection to a DebugPrint driver device called \Device\PHDDebugPrint. The DebugPrint driver also uses a driver interface so that user mode programs, such as DebugPrint Monitor, can find this device.

While drivers can use Plug and Play Notification to find other drivers that support a device interface, this is a complicated approach. Instead, the one and only DebugPrint device is given a kernel name of PHDDebugPrint. Calls to ZwCreateFile do not use Win32 symbolic link names for devices. Instead, as in this example, they must use the full kernel device name.

The filename must be specified as a UNICODE_STRING. RtlInitUnicodeString is used to initialize the DebugPrintName variable. The filename is set into an OBJECT_ATTRIBUTES structure using InitializeObjectAttributes . A pointer to this structure is finally passed to ZwCreateFile . Like its Win32 equivalent, you must specify access and share parameters to ZwCreateFile . There are a host of other options, so consult the documentation for full details. Finally, you get a file HANDLE to use in further I/O requests.

As mentioned earlier, subsequent calls to ZwReadFile, ZwWriteFile, ZwQueryInformationFile , and ZwClose must take place in the same thread context as the call to ZwCreateFile . All these file I/O routines must be called at PASSIVE_LEVEL.

A typical call to ZwWriteFile is illustrated in Listing 14.3. As well as the file handle, simply specify the data pointer and a transfer count. The completion details can be found in an IO_STATUS_BLOCK structure. Specify a file pointer byte offset.

The DebugPrint test driver code eventually closes the file handle using ZwClose just before it terminates.

The system thread code tried to open its connection to the DebugPrint driver for 5 minutes. This ensures that the DebugPrint driver has started during system startup.

Listing 14.4 DebugPrint test driver system thread file opening

// Make appropriate ObjectAttributes for ZwCreateFile

UNICODE_STRING DebugPrintName;

RtlInitUnicodeString(&DebugPrintName, _"\\Device\\PHDDebugPrint");

OBJECT_ATTRIBUTES ObjectAttributes;

InitializeObjectAttributes(&ObjectAttributes, &DebugPrintName, OBJ_CASE_INSENSITIVE, NULL, NULL);

// Open handle to DebugPrint device

IO_STATUS_BLOCK IoStatus;

HANDLE DebugPrintDeviceHandle = NULL;

NTSTATUS status = ZwCreateFile(&DebugPrintDeviceHandle,

GENERIC_READ | GENERIC_WRITE,

&ObjectAttributes, &IoStatus,

0, // alloc size = none

FILE_ATTRIBUTE_NORMAL,

FILE_SHARE_READ|FILE_SHARE_WRITE,

FILE_OPEN,

0,

NULL, // eabuffer

0); // ealength

if (!NT_SUCCESS(status) || DebugPrintDeviceHandle==NULL) goto exit1;

DebugPrint Driver

Referring to Figure 14.1, you can see that the job of the DebugPrint driver is to store trace events from all the drivers under test and make them available to the DebugPrint Monitor user mode application. As the figure illustrates, the test drivers only write to the DebugPrint driver, while the Monitor only reads.

This section will not look at all the DebugPrint driver code. The Plug and Play and Initialization code is largely the same as earlier WDM drivers. You should install just one DebugPrint device in the Other Devices category.

The interesting code is in the dispatch routines in Dispatch.cpp, along with a main header file DebugPrint.h. These files and the other source files can be found on the book's software disk.

Design

The DebugPrint driver uses a similar technique of storing all written trace events in a doubly-linked list called EventList. When the DebugPrint Monitor program starts, it reads all the available events. It then leaves one read request outstanding. When a new trace event is written by a test driver, the Monitor read request is satisfied straightaway. This design ensures that trace events get to the Monitor application as soon as possible.

This means that the DebugPrint driver has to be able to queue up incoming read requests. In fact, it only allows one read request to be queued. Any further read requests are rejected. As DebugPrint has an IRP queue, it must be prepared to cancel IRPs. The DbpCancelIrp routine described later does this job.

The DbpCreate and DbpClose routines simply complete their IRPs successfully. Note that these IRPs are issued from both test drivers and the Monitor application.

The DebugPrint driver uses Buffered I/O.

DebugPrint Devices

As mentioned previously, the DebugPrint driver uses both a device interface and a Windows 2000 device name. The DebugPrint Monitor application identifies a DebugPrint device using the device interface. The test drivers identify the DebugPrint device using the kernel name.

Listing 14.5 shows how a named Functional Device Object is created in DbpAddDevice in Pnp.cpp. The DebugPrintName variable is a UNICODE_STRING that is initialized with the desired kernel device name, \Device\PHDDebugPrint. This is passed to the IoCreateDevice call.

Later in DbpAddDevice , the DebugPrint device interface is registered in the same way as before. The device interface GUID is defined in DbgPrtGUID.h as {ED6026A2-6813-11d2-AE43-00C0DFE4C1F3}. This header file is also included by the DebugPrint Monitor project.

Listing 14.5 DebugPrint driver device creation

UNICODE_STRING DebugPrintName;

RtlInitUnicodeString(&DebugPrintName, L"\\Device\\PHDDebugPrint");

// Create our Functional Device Object in fdo

status = IoCreateDevice(DriverObject,

sizeof(DEBUGPRINT_DEVICE_EXTENSION),

&DebugPrintName,

FILE_DEVICE_UNKNOWN,

0,

FALSE, // Not exclusive

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

Интервал:

Закладка:

Сделать

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

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


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

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

x