podman
66 строк · 2.0 Кб
1#include <windows.h>2#include <MsiQuery.h>3
4BOOL isWSLEnabled();5LPCWSTR boolToNStr(BOOL bool);6
7/**
8* CheckWSL is a custom action loaded by the Podman Windows installer
9* to determine whether the system already has WSL installed.
10*
11* The intention is that this action is compiled for x86_64, which
12* can be ran on both Intel and Arm based systems (the latter through
13* emulation). While the code should build fine on MSVC and clang, the
14* intended usage is MingW-W64 (cross-compiling gcc targeting Windows).
15*
16* Previously this was implemented as a Golang c-shared cgo library,
17* however, the WoW x86_64 emulation layer struggled with dynamic
18* hot-loaded transformation of the goruntime into an existing process
19* (required by MSI custom actions). In the future this could be
20* converted back, should the emulation issue be resolved.
21*/
22
23__declspec(dllexport) UINT __cdecl CheckWSL(MSIHANDLE hInstall) {24BOOL hasWSL = isWSLEnabled();25// Set a property with the WSL state for the installer to operate on26MsiSetPropertyW(hInstall, L"HAS_WSLFEATURE", boolToNStr(hasWSL));27
28return 0;29}
30
31LPCWSTR boolToNStr(BOOL bool) {32return bool ? L"1" : L"0";33}
34
35BOOL isWSLEnabled() {36/*37* The simplest, and most reliable check across all variants and versions
38* of WSL appears to be changing the default version to WSL 2 and check
39* for errors, which we need to do anyway.
40*/
41STARTUPINFOW startup;42PROCESS_INFORMATION process;43
44ZeroMemory(&startup, sizeof(STARTUPINFOW));45startup.cb = sizeof(STARTUPINFOW);46
47// These settings hide the console window, so there is no annoying flash48startup.dwFlags = STARTF_USESHOWWINDOW;49startup.wShowWindow = SW_HIDE;50
51// CreateProcessW requires lpCommandLine to be mutable52wchar_t cmd[] = L"wsl --set-default-version 2";53if (! CreateProcessW(NULL, cmd, NULL, NULL, FALSE, CREATE_NEW_CONSOLE,54NULL, NULL, &startup, &process)) {55
56return FALSE;57}58
59DWORD exitCode;60WaitForSingleObject(process.hProcess, INFINITE);61if (! GetExitCodeProcess(process.hProcess, &exitCode)) {62return FALSE;63}64
65return exitCode == 0;66}
67