diff --git a/client/platform/Windows/entry.c b/client/platform/Windows/entry.c index 6c89044e..41e348bc 100644 --- a/client/platform/Windows/entry.c +++ b/client/platform/Windows/entry.c @@ -22,10 +22,68 @@ #include "common/win32.h" +#include +#include +#include +#include #include #include #include +static bool bindStandardStream(FILE * stream, DWORD streamId) +{ + const HANDLE handle = GetStdHandle(streamId); + if (!handle || handle == INVALID_HANDLE_VALUE) + return false; + + HANDLE duplicate = NULL; + if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(), + &duplicate, 0, FALSE, DUPLICATE_SAME_ACCESS)) + return false; + + const int sourceFd = _open_osfhandle((intptr_t)duplicate, _O_TEXT); + if (sourceFd < 0) + { + CloseHandle(duplicate); + return false; + } + + FILE * reopened = NULL; + if (freopen_s(&reopened, "NUL", "w", stream)) + { + _close(sourceFd); + return false; + } + + const int targetFd = _fileno(reopened); + if (targetFd < 0 || _dup2(sourceFd, targetFd)) + { + _close(sourceFd); + return false; + } + + _close(sourceFd); + clearerr(reopened); + setvbuf(reopened, NULL, _IONBF, 0); + return true; +} + +static void bindStandardStreams(void) +{ + const bool stdoutBound = bindStandardStream(stdout, STD_OUTPUT_HANDLE); + const bool stderrBound = bindStandardStream(stderr, STD_ERROR_HANDLE); + if ((stdoutBound && stderrBound) || IsDebuggerPresent()) + return; + + if (!AttachConsole(ATTACH_PARENT_PROCESS)) + return; + + if (!stdoutBound) + bindStandardStream(stdout, STD_OUTPUT_HANDLE); + if (!stderrBound) + bindStandardStream(stderr, STD_ERROR_HANDLE); +} + static void freeArguments(int argc, char * argv[]) { if (!argv) @@ -44,6 +102,8 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE previousInstance, (void)commandLine; (void)showCommand; + bindStandardStreams(); + int argc = 0; wchar_t ** wideArgv = CommandLineToArgvW(GetCommandLineW(), &argc); if (!wideArgv || argc < 1)