I have 2 drivers and 1 user mode application, one driver
runs in NT, one driver runs in Win2K and Win2003, they
share some common codes. The application uses IOCTLs to
communicate with driver.

There is an IOCTL, if device is in a specific internal
state, this IOCTL fails and the driver return
STATUS_INVALID_PARAMETER to system, but the driver also
return some internal error information to application,
this information is returned through output buffer
argument when calling IODeviceControl. In Windows NT,
this error information can be returned to application, so
when this IOCTL fails, the application can tell user why
it fails. In Windows 2000(SP4) and Windows 2003, this
error information cannot be returned to application, the
result is when this IOCTL fails, the application tells
user "unknown error", this is very bad.

This IOCTL uses BUFFERD_IO to communicate with kernel, I
wonder if this is because of security reason, when an
IOCTL fails, Win2K(sp4) and Win2003 doesn't copy the data
in kernel buffer to user mode buffer, but Windows NT still
does that?

Thanks.

RE: Code works in NT doesn't work in Win2K(SP4) and Win2003 by bburgin

bburgin
Fri Aug 01 19:59:38 CDT 2003

------=_NextPart_0001_51A623E0
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

This is by design, if an error is returned, then the system buffer is not
copied back. I'm submitting this to the DDK documentation folks so that
this is documented.

Bryan S. Burgin
bburgin@microsoft.com

This posting is provided "AS IS" with no warranties, and confers no rights.
------=_NextPart_0001_51A623E0
Content-Type: text/x-rtf
Content-Transfer-Encoding: 7bit

{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fprq2\fcharset0 MS Sans Serif;}}
\viewkind4\uc1\pard\f0\fs20 This is by design, if an error is returned, then the system buffer is not copied back. I'm submitting this to the DDK documentation folks so that this is documented.
\par
\par Bryan S. Burgin
\par bburgin@microsoft.com
\par
\par This posting is provided "AS IS" with no warranties, and confers no rights.
\par
\par }
------=_NextPart_0001_51A623E0--


Re: Code works in NT doesn't work in Win2K(SP4) and Win2003 by Maxim

Maxim
Fri Aug 01 20:02:09 CDT 2003

> state, this IOCTL fails and the driver return
> STATUS_INVALID_PARAMETER to system, but the driver also
> return some internal error information to application,
> this information is returned through output buffer
> argument when calling IODeviceControl.

You cannot do this, it works by mere accident. Return STATUS_SUCCESS and design
the private way of returning the additional failure info.

Max



Re: Code works in NT doesn't work in Win2K(SP4) and Win2003 by Alexei

Alexei
Fri Aug 01 20:51:52 CDT 2003

You can define you IOCTL as METHOD_NEITHER, in this case you will directly
update user buffer.

Alexei.

"wenhua" <liu_wenhua@sina.com> wrote in message
news:058401c35887$f1d986e0$a101280a@phx.gbl...
> I have 2 drivers and 1 user mode application, one driver
> runs in NT, one driver runs in Win2K and Win2003, they
> share some common codes. The application uses IOCTLs to
> communicate with driver.
>
> There is an IOCTL, if device is in a specific internal
> state, this IOCTL fails and the driver return
> STATUS_INVALID_PARAMETER to system, but the driver also
> return some internal error information to application,
> this information is returned through output buffer
> argument when calling IODeviceControl. In Windows NT,
> this error information can be returned to application, so
> when this IOCTL fails, the application can tell user why
> it fails. In Windows 2000(SP4) and Windows 2003, this
> error information cannot be returned to application, the
> result is when this IOCTL fails, the application tells
> user "unknown error", this is very bad.
>
> This IOCTL uses BUFFERD_IO to communicate with kernel, I
> wonder if this is because of security reason, when an
> IOCTL fails, Win2K(sp4) and Win2003 doesn't copy the data
> in kernel buffer to user mode buffer, but Windows NT still
> does that?
>
> Thanks.
>



Re: Code works in NT doesn't work in Win2K(SP4) and Win2003 by Maxim

Maxim
Fri Aug 01 21:56:27 CDT 2003

No data is returned to the caller if the IRP is completed with something other
then STATUS_SUCCESS. It worked on NT4 by mere luck.

If your app/driver interface relies on passing data back to the app, while
completing with error status - it needs remake.

Max

