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: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Writing Windows WDM Device Drivers»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Writing Windows WDM Device Drivers — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Writing Windows WDM Device Drivers», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

However, the default pipe can never be halted. If a timeout or stall occurs here, an error is reported, which is detectable using the USBD_ERROR macro, but not USBD_HALTED. The halt condition is cleared automatically to give transfers a chance of succeeding on this pipe. If they keep failing, you will have to reset the port.

Listing 21.3 Device reset routines

NTSTATUS UsbGetPortStatus(IN PUSBKBD_DEVICE_EXTENSION dx, OUT ULONG& PortStatus) {

DebugPrintMsg("Getting port status");

PortStatus = 0;

NTSTATUS status = CallUSBDI(dx, &PortStatus, IOCTL_INTERNAL_USB_GET_PORT_STATUS);

DebugPrint("Got port status %x", PortStatus);

return status;

}

NTSTATUS UsbResetPort(IN PUSBKBD_DEVICE_EXTENSION dx) {

DebugPrintMsg("Resetting port");

NTSTATUS status = CallUSBDI(dx, NULL, IOCTL_INTERNAL_USB_RESET_PORT);

DebugPrint("Port reset %x", status);

return status;

}

NTSTATUS UsbResetDevice(IN PUSBKBD_DEVICE_EXTENSION dx) {

ULONG PortStatus;

NTSTATUS status = UsbGetPortStatus(dx, PortStatus);

if (!NT_SUCCESS(status)) return status;

// Give up if device not connected

if (!(PortStatus & USBD_PORT_CONNECTED)) return STATUS_NO_SUCH_DEVICE;

// Return OK if port enabled

if (PortStatus & USBD_PORT_ENABLED) return status;

// Port disabled so attempt reset

status = UsbResetPort(dx);

if (!NT_SUCCESS(status)) return status;

// See if it is now working

status = UsbGetPortStatus(dx, PortStatus);

if (!NT_SUCCESS(status)) return status;

if (!(PortStatus & USBD_PORT_CONNECTED) || !(PortStatus & USBD_PORT_ENABLED)) return STATUS_NO_SUCH_DEVICE;

return status;

}

Issuing URBs

The Usb.cpp module contains many routines that build and send off URBs for processing by the USB class drivers. UsbGetDeviceDescriptor is used to retrieve the USB device descriptor. This routine is not essential in UsbKbd, but it is used to implement one of the IOCTLs that are available to user mode programs. UsbGetDeviceDescriptor allocates nonpaged memory for the device descriptor and puts the count of bytes transferred in its Size parameter. The routine that calls UsbGetDeviceDescriptor must free the memory using ExFreePool .

UsbGetDeviceDescriptor starts by allocating some nonpaged memory for the URB. The Get Descriptor URB function uses the URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE function code. For this function code, the _URB_CONTROL_DESCRIPTOR_REQUEST structure is used.

Next, UsbGetDeviceDescriptor allocates memory for the device descriptor. Then, it calls UsbBuildGetDescriptorRequest to do the hard work of formatting the URB. The URB pointer and its size are passed as the first two parameters. The next parameter specifies the descriptor type, a device descriptor in this case. The following Index and LanguageId fields are only used when requesting configuration and string descriptors.

The following parameters to UsbBuildGetDescriptorRequest specify the descriptor buffer and its length. This buffer can be specified as a plain pointer to nonpaged memory. Alternatively, an MDL can be used. The final parameter is UrbLink, an optional link to a follow on URB.

UsbGetDeviceDescriptor sends off the built URB using CallUSBDI . It checks both the CallUSBDI NTSTATUS return status and the URB completion status.

The final job for UsbGetDeviceDescriptor is simply to save the count of bytes transferred. This was stored in the URB UrbControlDescriptorRequest.TransferBufferLength field. The USB memory is freed.

Listing 21.4 Getting a USB device descriptor

NTSTATUS UsbGetDeviceDescriptor(IN PUSBKBD_DEVICE_EXTENSION dx, OUT PUSB_DEVICE_DESCRIPT0R& deviceDescriptor, OUT ULONGS Size) {

// Allocate memory for URB

USHORT UrbSize = sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST);

PURB urb = (PURB)ExAllocatePool(NonPagedPool, UrbSize);

if (urb==NULL) {

DebugPrintMsg("No URB memory");

return STATUS_INSUFFICIENT_RESOURCES;

}

// Allocate memory for device descriptor

ULONG sizeDescriptor = sizeof(USB_DEVICE_DESCRIPTOR);

deviceDescriptor = (PUSB_DEVICE_DESCRIPTOR)ExAllocatePool(NonPagedPool, sizeDescriptor);

if (deviceDescriptor==NULL) {

ExFreePool(urb);

DebugPrintMsg("No descriptor memory");

return STATUS_INSUFFICIENT_RESOURCES;

}

// Build the Get Descriptor URB

UsbBuildGetDescriptorRequest(urb, UrbSize,

USB_DEVICE_QESCRIPTOR_TYPE, 0, 0, // Types, Index & LanguageId

deviceDescriptor, NULL, sizeDescriptor, // Transfer buffer

NULL); // Link URB

// Call the USB driver

DebugPrintMsg("Getting device descriptor");

NTSTATUS status = CallUSBDI(dx, urb);

// Check statuses

if (!NT_SUCCESS(status) || !USBD_SUCCESS( urb->UrbHeader.Status)) {

DebugPrint("status %x URB status %x", status, urb->UrbHeader.Status);

status = STATUS_UNSUCCESSFUL;

}

// Remember count of bytes actually transferred

Size = urb->UrbControlDescriptorRequest.TransferBufferLength;

ExFreePool(urb);

return status;

}

Selecting an Interface

To start using a device, your driver must select one interface within one configuration. This is more of a job than you might expect. Routine UsbSelectConfiguration performs these steps, as shown in Listing 21.5.

1. Get the configuration, interface, endpoint descriptors, etc.

2. Find the appropriate interface descriptor.

3. Issue a select configuration URB.

4. Save the configuration handle and handles to any pipes that you use.

UsbGetConfigurationDescriptors (not listed) is used to retrieve all the descriptors that are needed. This routine issues a Get Descriptor request twice. The first call returns just the basic configuration descriptor. The wTotalLength field in there tells you how much memory to allocate to retrieve all the associated descriptors.

USBD_ParseConfigurationDescriptorEx is used to find an interface. The parameters to this routine specify the criteria that must match. In this case UsbKbd is not interested in matching the interface number or alternate settings, but is interested in the device class. The HID device class is 3 (USB_DEVICE_CLASS_HUMAN_INTERFACE). To match a HID keyboard the subclass and protocol interface descriptor fields must both be 1.

If USBD_ParseConfigurationDescriptorEx finds a matching interface, it returns the interface descriptor pointer. The next task is to build a suitable Select Configuration URB. The helper function USBD_CreateConfigurationRequestEx allocates and fills this URB. UsbSelectConfiguration specifies an array of USBD_INTERFACE_LIST_ENTRY structures as an input to this routine, with a NULL InterfaceDescriptor field indicating the end of the list. Each structure specifies the interface descriptor. When the Select Configuration URB has been run, the Interface field points to valid data.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Writing Windows WDM Device Drivers»

Представляем Вашему вниманию похожие книги на «Writing Windows WDM Device Drivers» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Writing Windows WDM Device Drivers»

Обсуждение, отзывы о книге «Writing Windows WDM Device Drivers» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x