|
|
|
@ -1,10 +1,207 @@
|
|
|
|
|
use std::io;
|
|
|
|
|
use std::io::Write;
|
|
|
|
|
use windows::Win32::{Foundation::GetLastError, System::Console};
|
|
|
|
|
|
|
|
|
|
fn print_input_mode(mode: Console::CONSOLE_MODE) {
|
|
|
|
|
// Characters read by the ReadFile or ReadConsole function are written to the active screen
|
|
|
|
|
// buffer as they are typed into the console. This mode can be used only if the
|
|
|
|
|
// ENABLE_LINE_INPUT mode is also enabled.
|
|
|
|
|
if (mode & Console::ENABLE_ECHO_INPUT).0 > 0 {
|
|
|
|
|
println!("Echo Input: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("Echo Input: Disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// When enabled, text entered in a console window will be inserted at the current cursor
|
|
|
|
|
// location and all text following that location will not be overwritten. When disabled, all
|
|
|
|
|
// following text will be overwritten.
|
|
|
|
|
if (mode & Console::ENABLE_INSERT_MODE).0 > 0 {
|
|
|
|
|
println!("Insert Mode: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("Insert Mode: Disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The ReadFile or ReadConsole function returns only when a carriage return character is read.
|
|
|
|
|
// If this mode is disabled, the functions return when one or more characters are available.
|
|
|
|
|
if (mode & Console::ENABLE_LINE_INPUT).0 > 0 {
|
|
|
|
|
println!("Line Input Mode: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("Line Input Mode: Disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the mouse pointer is within the borders of the console window and the window has the
|
|
|
|
|
// keyboard focus, mouse events generated by mouse movement and button presses are placed in
|
|
|
|
|
// the input buffer. These events are discarded by ReadFile or ReadConsole, even when this mode
|
|
|
|
|
// is enabled. The ReadConsoleInput function can be used to read MOUSE_EVENT input records from
|
|
|
|
|
// the input buffer.
|
|
|
|
|
if (mode & Console::ENABLE_MOUSE_INPUT).0 > 0 {
|
|
|
|
|
println!("Mouse Input: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("Mouse Input: Disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CTRL+C is processed by the system and is not placed in the input buffer. If the input buffer
|
|
|
|
|
// is being read by ReadFile or ReadConsole, other control keys are processed by the system and
|
|
|
|
|
// are not returned in the ReadFile or ReadConsole buffer. If the ENABLE_LINE_INPUT mode is
|
|
|
|
|
// also enabled, backspace, carriage return, and line feed characters are handled by the
|
|
|
|
|
// system.
|
|
|
|
|
if (mode & Console::ENABLE_PROCESSED_INPUT).0 > 0 {
|
|
|
|
|
println!("Processed Input: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("Processed Input: Disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This flag enables the user to use the mouse to select and edit text. To enable this mode,
|
|
|
|
|
// use ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS. To disable this mode, use
|
|
|
|
|
// ENABLE_EXTENDED_FLAGS without this flag.
|
|
|
|
|
if (mode & Console::ENABLE_QUICK_EDIT_MODE).0 > 0 {
|
|
|
|
|
println!("Quick Edit Mode: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("Quick Edit Mode: Disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// User interactions that change the size of the console screen buffer are reported in the
|
|
|
|
|
// console's input buffer. Information about these events can be read from the input buffer by
|
|
|
|
|
// applications using the ReadConsoleInput function, but not by those using ReadFile or
|
|
|
|
|
// ReadConsole.
|
|
|
|
|
if (mode & Console::ENABLE_WINDOW_INPUT).0 > 0 {
|
|
|
|
|
println!("Window Input: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("Window Input: Disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Setting this flag directs the Virtual Terminal processing engine to convert user input
|
|
|
|
|
// received by the console window into Console Virtual Terminal Sequences that can be retrieved
|
|
|
|
|
// by a supporting application through ReadFile or ReadConsole functions.
|
|
|
|
|
//
|
|
|
|
|
// The typical usage of this flag is intended in conjunction with
|
|
|
|
|
// ENABLE_VIRTUAL_TERMINAL_PROCESSING on the output handle to connect to an application that
|
|
|
|
|
// communicates exclusively via virtual terminal sequences.
|
|
|
|
|
if (mode & Console::ENABLE_VIRTUAL_TERMINAL_INPUT).0 > 0 {
|
|
|
|
|
println!("Virtual Terminal Input: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("Virtual Terminal Input: Disabled");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn print_output_mode(mode: Console::CONSOLE_MODE) {
|
|
|
|
|
// Characters written by the WriteFile or WriteConsole function or echoed by the ReadFile or
|
|
|
|
|
// ReadConsole function are parsed for ASCII control sequences, and the correct action is
|
|
|
|
|
// performed. Backspace, tab, bell, carriage return, and line feed characters are processed. It
|
|
|
|
|
// should be enabled when using control sequences or when ENABLE_VIRTUAL_TERMINAL_PROCESSING is
|
|
|
|
|
// set.
|
|
|
|
|
if (mode & Console::ENABLE_PROCESSED_OUTPUT).0 > 0 {
|
|
|
|
|
println!("Processed Output: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("Processed Output: Disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// When writing with WriteFile or WriteConsole or echoing with ReadFile or ReadConsole, the
|
|
|
|
|
// cursor moves to the beginning of the next row when it reaches the end of the current row.
|
|
|
|
|
// This causes the rows displayed in the console window to scroll up automatically when the
|
|
|
|
|
// cursor advances beyond the last row in the window. It also causes the contents of the
|
|
|
|
|
// console screen buffer to scroll up (../discarding the top row of the console screen buffer)
|
|
|
|
|
// when the cursor advances beyond the last row in the console screen buffer. If this mode is
|
|
|
|
|
// disabled, the last character in the row is overwritten with any subsequent characters.
|
|
|
|
|
if (mode & Console::ENABLE_WRAP_AT_EOL_OUTPUT).0 > 0 {
|
|
|
|
|
println!("Wrap at EOL: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("Wrap at EOL: Disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// When writing with WriteFile or WriteConsole, characters are parsed for VT100 and similar
|
|
|
|
|
// control character sequences that control cursor movement, color/font mode, and other
|
|
|
|
|
// operations that can also be performed via the existing Console APIs. For more information,
|
|
|
|
|
// see Console Virtual Terminal Sequences.
|
|
|
|
|
//
|
|
|
|
|
// Ensure ENABLE_PROCESSED_OUTPUT is set when using this flag.
|
|
|
|
|
if (mode & Console::ENABLE_VIRTUAL_TERMINAL_PROCESSING).0 > 0 {
|
|
|
|
|
println!("Terminal Processing: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("Terminal Processing: Disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// When writing with WriteFile or WriteConsole, this adds an additional state to end-of-line
|
|
|
|
|
// wrapping that can delay the cursor move and buffer scroll operations.
|
|
|
|
|
//
|
|
|
|
|
// Normally when ENABLE_WRAP_AT_EOL_OUTPUT is set and text reaches the end of the line, the
|
|
|
|
|
// cursor will immediately move to the next line and the contents of the buffer will scroll up
|
|
|
|
|
// by one line. In contrast with this flag set, the cursor does not move to the next line, and
|
|
|
|
|
// the scroll operation is not performed. The written character will be printed in the final
|
|
|
|
|
// position on the line and the cursor will remain above this character as if
|
|
|
|
|
// ENABLE_WRAP_AT_EOL_OUTPUT was off, but the next printable character will be printed as if
|
|
|
|
|
// ENABLE_WRAP_AT_EOL_OUTPUT is on. No overwrite will occur. Specifically, the cursor quickly
|
|
|
|
|
// advances down to the following line, a scroll is performed if necessary, the character is
|
|
|
|
|
// printed, and the cursor advances one more position.
|
|
|
|
|
//
|
|
|
|
|
// The typical usage of this flag is intended in conjunction with setting
|
|
|
|
|
// ENABLE_VIRTUAL_TERMINAL_PROCESSING to better emulate a terminal emulator where writing the
|
|
|
|
|
// final character on the screen (../in the bottom right corner) without triggering an
|
|
|
|
|
// immediate scroll is the desired behavior.
|
|
|
|
|
if (mode & Console::DISABLE_NEWLINE_AUTO_RETURN).0 > 0 {
|
|
|
|
|
println!("Newline Auto Return: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("Newline Auto Return: Disabled");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The APIs for writing character attributes including WriteConsoleOutput and
|
|
|
|
|
// WriteConsoleOutputAttribute allow the usage of flags from character attributes to adjust the
|
|
|
|
|
// color of the foreground and background of text. Additionally, a range of DBCS flags was
|
|
|
|
|
// specified with the COMMON_LVB prefix. Historically, these flags only functioned in DBCS code
|
|
|
|
|
// pages for Chinese, Japanese, and Korean languages.
|
|
|
|
|
//
|
|
|
|
|
// With exception of the leading byte and trailing byte flags, the remaining flags describing
|
|
|
|
|
// line drawing and reverse video (../swap foreground and background colors) can be useful for
|
|
|
|
|
// other languages to emphasize portions of output.
|
|
|
|
|
//
|
|
|
|
|
// Setting this console mode flag will allow these attributes to be used in every code page on
|
|
|
|
|
// every language.
|
|
|
|
|
//
|
|
|
|
|
// It is off by default to maintain compatibility with known applications that have
|
|
|
|
|
// historically taken advantage of the console ignoring these flags on non-CJK machines to
|
|
|
|
|
// store bits in these fields for their own purposes or by accident.
|
|
|
|
|
//
|
|
|
|
|
// Note that using the ENABLE_VIRTUAL_TERMINAL_PROCESSING mode can result in LVB grid and
|
|
|
|
|
// reverse video flags being set while this flag is still off if the attached application
|
|
|
|
|
// requests underlining or inverse video via Console Virtual Terminal Sequences.
|
|
|
|
|
if (mode & Console::ENABLE_LVB_GRID_WORLDWIDE).0 > 0 {
|
|
|
|
|
println!("LVB Grid: Enabled");
|
|
|
|
|
} else {
|
|
|
|
|
println!("LVB Grid: Disabled");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let stdin = io::stdin();
|
|
|
|
|
let mut stdout = io::stdout();
|
|
|
|
|
|
|
|
|
|
let mut mode = Console::CONSOLE_MODE(0);
|
|
|
|
|
unsafe {
|
|
|
|
|
let handle = Console::GetStdHandle(Console::STD_INPUT_HANDLE).unwrap();
|
|
|
|
|
if Console::GetConsoleMode(handle, &mut mode).as_bool() {
|
|
|
|
|
println!("Stdin details:");
|
|
|
|
|
print_input_mode(mode);
|
|
|
|
|
} else {
|
|
|
|
|
let err = GetLastError();
|
|
|
|
|
println!(
|
|
|
|
|
"Unable to get console mode: {:?}",
|
|
|
|
|
err.to_hresult().message()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let handle = Console::GetStdHandle(Console::STD_OUTPUT_HANDLE).unwrap();
|
|
|
|
|
if Console::GetConsoleMode(handle, &mut mode).as_bool() {
|
|
|
|
|
println!("Stdout details:");
|
|
|
|
|
print_output_mode(mode);
|
|
|
|
|
} else {
|
|
|
|
|
let err = GetLastError();
|
|
|
|
|
println!(
|
|
|
|
|
"Unable to get console mode: {:?}",
|
|
|
|
|
err.to_hresult().message()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let stdin = io::stdin();
|
|
|
|
|
let mut line = String::new();
|
|
|
|
|
loop {
|
|
|
|
|
if let Err(_) = stdout.write(b"> ") {
|
|
|
|
@ -15,7 +212,11 @@ fn main() {
|
|
|
|
|
}
|
|
|
|
|
match stdin.read_line(&mut line) {
|
|
|
|
|
Ok(_) => {
|
|
|
|
|
if let Err(_) = stdout.write(b"ok\n") {
|
|
|
|
|
if let Err(_) = stdout.write(
|
|
|
|
|
String::from("\u{001b}[31m ok \u{001b}[0m\n")
|
|
|
|
|
.as_str()
|
|
|
|
|
.as_bytes(),
|
|
|
|
|
) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|