diff options
author | Simon Rozman <simon@rozman.si> | 2020-11-10 10:24:02 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2020-11-13 14:42:54 +0100 |
commit | 9b12d13c68eb95049cddf8abf24bba0349e8cfe6 (patch) | |
tree | 5303e27d733b08c150b812b55b7062533f8577a9 | |
parent | build: sign ARM and ARM64 binaries (diff) | |
download | wireguard-windows-9b12d13c68eb95049cddf8abf24bba0349e8cfe6.tar.xz wireguard-windows-9b12d13c68eb95049cddf8abf24bba0349e8cfe6.zip |
installer: clean-up adapters and Wintun driver on uninstall
Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r-- | installer/customactions.c | 120 | ||||
-rw-r--r-- | installer/wireguard.wxs | 18 |
2 files changed, 137 insertions, 1 deletions
diff --git a/installer/customactions.c b/installer/customactions.c index 496d80b1..2629cbc8 100644 --- a/installer/customactions.c +++ b/installer/customactions.c @@ -255,12 +255,67 @@ out: return ret == ERROR_SUCCESS ? ret : ERROR_INSTALL_FAILURE; } +__declspec(dllexport) UINT __stdcall EvaluateWireGuardComponents(MSIHANDLE installer) +{ + UINT ret = ERROR_INSTALL_FAILURE; + bool is_com_initialized = SUCCEEDED(CoInitialize(NULL)); + INSTALLSTATE component_installed, component_action; + + ret = MsiGetComponentState(installer, TEXT("WireGuardExecutable"), &component_installed, &component_action); + if (ret != ERROR_SUCCESS) { + log_errorf(installer, LOG_LEVEL_ERR, ret, TEXT("MsiGetComponentState(\"WireGuardExecutable\") failed")); + goto out; + } + if (component_action >= INSTALLSTATE_LOCAL) { + /* WireGuardExecutable component shall be installed or updated. */ + } else if (component_action >= INSTALLSTATE_REMOVED) { + /* WireGuardExecutable component shall be uninstalled. */ + TCHAR path[MAX_PATH]; + DWORD path_len = _countof(path); + + log_messagef(installer, LOG_LEVEL_INFO, TEXT("WireGuardExecutable removal scheduled")); + ret = MsiSetProperty(installer, TEXT("RemoveConfigFolder"), TEXT("remove")); + if (ret != ERROR_SUCCESS) { + log_errorf(installer, LOG_LEVEL_ERR, ret, TEXT("MsiSetProperty(\"RemoveConfigFolder\") failed")); + goto out; + } + ret = MsiGetProperty(installer, TEXT("WireGuardFolder"), path, &path_len); + if (ret != ERROR_SUCCESS) { + log_errorf(installer, LOG_LEVEL_ERR, ret, TEXT("MsiFormatRecord failed")); + goto out; + } + if (!PathAppend(path, TEXT("wireguard.exe"))) { + log_errorf(installer, LOG_LEVEL_ERR, ret = GetLastError(), TEXT("PathAppend(\"%1\", \"wireguard.exe\") failed"), path); + goto out; + } + ret = MsiSetProperty(installer, TEXT("RemoveAdapters"), path); + if (ret != ERROR_SUCCESS) { + log_errorf(installer, LOG_LEVEL_ERR, ret, TEXT("MsiSetProperty(\"RemoveAdapters\") failed")); + goto out; + } + } + ret = ERROR_SUCCESS; + +out: + if (is_com_initialized) + CoUninitialize(); + return ret == ERROR_SUCCESS ? ret : ERROR_INSTALL_FAILURE; +} + __declspec(dllexport) UINT __stdcall RemoveConfigFolder(MSIHANDLE installer) { LSTATUS ret; TCHAR path[MAX_PATH]; + DWORD path_len = _countof(path); bool is_com_initialized = SUCCEEDED(CoInitialize(NULL)); + ret = MsiGetProperty(installer, TEXT("CustomActionData"), path, &path_len); + if (ret != ERROR_SUCCESS) { + log_errorf(installer, LOG_LEVEL_WARN, ret, TEXT("MsiGetProperty(\"CustomActionData\") failed")); + goto out; + } + if (_tcscmp(path, _T("remove"))) + goto out; ret = SHRegGetPath(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\S-1-5-18"), TEXT("ProfileImagePath"), path, 0); if (ret != ERROR_SUCCESS) { @@ -371,3 +426,68 @@ out: CoUninitialize(); return ERROR_SUCCESS; } + +__declspec(dllexport) UINT __stdcall RemoveAdapters(MSIHANDLE installer) +{ + UINT ret; + bool is_com_initialized = SUCCEEDED(CoInitialize(NULL)); + TCHAR path[MAX_PATH]; + DWORD path_len = _countof(path); + HANDLE pipe; + char buf[0x200]; + DWORD offset = 0, size_read; + PROCESS_INFORMATION pi; + STARTUPINFOW si = { + .cb = sizeof(STARTUPINFO), + .dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES, + .wShowWindow = SW_HIDE + }; + + ret = MsiGetProperty(installer, TEXT("CustomActionData"), path, &path_len); + if (ret != ERROR_SUCCESS) { + log_errorf(installer, LOG_LEVEL_WARN, ret, TEXT("MsiGetProperty(\"CustomActionData\") failed")); + goto out; + } + if (!path[0]) + goto out; + + if (!CreatePipe(&pipe, &si.hStdOutput, NULL, 0)) { + log_errorf(installer, LOG_LEVEL_WARN, GetLastError(), TEXT("CreatePipe failed")); + goto out; + } + if (!SetHandleInformation(si.hStdOutput, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { + log_errorf(installer, LOG_LEVEL_WARN, GetLastError(), TEXT("SetHandleInformation failed")); + goto cleanup_pipe_w; + } + if (!CreateProcess(path, TEXT("wireguard /removealladapters"), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { + log_errorf(installer, LOG_LEVEL_WARN, GetLastError(), TEXT("Failed to create \"%1\" process"), path); + goto cleanup_pipe_w; + } + CloseHandle(si.hStdOutput); + buf[sizeof(buf) - 1] = '\0'; + while (ReadFile(pipe, buf + offset, sizeof(buf) - offset - 1, &size_read, NULL)) { + char *nl; + buf[offset + size_read] = '\0'; + nl = strchr(buf, '\n'); + if (!nl) { + offset = size_read; + continue; + } + nl[0] = '\0'; + log_messagef(installer, LOG_LEVEL_INFO, TEXT("%1!hs!"), buf); + offset = strlen(&nl[1]); + memmove(buf, &nl[1], offset); + } + WaitForSingleObject(pi.hProcess, INFINITE); + CloseHandle(pi.hProcess); + goto cleanup_pipe_r; + +cleanup_pipe_w: + CloseHandle(si.hStdOutput); +cleanup_pipe_r: + CloseHandle(pipe); +out: + if (is_com_initialized) + CoUninitialize(); + return ERROR_SUCCESS; +} diff --git a/installer/wireguard.wxs b/installer/wireguard.wxs index 56d00163..8b18189f 100644 --- a/installer/wireguard.wxs +++ b/installer/wireguard.wxs @@ -100,11 +100,27 @@ </InstallExecuteSequence> <!-- + Evaluate WireGuard components + --> + <CustomAction Id="EvaluateWireGuardComponents" BinaryKey="customactions.dll" DllEntry="EvaluateWireGuardComponents" /> + <InstallExecuteSequence> + <Custom Action="EvaluateWireGuardComponents" After="ProcessComponents" /> + </InstallExecuteSequence> + + <!-- Clear out our config folder on uninstall --> <CustomAction Id="RemoveConfigFolder" BinaryKey="customactions.dll" DllEntry="RemoveConfigFolder" Execute="deferred" Impersonate="no" /> <InstallExecuteSequence> - <Custom Action="RemoveConfigFolder" After="DeleteServices">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom> + <Custom Action="RemoveConfigFolder" After="DeleteServices" /> + </InstallExecuteSequence> + + <!-- + Clear out our adapters on uninstall + --> + <CustomAction Id="RemoveAdapters" BinaryKey="customactions.dll" DllEntry="RemoveAdapters" Execute="deferred" Impersonate="no" /> + <InstallExecuteSequence> + <Custom Action="RemoveAdapters" Before="RemoveFiles" /> </InstallExecuteSequence> <!-- |