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», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
• the current system time in GMT,
• the driver name (specified in DebugPrintInit), and
• the message.
DebugPrintMsg first gets the current system time in GMT using KeQuerySystemTime . It converts the number of 100-nanosecond intervals since January 1, 1601 into a more recognizable TIME_FIELDS structure using RtlTimeToTimeFields . The ExSystemTimeToLocalTime function (which converts from GMT to local time) is only available in W2000, so it is not used here. The time is converted to the local timezone in the DebugPrint Monitor application.
It would reduce the event structure size if the LARGE_INTEGER output from KeQuerySystemTime were stored directly. However, there is no equivalent of the RtlTimeToTimeFields routine in Win32, so the event structure holds the time as time fields.
DebugPrintMsg now works out the size of the event data (i.e., the three previous data items, including the strings' terminating NULLs). It then determines the size of the DEBUGPRINT_EVENT structure that envelops the event data. It allocates some nonpaged memory for this structure and fills it in. It then uses ExInterlockedInsertTailList to insert the DEBUGPRINT_EVENT structure at the end of EventList.
Listing 14.2 DebugPrint test driver DebugPrintMsg function
void DebugPrintMsg(char* Msg) {
if (!DebugPrintStarted) return;
// Get current time
LARGE_INTEGER Now, NowLocal;
KeQuerySystemTime(&Now);
TIME_FIELDS NowTF;
RtlTimeToTimeFields(&Now, &NowTF);
// Get size of Msg and complete event
USHORT MsgLen = ANSIstrlen(Msg)+1;
ULONG EventDataLen = sizeof(TIME_FIELDS) + DriverNameLen + MsgLen;
ULONG len = sizeof(LIST_ENTRY)+sizeof(ULONG)+EventDataLen;
// Allocate event buffer
PDEBUGPRINT_EVENT pEvent = (PDEBUGPRINT_EVENT)ExAllocatePool(NonPagedPool.len);
if (pEvent!=NULL) {
PUCHAR buffer = (PUCHAR)pEvent->EventData;
// Copy event info to buffer
RtlCopyMemory(buffer, &NowTF, sizeof(TIME_FIELDS));
buffer += sizeof(TIME_FIELDS);
RtlCopyMemory( buffer, DriverName, DriverNameLen);
buffer += DriverNameLen;
RtlCopyMemory(buffer, Msg, MsgLen);
// Insert event into event list for processing by system thread
pEvent->len = EventDataLen;
ExInterlockedInsertTailList(&EventList, &pEvent->ListEntry, &EventListLock);
}
}
Doubly-Linked Lists
A doubly-linked list is a slightly complicated beast to use safely. First, you need to declare a LIST_ENTRY structure in nonpaged memory for the list head. Drivers that need one list per device declare the list head in the device extension. However, the DebugPrint test driver code declares just its EventList variable as a global, as it is available to all devices.
LIST_ENTRY EventList;
Next, define a structure that you want to put in your doubly-linked list. Include a LIST_ ENTRY field in this structure to provide the links in both directions of the list. The DebugPrint structure is called DEBUGPRINT_EVENT. EventData is a variable length field, as it is not always 1-byte long. The Len field gives its length.
typedef struct _DEBUGPRINT_EVENT {
LIST_ENTRY ListEntry;
ULONG Len;
UCHAR EventData[1];
} DEBUGPRINT_EVENT, *PDEBUGPRINT_EVENT;
Initialize a doubly-linked list using InitializeListHead , passing a pointer to the list head variable. You can now insert DEBUGPRINT_EVENT structures at the head or tail of the list using the InsertHeadList and InsertTailList routines. The corresponding RemoveHeadList and RemoveTailList routines remove entries from the list [33] The NT 4 DDK wrongly states that RemoveHeadList and RemoveTailList return NULL if the list is empty.
. Find out if the list is empty first using IsListEmpty .
All well and good. However, it is important that attempts to access the list are carried out safely so that the links are not corrupted in a multiprocessor environment. The kernel provides interlocked versions of the add and remove routines that use a spin lock to guard access to the link structure. The DebugPrint test driver code uses a spin lock called EventListLock and initializes it as normal.
KeInitializeSpinLock(&EventListLock);
InitializeListHead(&EventList);
Listing 14.2 shows how to use one of the interlocked linked list routines, ExInterlockedInsertTailList. It is passed pointers to the list head, the LIST_ENTRY field in your structure, and the spin lock.
Listing 14.3 shows an extract from the DebugPrint test driver system thread function. This is the code that is run every second to see if any events have been produced by calls to DebugPrintMsg.
Listing 14.3 DebugPrint test driver system thread event processing
// Loop until all available events have been removed
while(true) {
PLIST_ENTRY pListEntry = ExInterlockedRemoveHeadList(&EventList, &EventListLock);
if (pListEntry==NULL) break;
// Get event as DEBUGPRINT_EVENT
PDEBUGPRINT_EVENT pEvent = CONTAINING_RECORD(pListEntry, DEBUGPRINT_EVENT, ListEntry);
// Get length of event data
ULONG EventDataLen = pEvent->Len;
// Send event to DebugPrint
NTSTATUS status = ZwWriteFile(DebugPrintDeviceHandle, NULL, NULL, NULL,
&IoStatus, pEvent->EventData, EventDataLen, &ByteOffset, NULL);
// Ignore error returns
// Free our event buffer
ExFreePool(pEvent);
}
The code loops until all the events in EventList have been removed and sent to the DebugPrint driver. It removes the first entry from the doubly-linked list using ExInterlockedRemoveHeadList , passing pointers to the list head and the guarding spin lock. The return value is NULL if there is nothing left in the list.
ExInterlockedRemoveHeadList returns a pointer to the ListEntry field in the DEBUGPRINT_ EVENT structure. What is really needed is not this, but a pointer to the DEBUGPRINT_EVENT structure itself. For this particular structure, a simple cast would suffice. However, there is a way to deal correctly with the general case in which the LIST_ENTRY variable is not at the beginning of the structure. The system header files provide the appropriate macro, CONTAINING_RECORD. Pass the LIST_ENTRY pointer, the data type of your structure and the name of its LIST_ENTRY field. The returned value is the pointer to the DEBUGPRINT_EVENT structure.
Having got the correct event pointer in pEvent, the system thread extracts the length of the event data and writes the event data itself to the DebugPrint driver using ZwWriteFile . Finally, it frees the memory that was allocated for the DEBUGPRINT_EVENT structure, before checking to see if any more events are available.
The ClearEvents routine is called to clear any remaining events when the system thread finishes or DebugPrintClose is called. ClearEvents removes any events using ExInterlockedRemoveHeadList and frees the event memory.
Singly-Linked Lists
Читать дальшеИнтервал:
Закладка:
Похожие книги на «Writing Windows WDM Device Drivers»
Представляем Вашему вниманию похожие книги на «Writing Windows WDM Device Drivers» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.
Обсуждение, отзывы о книге «Writing Windows WDM Device Drivers» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.