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 other PnP messages are usually processed by drivers on the way down the device stack. However, in a few circumstances, you may wish to see what results the lower drivers have produced.
WDM drivers can process IRPs in both these orders. So far, I have only shown how to process IRPs in order going down the stack. I shall now look at how to process IRPs in the other order.
IRP Completion Routines
As mentioned before, the IoCallDriver routine is used to call another driver. It is important to realize that IoCallDriver may return before the IRP has been completely processed. In this case, IoCallDriver returns STATUS_PENDING.
If a driver wants to process an IRP when all lower drivers have completed processing it, the driver must set a completion routine for the IRP. The completion routine is called when all the lower drivers have finished processing the IRP. The completion routine is called in an arbitrary context. I now show how a completion routine signals that it has been run using a kernel event.
Listing 9.7 shows how the ForwardIrpAndWait routine forwards an IRP to the lower drivers and waits for its completion. As ForwardIrpAndWait waits for the completion routine event to become signalled, it must run at PASSIVE_LEVEL IRQL. Waiting for dispatcher objects, such as events, is covered in full in Chapter 14. PnP IRPs are always called at PASSIVE_LEVEL, so it is safe to call ForwardIrpAndWait .
To set a completion routine, the next IRP stack location must be set up correctly. As described previously, IoCopyCurrentIrpStackLocationToNext copies all the current stack location parameters. Having done this, IoSetCompletionRoutine is used to set the completion routine to the ForwardedIrpCompletionRoutine function. ForwardIrpAndWait is then ready to call the next driver using IoCallDriver .
The last three BOOLEAN parameters of IoSetCompletionRoutine specify the circumstances in which you want the completion routine called. If the first BOOLEAN, InvokeOnSuccess , is TRUE, the completion routine is called if the IRP completes successfully. The other two BOOLEAN parameters, InvokeOnError and InvokeOnCancel, state whether the completion routine should be called if an error is returned or the IRP is cancelled. In ForwardIrpAndWait , I want the completion routine called in all circumstances, so all these parameters are set to TRUE.
ForwardIrpAndWait now has two tasks to perform. The completion routine has to signal when it has run, and the main code must wait for this signal. The signalling mechanism is a kernel event, which is basically the same as its Win32 equivalent. Chapter 14 discusses kernel events in full. The event is initialized to the nonsignalled state using KeInitializeEvent . When the completion routine runs, it simply calls KeSetEvent to set the event into the signalled state. ForwardIrpAndWait uses KeWaitForSingleObject to wait for the event to become signalled.
A completion routine has a standard prototype, passing the device object, the IRP, and a context pointer. In this case, ForwardIrpAndWait uses a pointer to the event as the context pointer. The context pointer is set in the IoSetCompletionRoutine call. When the IRP has been processed by all the lower drivers, ForwardedIrpCompietionRoutine is called. It simply sets the event.
ForwardedIrpCompletionRoutine returns a status of STATUS_MORE_PROCESSING_REQUIRED. This means that the IRP has not been completed by this driver and some other part of the driver will complete it. The only other alternative is to return STATUS_SUCCESS, in which case the IRP continues its journey back up the device stack.
IoCallDriver returns STATUS_PENDING if the IRP has not completed its processing by the lower drivers. If this value is returned, ForwardIrpAndWait must wait for the completion routine to run. Once the event has been set, the call to KeWaitForSingleObject returns. ForwardIrpAndWait retrieves the status returned by the lower drivers from the IRP's IoStatus.Status field.
If IoCallDriver returns any value apart from STATUS_PENDING, this means that the IRP has been processed by all the lower drivers. The completion routine has been run and the event set. However, ForwardIrpAndWait does not need to wait for the event, as it already knows that the IRP has been processed in full.
There is no way to know in advance if IoCallDriver will return a pending status. Therefore, if you want to use an IRP after calling IoCallDriver you must set a completion routine.
Completion routines may run at DISPATCH_LEVEL IRQL or lower in an arbitrary thread context. To be safe, you should assume that it is running at DISPATCH_LEVEL IRQL. This means that the completion routine itself and the context pointer must not be in paged memory. The ForwardIrpAndWait event variable is in the kernel stack. This is normally in non-paged memory. Apparently, the kernel stack can be pageable if a user mode wait is issued. However, as a kernel mode wait is used here, the event memory should be safely nonpaged.
Listing 9.7 Wdm2 Forwarding IRPs and waiting for completion
NTSTATUS Forward IrpAndWait(IN PDEVICE_OBJECT fdo, IN PIRP Irp) {
DebugPrintMsg("ForwardIrpAndWait");
PWDM2_DEVICE_EXTENSION dx=(PWDM2_DEVICE_EXTENSION)fdo->DeviceExtension;
KEVENT event;
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)ForwardedIrpCompletionRoutine, (PVOID)&event, TRUE, TRUE, TRUE);
NTSTATUS status = IoCallDriver(dx->NextStackDevice, Irp);
if (status==STATUS_PENDING) {
DebugPrintMsg("ForwardIrpAndWait: waiting for completion");
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = Irp->IoStatus.Status;
}
#if DBG
if (status!=STATUS_SUCCESS) DebugPrint("ForwardIrpAndWait: completed %x",status);
#endif
return status;
}
NTSTATUS ForwardedIrpCompletionRoutine(IN PDEVICE_OBJECT fdo, IN PIRP Irp, IN PKEVENT ev) {
KeSetEvent(ev, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
Most completion routines should include the following code to remember if any lower driver has pended an IRP. If any driver in a stack marks an IRP as pending then the I/O Manager has to take special steps to ensure that the IRP results are returned to user space in the correct thread context.
Calling IoMarkIrpPending sets an internal pending flag in the current IRP stack location. When a lower driver completes an IRP, IoCompleteRequest sets the Irp->PendingReturned flag equal to the IRP stack internal flag. To remember that the IRP was pended, a completion routine must therefore call IoMarkIrpPending if Irp->PendingReturned is set.
if (Irp->PendingReturned) IoMarklrpPending(Irp);
PnP Start Device Handler
The Wdm2 driver handles the PnP Start Device message in its PnpStartDeviceHandler routine shown in Listing 9.8. The state diagram in Figure 9.1 shows that the Start Device message is received either from the Awaiting resources state or the Stopped state.
PnpStartDeviceHandler can then do whatever it needs to do to start its device. Wdm2 delegates this to the routine StartDevice , which will be covered later. StartDevice is passed a pointer to the allocated resources, in the IRP stack Parameters.StartDevice.AllocatedResourcesTranslated field.
Читать дальшеИнтервал:
Закладка:
Похожие книги на «Writing Windows WDM Device Drivers»
Представляем Вашему вниманию похожие книги на «Writing Windows WDM Device Drivers» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.
Обсуждение, отзывы о книге «Writing Windows WDM Device Drivers» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.