"wenhua" <liu_wenhua@sina.com> wrote in message
news:05c901c3589d$ecb76ea0$a301280a@phx.gbl...
> I have many applications depending on this driver, if I
> redefine this IOCTL as METHOD_NEITHER, all applications
> must be changed.
>
> I searched DDK(build 3718) sample code, found that in file
> \WINDDK\3718\src\storage\fdc\fdc\acpi.c,
> IOCTL_ACPI_ASYNC_EVAL_METHOD is defined as
> METHOD_BUFFERED, but the code handling this IOCTL uses Irp-
> >AssociatedIrp.SystemBuffer as input buffer and Irp-
> >UserBuffer as output buffer.
>
> I wonder in what condition I can use system buffer and
> user buffer as input and output for METHOD_BUFFERED IOCTLs.
>
> Thanks in advance.
>
> >-----Original Message-----
> >I have 2 drivers and 1 user mode application, one driver
> >runs in NT, one driver runs in Win2K and Win2003, they
> >share some common codes. The application uses IOCTLs to
> >communicate with driver.
> >
> >There is an IOCTL, if device is in a specific internal
> >state, this IOCTL fails and the driver return
> >STATUS_INVALID_PARAMETER to system, but the driver also
> >return some internal error information to application,
> >this information is returned through output buffer
> >argument when calling IODeviceControl. In Windows NT,
> >this error information can be returned to application, so
> >when this IOCTL fails, the application can tell user why
> >it fails. In Windows 2000(SP4) and Windows 2003, this
> >error information cannot be returned to application, the
> >result is when this IOCTL fails, the application tells
> >user "unknown error", this is very bad.
> >
> >This IOCTL uses BUFFERD_IO to communicate with kernel, I
> >wonder if this is because of security reason, when an
> >IOCTL fails, Win2K(sp4) and Win2003 doesn't copy the data
> >in kernel buffer to user mode buffer, but Windows NT
> still
> >does that?
> >
> >Thanks.
> >
> >.
> >



Re: Code works in NT doesn't work in Win2K(SP4) and Win2003 by Alexei

Alexei
Fri Aug 01 21:55:52 CDT 2003


> I searched DDK(build 3718) sample code, found that in file
> \WINDDK\3718\src\storage\fdc\fdc\acpi.c,
> IOCTL_ACPI_ASYNC_EVAL_METHOD is defined as
> METHOD_BUFFERED, but the code handling this IOCTL uses Irp-
> >AssociatedIrp.SystemBuffer as input buffer and Irp-
> >UserBuffer as output buffer.
>
> I wonder in what condition I can use system buffer and
> user buffer as input and output for METHOD_BUFFERED IOCTLs.
>

You can use this if you don't rely on IoManager to handle IRP for you. If
you allocated IRP using IoAlocateIrp you can fill information in it as you
pleased, given that whoever recieves the IRP knows your rules. You have no
way to use this for Applacation to driver comunication, it can be used only
for Driver to Driver communication.

Alexei.



Code works in NT doesn't work in Win2K(SP4) and Win2003 by wenhua

wenhua
Sat Aug 02 02:46:36 CDT 2003

Thanks for all your help. Now I have to decide how to fix
the problem.

Again, thanks for all your help.

>-----Original Message-----
>I have 2 drivers and 1 user mode application, one driver
>runs in NT, one driver runs in Win2K and Win2003, they
>share some common codes. The application uses IOCTLs to
>communicate with driver.
>
>There is an IOCTL, if device is in a specific internal
>state, this IOCTL fails and the driver return
>STATUS_INVALID_PARAMETER to system, but the driver also
>return some internal error information to application,
>this information is returned through output buffer
>argument when calling IODeviceControl. In Windows NT,
>this error information can be returned to application, so
>when this IOCTL fails, the application can tell user why
>it fails. In Windows 2000(SP4) and Windows 2003, this
>error information cannot be returned to application, the
>result is when this IOCTL fails, the application tells
>user "unknown error", this is very bad.
>
>This IOCTL uses BUFFERD_IO to communicate with kernel, I
>wonder if this is because of security reason, when an
>IOCTL fails, Win2K(sp4) and Win2003 doesn't copy the data
>in kernel buffer to user mode buffer, but Windows NT
still
>does that?
>
>Thanks.
>
>.
>

Re: Code works in NT doesn't work in Win2K(SP4) and Win2003 by Mark

Mark
Sat Aug 02 09:04:39 CDT 2003

On Sat, 2 Aug 2003 00:46:36 -0700, "wenhua" <liu_wenhua@sina.com>
wrote:

