Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

DeviceIOControl in kbfiltr

64 views
Skip to first unread message

Therg

unread,
Apr 29, 2009, 5:25:01 AM4/29/09
to
Hello, i'm writing kbfiltr and have to use DeviceIOControl in user
application to send requests to my driver.
HANDLE hHandle = CreateFileA( "\\\\.\\ProtectFilter",0,FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);

if (hHandle == INVALID_HANDLE_VALUE)
{
MessageBox(hwnd,_T("File not Found!"),_T("Error"),0);
PostQuitMessage(1);
return 0;
}

Calling
DeviceIoControl(hHandle,CTL_CODE(FILE_DEVICE_KEYBOARD, 0x800,
METHOD_BUFFERED, FILE_ANY_ACCESS),NULL, NULL, NULL, NULL,&BytesReturned,NULL
))

Failed with error code 1 (ERROR_INVALID_FUNCTION)

Looking through the DebugPrint Messages i can see, that my driver complite
KbFilter_CreateClose function 2 times(for opening file and close) so symbolik
link is correct, but function KbFilter_IoCtl haven't been called.

Driver Code:

NTSTATUS
DriverEntry (IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING
RegistryPath)
{
ULONG i;

UNREFERENCED_PARAMETER (RegistryPath);
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
DriverObject->MajorFunction[i] = KbFilter_DispatchPassThrough;
}

DriverObject->MajorFunction [IRP_MJ_CREATE] =
DriverObject->MajorFunction [IRP_MJ_CLOSE] = KbFilter_CreateClose;
DriverObject->MajorFunction [IRP_MJ_PNP] = KbFilter_PnP;
DriverObject->MajorFunction [IRP_MJ_POWER] = KbFilter_Power;

DriverObject->MajorFunction [IRP_MJ_INTERNAL_DEVICE_CONTROL] =
KbFilter_InternIoCtl;
DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = KbFilter_IoCtl; // !!
DriverObject->DriverUnload = KbFilter_Unload;
DriverObject->DriverExtension->AddDevice = KbFilter_AddDevice;

...

NTSTATUS KbFilter_AddDevice(IN PDRIVER_OBJECT Driver,IN PDEVICE_OBJECT PDO)
...
RtlInitUnicodeString( &devName, L"\\Device\\ProtectFilter" );
status =
IoCreateDevice(Driver,sizeof(DEVICE_EXTENSION),&devName,FILE_DEVICE_KEYBOARD,0,FALSE,&device);

RtlInitUnicodeString( &symLinkName, L"\\DosDevices\\ProtectFilter");
IoCreateSymbolicLink( &symLinkName, &devName );
...
NTSTATUS KbFilter_IoCtl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
NTSTATUS status = STATUS_SUCCESS;
ULONG BytesTxd =0;
PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
PDEVICE_EXTENSION devExt;

ULONG ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

devExt= (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
DbgPrint(("IOCTL Func"));

switch (ControlCode)
{
case TurnOn:
TurnedOn = TRUE;
DbgPrint(("Turn On"));
return KbFilter_Complete(DeviceObject,Irp,&status);
case TurnOff:
DbgPrint(("Turn Off"));
return KbFilter_Complete(DeviceObject,Irp,&status);
default:
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(devExt->TopOfStack, Irp);
}

return status;
}
...
NTSTATUS
KbFilter_CreateClose (IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
NTSTATUS status;
PDEVICE_EXTENSION devExt;


PAGED_CODE();

irpStack = IoGetCurrentIrpStackLocation(Irp);
devExt = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;

status = Irp->IoStatus.Status;
DebugPrint(("KbFilter_CreateClose"));
switch (irpStack->MajorFunction) {
case IRP_MJ_CREATE:
DebugPrint(("Create"));
InterlockedIncrement(&devExt->EnableCount);
if (NULL == devExt->UpperConnectData.ClassService)
{
status = STATUS_INVALID_DEVICE_STATE;
}
else if ( 1 == InterlockedIncrement(&devExt->EnableCount)) {
}
else
{
}

break;

case IRP_MJ_CLOSE:
DebugPrint(("Close"));
InterlockedDecrement(&devExt->EnableCount);

if (0 == InterlockedDecrement(&devExt->EnableCount))
{

}

break;
}

Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT );
return status;
}
NTSTATUS
KbFilter_DispatchPassThrough(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);

