Reactos
at master 162 lines 4.4 kB view raw
1// 2// initconin.cpp 3// 4// Copyright (c) Microsoft Corporation. All rights reserved. 5// 6// Defines the global console input handle and the __dcrt_lowio_initialize_console_input() and 7// __dcrt_terminate_console_input() 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_input_terminator); 14 15// The global console input handle. 16static HANDLE __dcrt_lowio_console_input_handle = _console_uninitialized_handle; 17 18// Initializes the global console input handle 19static void __dcrt_lowio_initialize_console_input() 20{ 21 __dcrt_lowio_console_input_handle = CreateFileW( 22 L"CONIN$", 23 GENERIC_READ | 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_input_initialized() 32{ 33 if (__dcrt_lowio_console_input_handle == _console_uninitialized_handle) 34 { 35 __dcrt_lowio_initialize_console_input(); 36 } 37 38 if (__dcrt_lowio_console_input_handle == _console_invalid_handle) 39 { 40 return FALSE; 41 } 42 return TRUE; 43} 44 45// Closes the global console input handle 46extern "C" void __cdecl __dcrt_terminate_console_input() 47{ 48 if ( __dcrt_lowio_console_input_handle != _console_invalid_handle 49 && __dcrt_lowio_console_input_handle != _console_uninitialized_handle) 50 { 51 CloseHandle(__dcrt_lowio_console_input_handle); 52 } 53} 54 55template <typename Func> 56static BOOL console_input_reopen_and_retry(Func const& fp) throw() 57{ 58 BOOL result = fp(); 59 if (!result && GetLastError() == ERROR_INVALID_HANDLE) { 60 __dcrt_terminate_console_input(); 61 __dcrt_lowio_initialize_console_input(); 62 result = fp(); 63 } 64 return result; 65} 66 67extern "C" BOOL __cdecl __dcrt_read_console_input( 68 _Out_ PINPUT_RECORD lpBuffer, 69 _In_ DWORD nLength, 70 _Out_ LPDWORD lpNumberOfEventsRead 71 ) 72{ 73 return console_input_reopen_and_retry( 74 [lpBuffer, nLength, lpNumberOfEventsRead]() 75 { 76 return ::ReadConsoleInputW( 77 __dcrt_lowio_console_input_handle, 78 lpBuffer, 79 nLength, 80 lpNumberOfEventsRead 81 ); 82 }); 83} 84 85extern "C" BOOL __cdecl __dcrt_read_console( 86 _Out_ LPVOID lpBuffer, 87 _In_ DWORD nNumberOfCharsToRead, 88 _Out_ LPDWORD lpNumberOfCharsRead 89 ) 90{ 91 return console_input_reopen_and_retry( 92 [lpBuffer, nNumberOfCharsToRead, lpNumberOfCharsRead]() 93 { 94 return ::ReadConsoleW( 95 __dcrt_lowio_console_input_handle, 96 lpBuffer, 97 nNumberOfCharsToRead, 98 lpNumberOfCharsRead, 99 nullptr 100 ); 101 }); 102} 103 104extern "C" BOOL __cdecl __dcrt_get_number_of_console_input_events( 105 _Out_ LPDWORD lpcNumberOfEvents 106 ) 107{ 108 return console_input_reopen_and_retry( 109 [lpcNumberOfEvents]() 110 { 111 return ::GetNumberOfConsoleInputEvents( 112 __dcrt_lowio_console_input_handle, 113 lpcNumberOfEvents 114 ); 115 }); 116} 117 118extern "C" BOOL __cdecl __dcrt_peek_console_input_a( 119 _Out_ PINPUT_RECORD lpBuffer, 120 _In_ DWORD nLength, 121 _Out_ LPDWORD lpNumberOfEventsRead 122 ) 123{ 124 return console_input_reopen_and_retry( 125 [lpBuffer, nLength, lpNumberOfEventsRead]() 126 { 127 return ::PeekConsoleInputA( 128 __dcrt_lowio_console_input_handle, 129 lpBuffer, 130 nLength, 131 lpNumberOfEventsRead 132 ); 133 }); 134} 135 136extern "C" BOOL __cdecl __dcrt_get_input_console_mode( 137 _Out_ LPDWORD lpMode 138 ) 139{ 140 return console_input_reopen_and_retry( 141 [lpMode]() 142 { 143 return ::GetConsoleMode( 144 __dcrt_lowio_console_input_handle, 145 lpMode 146 ); 147 }); 148} 149 150extern "C" BOOL __cdecl __dcrt_set_input_console_mode( 151 _In_ DWORD dwMode 152 ) 153{ 154 return console_input_reopen_and_retry( 155 [dwMode]() 156 { 157 return ::SetConsoleMode( 158 __dcrt_lowio_console_input_handle, 159 dwMode 160 ); 161 }); 162}