Reactos
1//
2// initcon.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Defines the global console output handle and the __dcrt_lowio_initialize_console_output() and
7// __dcrt_terminate_console_output() functions, which initialize and close that handle.
8// Also defines functions that can be used instead of the Console API to enable retry behavior
9// in case the cached console handle is freed.
10
11#include <corecrt_internal_lowio.h>
12
13_CRT_LINKER_FORCE_INCLUDE(__dcrt_console_output_terminator);
14
15// The global console output handle.
16static HANDLE __dcrt_lowio_console_output_handle = _console_uninitialized_handle;
17
18// Initializes the global console output handle
19static void __dcrt_lowio_initialize_console_output()
20{
21 __dcrt_lowio_console_output_handle = CreateFileW(
22 L"CONOUT$",
23 GENERIC_WRITE,
24 FILE_SHARE_READ | FILE_SHARE_WRITE,
25 nullptr,
26 OPEN_EXISTING,
27 0,
28 nullptr);
29}
30
31extern "C" BOOL __cdecl __dcrt_lowio_ensure_console_output_initialized()
32{
33 if (__dcrt_lowio_console_output_handle == _console_uninitialized_handle)
34 {
35 __dcrt_lowio_initialize_console_output();
36 }
37
38 if (__dcrt_lowio_console_output_handle == _console_invalid_handle)
39 {
40 return FALSE;
41 }
42 return TRUE;
43}
44
45// Closes the global console output handle
46extern "C" void __cdecl __dcrt_terminate_console_output()
47{
48 if ( __dcrt_lowio_console_output_handle != _console_invalid_handle
49 && __dcrt_lowio_console_output_handle != _console_uninitialized_handle)
50 {
51 CloseHandle(__dcrt_lowio_console_output_handle);
52 }
53}
54
55template <typename Func>
56static BOOL console_output_reopen_and_retry(Func const& fp) throw()
57{
58 BOOL result = fp();
59 if (!result && GetLastError() == ERROR_INVALID_HANDLE) {
60 __dcrt_terminate_console_output();
61 __dcrt_lowio_initialize_console_output();
62 result = fp();
63 }
64 return result;
65}
66
67extern "C" BOOL __cdecl __dcrt_write_console(
68 _In_ void const * lpBuffer,
69 _In_ DWORD nNumberOfCharsToWrite,
70 _Out_ LPDWORD lpNumberOfCharsWritten
71 )
72{
73 return console_output_reopen_and_retry(
74 [lpBuffer, nNumberOfCharsToWrite, lpNumberOfCharsWritten]()
75 {
76 return ::WriteConsoleW(
77 __dcrt_lowio_console_output_handle,
78 lpBuffer,
79 nNumberOfCharsToWrite,
80 lpNumberOfCharsWritten,
81 nullptr);
82 });
83}