DeviceIoControl return code using Overlapped I/O

So, I’ve read and re-read the documentation pertaining to Overlapped I/O operation for IOCTL requests here:

http://msdn.microsoft.com/en-us/library/aa363216(VS.85).aspx

And, even though I see the statement:

“Return Value
If the operation completes successfully, the return value is nonzero.
If the operation fails or is pending, the return value is zero. To get extended error information, call GetLastError.”

I’m not clear on how I handle errors returned from an overlapped DeviceIoControl() call. It looks like I get a ‘0’ back for a successful overlapped call, which typically means fail for non-overlapped operation. Is this basically telling me the call is ‘pending’, since it’s waiting for my driver to ‘singal’ the handle associated w/ the overlapped call?

If my overlapped DeviceIoControl() call fails because of whatever reason (bad handle or something), what is the return code?

I just want to ensure that I handle the return code properly. :slight_smile:

Here’s an excerpt of my code using the inverted call method:

Board::Board()
{

handle_ = CreateFile(DEV_NAME,
access, share, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

}

void BoardImpl::signalAtTimeCode(VideoTimeCode vtc, HANDLE h)
{
ULONG nbytes;
TimeCodeSignalParams tcsp;

// We do this so that we can associate the even handle, h, with
// this IOCTL request. The driver will pend the irp, and signal
// the handle when the proper VITC comes around.
OVERLAPPED overlapped;
overlapped.Offset = 0;
overlapped.OffsetHigh = 0;
overlapped.hEvent = h;

tcsp.handle = handle_;
tcsp.eventHandle = h;
tcsp.signalTime.hour = vtc.hour;
tcsp.signalTime.minute = vtc.minute;
tcsp.signalTime.second = vtc.second;
tcsp.signalTime.frame = vtc.frame;

// This will return immediately…
ULONG rc = DeviceIoControl(
handle_, IOCTL_TSII_BOARD_SIGNAL_AT_TIMECODE,
&tcsp, sizeof(tcsp), NULL, NULL, &nbytes, &overlapped);

// How do I handle this???
if (rc == 0)
{
if (GetLastError() == ???)
{
throw Exception(“overlapped i/o exception\n”);
}
}
}

Thanks guys!

Jason

The error back will be ERROR_IO_PENDING check for this if it is any other
value it is a real error. For that wait on the event or use
GetCompletionStatus.


Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

wrote in message news:xxxxx@ntdev…
> So, I’ve read and re-read the documentation pertaining to Overlapped I/O
> operation for IOCTL requests here:
>
> http://msdn.microsoft.com/en-us/library/aa363216(VS.85).aspx
>
> And, even though I see the statement:
>
> “Return Value
> If the operation completes successfully, the return value is nonzero.
> If the operation fails or is pending, the return value is zero. To get
> extended error information, call GetLastError.”
>
> I’m not clear on how I handle errors returned from an overlapped
> DeviceIoControl() call. It looks like I get a ‘0’ back for a successful
> overlapped call, which typically means fail for non-overlapped operation.
> Is this basically telling me the call is ‘pending’, since it’s waiting for
> my driver to ‘singal’ the handle associated w/ the overlapped call?
>
> If my overlapped DeviceIoControl() call fails because of whatever reason
> (bad handle or something), what is the return code?
>
> I just want to ensure that I handle the return code properly. :slight_smile:
>
> Here’s an excerpt of my code using the inverted call method:
>
> Board::Board()
> {
> …
> handle_ = CreateFile(DEV_NAME,
> access, share, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
> …
> }
>
> void BoardImpl::signalAtTimeCode(VideoTimeCode vtc, HANDLE h)
> {
> ULONG nbytes;
> TimeCodeSignalParams tcsp;
>
> // We do this so that we can associate the even handle, h, with
> // this IOCTL request. The driver will pend the irp, and signal
> // the handle when the proper VITC comes around.
> OVERLAPPED overlapped;
> overlapped.Offset = 0;
> overlapped.OffsetHigh = 0;
> overlapped.hEvent = h;
>
> tcsp.handle = handle_;
> tcsp.eventHandle = h;
> tcsp.signalTime.hour = vtc.hour;
> tcsp.signalTime.minute = vtc.minute;
> tcsp.signalTime.second = vtc.second;
> tcsp.signalTime.frame = vtc.frame;
>
> // This will return immediately…
> ULONG rc = DeviceIoControl(
> handle_, IOCTL_TSII_BOARD_SIGNAL_AT_TIMECODE,
> &tcsp, sizeof(tcsp), NULL, NULL, &nbytes, &overlapped);
>
> // How do I handle this???
> if (rc == 0)
> {
> if (GetLastError() == ???)
> {
> throw Exception(“overlapped i/o exception\n”);
> }
> }
> }
>
> Thanks guys!
>
> Jason
>
>
>
>
>
> Information from ESET NOD32 Antivirus, version of virus
> signature database 4493 (20091009)

>
> The message was checked by ESET NOD32 Antivirus.
>
> http://www.eset.com
>
>
>

Information from ESET NOD32 Antivirus, version of virus signature database 4493 (20091009)

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com

Cool, thanks Don! :slight_smile:

Jason

You could also use GetOverlappedResult function.
Your code could look as following

// This will return immediately…
ULONG rc = DeviceIoControl( handle_, IOCTL_TSII_BOARD_SIGNAL_AT_TIMECODE, &tcsp, sizeof(tcsp), NULL, NULL, &nbytes, &overlapped); // How do I handle this???
if (rc == 0){
if (GetLastError() != ERROR_IO_PENDING) {
throw Exception(“overlapped i/o exception\n”);

}
}
DWORD transf_byte;
if(GetOverlappedResult(handle_,&overlapped,&transf_byte,TRUE) == 0)
{ //ERROR

}

Ahh…that’s a good option for my driver ‘goody bag’ too. Thanks Igor!

> If my overlapped DeviceIoControl() call fails because of whatever reason (bad handle or something),

what is the return code?

Any code from DeviceIoControl except success and ERROR_IO_PENDING is immediate failure, you do not need to wait for overlapped IO to complete in this case.

In case of ERROR_IO_PENDING, you should wait and the final error code will be returned by GetOverlappedResult.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

If you use multiple threads with overlapped io you should watch for a few bugs. I ran into this one. I don’t remember exactly what I had to do to code around it but I think a call to GetOverlappedResult returned an error even though the IO hadn’t completed yet.

The Overlapped IO documentation suggests that you don’t actually need an event for every IO, but I had to go back and add one for every call and wait every time.

>Clipped from Microsoft
See also: Win7 fix for a bug introduced in Vista
http://msdn.microsoft.com/en-us/library/dd371711(VS.85).aspx

?Windows 7: Resolves a race condition where a multi-threaded app using GetOverlappedResult can return without resetting the event in the overlapped structure, causing the next call to this function to return prematurely.
?Windows Vista (default): Provides the behavior with the race condition that applications may have a dependency on. Applications wishing to avoid this race prior to the Windows 7 behavior should wait on the overlapped event and when signaled, call GetOverlappedResult with bWait == FALSE. "

>don’t remember exactly what I had to do to code around it but I think a call to GetOverlappedResult

returned an error even though the IO hadn’t completed yet.

Correct, ERROR_IO_PENDING.

The Overlapped IO documentation suggests that you don’t actually need an event for every IO, but I
had to go back and add one for every call and wait every time.

You can also use IOCP and Read/WriteFileEx.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com