>Thanks for all your help. Now I have to decide how to fix
>the problem.
>
>Again, thanks for all your help.
>
>>-----Original Message-----
>>I have 2 drivers and 1 user mode application, one driver
>>runs in NT, one driver runs in Win2K and Win2003, they
>>share some common codes. The application uses IOCTLs to
>>communicate with driver.
>>
>>There is an IOCTL, if device is in a specific internal
>>state, this IOCTL fails and the driver return
>>STATUS_INVALID_PARAMETER to system, but the driver also
>>return some internal error information to application,
>>this information is returned through output buffer
>>argument when calling IODeviceControl. In Windows NT,
>>this error information can be returned to application, so
>>when this IOCTL fails, the application can tell user why
>>it fails. In Windows 2000(SP4) and Windows 2003, this
>>error information cannot be returned to application, the
>>result is when this IOCTL fails, the application tells
>>user "unknown error", this is very bad.
>>
>>This IOCTL uses BUFFERD_IO to communicate with kernel, I
>>wonder if this is because of security reason, when an
>>IOCTL fails, Win2K(sp4) and Win2003 doesn't copy the data
>>in kernel buffer to user mode buffer, but Windows NT
>still
>>does that?
>>
You can return a ULONG value to the program in
Irp->IoStatus.Information. STATUS_BUFFER_TOO_SMALL and perhaps
STATUS_BUFFER_OVERFLOW are used in many APIs as indications that the
needed length is in Information. If you need to pass more than a
ULONG, then you should complete the IRP with STATUS_SUCCESS and use an
internal field to communicate the 'real results'.

Other options that attempt to bypass buffer management by using
UserBuffer or by embedding pointers into user space in the
InputBuffer, are fragile and should not be considered for production
code.




=====================
Mark Roddy
Windows XP/2000/NT Consulting, Microsoft DDK MVP
Hollis Technology Solutions 603-321-1032
www.hollistech.com
markr@hollistech.com
For Windows Device Driver Training: see www.azius.com

Code works in NT doesn't work in Win2K(SP4) and Win2003 by wenhua

wenhua
Mon Aug 04 14:17:07 CDT 2003

I checked the definitions of IRP and IO_STACK_LOCATION and
found the following:

//
// I/O Request Packet (IRP) definition
//

typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT)
_IRP {

...

//
// Note that the UserBuffer parameter is outside of
the stack so that I/O
// completion can copy data back into the user's
address space without
// having to know exactly which service was being
invoked. The length
// of the copy is stored in the second half of the I/O
status block. If
// the UserBuffer field is NULL, then no copy is
performed.
//

PVOID UserBuffer;

...
} IRP, *PIRP;


typedef struct _IO_STACK_LOCATION {

...

union {

...
//
// System service parameters for:
NtDeviceIoControlFile
//
// Note that the user's output buffer is stored in
the UserBuffer field
// and the user's input buffer is stored in the
SystemBuffer field.
//

struct {
ULONG OutputBufferLength;
ULONG POINTER_ALIGNMENT InputBufferLength;
ULONG POINTER_ALIGNMENT IoControlCode;
PVOID Type3InputBuffer;
} DeviceIoControl;

...
} Parameters;

...
} IO_STACK_LOCATION, *PIO_STACK_LOCATION;

The definitions are from .NET DDK 3718. This is very
confusing, they are different from what we've talked. from
the comment of UserBuffer, looks that we can always copy
data to UserBuffer.

From the comment of DeviceIoControl in the definition of
IO_STACK_LOCATION, SystemBuffer field is the input buffer,
UserBuffer field is output buffer. The comment doesn't say
anything about METHOD_BUFFERED or METHOD_NEITHER.

I also did a test, I still defined my IOCTL as
METHOD_BUFFERED, but I used SystemBuffer as input buffer
and UserBuffer as output buffer, it worked!!!

So, which is correct?