IoSkipCurrentIrpStackLocation(Irp);
DebugPrint(("KbFilter_DispatchPassThrough"));
return IoCallDriver(((PDEVICE_EXTENSION)
DeviceObject->DeviceExtension)->TopOfStack, Irp);
}

Thanks.

Doron Holan [MSFT]

unread,
Apr 29, 2009, 12:42:34 PM4/29/09
to
are you creating 2 device objects? the filter devobj and the control devobj?

--

This posting is provided "AS IS" with no warranties, and confers no rights.


"Therg" <Th...@discussions.microsoft.com> wrote in message
news:4AB52FD7-4A25-4B1E...@microsoft.com...

Therg

unread,
Apr 29, 2009, 2:06:01 PM4/29/09
to
No, i'm creating 1device object and then device extension
Full code of the function KbFilter_AddDevice:

NTSTATUS KbFilter_AddDevice(IN PDRIVER_OBJECT Driver,IN PDEVICE_OBJECT PDO)

{
PDEVICE_EXTENSION devExt;
IO_ERROR_LOG_PACKET errorLogEntry;
PDEVICE_OBJECT device;
NTSTATUS status = STATUS_SUCCESS;

UNICODE_STRING devName;
UNICODE_STRING symLinkName;

PAGED_CODE();

DebugPrint(("KbFilter_AddDevice"));

// Device Name


RtlInitUnicodeString( &devName, L"\\Device\\ProtectFilter" );

// Create Device
status =
IoCreateDevice(Driver,sizeof(DEVICE_EXTENSION),&devName,FILE_DEVICE_KEYBOARD,0,FALSE,&device);

//Create Symb link


RtlInitUnicodeString( &symLinkName, L"\\DosDevices\\ProtectFilter");
IoCreateSymbolicLink( &symLinkName, &devName );

if (!NT_SUCCESS(status))
{
return (status);
}

RtlZeroMemory(device->DeviceExtension, sizeof(DEVICE_EXTENSION));

devExt = (PDEVICE_EXTENSION) device->DeviceExtension;
devExt->TopOfStack = IoAttachDeviceToDeviceStack(device, PDO);

if (devExt->TopOfStack == NULL)
{
IoDeleteDevice(device);
return STATUS_DEVICE_NOT_CONNECTED;
}


ASSERT(devExt->TopOfStack);

devExt->Self = device;
devExt->PDO = PDO;
devExt->DeviceState = PowerDeviceD0;

devExt->SurpriseRemoved = FALSE;
devExt->Removed = FALSE;
devExt->Started = FALSE;

device->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
device->Flags &= ~DO_DEVICE_INITIALIZING;

return status;
}

---

Doron Holan [MSFT]

unread,
Apr 30, 2009, 12:50:04 PM4/30/09
to
there is no need to zero out the devext, it is already zeroed out for you.
are you layered above or below kbdclass? kbdclass will fail all unknown
IOCTLs (which includes yours). the typical way of getting around this is to
either
1) create a control devobj which your app opens
2) enumerate a raw PDO that your app opens

there is a full fledged kmdf sample which demonstrates 2. I think it is the
more robust solution b/c you get dynamic device arrival notifications for
the dev interface you register on the raw pdo and you do not have to deal
with a 1:N mapping if you are filtering more than one keyboard

d

--

This posting is provided "AS IS" with no warranties, and confers no rights.


"Therg" <Th...@discussions.microsoft.com> wrote in message

news:B0D27067-8174-4389...@microsoft.com...

Therg

unread,
May 3, 2009, 1:53:05 PM5/3/09
to
Thanks, Doron Holan, you have answered my questionm but i want to ask one
more: how i can install my driver above kbclass, using *.inf, to proceed
DeviceControl requests first.

Currernly i'm using ddk's kbfiltr inf.

Doron Holan [MSFT]

unread,
May 4, 2009, 3:59:48 PM5/4/09
to
I think you will need a device coinstaller, but once you are above kbdclass
you lose the service callback (read irps are used to report packets)

d

--

This posting is provided "AS IS" with no warranties, and confers no rights.


"Therg" <Th...@discussions.microsoft.com> wrote in message

news:B4769A05-2F01-4D1B...@microsoft.com...

0 new messages