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», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
DebugPrintMsg("WdmIoCancelIrp: IRP just dequeued for StartIo");
// IRP has just been dequeued but StartIo has not had a chance
// to remove this cancel routine yet. Irp->Cancel flag already set.
IoReleaseCancelSpinLock(Irp->CancelIrql);
// Cancel IRP and start next one
CompleteIrp(Irp, STATUS_CANCELLED);
IoStartNextPacket(fdo, TRUE);
} else
…
The start of the StartIo routine must also be changed. The main job is to remove the cancel routine using IoSetCancelRoutine . However, there is a small chance that the IRP has already been cancelled. The code in Listing 16.6 checks the IRP Cancel field first. If it has been cancelled, StartIo simply exits.
In my mind, this technique has a potential race condition. When the Cancel routine completes, the IRP memory may disappear straightaway. However, the StartIo routine may be just about to run on another processor. Accessing the IRP Cancel field might, therefore, cause an access violation (or refer to the next IRP to use this IRP structure). Moving the CompleteIrp and IoStartNextPacket calls into the StartIo routine (if Irp->Cancel is set) would solve this problem, but it would mean that the cancel routine does not complete the IRP.
Listing 16.6 Alternative StartIo initial processing
// Check whether cancelled already KIRQL OldIrql;
IoAcquireCancelSpinLock(&OldIrql);
if (Irp->Cancel) {
IoReleaseCancelSpinLock(OldIrql);
// IoStartNextPacket called by cancel routine
return;
}
// Remove cancel routine
IoSetCancelRoutine(Irp, NULL);
IoReleaseCancelSpinLock(OldIrql);
Cleanup IRP Handling
The Cleanup IRP is issued to cancel any IRPs that are outstanding when a file handle is closed. Even if the IRPs have cancel routines, they are not called.
To handle it correctly, the driver ought to cancel only IRPs that belong to the correct file handle. Only queued IRPs whose FileObject field matches the Cleanup IRP's stack FileObject field should be cancelled.
The WdmIo Cleanup IRP handler, WdmIoDispatchCleanup , shown in Listing 16.7, does not perform this FileObject check. This makes the code simpler.
WdmIoDispatchCleanup must hold the Cancel spin lock wherever it accesses the device queue. However, you must not be holding the Cancel spin lock when an IRP is completed.
The code keeps extracting IRPs using KeRemoveDeviceQueue until the device queue is empty. A pointer to the IRP is found using the usual CONTAINING_RECORD machinations. The IRP is marked for cancelling and its cancel routine is removed. The Cancel spin lock is released before UnlockDevice is called and the IRP is completed with status STATUS_CANCELLED.
The Cleanup IRP handler then goes on to try to cancel the IRP currently being processed by WdmIoStartIo or its follow-on code. CancelCurrentIrpSynch is called as a Critical Section routine. This returns TRUE if a transfer is in progress (i.e., if the device extension Timeout field is greater than or equal to zero). If a transfer is in progress, WdmIoDpcForIsr is called to complete the IRP with status STATUS_CANCELLED. The Timeout field and WdmIoDpcForIsr are described in the next chapter.
To handle the FileObject check correctly, you must still remove each IRP from the queue in turn. If the IRP's FileObject does not match the Cleanup FileObject, the IRP must be put in a temporary holding queue. At the end, all these IRPs must be reinserted in the main device queue.
Listing 16.7 WdmIo Cleanup IRP handling
NTSTATUS WdmIoDispatchCleanup(IN PDEVICE_OBJECT fdo, IN PIRP Irp) {
PWDMIO_DEVICE_EXTENSION dx = (PWDMIO_DEVICE_EXTENSION)fdo->DeviceExtension;
DebugPrintMsg("WdmIoDispatchCleanup");
KIRQL OldIrql;
IoAcquireCancelSpinLock(&OldIrql);
// Cancel all IRPs in the I/O Manager maintained queue in device object
PKDEVICE_QUEUE_ENTRY QueueEntry;
while((QueueEntry=KeRemoveDeviceQueue(&fdo->DeviceQueue)) != NULL) {
PIRP CancelIrp = CONTAINING_RECORD(QueueEntry, IRP, Tail.Overlay.DeviceQueueEntry);
CancelIrp->Cancel = TRUE;
CancelIrp->CancelIrql = OldIrql;
CancelIrp->CancelRoutine = NULL;
IoReleaseCancelSpinLock(OldIrql);
DebugPrint("WdmIoDispatchCleanup: Cancelling %I", CancelIrp);
UnlockDevice(dx);
CompleteIrp(CancelIrp, STATUS_CANCELLED);
IoAcquireCancelSpinLock(&OldIrql);
}
IoReleaseCancelSpinLock(OldIrql);
// Forceably cancel any in-progress IRP
if (dx->Timeout!=-1) {
if (KeSynchronizeExecution(dx->InterruptObject, (PKSYNCHRONIZE_ROUTINE)CancelCurrentIrpSynch, dx)) {
if (fdo->CurrentIrp!=NULL) {
DebugPrint("WdmIoDispatchCleanup: Cancelled in-progress IRP %I", fdo->CurrentIrp);
WdmIoDpcForIsr(NULL, fdo, fdo->CurrentIrp, dx);
}
}
}
return CompleteIrp(Irp, STATUS_SUCCESS);
}
static BOOLEAN CancelCurrentIrpSynch(IN PWDMIO_DEVICE_EXTENSION dx) {
if (dx->Timeout==-l) return FALSE;
dx->Timeout = –1;
dx->TxStatus = STATUS_CANCELLED;
return TRUE;
}
Testing, Cancelling, and Cleanup
I amended WdmIoTest so that I could test the WdmIo driver's IRP cancelling and Cleanup IRP handling.
The WdmIoCancel application is substantially the same as that of WdmIoTest and is contained in the book software WdmIo\Cancel directory. You will have to uncomment some of the code and recompile to undertake some of the tests. The PHDIoCancel application does similar tests for the PHDIo driver.
The tests are designed to be run with the printer switched off, so that Write IRPs do not complete straightaway. WdmIoCancel opens the WdmIo device for overlapped I/O, using the GetDeviceViaInterface01 function. It then issues two overlapped Write requests and does not wait for either of them to complete. It then exits straightaway. This behavior is designed to test the IRP cancelling.
Figure 16.2 shows the DebugPrint output that demonstrates that IRP cancelling works correctly. At points (1) in the diagram, one of the IOCTL IRPs has been issued. They are passed to WdmIoStartIo , which processes them immediately. At point (2), the first Write IRP is issued. At point (3), WdmIoStartIo starts processing this first Write. At point (4), the second Write IRP is issued. As the first Write is still in progress (the printer being off), this second Write IRP is queued.
Point (5) is where it gets interesting. WdmIoCancel has just exited. The I/O Manager tries to cancel all pending IRPs. It calls the cancel routine of the second Write. WdmIoCancelIrp finds that it is not the current IRP. It therefore removes it from the StartIo queue and completes the IRP with a cancelled status.
The I/O Manager then calls the cancel routine of the first Write IRP at point (6). WdmIoCancelIrp finds that this IRP is the current IRP. In this design, WdmIoCancelIrp simply exits. In due course, the Timeout1s time-out routine runs. Timeout1s finds that the IRP Cancel flag is set. The WdmIoDpcForIsr routine is called to complete the IRP with a cancelled status.
Читать дальшеИнтервал:
Закладка:
Похожие книги на «Writing Windows WDM Device Drivers»
Представляем Вашему вниманию похожие книги на «Writing Windows WDM Device Drivers» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.
Обсуждение, отзывы о книге «Writing Windows WDM Device Drivers» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.