DeviceIoControl always return 87, invalid parameter!

Hello!

I try to send message from User mode to Kernel mode by using IOCTL.
My problem is in my user process when I use DeviceIoControl it always returning 87, invalid parameter. I have copied the IOCTL example from the wddk and compiling it in Visual Studio.
Could any body tell me what parameter is wrong?

char OutputBuffer[100];
char InputBuffer[100];
hDevice = CreateFile( (LPCTSTR)“\\.\IoctlTest”,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
DeviceIoControl ( hDevice,
(DWORD) IOCTL_SIOCTL_METHOD_NEITHER,
&InputBuffer,
strlen ( InputBuffer )+1,
&OutputBuffer,
sizeof( OutputBuffer),
&bytesReturned,
NULL);

What can it be?
Best regards
Mattias Bergkvist

Mattias,

I doubt that the error code is coming from the user mode process,
DeviceIoControl() won’t do any parameter checking in user mode and
once the transition is made to kernel mode it will just plug the
passed in values to an IRP and send it down to the open device.

If you look in the driver where the IRP is handled,
SioctlDeviceControl() you will see the following:

if (!inBufLength || !outBufLength)
{
ntStatus = STATUS_INVALID_PARAMETER;
goto End;
}

My guess is that this is where the status code is coming from. Try
adding some debug in both user mode and kernel mode to check
precisely what values for these variables are being sent from user
mode and presented to the driver.

The sample driver is quite good at showing how the different ioctl
types need to be handled, but like quite a few of the user mode code
samples, testapp.c is not of the greatest quality. If you’ve added
some of your own code to the test sample, trace everything you’ve
done to find out what you might have affected.

Oh, and one thing more. If you’re just using the sample “as is”, why
don’t you try compiling in a WDK command line with build.exe ? It’s
how the sample is given in the WDK and removes any concerns about
getting the VS options correct.

Mark.

At 08:43 14/05/2008, you wrote:

Hello!

I try to send message from User mode to Kernel mode by using IOCTL.
My problem is in my user process when I use DeviceIoControl it
always returning 87, invalid parameter. I have copied the IOCTL
example from the wddk and compiling it in Visual Studio.
Could any body tell me what parameter is wrong?

char OutputBuffer[100];
char InputBuffer[100];
hDevice = CreateFile( (LPCTSTR)“\\.\IoctlTest”,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
DeviceIoControl ( hDevice,
(DWORD) IOCTL_SIOCTL_METHOD_NEITHER,
&InputBuffer,
strlen ( InputBuffer )+1,
&OutputBuffer,
sizeof( OutputBuffer),
&bytesReturned,
NULL);

What can it be?
Best regards
Mattias Bergkvist

If the code segment below is the actual code in your user mode test
application it has a lot of problems. The most obvious problem is that you
are using &OutputBuffer and &InputBuffer as parameter values to
DeviceIoControl when you should instead just be using OutputBuffer and
InputBuffer. In addition you do not appear to initalize InpuBuffer with a
string but you determine the size of the IOCTL input using
strlen(InputBuffer). Finally, you call CreateFile but you do not test the
return value and instead just use hDevice regardless of whether the call to
CreateFile was successful or not.

On Wed, May 14, 2008 at 3:43 AM, wrote:

> Hello!
>
> I try to send message from User mode to Kernel mode by using IOCTL.
> My problem is in my user process when I use DeviceIoControl it always
> returning 87, invalid parameter. I have copied the IOCTL example from the
> wddk and compiling it in Visual Studio.
> Could any body tell me what parameter is wrong?
>
> char OutputBuffer[100];
> char InputBuffer[100];
> hDevice = CreateFile( (LPCTSTR)“\\.\IoctlTest”,
> GENERIC_READ | GENERIC_WRITE,
> 0,
> NULL,
> CREATE_ALWAYS,
> FILE_ATTRIBUTE_NORMAL,
> NULL);
> DeviceIoControl ( hDevice,
> (DWORD) IOCTL_SIOCTL_METHOD_NEITHER,
> &InputBuffer,
> strlen ( InputBuffer )+1,
> &OutputBuffer,
> sizeof( OutputBuffer),
> &bytesReturned,
> NULL);
>
> What can it be?
> Best regards
> Mattias Bergkvist
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule debugging and file system seminars
> (including our new fs mini-filter seminar) visit:
> http://www.osr.com/seminars
>
> You are currently subscribed to ntfsd as: xxxxx@hollistech.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>


Mark Roddy

Those code snippets are straight from the WDK sample, without modification !!!

Of course, the sample does have some lines in between CreateFile and
DeviceIoControl setting up a string inside InputBuffer. I assume the
OP has the same lines since he appears to be working from the sample

  • though that may be a bad assumption.

When you look at the quality of the sample in the WDK, it’s no great
surprise to find people not understanding proper practice when it
comes to communicating with drivers. Fortunately, the accompanying
driver sample is much tighter.

Mark.

At 11:57 14/05/2008, you wrote:

If the code segment below is the actual code in your user mode test
application it has a lot of problems. The most obvious problem is
that you are using &OutputBuffer and &InputBuffer as parameter
values to DeviceIoControl when you should instead just be using
OutputBuffer and InputBuffer. In addition you do not appear to
initalize InpuBuffer with a string but you determine the size of the
IOCTL input using strlen(InputBuffer). Finally, you call CreateFile
but you do not test the return value and instead just use hDevice
regardless of whether the call to CreateFile was successful or not.

On Wed, May 14, 2008 at 3:43 AM,
<mailto:xxxxxxxxxx@netcleantech.com>
>wrote:
>Hello!
>
>I try to send message from User mode to Kernel mode by using IOCTL.
>My problem is in my user process when I use DeviceIoControl it
>always returning 87, invalid parameter. I have copied the IOCTL
>example from the wddk and compiling it in Visual Studio.
>Could any body tell me what parameter is wrong?
>
>char OutputBuffer[100];
>char InputBuffer[100];
>hDevice = CreateFile( (LPCTSTR)“\\.\IoctlTest”,
> GENERIC_READ | GENERIC_WRITE,
> 0,
> NULL,
> CREATE_ALWAYS,
> FILE_ATTRIBUTE_NORMAL,
> NULL);
>DeviceIoControl ( hDevice,
> (DWORD) IOCTL_SIOCTL_METHOD_NEITHER,
> &InputBuffer,
> strlen ( InputBuffer )+1,
> &OutputBuffer,
> sizeof( OutputBuffer),
> &bytesReturned,
> NULL);
>
>What can it be?
>Best regards
>Mattias Bergkvist</mailto:xxxxx>

Mark S. Edwards
You have right that this code have some lines between CreateFile and
DeviceIoControl. Sorry if I was unclear.

I have now tested to compile the IOCTL example in Visual Studio. I put the TestApp user mode code in a new project and compile it. The kernel mode code is compiled as usual in the checked build environment. I install the driver and start my TestApp. The return value is 87 invalid value.

So my conclusion is that it works when I compile in checked build environment but not in VS.
The code is the same so it most be the compiler that are doing something different here.

Are there someone that know what I am missing here?

Best regards
Mattias Bergkvist

Mattias,

Can’t help with regard to setting up VS, I never use it, I prefer
different methods. It’s not the compiler that’s wrong but the
settings you have directing what the compiler and linker produce that
are wrong.

However, I go back to my first reply. DeviceIoControl() does nothing
more than marshall the arguments in to kernel mode where the IRP is
constructed.

Provided the call to CreateFile succeeded, then the error value is
being returned by the driver and since the driver only sets that
error code in one place it’s quite easy to see what causes a failure.

Somehow, one or both the buffer lengths used in the DeviceIoControl
call resolves to zero. Try tracing values in both user and kernel
modes to see what’s going wrong.

Another sometimes useful option is to set the compiler to produce
.COD files, then you can really see what you’ve told the compiler to do.

Mark.

At 14:17 14/05/2008, you wrote:

Mark S. Edwards
You have right that this code have some lines between CreateFile and
DeviceIoControl. Sorry if I was unclear.

I have now tested to compile the IOCTL example in Visual Studio. I
put the TestApp user mode code in a new project and compile it. The
kernel mode code is compiled as usual in the checked build
environment. I install the driver and start my TestApp. The return
value is 87 invalid value.

So my conclusion is that it works when I compile in checked build
environment but not in VS.
The code is the same so it most be the compiler that are doing
something different here.

Are there someone that know what I am missing here?

Best regards
Mattias Bergkvist

Actually, (of course since all the code isn’t shown, all anyone can do is guess, which is usually a massive awaste of everyone’s time)- I’d say the most likely cause given the code snippet shown and symptoms reported is that CreateFile failed. INVALID_HANDLE_VALUE as a file handle is most certain to be rejected by DeviceIoControl with ERROR_INVALID_PARAMETER, and there’s no evidence this code tests for this.

Next most likely (IMO) is that the driver returned the code when validating the input.

Use OPEN_EXISTING instead of CREATE_ALWAYS in CreateFile

Harish

-----Original Message-----
From: xxxxx@netcleantech.com
[mailto:xxxxx@netcleantech.com]
Sent: Wednesday, May 14, 2008 12:44 AM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] DeviceIoControl always return 87, invalid parameter!

Hello!

I try to send message from User mode to Kernel mode by using IOCTL.
My problem is in my user process when I use DeviceIoControl it always
returning 87, invalid parameter. I have copied the IOCTL example from
the wddk and compiling it in Visual Studio.
Could any body tell me what parameter is wrong?

char OutputBuffer[100];
char InputBuffer[100];
hDevice = CreateFile( (LPCTSTR)“\\.\IoctlTest”,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
DeviceIoControl ( hDevice,
(DWORD) IOCTL_SIOCTL_METHOD_NEITHER,
&InputBuffer,
strlen ( InputBuffer )+1,
&OutputBuffer,
sizeof( OutputBuffer),
&bytesReturned,
NULL);

What can it be?
Best regards
Mattias Bergkvist


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars (including our new
fs mini-filter seminar) visit:
http://www.osr.com/seminars

You are currently subscribed to ntfsd as: xxxxx@netapp.com To
unsubscribe send a blank email to xxxxx@lists.osr.com

That’s just one of the many things that are wrong with the code. But
as I pointed out, the code below is taken directly from the WDK
sample !!! The OP hasn’t changed a single character.

At 18:30 14/05/2008, you wrote:

Use OPEN_EXISTING instead of CREATE_ALWAYS in CreateFile

Harish

-----Original Message-----
From: xxxxx@netcleantech.com
[mailto:xxxxx@netcleantech.com]
Sent: Wednesday, May 14, 2008 12:44 AM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] DeviceIoControl always return 87, invalid parameter!

Hello!

I try to send message from User mode to Kernel mode by using IOCTL.
My problem is in my user process when I use DeviceIoControl it always
returning 87, invalid parameter. I have copied the IOCTL example from
the wddk and compiling it in Visual Studio.
Could any body tell me what parameter is wrong?

char OutputBuffer[100];
char InputBuffer[100];
hDevice = CreateFile( (LPCTSTR)“\\.\IoctlTest”,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
DeviceIoControl ( hDevice,
(DWORD) IOCTL_SIOCTL_METHOD_NEITHER,
&InputBuffer,
strlen ( InputBuffer )+1,
&OutputBuffer,
sizeof( OutputBuffer),
&bytesReturned,
NULL);

What can it be?
Best regards
Mattias Bergkvist

> application it has a lot of problems. The most obvious problem is that you

are using &OutputBuffer and &InputBuffer as parameter values to
DeviceIoControl when you should instead just be using OutputBuffer and
InputBuffer.

For arrays, this is the same.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

>INVALID_HANDLE_VALUE as a file handle is most certain to be rejected by

DeviceIoControl with ERROR_INVALID_PARAMETER

I think “invalid handle” is another error code.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

The problem is that VS creates a UNICODE project and your code will compile
like this:

hDevice = CreateFileW( (LPCWSTR)“\\.\IoctlTest”,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);

You’re casting ASCII string to unicode. The flag “CREATE_ALWAYS” yields to
handle of a “new file” with chinese characters instead of opening the
device. Sending the control code to this newly created file you’ll receive
error code 87.

wrote news:xxxxx@ntfsd…
> Hello!
>
> I try to send message from User mode to Kernel mode by using IOCTL.
> My problem is in my user process when I use DeviceIoControl it always
> returning 87, invalid parameter. I have copied the IOCTL example from the
> wddk and compiling it in Visual Studio.
> Could any body tell me what parameter is wrong?
>
> char OutputBuffer[100];
> char InputBuffer[100];
> hDevice = CreateFile( (LPCTSTR)“\\.\IoctlTest”,
> GENERIC_READ | GENERIC_WRITE,
> 0,
> NULL,
> CREATE_ALWAYS,
> FILE_ATTRIBUTE_NORMAL,
> NULL);
> DeviceIoControl ( hDevice,
> (DWORD) IOCTL_SIOCTL_METHOD_NEITHER,
> &InputBuffer,
> strlen ( InputBuffer )+1,
> &OutputBuffer,
> sizeof( OutputBuffer),
> &bytesReturned,
> NULL);
>
> What can it be?
> Best regards
> Mattias Bergkvist
>

Sorry again if I am unclear, but I do all the necessary error handling.
I check the returned handle from CreateFile for INVALID_HANDLE_VALUE. And I initiate the arrays before I call DeviceIoControl.
I have copied the IOCTL example and no modification is don to it.

Mattias Bergkvist

Frank
Thank you, you have absolutely right that it was UNICODE project and I have changed it now and it all works fine.

Mattias Bergkvist

yeah that’s true. Wrong looking, but true.

On Wed, May 14, 2008 at 11:43 PM, Maxim S. Shatskih
wrote:

> > application it has a lot of problems. The most obvious problem is that
> you
> > are using &OutputBuffer and &InputBuffer as parameter values to
> > DeviceIoControl when you should instead just be using OutputBuffer and
> > InputBuffer.
>
> For arrays, this is the same.
>
> –
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
> —
> NTFSD is sponsored by OSR
>
> For our schedule debugging and file system seminars
> (including our new fs mini-filter seminar) visit:
> http://www.osr.com/seminars
>
> You are currently subscribed to ntfsd as: xxxxx@hollistech.com
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>


Mark Roddy

This is where renaming your c files to cpp becomes handy, to catch errors and poor written code like this. In cpp this will not compile, I have doubts if the C compiler will always resolve &OutputBuffer to &OutputBuffer[0]. Although tolerated, even passing an array as a pointer (just OutputBuffer) I consider much ambiguous.

/Daniel

“Mark Roddy” wrote in message news:xxxxx@ntfsd…
yeah that’s true. Wrong looking, but true.

On Wed, May 14, 2008 at 11:43 PM, Maxim S. Shatskih wrote:

> application it has a lot of problems. The most obvious problem is that you
> are using &OutputBuffer and &InputBuffer as parameter values to
> DeviceIoControl when you should instead just be using OutputBuffer and
> InputBuffer.

For arrays, this is the same.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com


NTFSD is sponsored by OSR

For our schedule debugging and file system seminars
(including our new fs mini-filter seminar) visit:
http://www.osr.com/seminars

You are currently subscribed to ntfsd as: xxxxx@hollistech.com

To unsubscribe send a blank email to xxxxx@lists.osr.com


Mark Roddy

>written code like this. In cpp this will not compile, I have doubts if the C
compiler

will always resolve &OutputBuffer to &OutputBuffer[0].

For arrays ( char OutputBuffer[10]; ), it is always so.

For pointers ( char* OutputBuffer; ) - not so.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com