Driver Problems? Questions? Issues?
Put OSR's experience to work for you! Contact us for assistance with:
  • Creating the right design for your requirements
  • Reviewing your existing driver code
  • Analyzing driver reliability/performance issues
  • Custom training mixed with consulting and focused directly on your specific areas of interest/concern.
Check us out. OSR, the Windows driver experts.

Monthly Seminars at OSR Headquarters

East Coast USA
Windows Internals and SW Drivers, Dulles (Sterling) VA, 13 November 2017

Kernel Debugging & Crash Analysis for Windows, Nashua (Amherst) NH, 4 December 2017

Writing WDF Drivers I: Core Concepts, Nashua (Amherst) NH, 8 January 2018

WDF Drivers II: Advanced Implementation Techniques, Nashua (Amherst) NH, 15 January 2018


Go Back   OSR Online Lists > ntdev
Welcome, Guest
You must login to post to this list
  Message 1 of 8  
17 Nov 17 09:39
Anand A
xxxxxx@gmail.com
Join Date: 05 Aug 2014
Posts To This List: 47
Correct way of accessing results for async ReadFile() that completed synchronously

ReadFile() documentation [https://msdn.microsoft.com/en-us/library/windows/desktop/aa365467(v=vs.85).aspx] says that even when called on a handle that was opened with FILE_FLAG_OVERLAPPED, the read can happen synchronously. So, for reads that have been requested as async, the following possibilities arise : 1) ReadFile() returns false and a) GetLastError() returns ERROR_HANDLE_EOF - Read completed synchronously b) GetLastError() returns ERROR_IO_PENDING - Asynch IO has been submitted - GetOverlappedResult() should be called later and that can also indicate an EOF condition c) GetLastError() returns some other error code - Read failed 2) ReadFile() returns true - Read completed synchronously. The requested bytes have been read - no EOF, no other error could have happened Now, the ReadFile() documentation says : --------------------------------------------------------------------------------- ------------ lpNumberOfBytesRead [out, optional] A pointer to the variable that receives the number of bytes read when using a synchronous hFile parameter. ReadFile sets this value to zero before doing any work or error checking. Use NULL for this parameter if this is an asynchronous operation to avoid potentially erroneous results. This parameter can be NULL only when the lpOverlapped parameter is not NULL. For more information, see the Remarks section. --------------------------------------------------------------------------------- ------------ So, it prohibits from using lpNumberOfBytesRead when requesting asynchronous read. The documentation also has a link to this [https://support.microsoft.com/en-us/help/156932/asynchronous-disk-i-o-appears-as -synchronous-on-windows] that says : --------------------------------------------------------------------------------- ------------ If, on the other hand, an operation is completed immediately, then &NumberOfBytesRead passed into ReadFile is valid for the number of bytes read. In this case, ignore the OVERLAPPED structure passed into ReadFile; do not use it with GetOverlappedResult or WaitForSingleObject. --------------------------------------------------------------------------------- ------------ So, as is usual with MSFT documentation, this is self-contradicting. Question : For 1(a) and 2, what is the correct way of accessing the number of bytes read.
  Message 2 of 8  
17 Nov 17 11:47
anton bassov
xxxxxx@hotmail.com
Join Date: 16 Jul 2006
Posts To This List: 4401
Correct way of accessing results for async ReadFile() that completed synchronously

> So, as is usual with MSFT documentation, this is self-contradicting > Question : For 1(a) and 2, what is the correct way of accessing the number of bytes read. I would say that(2) is correct.... The above contradiction lies with the fact that a driver may theoretically complete an asynch request straight away and return the actual completion status right on the spot. IIRC. according to Doron and/or other MSFT guys, the internal "convention" at MSFT is to return STATUS_PENDING regardless of what IoCallDriver() does. Once IoCallDriver() caller (I think in this particular case it is going to be someone in IoReadFile()'s path) is always able to go the above mentioned way and tp present synch IO completion as an asynch one, option (2) seems to be the only possible one in case of asynch read, no matter how underlying driver/filesystem _actually_ handles the request..... Anton Bassov
  Message 3 of 8  
17 Nov 17 11:48
anton bassov
xxxxxx@hotmail.com
Join Date: 16 Jul 2006
Posts To This List: 4401
Correct way of accessing results for async ReadFile() that completed synchronously

> I would say that(2) is correct. I mean option (1), of course..... Anton Bassov
  Message 4 of 8  
17 Nov 17 14:05
Tim Roberts
xxxxxx@probo.com
Join Date: 28 Jan 2005
Posts To This List: 11673
Correct way of accessing results for async ReadFile() that completed synchronously

xxxxx@gmail.com wrote: > ReadFile() documentation [https://msdn.microsoft.com/en-us/library/windows/desktop/aa365467(v=vs.85).aspx] says that even when called on a handle that was opened with FILE_FLAG_OVERLAPPED, the read can happen synchronously. > ... > Now, the ReadFile() documentation says : > --------------------------------------------------------------------------------- ------------ > lpNumberOfBytesRead [out, optional] > A pointer to the variable that receives the number of bytes read when using a synchronous hFile parameter. ReadFile sets this value to zero before doing any work or error checking. Use NULL for this parameter if this is an asynchronous operation to avoid potentially erroneous results. > This parameter can be NULL only when the lpOverlapped parameter is not NULL. > For more information, see the Remarks section. > --------------------------------------------------------------------------------- ------------ > <...excess quoted lines suppressed...> No, it doesn't.  "Avoid" is not a prohibition.  It is a recommendation.  It probably should be a warning that the value it returns is not meaningful when you get ERROR_IO_PENDING. When I've done overlapped I/O, I have always written the code to handle three cases: - ReadFile returns non-zero, treat it just like a synchronous read, with lpNumberOfBytesRead - ReadFile returns zero, GetLastError returns ERROR_IO_PENDING, go wait for GetOverlappedResult - ReadFile returns zero, GetLastError returns something else, this was an immediate error -- Tim Roberts, xxxxx@probo.com Providenza & Boekelheide, Inc.
  Message 5 of 8  
17 Nov 17 17:31
Alex Grig
xxxxxx@broadcom.com
Join Date: 14 Apr 2008
Posts To This List: 3219
Correct way of accessing results for async ReadFile() that completed synchronously

> IIRC. according to Doron and/or other MSFT guys, the internal "convention" at MSFT is to return STATUS_PENDING regardless of what IoCallDriver() does. It's only what a KMDF driver does, by the framework design. Some usermode code (the infamous MSCOMM32.OCX) can't handle that, by the way. When they expect a synchronous completion on an overlapped handle, they fail.
  Message 6 of 8  
17 Nov 17 19:09
anton bassov
xxxxxx@hotmail.com
Join Date: 16 Jul 2006
Posts To This List: 4401
Correct way of accessing results for async ReadFile() that completed synchronously

>> IIRC. according to Doron and/or other MSFT guys, the internal "convention" >> at MSFT is to return STATUS_PENDING regardless of what IoCallDriver() does. > It's only what a KMDF driver does, by the framework design. IIRC, the first time I heard it somewhere in the year 2006, i.e at the time when practically all drivers were written in WDM ( in fact, I am not sure that KMDF even existed back then). To be honest, I am not particularly surprised by the fact KMDF does things in accordance with MSFT's internal convention anyway. However, it does not necessarily imply that this is the only KM component that takes this approach, does it.... > Some usermode code (the infamous MSCOMM32.OCX) can't handle that, by the way. > When they expect a synchronous completion on an overlapped handle, they fail. I am, again, not really surprised by this,taking into consideration that with the above mentioned approach any IO operation on overlapped handle gets treated as an asynch IO - even if gets completed immediately by underlying driver. In fact, this is exactly the scenario that MSDN excerpt (1) provided by the OP warns about...... Anton Bassov
  Message 7 of 8  
20 Nov 17 05:20
Anand A
xxxxxx@gmail.com
Join Date: 05 Aug 2014
Posts To This List: 47
Correct way of accessing results for async ReadFile() that completed synchronously

Thanks everyone for the insights As Tim stated, I just need to handle 3 cases. What I put in the opening question as 1(a) and 1(c) are not distinct cases that need to be handled separately. Also did a small experiment and found that when the async request completes synchronously, then both lpNumberOfBytesRead as well as GetOverlappedResult() give the same details. Tested this on Windows Server 2008 R2 and 2012 R2. Will not be taking it for granted though
  Message 8 of 8  
20 Nov 17 11:55
Tim Roberts
xxxxxx@probo.com
Join Date: 28 Jan 2005
Posts To This List: 11673
Correct way of accessing results for async ReadFile() that completed synchronously

xxxxx@gmail.com wrote: > As Tim stated, I just need to handle 3 cases. What I put in the opening question as 1(a) and 1(c) are not distinct cases that need to be handled separately. > > Also did a small experiment and found that when the async request completes synchronously, then both lpNumberOfBytesRead as well as GetOverlappedResult() give the same details. Tested this on Windows Server 2008 R2 and 2012 R2. Will not be taking it for granted though Just to be clear, in that case you can rely on lpNumberOfBytesRead, but not GetOverlappedResult.  The documentation for GetOverlappedResult states that its results are only meaningful following an I/O operation that returned ERROR_IO_PENDING.  As you say, experience suggests that it does work just fine after a synchronous return, but that's not the "contract". -- Tim Roberts, xxxxx@probo.com Providenza & Boekelheide, Inc.
Posting Rules  
You may not post new threads
You may not post replies
You may not post attachments
You must login to OSR Online AND be a member of the ntdev list to be able to post.

All times are GMT -5. The time now is 21:44.


Copyright ©2015, OSR Open Systems Resources, Inc.
Based on vBulletin Copyright ©2000 - 2005, Jelsoft Enterprises Ltd.
Modified under license