0

This code, which I have no control over, reads a file using overlapped I/O:

// Read file asynchronously
HANDLE hFile = CreateFile(..., FILE_FLAG_OVERLAPPED, ...);
BYTE buffer[10];
OVERLAPPED oRead = { 0 };
ReadFile(hFile, buffer, 10, NULL, &oRead);

// Do work while file is being read
...

// Wait for read to finish
WaitForSingleObject(hFile, INFINITE);

// ReadFile has finished 
// buffer now contains data which can be used
...

In another thread (actually in an API hook of ReadFile), I need to signal the hFile to unblock the WaitForSingleObject. Normally Windows (or the device driver handling the ReadFile) does this, but I need to simulate it.

None of the APIs I found that normally do this work with hFile, including ReleaseMutex, ReleaseSemaphore, and SetEvent. They all return Error 6 (handle is invalid). Is there an API that works with a file, named pipe, or communications device?

I know it is not recommended to WaitForSingleObject(hFile), but the above code is a given, and I need to work with it. Thanks!

Community
  • 1
  • 1
David Ching
  • 1,903
  • 17
  • 21
  • "Simulation" is rough, it actually posts a request to a driver and you must cancel it. That takes CancelIo() – Hans Passant Dec 19 '15 at 16:14
  • @HansPassant - my hook returns its own data and doesn't actually forward the call to the driver. That's why my hook needs to signal hFile without involving the driver. – David Ching Dec 19 '15 at 16:57
  • 2
    Hmm, hooks, that wasn't exactly obvious. I suppose you'd better hook WFSO as well then. – Hans Passant Dec 19 '15 at 17:03
  • @HansPassant - sorry it wasn't clear. It [was suggested](http://forum.madshi.net/viewtopic.php?f=7&t=28151) to hook WFSO and substitute `hFile` for an `hEvent` that I would create. Then the hook could call `SetEvent`. But I can't believe there is no API to signal an `hFile`. How does the driver do it (although such an API would undoubtedly be kernel mode)? – David Ching Dec 19 '15 at 17:07
  • A file handle enters the signaled state, when a file operation completes. Any file operation on that handle. A robust solution can only be implemented, if the code (as posted) is fixed, either by calling [GetOverlappedResult](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683209.aspx) in place of waiting on the file handle, or use one of the synchronization functions on the `OVERLAPPED` structure's event. – IInspectable Dec 19 '15 at 17:50
  • Why not just have an associated Win32 Event handle ala... `hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);`... that is created the same time as the file? When the file operation is completed, call `SetEvent(hEvent)`. Instead of waiting on `hFile`, wait on `hEvent` instead. – selbie Dec 19 '15 at 18:05
  • @selbie: As outlined in the documentation for the [OVERLAPPED structure](https://msdn.microsoft.com/en-us/library/windows/desktop/ms684342.aspx), it is discouraged to use an auto-reset event, for good reasons. It is safer to use a manual-reset event instead, by passing `TRUE` as the second argument to `CreateEvent`. – IInspectable Dec 19 '15 at 18:44
  • @selbie I'm sorry I can't change the WFSO call. It is third party code, my hook has to work with it. There seems to be a missing API to signal the hFile, MS tries to encourage using hEvent but doesn't prohibit the hFile. So I am stuck supporting it. – David Ching Dec 19 '15 at 19:31
  • @selbie What is broken about needing to be compatible with less than optimal third party software? – David Ching Dec 19 '15 at 19:49
  • @DavidChing - I'll withdraw that comment. You are already aware that WSFO wasn't meant to work with file handles. But how did this ever work in the first place? – selbie Dec 19 '15 at 19:52
  • @selbie I understand it does work since hFile is signaled when data is available. I read this in Jeffrey Richter's 'Wimdows Via C/C++'. Also in your linked article, it had conflicting info. Instead of WFSO it is the same story as GetOverlappedResult asIInspectable says. Either way, waiting for hFile seems to work but is not optimal because it does distinguish which overlapped operation has completed, but using hEvent, you can use unique events for each operation. – David Ching Dec 19 '15 at 20:27
  • 2
    @selbie: `WaitForSingleObject` **does** work with file handles (like any other kernel object handle). In fact, the system signals *hFile* in place of *hEvent*, when passing `NULL` for the *hEvent* member of the `OVERLAPPED` structure. This is documented under [GetOverlappedResult](https://msdn.microsoft.com/en-us/library/windows/desktop/ms683209.aspx). – IInspectable Dec 19 '15 at 21:25

1 Answers1

0

So far as I know, signaling the file handle takes place internally to Windows, and there is no API even when running in kernel mode. (I believe the file system driver simply tells Windows that the operation is complete and lets Windows figure out how to notify the user-mode process. I may be wrong.)

One resolution would be to issue a genuine ReadFile (a zero-byte read might be sufficient) against the handle in order to signal it.

But it would probably be more sensible to hook WaitForSingleObject, check whether it is being called on the file handle in question, and if so modify the behaviour as appropriate.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158