DeviceIOControl Switch Statement

I am trying to send io control to my driver from an C# application but strangely switch statement always fallbacks to default in DeviceIoControl event.

Here is how control codes defined in Driver

#define TD_IOCTL_FILTER_PROCESS_ADD CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#define TD_IOCTL_FILTER_PROCESS_REMOVE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x801), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#define TD_IOCTL_FILTER_ENABLE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x802), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#define TD_IOCTL_FILTER_DISABLE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x803), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

Here is the C# Enumeration of control codes

public enum PS_FILTER_IOCTL : int
{
TD_IOCTL_FILTER_PROCESS_ADD = 0x800,
TD_IOCTL_FILTER_PROCESS_REMOVE = 0x801,
TD_IOCTL_FILTER_ENABLE = 0x802,
TD_IOCTL_FILTER_DISABLE = 0x803,
}

And finally the switch statement in the driver

switch (IoControlCode)
{
case TD_IOCTL_FILTER_PROCESS_ADD:
break;
case TD_IOCTL_FILTER_PROCESS_REMOVE:
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}

For some reason its always switched to default. Am i missing something?

The result of CTL_CODE is the final IOCTL value you should use in the switch, ie TD_IOCTL_XXxxx. It is strongly recommeneed that you never break apart the IOCTL into the 4 separate pieces (device type, number, method type, access) in the driver. You C# enum is incorrect in that regard, the enum values should be the whole IOCTL value created by CTL_CODE

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@netprojects.gr
Sent: Wednesday, May 1, 2013 9:47 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] DeviceIOControl Switch Statement

I am trying to send io control to my driver from an C# application but strangely switch statement always fallbacks to default in DeviceIoControl event.

Here is how control codes defined in Driver

#define TD_IOCTL_FILTER_PROCESS_ADD CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#define TD_IOCTL_FILTER_PROCESS_REMOVE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x801), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#define TD_IOCTL_FILTER_ENABLE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x802), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#define TD_IOCTL_FILTER_DISABLE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x803), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

Here is the C# Enumeration of control codes

public enum PS_FILTER_IOCTL : int
{
TD_IOCTL_FILTER_PROCESS_ADD = 0x800,
TD_IOCTL_FILTER_PROCESS_REMOVE = 0x801,
TD_IOCTL_FILTER_ENABLE = 0x802,
TD_IOCTL_FILTER_DISABLE = 0x803,
}

And finally the switch statement in the driver

switch (IoControlCode)
{
case TD_IOCTL_FILTER_PROCESS_ADD:
break;
case TD_IOCTL_FILTER_PROCESS_REMOVE:
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}

For some reason its always switched to default. Am i missing something?


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

xxxxx@netprojects.gr wrote:

I am trying to send io control to my driver from an C# application but strangely switch statement always fallbacks to default in DeviceIoControl event.

Here is how control codes defined in Driver

#define TD_IOCTL_FILTER_PROCESS_ADD CTL_CODE (FILE_DEVICE_UNKNOWN, (0x800), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#define TD_IOCTL_FILTER_PROCESS_REMOVE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x801), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#define TD_IOCTL_FILTER_ENABLE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x802), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
#define TD_IOCTL_FILTER_DISABLE CTL_CODE (FILE_DEVICE_UNKNOWN, (0x803), METHOD_BUFFERED, FILE_SPECIAL_ACCESS)

Those lines should be in an include file that is shared between the
driver and your applications.

Here is the C# Enumeration of control codes

public enum PS_FILTER_IOCTL : int
{
TD_IOCTL_FILTER_PROCESS_ADD = 0x800,
TD_IOCTL_FILTER_PROCESS_REMOVE = 0x801,
TD_IOCTL_FILTER_ENABLE = 0x802,
TD_IOCTL_FILTER_DISABLE = 0x803,
}

Those are wrong. It didn’t strike you as odd to have a single name with
two different numeric values?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

OK i was a little sloppy i guess and didn’t notice that macro CTL_CODE.
To much copy pasting from sample projects :slight_smile:

Thanks a lot guys it all works now!

On 01-May-2013 20:57, xxxxx@netprojects.gr wrote:

OK i was a little sloppy i guess and didn’t notice that macro CTL_CODE.
To much copy pasting from sample projects :slight_smile:

By the way, about CTL_CODE: this macro is defined in a C/C++ include
file and drags a lot of other #defines specific to C/C++.
Using it “as is” in other languages is pain.
This can be solved by providing a simple enum to the non-C app and
converting it to full IOCTL codes in interface module written in C.
Or have the interface library to completely hide ioctl codes from the app.

Regards,
–pa

Pavel A. wrote:

By the way, about CTL_CODE: this macro is defined in a C/C++ include
file and drags a lot of other #defines specific to C/C++.
Using it “as is” in other languages is pain.

Well, <winioctl.h> actually stands alone – it has no other include file
dependencies.

However, it’s more than 6,000 lines long, so you do have a point. On
the other hand, the CTL_CODE macro itself and the 10 or 12 constants it
requires are pretty easy to port. I’ve done it in a few lines of Python.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.</winioctl.h>

In the past for c# I wrote a simple class that took the 4 parameters to the macro and built the value behind the scenes. My pinvoke wrapper took the class as the type for the ioctl value and used the marshalling engine to convert from the class type to a 32 bit int

d

Bent from my phone


From: Pavel A.mailto:xxxxx
Sent: ?5/?1/?2013 4:12 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: Re:[ntdev] DeviceIOControl Switch Statement

On 01-May-2013 20:57, xxxxx@netprojects.gr wrote:
> OK i was a little sloppy i guess and didn’t notice that macro CTL_CODE.
> To much copy pasting from sample projects :slight_smile:

By the way, about CTL_CODE: this macro is defined in a C/C++ include
file and drags a lot of other #defines specific to C/C++.
Using it “as is” in other languages is pain.
This can be solved by providing a simple enum to the non-C app and
converting it to full IOCTL codes in interface module written in C.
Or have the interface library to completely hide ioctl codes from the app.

Regards,
–pa


NTDEV is sponsored by OSR

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

On 02-May-2013 02:32, Tim Roberts wrote:

Pavel A. wrote:
>
> By the way, about CTL_CODE: this macro is defined in a C/C++ include
> file and drags a lot of other #defines specific to C/C++.
> Using it “as is” in other languages is pain.

Well, <winioctl.h> actually stands alone – it has no other include file
> dependencies.
>
> However, it’s more than 6,000 lines long, so you do have a point. On
> the other hand, the CTL_CODE macro itself and the 10 or 12 constants it
> requires are pretty easy to port. I’ve done it in a few lines of Python.

Yes, the macro itself is trivial - but if you expose it to user, you
need to define all these METHOD_BUFFERED, METHOD_IN_DIRECT …
FILE_ANY_ACCESS … FILE_DEVICE_UNKNOWN, and so on.
(And maybe the two ‘custom’ bits, which are not explicitly defined in
winioctl.h). Away them all.

regards,
– pa</winioctl.h>