From e8c6fcdd4eaf70a6d7c9ee3448ed1f7718d52f20 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Thu, 19 Jun 2025 21:55:54 -0400 Subject: [PATCH] Add support for Client Named Pipe on Windows --- src/device/serial_passthrough.c | 2 -- src/qt/win_serial_passthrough.c | 36 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/device/serial_passthrough.c b/src/device/serial_passthrough.c index 479c1dc24..426bfbc7b 100644 --- a/src/device/serial_passthrough.c +++ b/src/device/serial_passthrough.c @@ -246,9 +246,7 @@ static const device_config_t serial_passthrough_config[] = { .selection = { #ifdef _WIN32 { .description = "Named Pipe (Server)", .value = SERPT_MODE_NPIPE_SRV }, -#if 0 /* TODO */ { .description = "Named Pipe (Client)", .value = SERPT_MODE_NPIPE_CLNT }, -#endif #else /* _WIN32 */ { .description = "Pseudo Terminal/Virtual Console", .value = SERPT_MODE_VCON }, #endif /* _WIN32 */ diff --git a/src/qt/win_serial_passthrough.c b/src/qt/win_serial_passthrough.c index e17d70f16..725dc096f 100644 --- a/src/qt/win_serial_passthrough.c +++ b/src/qt/win_serial_passthrough.c @@ -189,6 +189,38 @@ open_pseudo_terminal(serial_passthrough_t *dev) return 1; } +static int +connect_named_pipe_client(serial_passthrough_t *dev) +{ + char ascii_pipe_name[1024] = { 0 }; + strncpy(ascii_pipe_name, dev->named_pipe, sizeof(ascii_pipe_name) - 1); + + HANDLE hPipe = CreateFileA( + ascii_pipe_name, // pipe name + GENERIC_READ | GENERIC_WRITE, + 0, // no sharing + NULL, // default security attributes + OPEN_EXISTING, // open existing pipe + 0, // default attributes + NULL); // no template file + + if (hPipe == INVALID_HANDLE_VALUE) { + DWORD error = GetLastError(); + wchar_t errorMsg[1024] = { 0 }; + wchar_t finalMsg[1024] = { 0 }; + FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errorMsg, 1024, NULL); + swprintf(finalMsg, 1024, L"Named Pipe (client, named_pipe=\"%hs\", port=COM%d): %ls\n", ascii_pipe_name, dev->port + 1, errorMsg); + ui_msgbox(MBX_ERROR | MBX_FATAL, finalMsg); + return 0; + } + + DWORD mode = PIPE_READMODE_BYTE | PIPE_NOWAIT; + SetNamedPipeHandleState(hPipe, &mode, NULL, NULL); + dev->master_fd = (intptr_t) hPipe; + pclog("Named Pipe client connected to %s\n", ascii_pipe_name); + return 1; +} + static int open_host_serial_port(serial_passthrough_t *dev) { @@ -228,6 +260,10 @@ plat_serpt_open_device(void *priv) if (open_pseudo_terminal(dev)) return 0; break; + case SERPT_MODE_NPIPE_CLNT: + if (connect_named_pipe_client(dev)) + return 0; + break; case SERPT_MODE_HOSTSER: if (open_host_serial_port(dev)) return 0;