aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorSimon Rozman <simon@rozman.si>2020-11-10 10:24:02 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2020-11-10 17:35:01 +0100
commitabdc6d8d5aa5233649f5d880f01fa18a84a43ce7 (patch)
tree92ac75bb3996520a60d18d6560b3e4cae52508fc
parentbuild: sign ARM and ARM64 binaries (diff)
downloadwireguard-windows-abdc6d8d5aa5233649f5d880f01fa18a84a43ce7.tar.xz
wireguard-windows-abdc6d8d5aa5233649f5d880f01fa18a84a43ce7.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.c120
-rw-r--r--installer/wireguard.wxs18
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>
<!--