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');

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату
×