2

Is there any way to read from and write to the console asynchronously, using APC completion routines, without creating new threads? Like it is possible with named pipes.

The problem is that in case of console, FILE_FLAG_OVERLAPPED is ignored by CreateFile function.

Edit. This is to clarify, what I'm trying to do. Windows provides functions ReadFileEx and WriteFileEx for working with Asynchronous Procedure Calls. Documentaion to these function says about parameter hFile:

This parameter can be any handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile function<...>

Then, documentation to CreateFile says that if pass CONIN$ or CONOUT& to them, than FILE_FLAG_OVERLAPPED is ignored.

And indeed, when I try following sequence:

HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
if(!WriteFileEx(h, ...)) {
   auto errorCode = GetLastError(); //I get 6 here
}

...I get error code 6 - ERROR_INVALID_HANDLE. If use named pipe instead of console handles, all works perfectly.

So my question is whether there is some way to make ReadFileEx and WriteFileEx to work with console handles.

Dmitry J
  • 867
  • 7
  • 20
  • how is `CreateFile` related to `STD_INPUT_HANDLE` and `STD_OUTPUT_HANDLE` ? by using `CreateFile` you can create some new file yourself. by using standard handles you use already created file, and you not control it mode. console handles created with flag `FO_SYNCHRONOUS_IO` - as result you can not perform asynchronous io on it – RbMm Jun 29 '17 at 21:12
  • @RbMm, Windows function `CreateFile`, despite its confusing name, can also open (not only create) files, pipes, console input/ouput, and many more. As for your last statement: that's exactly what I'm asking, is there any way to do it. You say that no, but no offense, I'll wait for some more answers. – Dmitry J Jun 29 '17 at 21:29
  • `CreateFile` can open existing file in filesystem, but `FILE_OBJECT` anyway will be created new. but how all this related to console std handles ? – RbMm Jun 29 '17 at 21:32
  • 2
    @RbMm: `CreateFile("CONIN$", ...)` – Dietrich Epp Jun 29 '17 at 21:32
  • with CreateFile(L"CONIN$", ...) `FILE_FLAG_OVERLAPPED` is **not ignored** and asynchronous io work without any problems – RbMm Jun 29 '17 at 21:53
  • @DietrichEpp, that creates an explicit console handle, but if you're doing that then you're not using the standard handles. – Harry Johnston Jun 29 '17 at 21:54
  • Dmitry, I've edited your question to remove the reference to the standard handles, since it sounds as if you said "standard handles" when you meant "console handles". If I've misunderstood, please edit yourself to clarify. – Harry Johnston Jun 29 '17 at 21:55
  • What version of Windows are you using? Can you provide a [mcve]? – Harry Johnston Jun 29 '17 at 21:56
  • @HarryJohnston - really Dietrich Epp correct - I test (how minimum on windows 10) CreateFile(L"CONIN$", ...) open input console handle it asynchronous io work on it – RbMm Jun 29 '17 at 22:07
  • @RbMm, I suspect it won't work on Windows 7, though. If the OP can post some code, I'll give it a try. – Harry Johnston Jun 29 '17 at 22:17
  • @HarryJohnston - now, I not under working comp, can not check on different systems, but on win10 work well. I think (but until can not check) that on win7 also will be worked (or even in vista) when console begin use true file handles ? – RbMm Jun 29 '17 at 22:19
  • @RbMm, I think they're still psuedohandles in Windows 7, but I'm not sure. – Harry Johnston Jun 29 '17 at 22:30
  • @HarryJohnston, I edited my question, suppose the code snippet is enough to test. – Dmitry J Jun 29 '17 at 22:32
  • @HarryJohnston - on win7 this is already real handles on `\Device\ConDrv`, in xp pseudo handles. how about vista, not looking – RbMm Jun 29 '17 at 22:33
  • 1
    I'm confused by your latest edit; that code snippet is using the standard handle, provided to you by your parent process, which of course doesn't have `FILE_FLAG_OVERLAPPED` set. I thought you were using `CreateFile` to open your own handle to the console? – Harry Johnston Jun 29 '17 at 22:35
  • `ERROR_INVALID_HANDLE` - are this on xp ? what windows you use ? – RbMm Jun 29 '17 at 22:42
  • @HarryJohnston, I get the same error with `HANDLE h = CreateFile(L"CONOUT$",GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);` – Dmitry J Jun 29 '17 at 22:46
  • @RbMm, it's Windows7 x64. Have you really tried `WriteFileEx` with console handle? Does it return true or false to you? – Dmitry J Jun 29 '17 at 22:48
  • @RbMm, you get `ERROR_INVALID_HANDLE` if you use a handle that doesn't have `FILE_FLAG_OVERLAPPED` set, e.g., if you use `GetStdHandle` rather than `CreateFile`. If you use `CreateFile` with `STDOUT$` and `FILE_FLAG_OVERLAPPED` then it works on Windows 10 but fails on Windows 7 with `ERROR_ACCESS_DENIED`. – Harry Johnston Jun 29 '17 at 22:50
  • @HarryJohnston - `ERROR_INVALID_HANDLE` this error we get only if handle not valid file handle. otherwise we got some another error, say `ERROR_INVALID_PARAMETER`. on win7 I can not test just now. on win10 code worked with `"CONIN$"` – RbMm Jun 29 '17 at 22:56
  • are you check hFile value ? what it in hex ? – RbMm Jun 29 '17 at 23:03
  • @RbMm, on Windows 7, if you pass `GetStdHandle(STD_OUTPUT_HANDLE)` to `WriteFileEx` you get `ERROR_INVALID_HANDLE`. (This *does* work on Windows 10, my previous test was buggy.) The integer value of the handle is 7, as per [my earlier experiments here](https://stackoverflow.com/a/30520800/886887). On Windows 10, the integer value is 88 and `WriteFileEx` succeeds. – Harry Johnston Jun 29 '17 at 23:05
  • and how minimum on win10 - dwFlagsAndAttributes not ignored with CONIN$ - worked well – RbMm Jun 29 '17 at 23:05
  • ... I really do think the low-valued handle numbers (as seen on Windows 7) aren't entirely real handles, even if there's a real device associated with them. – Harry Johnston Jun 29 '17 at 23:06
  • this mean console implementation very volatile and changed from version to version. real file handles (which is pointer to FILE_OBJECT) is `4*n` value. 3 and 7 not a handles or not a file handles. if look on ntstatus - all be just clear - if it `STATUS_INVALID_HANDLE` - not handle at all, `STATUS_OBJECT_TYPE_MISMATCH` - handle but not file handle. but win32 when convert ntstatus lost precise - both this status and many other converted to same `ERROR_INVALID_HANDLE` – RbMm Jun 29 '17 at 23:17

1 Answers1

2

Windows 10:

Yes. You can call CreateFile with CONIN$ or CONOUT$ and the FILE_FLAG_OVERLAPPED flag, and it will all just work.

Windows 7:

No. The console does not support overlapped operation.

If you have existing code using ReadFileEx/WriteFileEx and do not wish to rewrite it, you could pass it a named pipe handle and have another thread (or process) pass the data between the other end of the named pipe and the actual console. Performance isn't an issue, since console I/O is so slow anyway, so there's no real harm done in having a separate thread involved.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
  • yes, because console become true file handle (which bind to `FILE_OBJECT`) only begin from win 8.1 (or 8) . on win7 this is still pseudo-handles which of course can not support asynchronous io – RbMm Jun 30 '17 at 06:49