【问题标题】:KMDF lower Filter driverKMDF 下层过滤器驱动程序
【发布时间】:2018-06-20 20:15:43
【问题描述】:

我正在编写过滤器驱动程序,并希望将过滤器附加到系统中的多个物理键盘。 如果我将过滤器附加到第一个键盘“\Device\KeyboardClass0”它工作正常,但它不适用于另一个。 “\Device\KeyboardClass1”的 IoAttachDevice 失败。其他班级也一样。我已经连接了 3 个物理键盘。

status = IoAttachDevice(gkbdDevice, &TargetDevice, &((PDEVICE_EXTENSION)gkbdDevice->DeviceExtension)->kbdDevice);

有人可以帮忙吗?

【问题讨论】:

  • 是否可以一次将键盘过滤器附加到所有键盘?
  • 你甚至不说哪个status返回给你IoAttachDevice。在许多情况下,IoAttachDevice 可能会因为设备上的DO_EXCLUSIVE 标志而失败,而它已经打开。需要使用 IoCreateFileIO_ATTACH_DEVICE 选项 + IoAttachDeviceToDeviceStackSafe。并怀疑您使用的是真正的 kmdf 驱动程序
  • 在调用 IoAttachDevice 之前,我调用“status = IoGetDeviceObjectPointer(&devName, FILE_ALL_ACCESS, &pFileObject, &(pLBKdev));”此函数也失败并返回“0”。
  • IoGetDeviObjectPointer 在第二个或第三个键盘上返回 STATUS_SHARING_VIOLATION。为什么会这样?
  • 正是因为我写了 - 使用 IoCreateFileIO_ATTACH_DEVICE 选项

标签: windows kernel driver kmdf


【解决方案1】:

使用以下代码,我现在可以打开第二个键盘,但是...

    /*
* Form the Device Name and symbolic name
*/
RtlInitUnicodeString(&devNameFlt, L"\\Device\\KeyboardClass0");
RtlInitUnicodeString(&devName, L"\\Device\\MultikeyboardCnt");

status = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION),
    &devName,
    FILE_DEVICE_KEYBOARD,
    SYNCHRONIZE,
    FALSE,
    &pDevObj);

if (!NT_SUCCESS(status))
{
    DbgPrint("%s, IoCreateDevice failed:0x%0x\n", __FUNCTION__, status);
    return status;
}

HANDLE hFile;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, 0, OBJ_CASE_INSENSITIVE };
oa.ObjectName = &devNameFlt;

IO_STATUS_BLOCK iosb;
status = IoCreateFile(&hFile, SYNCHRONIZE, &oa, &iosb, 0, 0, FILE_SHARE_VALID_FLAGS, FILE_OPEN,
    0, 0, 0, CreateFileTypeNone, 0, IO_ATTACH_DEVICE);
if (!NT_SUCCESS(status))
{
    DbgPrint("%s, IoCreateFile failed to call:0x%0x\n", __FUNCTION__, status);
    return status;
}

/* Get File Object */
PFILE_OBJECT LocalFileObject;
status = ObReferenceObjectByHandle(hFile,
                                   0,
                                   *IoFileObjectType,
                                   KernelMode,
                                   (PVOID*)&LocalFileObject,
                                   NULL);

pLBKdev = IoGetRelatedDeviceObject(LocalFileObject);
DbgPrint("%s at IoCreateFile ok\n", __FUNCTION__);
ObReferenceObject(pLBKdev);

/*
* Retrieve device extension pointer from device object
*/
pDevExt = (PDEVICE_EXTENSION)pLBKdev->DeviceExtension;

status = IoAttachDeviceToDeviceStackSafe(pDevObj, pLBKdev, &pDevExt->kbdDevice);
if (status != STATUS_SUCCESS) {
    DbgPrint("IoGetDeviceObjectPointer failed with error = 0x%0x\n", status);
    goto cleanup_failure;
}

pDevObj->Flags |= DO_BUFFERED_IO;
pDevObj->Flags &= ~DO_DEVICE_INITIALIZING;

/*
* Create the symbolic link name, this is not mandatory
* but can be helpful for user mode apps to communicate
*/
status = IoCreateSymbolicLink(&symLinkNameFlt, &devNameFlt);
if (!NT_SUCCESS(status)) {
    // if it fails now, must delete Device object
    DbgPrint("IoCreateSymbolicLink failed with error = 0x%0x\n", status);
    goto cleanup_failure;
}

但是如果我在键盘上键入一个键,例程 DispatchRead 就会崩溃。

【讨论】:

  • 问题是在DispatchRead函数中调用IoCallDriver(pDevExt->kbdDevice, Irp);指针 pDevExt->kbdDevice 为 NULL。为什么会这样,因为它以前有效。
【解决方案2】:

尝试在 DO_BUFFERED_IO 和 ~DO_DEVICE_INITIALIZING 之后执行 IoAttachDeviceToDeviceStackSafe()。

pDevObj->Flags |= DO_BUFFERED_IO;
pDevObj->Flags &= ~DO_DEVICE_INITIALIZING;

status = IoAttachDeviceToDeviceStackSafe(pDevObj, pLBKdev, &pDevExt->kbdDevice);
if (status != STATUS_SUCCESS) {
    DbgPrint("IoGetDeviceObjectPointer failed with error = 0x%0x\n", status);
    goto cleanup_failure;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-03
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多