diff --git a/lib/win_util.cpp b/lib/win_util.cpp index bcc16b95f4..d9b70f9cc9 100644 --- a/lib/win_util.cpp +++ b/lib/win_util.cpp @@ -26,9 +26,8 @@ #include "str_replace.h" #include "str_util.h" -/** - * This function terminates a process by process id instead of a handle. - **/ +// terminate a process by process ID instead of a handle. +// BOOL TerminateProcessById( DWORD dwProcessID ) { HANDLE hProcess; BOOL bRetVal = FALSE; @@ -187,3 +186,50 @@ char* windows_format_error_string( return pszBuf; } + +// WSL_CMD: run commands in a WSL distro + +typedef HRESULT(WINAPI *PWslLaunch)( + PCWSTR, PCWSTR, BOOL, HANDLE, HANDLE, HANDLE, HANDLE* +); + +static PWslLaunch pWslLaunch = NULL; +static HINSTANCE wsl_lib = NULL; + +int WSL_CMD::setup() { + in_read = NULL; + in_write = NULL; + out_read = NULL; + out_write = NULL; + + if (!pWslLaunch) { + wsl_lib = LoadLibraryA("wslapi.dll"); + if (!wsl_lib) return -1; + pWslLaunch = (PWslLaunch)GetProcAddress(wsl_lib, "WslLaunch"); + if (!pWslLaunch) return -1; + } + + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.bInheritHandle = TRUE; + sa.lpSecurityDescriptor = NULL; + + if (!CreatePipe(&out_read, &out_write, &sa, 0)) return -1; + if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) return -1; + if (!CreatePipe(&in_read, &in_write, &sa, 0)) return -1; + if (!SetHandleInformation(in_write, HANDLE_FLAG_INHERIT, 0)) return -1; + return 0; +} + +int WSL_CMD::run_command( + const std::string distro_name, const std::string command, + HANDLE* proc_handle, bool use_cwd +) { + HRESULT ret = pWslLaunch( + boinc_ascii_to_wide(distro_name).c_str(), + boinc_ascii_to_wide(command).c_str(), + use_cwd, in_read, out_write, out_write, + proc_handle + ); + return (ret == S_OK)?0:-1; +} diff --git a/lib/win_util.h b/lib/win_util.h index 35345e70e4..4dadc85b96 100644 --- a/lib/win_util.h +++ b/lib/win_util.h @@ -28,4 +28,29 @@ extern char* windows_format_error_string( unsigned long dwError, char* pszBuf, int iSize ... ); +// struct for running a WSL command, connected via pipes +// +struct WSL_CMD { + HANDLE in_read = NULL; + HANDLE in_write = NULL; + HANDLE out_read = NULL; + HANDLE out_write = NULL; + + ~WSL_CMD() { + if (in_read) CloseHandle(in_read); + if (in_write) CloseHandle(in_write); + if (out_read) CloseHandle(out_read); + if (out_write) CloseHandle(out_write); + } + + int setup(); + + // run command, direct both stdout and stderr to the out pipe + // + int run_command( + const std::string distro_name, const std::string command, + HANDLE* proc_handle, bool use_cwd = false + ); +}; + #endif diff --git a/lib/wslinfo.cpp b/lib/wslinfo.cpp index 610eff4285..8e6b9582af 100644 --- a/lib/wslinfo.cpp +++ b/lib/wslinfo.cpp @@ -15,16 +15,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . -#ifdef _WIN64 -#include "win_util.h" -#endif - #include "wslinfo.h" -WSL_DISTRO::WSL_DISTRO() { - clear(); -} - void WSL_DISTRO::clear() { distro_name = ""; os_name = ""; @@ -116,50 +108,3 @@ int WSL_DISTROS::parse(XML_PARSER& xp) { } return ERR_XML_PARSE; } - -#ifdef _WIN64 -typedef HRESULT(WINAPI *PWslLaunch)( - PCWSTR, PCWSTR, BOOL, HANDLE, HANDLE, HANDLE, HANDLE* -); - -static PWslLaunch pWslLaunch = NULL; -static HINSTANCE wsl_lib = NULL; - -int WSL_CMD::setup() { - in_read = NULL; - in_write = NULL; - out_read = NULL; - out_write = NULL; - - if (!pWslLaunch) { - wsl_lib = LoadLibraryA("wslapi.dll"); - if (!wsl_lib) return -1; - pWslLaunch = (PWslLaunch)GetProcAddress(wsl_lib, "WslLaunch"); - if (!pWslLaunch) return -1; - } - - SECURITY_ATTRIBUTES sa; - sa.nLength = sizeof(SECURITY_ATTRIBUTES); - sa.bInheritHandle = TRUE; - sa.lpSecurityDescriptor = NULL; - - if (!CreatePipe(&out_read, &out_write, &sa, 0)) return -1; - if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) return -1; - if (!CreatePipe(&in_read, &in_write, &sa, 0)) return -1; - if (!SetHandleInformation(in_write, HANDLE_FLAG_INHERIT, 0)) return -1; - return 0; -} - -int WSL_CMD::run_command( - const std::string distro_name, const std::string command, - HANDLE* proc_handle, bool use_cwd -) { - HRESULT ret = pWslLaunch( - boinc_ascii_to_wide(distro_name).c_str(), - boinc_ascii_to_wide(command).c_str(), - use_cwd, in_read, out_write, out_write, - proc_handle - ); - return (ret == S_OK)?0:-1; -} -#endif // _WIN64 diff --git a/lib/wslinfo.h b/lib/wslinfo.h index c54b71e192..ba041dca4d 100644 --- a/lib/wslinfo.h +++ b/lib/wslinfo.h @@ -15,6 +15,9 @@ // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see . +// structs describing WSL (Windows Subsystem for Linux) distros. +// Used in Win client and also in server code (for plan class logic) + #ifndef BOINC_WSLINFO_H #define BOINC_WSLINFO_H @@ -45,7 +48,9 @@ struct WSL_DISTRO { std::string docker_compose_version; // version of Docker Compose - WSL_DISTRO(); + WSL_DISTRO(){ + clear(); + }; void clear(); void write_xml(MIOFILE&); int parse(XML_PARSER&); @@ -62,31 +67,4 @@ struct WSL_DISTROS { int parse(XML_PARSER&); }; -#ifdef _WIN64 -// struct for running a WSL command, connected via pipes -// -struct WSL_CMD { - HANDLE in_read = NULL; - HANDLE in_write = NULL; - HANDLE out_read = NULL; - HANDLE out_write = NULL; - - ~WSL_CMD() { - if (in_read) CloseHandle(in_read); - if (in_write) CloseHandle(in_write); - if (out_read) CloseHandle(out_read); - if (out_write) CloseHandle(out_write); - } - - int setup(); - - // run command, direct both stdout and stderr to the out pipe - // - int run_command( - const std::string distro_name, const std::string command, - HANDLE* proc_handle, bool use_cwd = false - ); -}; -#endif - #endif