The MSDN documentation for lpNumberOfBytesTransferred in
GetOverlappedResult() says:

BOOL WINAPI GetOverlappedResult(
__in HANDLE hFile,
__in LPOVERLAPPED lpOverlapped,
__out LPDWORD lpNumberOfBytesTransferred,
__in BOOL bWait
);

>>> lpNumberOfBytesTransferred
"A pointer to a variable that receives the number of bytes that were
actually transferred by a read or *write* operation. For a
DeviceIoControl operation, this is the number of bytes of output data
returned by the device driver."

Now, for the life of me, I just don't seem to understand a very basic
issue here:

What is that mystical "the number of bytes of output data returned by
the device driver" when doing a WRITE operation (via a DeviceIoControl
call)?

Case in question: I wrote a driver that responds to DeviceIoControl()
commands, supporting overlapped I/O in both read and write directions.
With read I have no problems. However, with write, I just don't seem
to get the crux of this lpNumberOfBytesTransferred (or
IoStatus.Information in the driver).

In my driver, when I do:

pIRP->IoStatus.Information =
actualNumberWritten; // 0 <= int <= 512

The GetOverlappedResult() call on the user mode side (the application
that uses the driver) crashes the program!

But when I do:

pIRP->IoStatus.Information =
pIRPStack->Parameters.DeviceIoControl.OutputBufferLength;

The program doesn't crash.

Now... I thought that, just as the GetOverlappedResult() documentation
says, IoStatus.Information should return "the number of bytes that
were actually transferred by a write operation".

So what's going on here?

Why must IoStatus.Information, on a DeviceIoControl *write* operation,
return the size of the output buffer instead of "the number of bytes
that were actually transferred by a write operation"?

What am I missing here?

Thanks,
Don

Re: GetOverlappedResult() and IoStatus.Information by Don

Don
Wed Feb 06 10:04:47 CST 2008

Because by the nature of DeviceIoControl it is two way. If you use it with
input and output buffers the system and the application must have an idea
how much data is in the output buffer. If you want to return the number of
bytes written make that the output buffer and return sizeof(ULONG) for the
length.


--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply


<0dbell@gmail.com> wrote in message
news:ac65bf4e-a5d7-467b-b863-09adbeed0b02@k2g2000hse.googlegroups.com...
> The MSDN documentation for lpNumberOfBytesTransferred in
> GetOverlappedResult() says:
>
> BOOL WINAPI GetOverlappedResult(
> __in HANDLE hFile,
> __in LPOVERLAPPED lpOverlapped,
> __out LPDWORD lpNumberOfBytesTransferred,
> __in BOOL bWait
> );
>
>>>> lpNumberOfBytesTransferred
> "A pointer to a variable that receives the number of bytes that were
> actually transferred by a read or *write* operation. For a
> DeviceIoControl operation, this is the number of bytes of output data
> returned by the device driver."
>
> Now, for the life of me, I just don't seem to understand a very basic
> issue here:
>
> What is that mystical "the number of bytes of output data returned by
> the device driver" when doing a WRITE operation (via a DeviceIoControl
> call)?
>
> Case in question: I wrote a driver that responds to DeviceIoControl()
> commands, supporting overlapped I/O in both read and write directions.
> With read I have no problems. However, with write, I just don't seem
> to get the crux of this lpNumberOfBytesTransferred (or
> IoStatus.Information in the driver).
>
> In my driver, when I do:
>
> pIRP->IoStatus.Information =
> actualNumberWritten; // 0 <= int <= 512
>
> The GetOverlappedResult() call on the user mode side (the application
> that uses the driver) crashes the program!
>
> But when I do:
>
> pIRP->IoStatus.Information =
> pIRPStack->Parameters.DeviceIoControl.OutputBufferLength;
>
> The program doesn't crash.
>
> Now... I thought that, just as the GetOverlappedResult() documentation
> says, IoStatus.Information should return "the number of bytes that
> were actually transferred by a write operation".
>
> So what's going on here?
>
> Why must IoStatus.Information, on a DeviceIoControl *write* operation,
> return the size of the output buffer instead of "the number of bytes
> that were actually transferred by a write operation"?
>
> What am I missing here?
>
> Thanks,
> Don



Re: GetOverlappedResult() and IoStatus.Information by 0dbell

0dbell
Wed Feb 06 10:18:16 CST 2008

On Feb 6, 11:04=A0am, "Don Burn" <b...@stopspam.windrvr.com> wrote:
> Because by the nature of DeviceIoControl it is two way. =A0If you use it w=
ith
> input and output buffers the system and the application must have an idea
> how much data is in the output buffer. =A0If you want to return the number=
of
> bytes written make that the output buffer and return sizeof(ULONG) for the=

> length.
>

