github.com/containers/podman/v4@v4.9.4/contrib/win-installer/podman-msihooks/check.c (about)

     1  #include <windows.h>
     2  #include <MsiQuery.h>
     3  
     4  BOOL isWSLEnabled();
     5  LPCWSTR 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) {
    24  	BOOL hasWSL = isWSLEnabled();
    25  	// Set a property with the WSL state for the installer to operate on
    26  	MsiSetPropertyW(hInstall, L"HAS_WSLFEATURE", boolToNStr(hasWSL));
    27  
    28  	return 0;
    29  }
    30  
    31  LPCWSTR boolToNStr(BOOL bool) {
    32  	return bool ? L"1" : L"0";
    33  }
    34  
    35  BOOL 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  	 */
    41  	STARTUPINFOW startup;
    42  	PROCESS_INFORMATION process;
    43  
    44  	ZeroMemory(&startup, sizeof(STARTUPINFOW));
    45  	startup.cb = sizeof(STARTUPINFOW);
    46  
    47  	// These settings hide the console window, so there is no annoying flash
    48  	startup.dwFlags = STARTF_USESHOWWINDOW;
    49  	startup.wShowWindow = SW_HIDE;
    50  
    51  	// CreateProcessW requires lpCommandLine to be mutable
    52  	wchar_t cmd[] = L"wsl --set-default-version 2";
    53  	if (! CreateProcessW(NULL, cmd, NULL, NULL, FALSE, CREATE_NEW_CONSOLE,
    54  					     NULL, NULL, &startup, &process)) {
    55  
    56  		return FALSE;
    57  	}
    58  
    59  	DWORD exitCode;
    60  	WaitForSingleObject(process.hProcess, INFINITE);
    61  	if (! GetExitCodeProcess(process.hProcess, &exitCode)) {
    62  		return FALSE;
    63  	}
    64  
    65  	return exitCode == 0;
    66  }