>-----Original Message-----
>I have 2 drivers and 1 user mode application, one driver
>runs in NT, one driver runs in Win2K and Win2003, they
>share some common codes. The application uses IOCTLs to
>communicate with driver.
>
>There is an IOCTL, if device is in a specific internal
>state, this IOCTL fails and the driver return
>STATUS_INVALID_PARAMETER to system, but the driver also
>return some internal error information to application,
>this information is returned through output buffer
>argument when calling IODeviceControl. In Windows NT,
>this error information can be returned to application, so
>when this IOCTL fails, the application can tell user why
>it fails. In Windows 2000(SP4) and Windows 2003, this
>error information cannot be returned to application, the
>result is when this IOCTL fails, the application tells
>user "unknown error", this is very bad.
>
>This IOCTL uses BUFFERD_IO to communicate with kernel, I
>wonder if this is because of security reason, when an
>IOCTL fails, Win2K(sp4) and Win2003 doesn't copy the data
>in kernel buffer to user mode buffer, but Windows NT
still
>does that?
>
>Thanks.
>
>.
>

Re: Code works in NT doesn't work in Win2K(SP4) and Win2003 by Alexei

Alexei
Mon Aug 04 16:54:17 CDT 2003

Actually IoManager uses UserBuffer field internally to copy data from
SystemBuffer back to user process. While you are not supposed to use it
directly but it does work as far as IoManager doesn't overwrite your data
from SystemBuffer and you are in the context of the original process.
I have found the description of buffer allocation algorithm for IOCLT in
fsctlbuf.h that is a part of ntifs kit.

Alexei.

"wenhua" <liu_wenhua@sina.com> wrote in message
news:02fe01c35abc$feb62fd0$a401280a@phx.gbl...
> I checked the definitions of IRP and IO_STACK_LOCATION and
> found the following:
>
> //
> // I/O Request Packet (IRP) definition
> //
>
> typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT)
> _IRP {
>
> ...
>
> //
> // Note that the UserBuffer parameter is outside of
> the stack so that I/O
> // completion can copy data back into the user's
> address space without
> // having to know exactly which service was being
> invoked. The length
> // of the copy is stored in the second half of the I/O
> status block. If
> // the UserBuffer field is NULL, then no copy is
> performed.
> //
>
> PVOID UserBuffer;
>
> ...
> } IRP, *PIRP;
>
>
> typedef struct _IO_STACK_LOCATION {
>
> ...
>
> union {
>
> ...
> //
> // System service parameters for:
> NtDeviceIoControlFile
> //
> // Note that the user's output buffer is stored in
> the UserBuffer field
> // and the user's input buffer is stored in the
> SystemBuffer field.
> //
>
> struct {
> ULONG OutputBufferLength;
> ULONG POINTER_ALIGNMENT InputBufferLength;
> ULONG POINTER_ALIGNMENT IoControlCode;
> PVOID Type3InputBuffer;
> } DeviceIoControl;
>
> ...
> } Parameters;
>
> ...
> } IO_STACK_LOCATION, *PIO_STACK_LOCATION;
>
> The definitions are from .NET DDK 3718. This is very
> confusing, they are different from what we've talked. from
> the comment of UserBuffer, looks that we can always copy
> data to UserBuffer.
>
> From the comment of DeviceIoControl in the definition of
> IO_STACK_LOCATION, SystemBuffer field is the input buffer,
> UserBuffer field is output buffer. The comment doesn't say
> anything about METHOD_BUFFERED or METHOD_NEITHER.
>
> I also did a test, I still defined my IOCTL as
> METHOD_BUFFERED, but I used SystemBuffer as input buffer
> and UserBuffer as output buffer, it worked!!!
>
> So, which is correct?
>
>
>
>
>
> >-----Original Message-----
> >I have 2 drivers and 1 user mode application, one driver
> >runs in NT, one driver runs in Win2K and Win2003, they
> >share some common codes. The application uses IOCTLs to
> >communicate with driver.
> >
> >There is an IOCTL, if device is in a specific internal
> >state, this IOCTL fails and the driver return
> >STATUS_INVALID_PARAMETER to system, but the driver also
> >return some internal error information to application,
> >this information is returned through output buffer
> >argument when calling IODeviceControl. In Windows NT,
> >this error information can be returned to application, so
> >when this IOCTL fails, the application can tell user why
> >it fails. In Windows 2000(SP4) and Windows 2003, this
> >error information cannot be returned to application, the
> >result is when this IOCTL fails, the application tells
> >user "unknown error", this is very bad.
> >
> >This IOCTL uses BUFFERD_IO to communicate with kernel, I
> >wonder if this is because of security reason, when an
> >IOCTL fails, Win2K(sp4) and Win2003 doesn't copy the data
> >in kernel buffer to user mode buffer, but Windows NT
> still
> >does that?
> >
> >Thanks.
> >
> >.
> >