diff --git a/src/win/tty.c b/src/win/tty.c index a98fe263..07436dc8 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -2280,6 +2280,8 @@ static void uv__determine_vterm_state(HANDLE handle) { static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param) { CONSOLE_SCREEN_BUFFER_INFO sb_info; + NTSTATUS status; + ULONG_PTR conhost_pid; MSG msg; if (!GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info)) @@ -2288,14 +2290,29 @@ static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param) { uv__tty_console_width = sb_info.dwSize.X; uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1; - if (pSetWinEventHook == NULL) + if (pSetWinEventHook == NULL || pNtQueryInformationProcess == NULL) return 0; + status = pNtQueryInformationProcess(GetCurrentProcess(), + ProcessConsoleHostProcess, + &conhost_pid, + sizeof(conhost_pid), + NULL); + + if (!NT_SUCCESS(status)) + /* We couldn't retrieve our console host process, probably because this + * is a 32-bit process running on 64-bit Windows. Fall back to receiving + * console events from all processes. */ + conhost_pid = 0; + + /* Ensure the PID is a multiple of 4, which is required by SetWinEventHook */ + conhost_pid &= ~(ULONG_PTR)0x3; + if (!pSetWinEventHook(EVENT_CONSOLE_LAYOUT, EVENT_CONSOLE_LAYOUT, NULL, uv__tty_console_resize_event, - 0, + (DWORD)conhost_pid, 0, WINEVENT_OUTOFCONTEXT)) return 0; diff --git a/src/win/winapi.c b/src/win/winapi.c index fbbbceed..19e4377f 100644 --- a/src/win/winapi.c +++ b/src/win/winapi.c @@ -34,6 +34,7 @@ sNtSetInformationFile pNtSetInformationFile; sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile; sNtQueryDirectoryFile pNtQueryDirectoryFile; sNtQuerySystemInformation pNtQuerySystemInformation; +sNtQueryInformationProcess pNtQueryInformationProcess; /* Kernel32 function pointers */ sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; @@ -106,6 +107,13 @@ void uv_winapi_init(void) { uv_fatal_error(GetLastError(), "GetProcAddress"); } + pNtQueryInformationProcess = (sNtQueryInformationProcess) GetProcAddress( + ntdll_module, + "NtQueryInformationProcess"); + if (pNtQueryInformationProcess == NULL) { + uv_fatal_error(GetLastError(), "GetProcAddress"); + } + kernel32_module = GetModuleHandleA("kernel32.dll"); if (kernel32_module == NULL) { uv_fatal_error(GetLastError(), "GetModuleHandleA"); diff --git a/src/win/winapi.h b/src/win/winapi.h index 82c5ed46..203393c2 100644 --- a/src/win/winapi.h +++ b/src/win/winapi.h @@ -4436,6 +4436,10 @@ typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { # define SystemProcessorPerformanceInformation 8 #endif +#ifndef ProcessConsoleHostProcess +# define ProcessConsoleHostProcess 49 +#endif + #ifndef FILE_DEVICE_FILE_SYSTEM # define FILE_DEVICE_FILE_SYSTEM 0x00000009 #endif @@ -4578,6 +4582,13 @@ typedef NTSTATUS (NTAPI *sNtQueryDirectoryFile) BOOLEAN RestartScan ); +typedef NTSTATUS (NTAPI *sNtQueryInformationProcess) + (HANDLE ProcessHandle, + UINT ProcessInformationClass, + PVOID ProcessInformation, + ULONG Length, + PULONG ReturnLength); + /* * Kernel32 headers */ @@ -4718,6 +4729,7 @@ extern sNtSetInformationFile pNtSetInformationFile; extern sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile; extern sNtQueryDirectoryFile pNtQueryDirectoryFile; extern sNtQuerySystemInformation pNtQuerySystemInformation; +extern sNtQueryInformationProcess pNtQueryInformationProcess; /* Kernel32 function pointers */ extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;