I'm not sure, so I'm pretty open to comments, but I think:
ReadFileEx used to use NtReadFile (more or less, it's just a thin wrapper around it). NtReadFile does a lot of things, but uses IoBuildAsynchronousFsdRequest (or IoBuildSynchronousFsdRequest ) to accomplish its task. From this article, we know that:
If the target device object is configured, do direct I / O (DO_DIRECT_IO), then IoBuildAsynchronousFsdRequest creates an MDL to describe the buffer and blocks the pages .
(my emphasis)
Then I assume that they call MmProbeAndLockPages using IoWriteAccess , this is done by the driver in kernel mode, then the buffer available to the user (in user mode) cannot be read.
I don't know what will happen if you do this, the SEH exception will probably be thrown, and your code will fail.
EDIT
As indicated in the edited question, even the ReadFile function prevents the user from reading from the buffer before the operation is completed and can return ERROR_NOT_ENOUGH_QUOTA :
The ReadFile function may fail using ERROR_NOT_ENOUGH_QUOTA, which means that the buffer of the calling process cannot be blocked on the page.
At the very least, it makes it clear that ReadFile (where the buffer is not provided by the user) will select the page and it will block (itβs well said in the article I also contacted ...). It remains to be seen whether corruption (if any, I completely agree with @David) can occur with a user-defined buffer (where blocking on a page, as indicated by @Ben, is impossible in most cases).
I do not think that he uses page errors to detect buffer overflows simply because he knows the required amount of data before the call, and then he can select it once.
So why can the data get corrupted? After all, everything here may be due to an error, but not to data corruption. This is a big guess, but there was a known issue about MmProbeAndLockPages :
This problem occurs due to the race condition in the memory manager. When the driver calls the MmProbeAndLockPages procedure, this procedure can read some data that is being changed by another thread. Consequently, data corruption occurs. Depending on how the damaged data is used, the application or system may crash.
It is hard to say if this problem was resolved at a very low level or if it can still be used if the application does something strange ...