summaryrefslogtreecommitdiffstats
path: root/platform/windows/os_windows.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/windows/os_windows.cpp')
-rw-r--r--platform/windows/os_windows.cpp153
1 files changed, 149 insertions, 4 deletions
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index bff3443214..b3ae58212a 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;
@@ -1639,16 +1685,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) {