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», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

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

Интервал:

Закладка:

Сделать

Listing 23.8 HidKbd CreateDevice routine

void CreateDevice( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING HidSymLinkName) {

if (HidKbdDo!=NULL) {

DebugPrintMsg("Already got HidKbdDo");

return;

}

PFILE_OBJECT HidFileObject = NULL;

PDEVICE_OBJECT HidDevice;

NTSTATUS status = IoGetDeviceObjectPointer(HidSymLinkName, FILE_ALL_ACCESS, &HidFileObject, &HidDevice);

if (!NT_SUCCESS(status)) {

DebugPrintMsg("IoGetDeviceObjectPointer failed");

return;

}

// Close file object

ObDereferenceObject(HidFileObject);

// Inspect HID capabilities here

PHIDP_PREPARSED_DATA HidPreparsedData = NULL;

USHORT HidInputReportLen, HidOutputReportLen;

if (!GetCapabilities(HidDevice, HidPreparsedData, HidInputReportLen, HidOutputReportLen)) {

DebugPrintMsg("GetCapabilities failed");

FreeIfAllocated(HidPreparsedData);

return;

}

// Reference device object

status = ObReferenceObjectByPointer(HidDevice, FILE_ALL_ACCESS, NULL, Kernel Mode);

if (!NT_SUCCESS(status)) {

DebugPrintMsg("ObReferenceObjectByPointer failed");

FreeIfAllocated(HidPreparsedData);

return;

}

// Allocate a buffer for the device ext HidSymLinkName

PWSTR HidSymLinkNameBuffer = (PWSTR)ExAllocatePool(NonPagedPool, HidSymLinkName->MaximumLength);

if (HidSymLinkNameBuffer==NULL) {

FreelfAllocated(HidPreparsedData);

ObDereferenceObject(HidDevice);

return;

}

#define NT_DEVICE_NAME L"\\Device\\HidKbd"

#define SYM_LINK_NAME L"\\DosDevices\\HidKbd"

// Initialise NT and Symbolic link names

UNICODE_STRING deviceName, linkName;

RtlInitUnicodeString(&deviceName, NT_DEVICE_NAME);

RtlInitUnicodeString(&linkName, SYM_LINK_NAME);

// Create our device object

status = IoCreateDevice(DriverObject, sizeof(HIDKBD_DEVICE_EXTENSION), &deviceName, FILE_DEVICE_KEYBOARD, 0, FALSE, &HidKbdDo);

if (!NT_SUCCESS(status)) {

HidKbdDo = NULL;

FreeIfAllocated(HidSymLinkNameBuffer);

FreeIfAllocated(HidPreparsedData);

ObDereferenceObject(HidDevice);

return;

}

// Set up our device extension

PHIDKBD_DEVICE_EXTENSION dx = (PHIDKBD_DEVICE_EXTENSION)HidKbdDo->DeviceExtension;

dx->HidKbdDo = HidKbdDo;

dx->HidDevice = HidDevice;

dx->HidPreparsedData = HidPreparsedData;

dx->HidSymLinkName.Length = 0;

dx->HidSymLinkName.MaximumLength = HidSymLinkName->MaximumLength;

dx->HidSymLinkName.Buffer = HidSymLinkNameBuffer;

RtlCopyUnicodeString(&dx->HidSymLinkName, HidSymLinkName);

// Create a symbolic link so our device is visible to Win32…

DebugPrint("Creating symbolic link XT", &linkName);

status = IoCreateSymbolicLink(&linkName, &deviceName);

if (!NT_SUCCESS(status)) {

DebugPrintMsg("Could not create symbolic link");

FreeIfAllocated(dx->HidSymLinkName.Buffer);

IoDeleteDevice(HidKbdDo);

ObDereferenceObject(HidDevice);

HidKbdDo = NULL;

return;

}

HidKbdDo->Flags |= DO_BUFFERED_IO;

HidKbdDo->Flags &= ~DO_DEVICE_INITIALIZING;

HidKbdDo->StackSize = HidDevice->StackSize+1;

DebugPrintMsg("Device created OK");

}

Deleting the HidKbd Device

The HidKbd device must be deleted in two circumstances. First, if HidKbd is notified that the HID device has been removed. Second, if the HidKbd driver is unloaded. The DeleteDevice routine shown in Listing 23.9 handles both these cases. When the driver is unloaded the HidSymLinkName parameter is NULL. However, if a HID device is being removed, HidSymLinkName contains the symbolic link name of the device.

DeleteDevice first checks that a HidKbd device has been created. If one has and a device is being removed, DeleteDevice calls RtlCompareUnicodeString to see if the device name matches the one to which HidKbd refers. If it is a different HID device, nothing more is done.

Before the device is deleted, DeleteDevice must free any memory that is associated with it (i.e., the preparsed data and the buffer for the copy of the symbolic link name). DeleteDevice now remakes the HidKbd symbolic link name. The symbolic link name is deleted using IoDeleteSymbolicLink . ObDereferenceObject is called to deference the HID device object. Finally, IoDeleteDevice deletes the HidKbd device.

Listing 23.9 HidKbd DeleteDevice routine

void DeleteDevice(IN PUNICODE_STRING HidSymLinkName) {

if (HidKbdDo==NULL) return;

PHIDKBD_DEVICE_EXTENSION dx = (PHIDKBD_DEVICE_EXTENSION)HidKbdDo->DeviceExtension;

if (HidSymLinkName!=NULL && RtlCompareUnicodeString(HidSymLinkName, &dx->HidSymLinkName, FALSE)!=0) {

DebugPrintMsg("DeleteDevice: symbolic link does not match our device");

return;

}

DebugPrintMsg("Deleting our device");

FreelfAllocated(dx->HidPreparsedData);

FreeIfAllocated(dx->HidSymLinkName.Buffer);

// Initialise Symbolic link names

UNICODE_STRING linkName;

RtlInitUnicodeString(&linkName, SYM_LINK_NAME);

// Remove symbolic link

DebugPrint("Deleting symbolic link XT", &linkName);

IoDeleteSymbolicLink(&linkName);

ObDereferenceObject(dx->HidDevice);

IoDeleteDevice(HidKbdDo);

HidKbdDo = NULL;

}

Getting HID capabilities

The HidKbd GetCapabilities routine is largely the same as its equivalent in HidKbdUser. It returns true if the HID device capabilities indicate that it is a HID keyboard.

However, GetCapabilities must obtain the device attributes and the preparsed data in a different way from HidKbdUser. The GetPreparsedData routine shown in Listing 23.10 does this job.

GetPreparsedData uses two IOCTLs to obtain the information needed from the HID class driver. IOCTL_HID_GET_COLLECTION_INFORMATION returns the attributes and the size of memory buffer required for the preparsed data. Next, IOCTL_HID_GET_COLLECTION_DESCRIPTOR is used to get the preparsed data itself. GetPreparsedData returns a pointer to the preparsed data memory. This memory must eventually be freed.

The CallHidIoctl routine is used to issue the two IOCTLs. This works in a very similar way to the CallUSBDI routine shown in Listing 21.2. It calls IoBuildDeviceIoControlRequest to build the IOCTL passing the IOCTL code, the output buffer details and a completion event. CallHidIoctl calls the HID class driver using IoCallDriver , waiting until it completes using the event, if necessary.

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

Интервал:

Закладка:

Сделать

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

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


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

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

x