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», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.
Интервал:
Закладка:
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;
}
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» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.