summaryrefslogtreecommitdiffstats
path: root/platform
diff options
context:
space:
mode:
authorThaddeus Crews <repiteo@outlook.com>2024-11-12 12:13:12 -0600
committerThaddeus Crews <repiteo@outlook.com>2024-11-12 12:13:12 -0600
commit179321a0a3decf8b2b759160b348f4b969465089 (patch)
tree50a0c242263b28a7794d5b55e38628a53771e8f7 /platform
parentf1d31304b2e165af74a5af5a2a46b03216f65e0c (diff)
parent76164c2aa9e94a0002ed266ac6b6ba5193801bb3 (diff)
downloadredot-engine-179321a0a3decf8b2b759160b348f4b969465089.tar.gz
Merge pull request #91201 from bruvzg/con_type
[OS] Add functions to determine standard I/O device type.
Diffstat (limited to 'platform')
-rw-r--r--platform/windows/os_windows.cpp153
-rw-r--r--platform/windows/os_windows.h9
-rw-r--r--platform/windows/windows_terminal_logger.cpp4
3 files changed, 160 insertions, 6 deletions
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 294a34bb91..4d253059b2 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -156,6 +156,52 @@ void RedirectIOToConsole() {
}
}
+bool OS_Windows::is_using_con_wrapper() const {
+ static String exe_renames[] = {
+ ".console.exe",
+ "_console.exe",
+ " console.exe",
+ "console.exe",
+ String(),
+ };
+
+ bool found_exe = false;
+ bool found_conwrap_exe = false;
+ String exe_name = get_executable_path().to_lower();
+ String exe_dir = exe_name.get_base_dir();
+ String exe_fname = exe_name.get_file().get_basename();
+
+ DWORD pids[256];
+ DWORD count = GetConsoleProcessList(&pids[0], 256);
+ for (DWORD i = 0; i < count; i++) {
+ HANDLE process = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, pids[i]);
+ if (process != NULL) {
+ WCHAR proc_name[MAX_PATH];
+ DWORD len = MAX_PATH;
+ if (QueryFullProcessImageNameW(process, 0, &proc_name[0], &len)) {
+ String name = String::utf16((const char16_t *)&proc_name[0], len).replace("\\", "/").to_lower();
+ if (name == exe_name) {
+ found_exe = true;
+ }
+ for (int j = 0; !exe_renames[j].is_empty(); j++) {
+ if (name == exe_dir.path_join(exe_fname + exe_renames[j])) {
+ found_conwrap_exe = true;
+ }
+ }
+ }
+ CloseHandle(process);
+ if (found_conwrap_exe && found_exe) {
+ break;
+ }
+ }
+ }
+ if (!found_exe) {
+ return true; // Unable to read console info, assume true.
+ }
+
+ return found_conwrap_exe;
+}
+
BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) {
if (!EngineDebugger::is_active()) {
return FALSE;
@@ -1682,16 +1728,115 @@ void OS_Windows::unset_environment(const String &p_var) const {
SetEnvironmentVariableW((LPCWSTR)(p_var.utf16().get_data()), nullptr); // Null to delete.
}
-String OS_Windows::get_stdin_string() {
- char buff[1024];
+String OS_Windows::get_stdin_string(int64_t p_buffer_size) {
+ if (get_stdin_type() == STD_HANDLE_INVALID) {
+ return String();
+ }
+
+ Vector<uint8_t> data;
+ data.resize(p_buffer_size);
DWORD count = 0;
- if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buff, 1024, &count, nullptr)) {
- return String::utf8((const char *)buff, count);
+ if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), data.ptrw(), data.size(), &count, nullptr)) {
+ return String::utf8((const char *)data.ptr(), count);
}
return String();
}
+PackedByteArray OS_Windows::get_stdin_buffer(int64_t p_buffer_size) {
+ Vector<uint8_t> data;
+ data.resize(p_buffer_size);
+ DWORD count = 0;
+ if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), data.ptrw(), data.size(), &count, nullptr)) {
+ return data;
+ }
+
+ return PackedByteArray();
+}
+
+OS_Windows::StdHandleType OS_Windows::get_stdin_type() const {
+ HANDLE h = GetStdHandle(STD_INPUT_HANDLE);
+ if (h == 0 || h == INVALID_HANDLE_VALUE) {
+ return STD_HANDLE_INVALID;
+ }
+ DWORD ftype = GetFileType(h);
+ if (ftype == FILE_TYPE_UNKNOWN && GetLastError() != ERROR_SUCCESS) {
+ return STD_HANDLE_UNKNOWN;
+ }
+ ftype &= ~(FILE_TYPE_REMOTE);
+
+ if (ftype == FILE_TYPE_DISK) {
+ return STD_HANDLE_FILE;
+ } else if (ftype == FILE_TYPE_PIPE) {
+ return STD_HANDLE_PIPE;
+ } else {
+ DWORD conmode = 0;
+ BOOL res = GetConsoleMode(h, &conmode);
+ if (!res && (GetLastError() == ERROR_INVALID_HANDLE)) {
+ return STD_HANDLE_UNKNOWN; // Unknown character device.
+ } else {
+#ifndef WINDOWS_SUBSYSTEM_CONSOLE
+ if (!is_using_con_wrapper()) {
+ return STD_HANDLE_INVALID; // Window app can't read stdin input without werapper.
+ }
+#endif
+ return STD_HANDLE_CONSOLE;
+ }
+ }
+}
+
+OS_Windows::StdHandleType OS_Windows::get_stdout_type() const {
+ HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (h == 0 || h == INVALID_HANDLE_VALUE) {
+ return STD_HANDLE_INVALID;
+ }
+ DWORD ftype = GetFileType(h);
+ if (ftype == FILE_TYPE_UNKNOWN && GetLastError() != ERROR_SUCCESS) {
+ return STD_HANDLE_UNKNOWN;
+ }
+ ftype &= ~(FILE_TYPE_REMOTE);
+
+ if (ftype == FILE_TYPE_DISK) {
+ return STD_HANDLE_FILE;
+ } else if (ftype == FILE_TYPE_PIPE) {
+ return STD_HANDLE_PIPE;
+ } else {
+ DWORD conmode = 0;
+ BOOL res = GetConsoleMode(h, &conmode);
+ if (!res && (GetLastError() == ERROR_INVALID_HANDLE)) {
+ return STD_HANDLE_UNKNOWN; // Unknown character device.
+ } else {
+ return STD_HANDLE_CONSOLE;
+ }
+ }
+}
+
+OS_Windows::StdHandleType OS_Windows::get_stderr_type() const {
+ HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
+ if (h == 0 || h == INVALID_HANDLE_VALUE) {
+ return STD_HANDLE_INVALID;
+ }
+ DWORD ftype = GetFileType(h);
+ if (ftype == FILE_TYPE_UNKNOWN && GetLastError() != ERROR_SUCCESS) {
+ return STD_HANDLE_UNKNOWN;
+ }
+ ftype &= ~(FILE_TYPE_REMOTE);
+
+ if (ftype == FILE_TYPE_DISK) {
+ return STD_HANDLE_FILE;
+ } else if (ftype == FILE_TYPE_PIPE) {
+ return STD_HANDLE_PIPE;
+ } else {
+ DWORD conmode = 0;
+ BOOL res = GetConsoleMode(h, &conmode);
+ if (!res && (GetLastError() == ERROR_INVALID_HANDLE)) {
+ return STD_HANDLE_UNKNOWN; // Unknown character device.
+ } else {
+ return STD_HANDLE_CONSOLE;
+ }
+ }
+}
+
Error OS_Windows::shell_open(const String &p_uri) {
INT_PTR ret = (INT_PTR)ShellExecuteW(nullptr, nullptr, (LPCWSTR)(p_uri.utf16().get_data()), nullptr, nullptr, SW_SHOWNORMAL);
if (ret > 32) {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index c200ba5b43..a32e535f0b 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -134,6 +134,8 @@ class OS_Windows : public OS {
DWRITE_FONT_WEIGHT _weight_to_dw(int p_weight) const;
DWRITE_FONT_STRETCH _stretch_to_dw(int p_stretch) const;
+ bool is_using_con_wrapper() const;
+
// functions used by main to initialize/deinitialize the OS
protected:
virtual void initialize() override;
@@ -143,7 +145,12 @@ protected:
virtual void finalize() override;
virtual void finalize_core() override;
- virtual String get_stdin_string() override;
+
+ virtual String get_stdin_string(int64_t p_buffer_size = 1024) override;
+ virtual PackedByteArray get_stdin_buffer(int64_t p_buffer_size = 1024) override;
+ virtual StdHandleType get_stdin_type() const override;
+ virtual StdHandleType get_stdout_type() const override;
+ virtual StdHandleType get_stderr_type() const override;
String _quote_command_line_argument(const String &p_text) const;
diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp
index 6c54faa13a..e25c612008 100644
--- a/platform/windows/windows_terminal_logger.cpp
+++ b/platform/windows/windows_terminal_logger.cpp
@@ -30,6 +30,8 @@
#include "windows_terminal_logger.h"
+#include "core/os/os.h"
+
#ifdef WINDOWS_ENABLED
#include <stdio.h>
@@ -78,7 +80,7 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file
}
HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
- if (!hCon || hCon == INVALID_HANDLE_VALUE) {
+ if (OS::get_singleton()->get_stdout_type() != OS::STD_HANDLE_CONSOLE || !hCon || hCon == INVALID_HANDLE_VALUE) {
StdLogger::log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
} else {
CONSOLE_SCREEN_BUFFER_INFO sbi; //original