ERROR_INVALID_FUNCTION from EvtIoDeviceControl

Hello,

A driver for a PCI device that I am developing utilizing KMDF refuses to reply to DeviceIoControl.
When invoking the DeviceIoControl with a successfully opened handle in a user space application the status is 0 with GetLastError providing ERROR_INVALID_FUNCTION.

The IOCTL is a “user defined” IOCTL:
CTL_CODE( 4001, 0x801,METHOD_BUFFERED, FILE_ANY_ACCESS ).

I see that my callback EvtIoDeviceControl function is NOT invoked at all (WPP not printed). While the create callback function is invoked as mentioned above (just before calling the DeviceIoControl function).

Any ideas?

Igal

Sorry,

there is a typo in my original thread the IOCTL is:
CTL_CODE( 4001, 0x8001,METHOD_BUFFERED, FILE_ANY_ACCESS )

Igal

>CTL_CODE( 4001, 0x8001,METHOD_BUFFERED, FILE_ANY_ACCESS )

“The function code cannot be larger 4095.”

//Daniel

Daniel,

Thanks I looked into the winioctl.h and saw my mistake. Thanks.

Igal

Hi,

Now that I am getting the IOCTLs, it looks to me that sometimes I am getting the full IOCTL and sometimes I am getting only the function part. Is it possible ? or did I do something really incorrect?

Igal

xxxxx@gmail.com wrote:

Now that I am getting the IOCTLs, it looks to me that sometimes I am getting the full IOCTL and sometimes I am getting only the function part. Is it possible ? or did I do something really incorrect?

The ioctl code you get in your driver is just a DWORD, copied directly
from the user-mode application. It gets passed through to you
unchanged. So, either you are not printing what you think you are
printing, or the user-mode application isn’t sending what you think it
is sending.


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

Tim,

thanks for your reply.

I am printing the ioctl code at the same place. Moreover, I am sending a
different code from a user mode application a different code which composed
as following:

#define IOCTL_GET_VERSION CTL_CODE( MY_FILE_DEVICE,
BUILD_FUNCTION(GET_VERSION), METHOD_BUFFERED, FILE_ANY_ACCESS )
#define IOCTL_READ_BIT_REGISTER CTL_CODE( MY_FILE_DEVICE,
BUILD_FUNCTION(READ_BIT_REGISTER), METHOD_BUFFERED, FILE_ANY_ACCESS )

#define BUILD_FUNCTION(function) (0x800|(function &
0x7FF))
#define MY_FILE_DEVICE (0x8001)

#define GET_VERSION (0x01)
#define READ_BIT_REGISTER (0x02)

when I send IOCTL_GET_VERSION I receive in the callback 0x1
when I send IOCTL_READ_BIT_REGISTER I receive in the callback 0x80012008

I am sure that I miss something but it is too consistent.

Igal

Igal Kroyter

On Tue, Mar 15, 2016 at 9:28 PM, Tim Roberts wrote:

> xxxxx@gmail.com wrote:
> > Now that I am getting the IOCTLs, it looks to me that sometimes I am
> getting the full IOCTL and sometimes I am getting only the function part.
> Is it possible ? or did I do something really incorrect?
>
> The ioctl code you get in your driver is just a DWORD, copied directly
> from the user-mode application. It gets passed through to you
> unchanged. So, either you are not printing what you think you are
> printing, or the user-mode application isn’t sending what you think it
> is sending.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> 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://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>

Igal Kroyter wrote:

I am printing the ioctl code at the same place. Moreover, I am sending
a different code from a user mode application a different code which
composed as following:

#define IOCTL_GET_VERSIONCTL_CODE( MY_FILE_DEVICE,
BUILD_FUNCTION(GET_VERSION),METHOD_BUFFERED, FILE_ANY_ACCESS )
#define IOCTL_READ_BIT_REGISTERCTL_CODE( MY_FILE_DEVICE,
BUILD_FUNCTION(READ_BIT_REGISTER),METHOD_BUFFERED, FILE_ANY_ACCESS )

#define BUILD_FUNCTION(function) (0x800|(function &
0x7FF))
#define MY_FILE_DEVICE (0x8001)

#define GET_VERSION(0x01)
#define READ_BIT_REGISTER(0x02)

when I send IOCTL_GET_VERSION I receive in the callback 0x1
when I send IOCTL_READ_BIT_REGISTER I receive in the callback 0x80012008

Then I’m pretty sure your user-mode application is actually sending
GET_VERSION, not IOCTL_GET_VERSION.

This is one reason why I don’t do the definitions like that. Too easy
to confuse them.

// 80012004
#define IOCTL_GET_VERSION CTL_CODE( MY_FILE_DEVICE, 0x01,
METHOD_BUFFERED, FILE_ANY_ACCESS )
// 80012008
#define IOCTL_READ_BIT_REGISTER CTL_CODE( MY_FILE_DEVICE, 0x02,
METHOD_BUFFERED, FILE_ANY_ACCESS )


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

Tim,

As always correct, and thanks for the tip.

Igal