FW: Windows Filter driver on different keyboards

If you are going to do a filter driver, you should be Plug and Play. Your
approach of using IoCreateFile and trying to attach to the is not going to
work. Take a look at the generic filter in the Toaster sample of the WDK,
and start there.

If you make the filter a class filter, you will attach to all keyboards.

Don Burn

Windows Driver Consulting

Website: http: http://www.windrvr.com

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@x-publisher.com
Sent: Friday, January 12, 2018 3:03 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] FW: Windows Filter driver on different keyboards

Hi All,

I am writing an filter driver and want to attach the filter to more than one
physical keyboard in the system. If I attach the filter to the first
keyboard “\Device\KeyboardClass0” it works fine but it works not for the
other keyboards. The IoAttachDevice failed for “\Device\KeyboardClass1”. The
same with other class. I have attached 3 physical keyboard.

Now I have changed the creation of the device to work with IoCreateFile. The
routines create and attach my device but now in the DispatchRead the
return IoCallDriver(pDevExt->kbdDevice, Irp);
((PDEVICE_EXTENSION)DeviceObject->DeviceExtension) the “kbdDevice” is NULL.

The function status = IoAttachDeviceToDeviceStackSafe(pDevObj, pLBKdev,
&pDevExt->kbdDevice); calls correctly at the time of creation.

It worked before the modification.

Now the routine which create and attach the device:

RtlInitUnicodeString(&devNameFlt, L"\Device\KeyboardClass1
<file:> “);
RtlInitUnicodeString(&devName, L”\Device\MultikeyboardCnt
<file:> “);

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;
}


NTDEV is sponsored by OSR

Visit the list online at:
http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at
http:</http:></http:></http:></file:></file:></http:>

To echo what don said, if you install yourself as a class filter driver you will be inserted into all stacks. The legacy names (\device\keyboardclassN) you are using to open devices are problematic and not guaranteed to be sequential (their may be gaps) and you really need to be in the stack as it starts, not afterwards. There is a kbfiltr example in git

https://github.com/Microsoft/Windows-driver-samples/tree/master/input/kbfiltr

which is written as a device upper filter, but it will work as is as a class filter and you just need to change how it is installed.

d

From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@windrvr.com
Sent: Friday, January 12, 2018 12:25 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] FW: Windows Filter driver on different keyboards

If you are going to do a filter driver, you should be Plug and Play. Your approach of using IoCreateFile and trying to attach to the is not going to work. Take a look at the generic filter in the Toaster sample of the WDK, and start there.
If you make the filter a class filter, you will attach to all keyboards.

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.comhttps:

From: xxxxx@lists.osr.commailto:xxxxx [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@x-publisher.commailto:xxxxx
Sent: Friday, January 12, 2018 3:03 PM
To: Windows System Software Devs Interest List >
Subject: [ntdev] FW: Windows Filter driver on different keyboards

Hi All,

I am writing an filter driver and want to attach the filter to more than one physical keyboard in the system. If I attach the filter to the first keyboard “\Device\KeyboardClass0” it works fine but it works not for the other keyboards. The IoAttachDevice failed for “\Device\KeyboardClass1”. The same with other class. I have attached 3 physical keyboard.

Now I have changed the creation of the device to work with IoCreateFile. The routines create and attach my device but now in the DispatchRead the return IoCallDriver(pDevExt->kbdDevice, Irp); ((PDEVICE_EXTENSION)DeviceObject->DeviceExtension) the “kbdDevice” is NULL.

The function status = IoAttachDeviceToDeviceStackSafe(pDevObj, pLBKdev, &pDevExt->kbdDevice); calls correctly at the time of creation.

It worked before the modification.
Now the routine which create and attach the device:

RtlInitUnicodeString(&devNameFlt, L"\Device\KeyboardClass1<file:>“);
RtlInitUnicodeString(&devName, L”\Device\MultikeyboardCnt<file:>“);
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;
}


NTDEV is sponsored by OSR

Visit the list online at: http:>

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:>

To unsubscribe, visit the List Server section of OSR Online at http:>


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></http:></http:></http:></file:></file:></mailto:xxxxx></mailto:xxxxx></https:>

Thanks for the answer. I know this with plug and play and this with the class name.

My question was what is wrong in the code that it succeeds and the mentioned reference at DispatchRead is NULL.