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», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
Internally, it seems as though IoBuildDeviceIoControlRequest allocates some nonpaged memory to hold the combined input and output buffer, to make it work exactly like a standard IOCTL call. IoBuildDeviceIoControlRequest copies the input buffer there initially. It must set its own completion routine that copies the data back into your given output buffer (as well as setting the event and freeing the IRP memory).
The USB Internal IOCTLs do not use the standard input and output buffers [51] Presumably to avoid unnecessary copying of large buffers.
. Instead, you have to set up the next stack location Parameters.Others.Argument1 field. This is more complicated than you might think.
Previous examples have used IoSkipCurrentIrpStackLocation to reuse the current IRP stack location, and IoCopyCurrentIrpStackLocationToNext to copy the current stack location to the next when setting a completion routine. We cannot use these routines, as the current stack location is not set up yet.
The IoCallDriver call moves onto the next IRP stack location. CallUSBDI wants to change the stack location that the next lower driver sees. The IoGetNextIrpStackLocation call returns the required IRP stack location pointer [52] Unlike a processor execution stack, there is nothing wrong with altering the next item down the stack.
. The IoBuildDeviceIoControlRequest call has already set up most of the correct values for this stack location. The required values are set into the Parameters.Others.Argument1 field, etc.
In summary, CallUSBDI does the following jobs.
1. Initializes an IRP completion event
2. Builds an Internal IOCTL
3. Stores the URB pointer, etc., in the IRP's next stack location
4. Calls the next driver
5. If the request is still pending, wait for the completion event to become signalled. The KeWaitForSingleObjectWaitReason parameter must be set to Suspended.
Listing 21.2 Calling USBDI
NTSTATUS CallUSBDI(IN PUSBKBD_DEVICE_EXTENSION dx, IN PVOID UrbEtc,
IN ULONG IoControlCode/*=IOCTL_INTERNAL_USB_SUBMIT_URB*/,
IN ULONG Arg2/*=0*/) {
IO_STATUS_BLOCK IoStatus;
KEVENT event;
// Initialise IRP completion event
KeInitializeEvent(&event, NotificationEvent, FALSE);
// Build Internal IOCTL IRP
PIRP Irp = IoBuildDeviceIoControlRequest(
IoControlCode, dx->NextStackDevice,
NULL, 0, // Input buffer
NULL, 0, // Output buffer
TRUE, &event, &IoStatus);
// Get IRP stack location for next driver down (already set up)
PIO_STACK_LOCATION NextIrpStack = IoGetNextIrpStackLocation(Irp);
// Store pointer to the URB etc
NextIrpStack->Parameters.Others.Argument1 = UrbEtc;
NextIrpStack->Parameters.Others.Argument2 = (PVOID)Arg2;
// Call the driver and wait for completion if necessary
NTSTATUS status = IoCallDriver(dx->NextStackDevice, Irp);
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
status = IoStatus.Status;
}
// return IRP completion status
return status;
}
Other IRP Allocations
Other kernel calls can be used to allocate IRPs. IoBuildSynchronousFsdRequest builds a Read, Write, Flush, or Shutdown IRP that uses an event to signal completion in the same way as IoBuildDeviceIoControlRequest. IoBuildSynchronousFsdRequest must be called at PASSIVE_LEVEL IRQL.
IoBuildAsynchronousFsdRequest works asynchronously, as it does not use an event to signal its completion. Consequently, it can be called at or below DISPATCH_LEVEL. Note that the IRP must be freed using IoFreeIrp . A common way to do this is to attach a completion routine. It is OK to call IoFreeIrp here and then return STATUS_MORE_PROCESSING_REQUIRED.
There are two final macho ways of building IRPs. IoAllocateIrp allocates an IRP, while IoInitializeIrp makes an IRP out of some driver allocated memory. Be very careful to set up all IRP and IRP stack locations correctly. Both of these methods allow you specify the size of the IRP stack size. Use IoGetNextIrpStackLocation to get the first IRP stack location if you need to set up a completion routine. Call IoFreeIrp to free an IRP created by IoAllocateIrp .
The old DDK documentation wrongly says that you can call IoInitializeIrp to reuse an IRP allocated using IoAllocateIrp . You can use this function as long as you preserve the IRP AllocationFlags field, as shown in Chapter 23. In W2000, you can reuse an IRP created with IoAllocateIrp using IoReuseIrp .
Multiple USBDI Calls
If you were reading carefully, you will have noticed that the Call USBDI routine can only be called at PASSIVE_LEVEL. This means that it cannot be called from a StartIo routine, which runs at DISPATCH_LEVEL. UsbKbd makes its USB calls direct from its dispatch routines that run at PASSIVE_LEVEL.
In UsbKbd, it is possible for a user program to issue two overlapped read requests "simultaneously". This might easily result in the USB class drivers being sent two IRPs for processing at the same time. There is nothing in the documentation that says this is a problem. I suspect that it is not, as the USB class driver will almost certainly serialize requests.
If you feel that you ought to serialize your USBDI calls, you will have to use a StartIo routine. A single prebuilt IRP can be reused for each call. Chapter 23 shows how to build, use, and free such an IRP.
In many cases, it might be useful to send off a series of IRPs to the USB class drivers. As there will usually be a spare IRP queued up for processing, no incoming data will be lost.
Talking USB
There are several jobs that a USB client driver must do to initialize its connection to its device. The UsbKbd driver does these jobs in its Create IRP handler. However, most USB drivers will want to initialize their device when processing the Start Device Plug and Play IRP.
1. Check device enabled. Reset and enable the device, if necessary.
2. Select one interface in one of the configurations.
3. Possibly read other descriptors, such as the string-, class-, or vendor-specific descriptors.
4. Talk to your device to issue whatever commands are relevant, get device status, and initialize pipes.
Device Reset
Listing 21.3 shows how UsbKbd resets its device in routine UsbResetDevice when a Win32 program opens a handle to it. UsbGetPortStatus issues IOCTL_INTERNAL_USB_GET_PORT_STATUS to retrieve the port status bits. UsbResetDevice checks the USBD_PORT_CONNECTED and USBD_PORT_ENABLED bits, and calls UsbResetPort , if necessary. UsbResetPort simply issues IOCTL_INTERNAL_USB_RESET_PORT to the USB class drivers.
You may need to reset the port if some drastic communication problem has arisen with your device (e.g., if control transfers to the default pipe keep failing). However, if another pipe stalls, do not reset the port.
If a pipe stalls or USBDI detects a timeout, the pipe becomes halted. The USBD_HALTED macro detects this condition. All URBs linked to the current URB are cancelled. A halted pipe cannot accept any more transfers until a Reset Pipe URB is issued.
Читать дальшеИнтервал:
Закладка:
Похожие книги на «Writing Windows WDM Device Drivers»
Представляем Вашему вниманию похожие книги на «Writing Windows WDM Device Drivers» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.
Обсуждение, отзывы о книге «Writing Windows WDM Device Drivers» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.