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
- Автор:
- Издательство:R & D Books
- Жанр:
- Год:неизвестен
- Город:Lawrence, Kansas 66046
- ISBN:0-87930-565-7
- Рейтинг книги:5 / 5. Голосов: 1
-
Избранное:Добавить в избранное
- Отзывы:
-
Ваша оценка:
- 100
- 1
- 2
- 3
- 4
- 5
Writing Windows WDM Device Drivers: краткое содержание, описание и аннотация
Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Writing Windows WDM Device Drivers»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.
Writing Windows WDM Device Drivers — читать онлайн бесплатно полную книгу (весь текст) целиком
Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Writing Windows WDM Device Drivers», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
Before I start in earnest, note that the WdmIo driver is a standard WDM driver in a device stack. It is layered over the Unknown bus driver. It does not use the Unknown driver to access hardware. Instead, it talks to hardware directly.
The StartDevice, RetrieveResources , and StopDevice routines in DeviceIo.cpp have been altered slightly from their originals in Wdm2. They insist that one port or memory resource be allocated. If necessary a memory-mapped set of registers is mapped into memory, and unmapped when the device is stopped. Similarly, if WdmIo has connected to an interrupt, StopDevice disconnects and StartDevice connects again.
The WriteByte and ReadByte routines are shown in Listing 16.1. They both fail silently if the register offset is out of range. The DebugPrint trace calls should not be used in these routines, as they may be called at device IRQL (DIRQL) (i.e., above the maximum IRQL suitable for DebugPrint calls, DISPATCH_LEVEL).
If you need to delay for a short period, use the KeStallExecutionProcessor routine, specifying the stall period in microseconds. The DDK recommends that you keep the delay as short as possible, and definitely no more than 50µs. Longer delays usually mean writing code in a very different way. For example, you could use custom timers, as described in the next chapter. Alternatively, a system thread could use the KeDelayExecutionThread function for longer delays.
Listing 16.1 WriteByte and ReadByte
void WriteByte(IN PWDMIO_DEVICE_EXTENSION dx, IN ULONG offset, IN UCHAR byte) {
if (offset>=dx->PortLength) return;
PUCHAR Port = dx->PortBase+offset;
if (dx->PortInIOSpace) WRITE_PORT_UCHAR(Port, byte);
else WRITE_REGISTER_UCHAR(Port, byte);
}
UCHAR ReadByte(IN PWDMIO_DEVICE_EXTENSION dx, IN ULONG offset) {
if (offset>=dx->PortLength) return 0;
PUCHAR Port = dx->PortBase+offset;
UCHAR b;
if (dx->PortInIOSpace) b = READ_PORT_UCHAR(Port);
else b = READ_REGISTER_UCHAR(Port);
return b;
}
Finally, note that the WdmIo driver read and write dispatch routines and the IOCTLs all use Buffered I/O.
IRP Queuing
The DebugPrint in Chapter 14 used doubly-linked lists as a means of storing blocks of memory for later processing. The WdmIo driver uses the built-in IRP device queue to serialize the processing of its main IRPs. A device queue is a doubly-linked list with special features that tailor it for IRP processing. One of its special features is that it has a built-in spin lock. Thus, a driver does not need to provide its own spin lock to guard access to the queue, as DebugPrint had to do for its doubly-linked lists.
The WdmIo Functional Device Object (FDO) contains a device queue field that stores the queue's linked list head. Each IRP also contains a linked list entry that is used to store the pointers to its linked IRPs. For the moment, the names of these fields do not matter, as most ordinary queue actions are handled internally by the I/O Manager. However, to cleanup the device queue, these entries must be manipulated directly. The I/O Manager also initializes the device queue.
Inserting IRPs into the device queue is actually fairly straightforward. This except from the Read IRP dispatch handler in Dispatch.cpp shows the necessary steps. First, the IRP must be marked as pending using IoMarkIrpPending . Then, IoStartPacket is called to insert the IRP into the queue. If there are no queued IRPs, the IRP is sent for processing in the StartIo routine straightaway. Finally, the Read IRP returns STATUS_PENDING to confirm that the IRP is indeed pending.
IoMarkIrpPending(Irp);
IoStartPacket(fdo, Irp, 0, WdmIoCancelIrp);
return STATUS_PENDING;
The call to IoStartPacket passes a pointer to the cancel routine. I shall show later how this works. The third parameter to IoStartPacket is a key that can be used to sort the IRPs in the device queue. This feature is not used by WdmIo, so the key is always zero.
The WdmIo driver still uses the Plug and Play device locking technique to ensure that IRP processing is not interrupted by Plug and Play stop device requests. Note that the UnlockDevice routine is not called when an IRP is queued. This is deliberate, as the IRP has not been completed. I ensure that UnlockDevice is called on all paths that will later complete the IRP.
The main Read, Write, and IOCTL dispatch routines in WdmIo perform device locking and parameter checking. All valid IRPs of these types are put in the device queue for processing later serially in the WdmIo StartIo routine.
The WdmIoStartIo routine shown in Listing 16.2 processes IRPs for each WdmIo device one by one [37] If there is more than one WdmIo device, each device has a device queue that can be processed simultaneously by WdmIoStartIo.
. All queued IRPs, whatever their major function code, come through this same routine. Therefore, StartIo routines usually have a big switch statement at their heart. Listing 16.2 shows the complete code for IOCTL IRPs with major function code IRP_MJ_DEVICE_CONTROL However, the code for Read and Write IRPs is not shown for now. This is explained in the next chapter.
When an IRP is passed to the StartIo routine, it has just been removed from the device queue. The I/O Manager has also put the IRP pointer in the FDO CurrentIrp field. This is particularly useful for interrupt handlers as will be seen in the chapter, but is also used by IRP cancel and cleanup routines. The IRP Cancel field is set to TRUE when the IRP is cancelled. The IRP Cancel field may even be set before StartIo is called. Both WdmIoStartIo and the interrupt handling routines check the Cancel field at various points, as shown later.
StartIo routines are always called at DISPATCH_LEVEL IRQL. This means that all the code and the variables it accesses must be in nonpaged memory. It restricts the set of kernel calls that can be made. However, calls to the DebugPrint trace output routines can be made safely. WdmIoStartIo processes IRPs in two different ways. All the IOCTL IRPs are handled straightaway; the IRP is processed in the relevant way and is completed at the end of WdmIoStartIo . However, Read and Write IRPs use interrupt driven I/O to transfer one byte at a time. These IRPs are usually completed later, as described in the next chapter. In this case, WdmIoStartIo simply returns; the current IRP is still pending and is still being processed.
WdmIoStartIo is only called to process another IRP in the device queue when IoStartNextPacket is called (or IoStartNextPacketByKey ). For IRPs that are processed entirely by WdmIoStartIo, IoStartNextPacket is called after the IRP is completed [38] Note that the IoStartNextPacket implementation will, in fact, call WdmIoStartIo recursively (if there is another IRP in the queue). In the worst case, this recursive technique could overflow the kernel stack. One of the DDK examples shows a way of avoiding this problem by not queuing an IRP if the queue is "full".
. The TRUE second parameter to IoStartNextPacket indicates that cancel routines are being used.
WdmIoStartIo begins by zeroing the CmdOutputCount field in the device extension. This field stores the count of bytes transferred during immediate IRP processing. CmdOutputCount is passed to CompleteIrp at the end of WdmIoStartIo .
Читать дальшеИнтервал:
Закладка:
Похожие книги на «Writing Windows WDM Device Drivers»
Представляем Вашему вниманию похожие книги на «Writing Windows WDM Device Drivers» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.
Обсуждение, отзывы о книге «Writing Windows WDM Device Drivers» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.