cleanup: refactor console helper class (#14091)
* cleanup: refactor console helper class * make opening CONIN and CONOUT non-fatal --------- Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
Ben Hillis committed
Jan 22, 2026 at 11:18 UTC
e663585eeb8fa332f229a7d908bbbaa7af1adafa
12 files changed
+251
-269
src/windows/common/CMakeLists.txt
+2
-2
@@ -32,7 +32,7 @@ set(SOURCES
32
string.cpp
33
SubProcess.cpp
34
svccomm.cpp
35
- svccommio.cpp
35
+ ConsoleState.cpp
36
WslClient.cpp
37
WslCoreConfig.cpp
38
WslCoreFilesystem.cpp
@@ -107,7 +107,7 @@ set(HEADERS
107
Stringify.h
108
SubProcess.h
109
svccomm.hpp
110
- svccommio.hpp
110
+ ConsoleState.h
111
WslClient.h
112
WslCoreConfig.h
113
WslCoreFilesystem.h
src/windows/common/ConsoleState.cpp
new
+167
@@ -0,0 +1,167 @@
1
+/*++
2
+
3
+Copyright (c) Microsoft. All rights reserved.
4
+
5
+Module Name:
6
+
7
+ ConsoleState.cpp
8
+
9
+Abstract:
10
+
11
+ This file contains function definitions for the ConsoleState helper class.
12
+--*/
13
+
14
+#include "precomp.h"
15
+#include "svccomm.hpp"
16
+#include "ConsoleState.h"
17
+#pragma hdrstop
18
+
19
+namespace {
20
+
21
+void ChangeConsoleMode(_In_ HANDLE Handle, _In_ DWORD Mode)
22
+{
23
+ // Use the invalid parameter error code to detect the v1 console that does not support the provided mode.
24
+ // This can be improved in the future when a more elegant solution exists.
25
+ //
26
+ // N.B. Ignore failures setting the mode if the console has already disconnected.
27
+ if (!SetConsoleMode(Handle, Mode))
28
+ {
29
+ // DISABLE_NEWLINE_AUTO_RETURN is not supported everywhere, if the flag was present fall back and try again.
30
+ if (WI_IsFlagSet(Mode, DISABLE_NEWLINE_AUTO_RETURN))
31
+ {
32
+ Mode = WI_ClearFlag(Mode, DISABLE_NEWLINE_AUTO_RETURN);
33
+ if (SetConsoleMode(Handle, Mode))
34
+ {
35
+ return;
36
+ }
37
+ }
38
+
39
+ switch (GetLastError())
40
+ {
41
+ case ERROR_PIPE_NOT_CONNECTED:
42
+ break;
43
+
44
+ case ERROR_INVALID_PARAMETER:
45
+ THROW_HR_MSG(WSL_E_CONSOLE, "SetConsoleMode(0x%x) failed", Mode);
46
+
47
+ default:
48
+ THROW_LAST_ERROR_MSG("SetConsoleMode(0x%x) failed", Mode);
49
+ }
50
+ }
51
+}
52
+
53
+void TrySetConsoleMode(_In_ HANDLE Handle, _In_ DWORD Mode)
54
+try
55
+{
56
+ ChangeConsoleMode(Handle, Mode);
57
+}
58
+CATCH_LOG()
59
+
60
+} // namespace
61
+
62
+namespace wsl::windows::common {
63
+
64
+ConsoleState::ConsoleState()
65
+{
66
+ // Ensure console state is restored if the constructor throws.
67
+ auto cleanup = wil::scope_exit_log(WI_DIAGNOSTICS_INFO, [&]() { RestoreConsoleState(); });
68
+
69
+ m_InputHandle.reset(
70
+ CreateFileW(L"CONIN$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr));
71
+
72
+ if (m_InputHandle)
73
+ {
74
+ m_SavedInputCodePage = GetConsoleCP();
75
+ LOG_IF_WIN32_BOOL_FALSE(SetConsoleCP(CP_UTF8));
76
+
77
+ // Configure for raw input with VT support.
78
+ DWORD mode;
79
+ THROW_LAST_ERROR_IF(!GetConsoleMode(m_InputHandle.get(), &mode));
80
+
81
+ DWORD NewMode = mode;
82
+ WI_SetAllFlags(NewMode, ENABLE_WINDOW_INPUT | ENABLE_VIRTUAL_TERMINAL_INPUT);
83
+ WI_ClearAllFlags(NewMode, ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
84
+ ChangeConsoleMode(m_InputHandle.get(), NewMode);
85
+ m_SavedInputMode = mode;
86
+ }
87
+ else
88
+ {
89
+ LOG_LAST_ERROR_MSG("CreateFileW(CONIN$) failed");
90
+ }
91
+
92
+ m_OutputHandle.reset(
93
+ CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr));
94
+
95
+ if (m_OutputHandle)
96
+ {
97
+ m_SavedOutputCodePage = GetConsoleOutputCP();
98
+ LOG_IF_WIN32_BOOL_FALSE(SetConsoleOutputCP(CP_UTF8));
99
+
100
+ // Configure for VT output.
101
+ DWORD mode;
102
+ THROW_LAST_ERROR_IF(!GetConsoleMode(m_OutputHandle.get(), &mode));
103
+
104
+ DWORD NewMode = mode;
105
+ WI_SetAllFlags(NewMode, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN);
106
+ ChangeConsoleMode(m_OutputHandle.get(), NewMode);
107
+ m_SavedOutputMode = mode;
108
+ }
109
+ else
110
+ {
111
+ LOG_LAST_ERROR_MSG("CreateFileW(CONOUT$) failed");
112
+ }
113
+
114
+ cleanup.release();
115
+}
116
+
117
+ConsoleState::~ConsoleState()
118
+{
119
+ RestoreConsoleState();
120
+}
121
+
122
+void ConsoleState::RestoreConsoleState()
123
+{
124
+ if (m_InputHandle)
125
+ {
126
+ if (m_SavedInputCodePage.has_value())
127
+ {
128
+ LOG_IF_WIN32_BOOL_FALSE(SetConsoleCP(m_SavedInputCodePage.value()));
129
+ }
130
+
131
+ if (m_SavedInputMode.has_value())
132
+ {
133
+ TrySetConsoleMode(m_InputHandle.get(), m_SavedInputMode.value());
134
+ }
135
+ }
136
+
137
+ if (m_OutputHandle)
138
+ {
139
+ if (m_SavedOutputCodePage.has_value())
140
+ {
141
+ LOG_IF_WIN32_BOOL_FALSE(SetConsoleOutputCP(m_SavedOutputCodePage.value()));
142
+ }
143
+
144
+ if (m_SavedOutputMode.has_value())
145
+ {
146
+ TrySetConsoleMode(m_OutputHandle.get(), m_SavedOutputMode.value());
147
+ }
148
+ }
149
+}
150
+
151
+COORD ConsoleState::GetWindowSize() const
152
+{
153
+ if (m_OutputHandle)
154
+ {
155
+ CONSOLE_SCREEN_BUFFER_INFOEX Info{};
156
+ Info.cbSize = sizeof(Info);
157
+ THROW_IF_WIN32_BOOL_FALSE(GetConsoleScreenBufferInfoEx(m_OutputHandle.get(), &Info));
158
+ return {
159
+ static_cast<short>(Info.srWindow.Right - Info.srWindow.Left + 1),
160
+ static_cast<short>(Info.srWindow.Bottom - Info.srWindow.Top + 1)};
161
+ }
162
+
163
+ LOG_HR_MSG(E_UNEXPECTED, "No console handle available for GetWindowSize");
164
+ return {80, 24};
165
+}
166
+
167
+} // namespace wsl::windows::common
src/windows/common/ConsoleState.h
new
+46
@@ -0,0 +1,46 @@
1
+/*++
2
+
3
+Copyright (c) Microsoft. All rights reserved.
4
+
5
+Module Name:
6
+
7
+ ConsoleState.h
8
+
9
+Abstract:
10
+
11
+ This file contains function declarations for the ConsoleState helper class.
12
+
13
+--*/
14
+
15
+#pragma once
16
+
17
+#include <wil/filesystem.h>
18
+#include <wil/result.h>
19
+#include "wslservice.h"
20
+
21
+namespace wsl::windows::common {
22
+
23
+// RAII wrapper for console state configuration and restoration
24
+class ConsoleState
25
+{
26
+public:
27
+ ConsoleState();
28
+ ~ConsoleState();
29
+ ConsoleState(const ConsoleState&) = delete;
30
+ ConsoleState& operator=(const ConsoleState&) = delete;
31
+ ConsoleState(ConsoleState&&) = delete;
32
+ ConsoleState& operator=(ConsoleState&&) = delete;
33
+
34
+ COORD GetWindowSize() const;
35
+
36
+private:
37
+ void RestoreConsoleState();
38
+
39
+ wil::unique_hfile m_InputHandle;
40
+ wil::unique_hfile m_OutputHandle;
41
+ std::optional<DWORD> m_SavedInputMode{};
42
+ std::optional<UINT> m_SavedInputCodePage{};
43
+ std::optional<DWORD> m_SavedOutputMode{};
44
+ std::optional<UINT> m_SavedOutputCodePage{};
45
+};
46
+} // namespace wsl::windows::common
src/windows/common/WslClient.cpp
+1
-1
@@ -1501,7 +1501,7 @@ int RunDebugShell()
1501
THROW_IF_WIN32_BOOL_FALSE(WriteFile(pipe.get(), "\n", 1, nullptr, nullptr));
1502
1503
// Create a thread to relay stdin to the pipe.
1504
- wsl::windows::common::SvcCommIo Io;
1504
+ wsl::windows::common::ConsoleState Io;
1505
auto exitEvent = wil::unique_event(wil::EventOptions::ManualReset);
1506
std::thread inputThread(
1507
[&]() { wsl::windows::common::RelayStandardInput(GetStdHandle(STD_INPUT_HANDLE), pipe.get(), {}, exitEvent.get(), &Io); });
src/windows/common/precomp.h
+1
-1
@@ -160,7 +160,7 @@ Abstract:
160
#include "LxssDynamicFunction.h"
161
#include "relay.hpp"
162
#include "svccomm.hpp"
163
-#include "svccommio.hpp"
163
+#include "ConsoleState.h"
164
#include "disk.hpp"
165
#include "WslSecurity.h"
166
#include "ExecutionContext.h"
src/windows/common/relay.hpp
+1
-1
@@ -15,7 +15,7 @@ Abstract:
15
#pragma once
16
17
#include <winsock2.h>
18
-#include "svccommio.hpp"
18
+#include "ConsoleState.h"
19
20
#define LX_RELAY_BUFFER_SIZE 0x1000
21
src/windows/common/svccomm.cpp
+17
-4
@@ -216,7 +216,7 @@ void wsl::windows::common::RelayStandardInput(
216
HANDLE OutputHandle,
217
const std::shared_ptr<wsl::shared::SocketChannel>& ControlChannel,
218
HANDLE ExitEvent,
219
- wsl::windows::common::SvcCommIo* Io)
219
+ wsl::windows::common::ConsoleState* Io)
220
try
221
{
222
if (GetFileType(ConsoleHandle) != FILE_TYPE_CHAR)
@@ -666,8 +666,7 @@ wsl::windows::common::SvcComm::LaunchProcess(
666
// Create the process.
667
//
668
669
- SvcCommIo Io;
670
- PLXSS_STD_HANDLES StdHandles = Io.GetStdHandles();
669
+ ConsoleState Io;
670
COORD WindowSize = Io.GetWindowSize();
671
ULONG Flags = LXSS_CREATE_INSTANCE_FLAGS_ALLOW_FS_UPGRADE;
672
if (WI_IsFlagSet(LaunchFlags, LXSS_LAUNCH_FLAG_USE_SYSTEM_DISTRO))
@@ -684,6 +683,20 @@ wsl::windows::common::SvcComm::LaunchProcess(
683
// See: https://github.com/microsoft/terminal/blob/ec434e3fba2a6ef254123e31f5257c25b04f2547/src/tools/ConsoleBench/conhost.cpp#L159-L164
684
HANDLE console = NtCurrentTeb()->ProcessEnvironmentBlock->ProcessParameters->Reserved2[0];
685
686
+ LXSS_STD_HANDLES StdHandles{};
687
+ const HANDLE InputHandle = GetStdHandle(STD_INPUT_HANDLE);
688
+ const bool IsConsoleInput = wsl::windows::common::wslutil::IsConsoleHandle(InputHandle);
689
+ StdHandles.StdIn.HandleType = IsConsoleInput ? LxssHandleConsole : LxssHandleInput;
690
+ StdHandles.StdIn.Handle = IsConsoleInput ? LXSS_HANDLE_USE_CONSOLE : HandleToUlong(InputHandle);
691
+ const HANDLE OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
692
+ const bool IsConsoleOutput = wsl::windows::common::wslutil::IsConsoleHandle(OutputHandle);
693
+ StdHandles.StdOut.HandleType = IsConsoleOutput ? LxssHandleConsole : LxssHandleOutput;
694
+ StdHandles.StdOut.Handle = IsConsoleOutput ? LXSS_HANDLE_USE_CONSOLE : HandleToUlong(OutputHandle);
695
+ const HANDLE ErrorHandle = GetStdHandle(STD_ERROR_HANDLE);
696
+ const bool IsConsoleError = wsl::windows::common::wslutil::IsConsoleHandle(ErrorHandle);
697
+ StdHandles.StdErr.HandleType = IsConsoleError ? LxssHandleConsole : LxssHandleOutput;
698
+ StdHandles.StdErr.Handle = IsConsoleError ? LXSS_HANDLE_USE_CONSOLE : HandleToUlong(ErrorHandle);
699
+
700
GUID DistributionId;
701
GUID InstanceId;
702
wil::unique_handle ProcessHandle;
@@ -712,7 +725,7 @@ wsl::windows::common::SvcComm::LaunchProcess(
725
WindowSize.X,
726
WindowSize.Y,
727
HandleToUlong(console),
715
- StdHandles,
728
+ &StdHandles,
729
Flags,
730
&DistributionId,
731
&InstanceId,
src/windows/common/svccomm.hpp
+1
-1
@@ -21,7 +21,7 @@ Abstract:
21
22
namespace wsl::windows::common {
23
24
-void RelayStandardInput(HANDLE ConsoleHandle, HANDLE OutputHandle, const std::shared_ptr<wsl::shared::SocketChannel>& ControlChannel, HANDLE ExitEvent, SvcCommIo* Io);
24
+void RelayStandardInput(HANDLE ConsoleHandle, HANDLE OutputHandle, const std::shared_ptr<wsl::shared::SocketChannel>& ControlChannel, HANDLE ExitEvent, ConsoleState* Io);
25
26
class SvcComm
27
{
src/windows/common/svccommio.cpp
deleted
-178
@@ -1,178 +0,0 @@
1
-/*++
2
-
3
-Copyright (c) Microsoft. All rights reserved.
4
-
5
-Module Name:
6
-
7
- svccommio.cpp
8
-
9
-Abstract:
10
-
11
- This file contains function definitions for the SvcCommIo helper class.
12
-
13
---*/
14
-
15
-#include "precomp.h"
16
-#include "svccomm.hpp"
17
-#include "svccommio.hpp"
18
-#pragma hdrstop
19
-
20
-namespace {
21
-
22
-bool IsConsoleHandle(_In_ HANDLE Handle)
23
-{
24
- DWORD Mode;
25
- return GetFileType(Handle) == FILE_TYPE_CHAR && GetConsoleMode(Handle, &Mode);
26
-}
27
-
28
-void ChangeConsoleMode(_In_ HANDLE Handle, _In_ DWORD Mode)
29
-{
30
- //
31
- // Use the invalid parameter error code to detect the v1 console that does
32
- // not support the provided mode. This can be improved in the future when
33
- // a more elegant solution exists.
34
- //
35
- // N.B. Ignore failures setting the mode if the console has already
36
- // disconnected.
37
- //
38
-
39
- if (!SetConsoleMode(Handle, Mode))
40
- {
41
- // DISABLE_NEWLINE_AUTO_RETURN is not supported everywhere, if the flag was present fall back and try again.
42
- if (WI_IsFlagSet(Mode, DISABLE_NEWLINE_AUTO_RETURN))
43
- {
44
- if (SetConsoleMode(Handle, WI_ClearFlag(Mode, DISABLE_NEWLINE_AUTO_RETURN)))
45
- {
46
- return;
47
- }
48
- }
49
-
50
- switch (GetLastError())
51
- {
52
- case ERROR_INVALID_PARAMETER:
53
- THROW_HR(WSL_E_CONSOLE);
54
-
55
- case ERROR_PIPE_NOT_CONNECTED:
56
- break;
57
-
58
- default:
59
- THROW_LAST_ERROR();
60
- }
61
- }
62
-}
63
-
64
-void TrySetConsoleMode(_In_ HANDLE Handle, _In_ DWORD Mode)
65
-try
66
-{
67
- ChangeConsoleMode(Handle, Mode);
68
-}
69
-CATCH_LOG()
70
-
71
-} // namespace
72
-
73
-namespace wsl::windows::common {
74
-
75
-ConsoleInput::ConsoleInput(HANDLE Handle, DWORD SavedMode) :
76
- m_Handle(Handle), m_SavedMode(SavedMode), m_SavedCodePage(GetConsoleCP())
77
-{
78
- // Configure for raw input with VT support.
79
- DWORD NewMode = m_SavedMode;
80
- WI_SetAllFlags(NewMode, ENABLE_WINDOW_INPUT | ENABLE_VIRTUAL_TERMINAL_INPUT);
81
- WI_ClearAllFlags(NewMode, ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
82
- ChangeConsoleMode(Handle, NewMode);
83
-
84
- // Set UTF-8 code page.
85
- LOG_IF_WIN32_BOOL_FALSE(SetConsoleCP(CP_UTF8));
86
-}
87
-
88
-ConsoleInput::~ConsoleInput()
89
-{
90
- TrySetConsoleMode(m_Handle, m_SavedMode);
91
- LOG_IF_WIN32_BOOL_FALSE(SetConsoleCP(m_SavedCodePage));
92
-}
93
-
94
-ConsoleOutput::ConsoleOutput(wil::unique_hfile&& ConsoleHandle, DWORD SavedMode) :
95
- m_ConsoleHandle(std::move(ConsoleHandle)), m_SavedMode(SavedMode), m_SavedCodePage(GetConsoleOutputCP())
96
-{
97
- // Configure for VT output.
98
- DWORD NewMode = m_SavedMode;
99
- WI_SetAllFlags(NewMode, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN);
100
- ChangeConsoleMode(m_ConsoleHandle.get(), NewMode);
101
-
102
- // Set UTF-8 code page.
103
- LOG_IF_WIN32_BOOL_FALSE(SetConsoleOutputCP(CP_UTF8));
104
-}
105
-
106
-ConsoleOutput::~ConsoleOutput()
107
-{
108
- TrySetConsoleMode(m_ConsoleHandle.get(), m_SavedMode);
109
- LOG_IF_WIN32_BOOL_FALSE(SetConsoleOutputCP(m_SavedCodePage));
110
-}
111
-
112
-SvcCommIo::SvcCommIo()
113
-{
114
- const HANDLE InputHandle = GetStdHandle(STD_INPUT_HANDLE);
115
- const HANDLE OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
116
- const HANDLE ErrorHandle = GetStdHandle(STD_ERROR_HANDLE);
117
-
118
- // Configure input console
119
- DWORD InputMode;
120
- if (GetFileType(InputHandle) == FILE_TYPE_CHAR && GetConsoleMode(InputHandle, &InputMode))
121
- {
122
- m_ConsoleInput.emplace(InputHandle, InputMode);
123
- }
124
-
125
- // Configure output console
126
- wil::unique_hfile ConsoleHandle(
127
- CreateFileW(L"CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr));
128
-
129
- if (ConsoleHandle)
130
- {
131
- DWORD OutputMode;
132
- if (GetConsoleMode(ConsoleHandle.get(), &OutputMode))
133
- {
134
- m_ConsoleOutput.emplace(std::move(ConsoleHandle), OutputMode);
135
- }
136
- }
137
-
138
- // Initialize the standard handles structure
139
- const bool IsConsoleInput = m_ConsoleInput.has_value();
140
- m_StdHandles.StdIn.HandleType = IsConsoleInput ? LxssHandleConsole : LxssHandleInput;
141
- m_StdHandles.StdIn.Handle = IsConsoleInput ? LXSS_HANDLE_USE_CONSOLE : HandleToUlong(InputHandle);
142
-
143
- const bool IsConsoleOutput = IsConsoleHandle(OutputHandle);
144
- m_StdHandles.StdOut.HandleType = IsConsoleOutput ? LxssHandleConsole : LxssHandleOutput;
145
- m_StdHandles.StdOut.Handle = IsConsoleOutput ? LXSS_HANDLE_USE_CONSOLE : HandleToUlong(OutputHandle);
146
-
147
- const bool IsConsoleError = IsConsoleHandle(ErrorHandle);
148
- m_StdHandles.StdErr.HandleType = IsConsoleError ? LxssHandleConsole : LxssHandleOutput;
149
- m_StdHandles.StdErr.Handle = IsConsoleError ? LXSS_HANDLE_USE_CONSOLE : HandleToUlong(ErrorHandle);
150
-
151
- // Cache a console handle for GetWindowSize
152
- m_WindowSizeHandle = IsConsoleOutput ? OutputHandle : (IsConsoleError ? ErrorHandle : nullptr);
153
-}
154
-
155
-PLXSS_STD_HANDLES
156
-SvcCommIo::GetStdHandles()
157
-{
158
- return &m_StdHandles;
159
-}
160
-
161
-COORD
162
-SvcCommIo::GetWindowSize() const
163
-{
164
- if (m_WindowSizeHandle)
165
- {
166
- CONSOLE_SCREEN_BUFFER_INFOEX Info{};
167
- Info.cbSize = sizeof(Info);
168
- THROW_IF_WIN32_BOOL_FALSE(GetConsoleScreenBufferInfoEx(m_WindowSizeHandle, &Info));
169
- return {
170
- static_cast<short>(Info.srWindow.Right - Info.srWindow.Left + 1),
171
- static_cast<short>(Info.srWindow.Bottom - Info.srWindow.Top + 1)};
172
- }
173
-
174
- LOG_HR_MSG(E_UNEXPECTED, "No console handle available for GetWindowSize");
175
- return {80, 24};
176
-}
177
-
178
-} // namespace wsl::windows::common
src/windows/common/svccommio.hpp
deleted
-74
@@ -1,74 +0,0 @@
1
-/*++
2
-
3
-Copyright (c) Microsoft. All rights reserved.
4
-
5
-Module Name:
6
-
7
- svccommio.hpp
8
-
9
-Abstract:
10
-
11
- This file contains function declarations for the SvcCommIo helper class.
12
-
13
---*/
14
-
15
-#pragma once
16
-
17
-#include <optional>
18
-#include <wil/filesystem.h>
19
-#include <wil/result.h>
20
-#include "wslservice.h"
21
-
22
-namespace wsl::windows::common {
23
-
24
-// RAII wrapper for console input configuration and restoration
25
-class ConsoleInput
26
-{
27
-public:
28
- ConsoleInput(HANDLE Handle, DWORD SavedMode);
29
- ~ConsoleInput();
30
- ConsoleInput(const ConsoleInput&) = delete;
31
- ConsoleInput& operator=(const ConsoleInput&) = delete;
32
- ConsoleInput(ConsoleInput&&) = delete;
33
- ConsoleInput& operator=(ConsoleInput&&) = delete;
34
-
35
-private:
36
- HANDLE m_Handle{};
37
- DWORD m_SavedMode{};
38
- UINT m_SavedCodePage{};
39
-};
40
-
41
-// RAII wrapper for console output configuration and restoration
42
-class ConsoleOutput
43
-{
44
-public:
45
- ConsoleOutput(wil::unique_hfile&& ConsoleHandle, DWORD SavedMode);
46
- ~ConsoleOutput();
47
- ConsoleOutput(const ConsoleOutput&) = delete;
48
- ConsoleOutput& operator=(const ConsoleOutput&) = delete;
49
- ConsoleOutput(ConsoleOutput&&) = delete;
50
- ConsoleOutput& operator=(ConsoleOutput&&) = delete;
51
-
52
-private:
53
- wil::unique_hfile m_ConsoleHandle;
54
- DWORD m_SavedMode{};
55
- UINT m_SavedCodePage{};
56
-};
57
-
58
-class SvcCommIo
59
-{
60
-public:
61
- SvcCommIo();
62
-
63
- PLXSS_STD_HANDLES GetStdHandles();
64
- COORD GetWindowSize() const;
65
-
66
-private:
67
- LXSS_STD_HANDLES m_StdHandles{};
68
- HANDLE m_WindowSizeHandle = nullptr; // Cached console handle for GetWindowSize
69
-
70
- // RAII members for automatic restoration
71
- std::optional<ConsoleInput> m_ConsoleInput;
72
- std::optional<ConsoleOutput> m_ConsoleOutput;
73
-};
74
-} // namespace wsl::windows::common
src/windows/common/wslutil.cpp
+11
-7
@@ -209,13 +209,6 @@ wil::unique_hlocal_string GetWinInetErrorString(HRESULT error)
209
return message;
210
}
211
212
-bool IsInteractiveConsole()
213
-{
214
- const HANDLE stdinHandle = GetStdHandle(STD_INPUT_HANDLE);
215
- DWORD mode{};
216
- return GetFileType(stdinHandle) == FILE_TYPE_CHAR && GetConsoleMode(stdinHandle, &mode);
217
-}
218
-
212
bool IsWinInetError(HRESULT error)
213
{
214
const DWORD code = error - 0x80070000;
@@ -1144,6 +1137,17 @@ void wsl::windows::common::wslutil::InitializeWil()
1137
}
1138
}
1139
1140
+bool wsl::windows::common::wslutil::IsConsoleHandle(HANDLE Handle)
1141
+{
1142
+ DWORD Mode;
1143
+ return GetFileType(Handle) == FILE_TYPE_CHAR && GetConsoleMode(Handle, &Mode);
1144
+}
1145
+
1146
+bool wsl::windows::common::wslutil::IsInteractiveConsole()
1147
+{
1148
+ return IsConsoleHandle(GetStdHandle(STD_INPUT_HANDLE));
1149
+}
1150
+
1151
bool wsl::windows::common::wslutil::IsRunningInMsix()
1152
{
1153
UINT32 dummy{};
src/windows/common/wslutil.h
+4
@@ -137,6 +137,10 @@ std::vector<BYTE> HashFile(HANDLE File, DWORD Algorithm);
137
138
void InitializeWil();
139
140
+bool IsConsoleHandle(HANDLE Handle);
141
+
142
+bool IsInteractiveConsole();
143
+
144
bool IsRunningInMsix();
145
146
bool IsVhdFile(_In_ const std::filesystem::path& path);