Paul Houle
Paul Houle

Reputation: 735

is it legal to pass STD_OUTPUT_HANDLE directly as input HANDLE to WriteFile?

The WinApi WriteFile() function seems to accept the STD_xxx_HANDLE constants directly as a first argument. I executed the following:

#include <windows.h>
main() {
    DWORD bw;

    WriteFile( (void *)STD_OUTPUT_HANDLE,       "output", 6, &bw, NULL);
    WriteFile( GetStdHandle(STD_OUTPUT_HANDLE), "output", 6, &bw, NULL);

    WriteFile( (void *)STD_ERROR_HANDLE,        "error", 5, &bw, NULL);
    WriteFile( GetStdHandle(STD_ERROR_HANDLE),  "error", 6, &bw, NULL);
}

The above example writes "output" twice to stdout and "error" twice to stderr. I have tested on Win XP and Win 7 (I have no access to WINE or Win 10).

I can see GetStdHandle() does convert the value (from -11 to 7 in the case of STD_OUTPUT_HANDLE), but either value works the same as a WriteFile() input HANDLE.

Is WriteFile implicitly doing GetStdHandle() when it recognizes a STD_xxx_HANDLE constant as its HANDLE input? I have looked but can't find this documented.

Yes I know if it's not documented, don't do it... I'm simply wondering if I missed something.

Upvotes: 1

Views: 638

Answers (3)

Ex-Kyuto
Ex-Kyuto

Reputation: 81

Nope, it's treated as pseudohandles, same as GetCurrentProcess() handle.

Try to peek inside KernelBase.dll, It checks the hFile argument if it's equal to STD_X_HANDLE macros.

If yes, the hFile handles turn into NtCurrentPeb()->ProcessParameter->StandardXxx handle.

And there are other functions that recognized STD_XXX_HANDLE macros. GetFiletype , FlushFileBuffers, CloseHandle, and WaitForSingleObject(Ex)also recognize STD_XXX_HANDLE.

Upvotes: 0

Anders
Anders

Reputation: 101746

Surprisingly, this works even on Windows 95 RTM and NT 4 (and XP and 8) so it seems like it is on purpose. I can't tell you why nor how far back in NT 3.x this goes.

But it is undocumented and not really part of the ABI so I would suggest that you continue calling GetStdHandle to avoid a nasty surprise in the future.

Upvotes: 1

IInspectable
IInspectable

Reputation: 51471

WriteFile expects a handle. The STD_xxx_HANDLE values are not handles. It is not legal to pass those values to WriteFile. You have to convert them to handles by calling GetStdHandle.

Upvotes: 0

Related Questions