Thanks, Don. So if I understand you correctly, for *WRITE* operation,
"the number of bytes written" should not be returned in
lpBytesReturned (7th param in DeviceIoControl) or
lpNumberOfBytesTransferred (3rd param in GetOverlappedResult), but
rather in lpOutBuffer (5th param in DeviceIoControl).

Did I get this right?

If so, why then is the MSDN documentation so confusing? Why does it
say that lpNumberOfBytesTransferred is:

"A pointer to a variable that receives the number of bytes that were
actually transferred by a read or *write* operation. For a
DeviceIoControl operation, this is the number of bytes of output data
returned by the device driver."

When in fact it is a pointer to a variable that receives the number of
bytes that make lpOutBuffer (5th param in DeviceIoControl,
sizeof(ULONG) as you correctly pointed out)?

Is it just me that find this particular MSDN phrasing so confusing?

Thanks,
Don

Re: GetOverlappedResult() and IoStatus.Information by Don

Don
Wed Feb 06 11:05:51 CST 2008

By "WRITE" you mean a DeviceIoControl to send data by the driver, the answer
is yes. If you did an IRP_MJ_WRITE operation then the value returned is the
number of bytes sent by the driver. The two way nature of DeviceIoControl
means this is special. The MSDN documentation is describing the generic
case where a write means an IRP_MJ_WRITE operation,


--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply


<0dbell@gmail.com> wrote in message
news:6656b0e3-3dd5-40c5-9f65-95685a2845d5@d4g2000prg.googlegroups.com...
On Feb 6, 11:04 am, "Don Burn" <b...@stopspam.windrvr.com> wrote:
> Because by the nature of DeviceIoControl it is two way. If you use it with
> input and output buffers the system and the application must have an idea
> how much data is in the output buffer. If you want to return the number of
> bytes written make that the output buffer and return sizeof(ULONG) for the
> length.
>

Thanks, Don. So if I understand you correctly, for *WRITE* operation,
"the number of bytes written" should not be returned in
lpBytesReturned (7th param in DeviceIoControl) or
lpNumberOfBytesTransferred (3rd param in GetOverlappedResult), but
rather in lpOutBuffer (5th param in DeviceIoControl).

Did I get this right?

If so, why then is the MSDN documentation so confusing? Why does it
say that lpNumberOfBytesTransferred is:

"A pointer to a variable that receives the number of bytes that were
actually transferred by a read or *write* operation. For a
DeviceIoControl operation, this is the number of bytes of output data
returned by the device driver."

When in fact it is a pointer to a variable that receives the number of
bytes that make lpOutBuffer (5th param in DeviceIoControl,
sizeof(ULONG) as you correctly pointed out)?

Is it just me that find this particular MSDN phrasing so confusing?

Thanks,
Don



Re: GetOverlappedResult() and IoStatus.Information by Maxim

Maxim
Wed Feb 06 11:11:38 CST 2008

>Thanks, Don. So if I understand you correctly, for *WRITE* operation,
>"the number of bytes written" should not be returned in
>lpBytesReturned (7th param in DeviceIoControl)

This parameter is the number of bytes in OutputBuffer actually filled by the
driver (Irp->IoStatus.Information)

>lpNumberOfBytesTransferred (3rd param in GetOverlappedResult),

This is the same as above.

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


Re: GetOverlappedResult() and IoStatus.Information by 0dbell

0dbell
Wed Feb 06 13:39:53 CST 2008

On Feb 6, 12:05=A0pm, "Don Burn" <b...@stopspam.windrvr.com> wrote:
> By "WRITE" you mean a DeviceIoControl to send data by the driver, the answ=
er
> is yes. =A0If you did an IRP_MJ_WRITE operation then the value returned is=
the
> number of bytes sent by the driver. =A0 The two way nature of DeviceIoCont=
rol
> means this is special. =A0The MSDN documentation is describing the generic=

> case where a write means an IRP_MJ_WRITE operation,
>

Yes, by "WRITE" I meant a DeviceIoControl to send data by the driver.

OK, so now I understand that the MSDN documentation was describing
only the generic case where a write means an IRP_MJ_WRITE operation,
but then why did it say: "for DeviceIoControl() operation, this is the
number of bytes of output data returned by the device driver."?

In other words, it did attempt to refer to DeviceIoControl() as well.

Except that the phrase "the number of bytes of output data returned by
the device driver" was not clear to me (now it is)".

I am not trying to be neat-picking, just understand why couldn't I
understand from the MSDN documentation something that I should have
understood.

Thanks to you and Maxim the meaning of Irp->IoStatus.Information in
DeviceIoControl *WRITE* operation is now clear to me.

But I somehow feel dumb that I couldn't grasp it immediately from the
documentation.

Thanks,
Don