aboutsummaryrefslogtreecommitdiffstats
path: root/installer/msi.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--installer/msi.c266
1 files changed, 0 insertions, 266 deletions
diff --git a/installer/msi.c b/installer/msi.c
deleted file mode 100644
index 348ef42..0000000
--- a/installer/msi.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0
- *
- * Copyright (C) 2018-2019 WireGuard LLC. All Rights Reserved.
- */
-
-#include "installation.h"
-#include <Windows.h>
-#include <Msi.h>
-#include <MsiQuery.h>
-#include <tchar.h>
-
-#pragma warning(disable : 4100) /* unreferenced formal parameter */
-
-static MSIHANDLE MsiHandle;
-
-#define ANCHOR_COMPONENT TEXT("{B668D4C7-ABB3-485A-B8DF-D34200489A43}")
-#define PROCESS_ACTION TEXT("ProcessWintun")
-#define ACTION_INSTALL TEXT("/WintunAction=Install")
-#define ACTION_INSTALL_SEPERATOR TEXT('-')
-#define ACTION_INSTALL_SEPERATORS TEXT("-%s-%s-%s")
-#define ACTION_UNINSTALL TEXT("/WintunAction=Uninstall")
-#define PROPERTY_INSTALLER_HASH TEXT("WintunInstallerHash")
-#define PROPERTY_INSTALLER_BUILDTIME TEXT("WintunInstallerBuildtime")
-#define PROPERTY_VERSION TEXT("WintunVersion")
-#define REGKEY_WINTUN TEXT("Software\\Wintun")
-#define REGKEY_INSTALLER_HASH TEXT("InstallerHash")
-#define REGKEY_INSTALLER_BUILDTIME TEXT("InstallerBuildtime")
-#define REGKEY_VERSION TEXT("Version")
-
-static VOID
-MsiLogger(_In_ LOGGER_LEVEL Level, _In_ const TCHAR *LogLine)
-{
- MSIHANDLE Record = MsiCreateRecord(2);
- if (!Record)
- return;
- TCHAR *Template;
- INSTALLMESSAGE Type;
- switch (Level)
- {
- case LOG_INFO:
- Template = TEXT("Wintun: [1]");
- Type = INSTALLMESSAGE_INFO;
- break;
- case LOG_WARN:
- Template = TEXT("Wintun warning: [1]");
- Type = INSTALLMESSAGE_INFO;
- break;
- case LOG_ERR:
- Template = TEXT("Wintun error: [1]");
- Type = INSTALLMESSAGE_ERROR;
- break;
- default:
- goto cleanup;
- }
- MsiRecordSetString(Record, 0, Template);
- MsiRecordSetString(Record, 1, LogLine);
- MsiProcessMessage(MsiHandle, Type, Record);
-cleanup:
- MsiCloseHandle(Record);
-}
-
-static BOOL
-IsInstalling(_In_ INSTALLSTATE InstallState, _In_ INSTALLSTATE ActionState)
-{
- return INSTALLSTATE_LOCAL == ActionState || INSTALLSTATE_SOURCE == ActionState ||
- (INSTALLSTATE_DEFAULT == ActionState &&
- (INSTALLSTATE_LOCAL == InstallState || INSTALLSTATE_SOURCE == InstallState));
-}
-
-static BOOL
-IsReInstalling(_In_ INSTALLSTATE InstallState, _In_ INSTALLSTATE ActionState)
-{
- return (INSTALLSTATE_LOCAL == ActionState || INSTALLSTATE_SOURCE == ActionState ||
- INSTALLSTATE_DEFAULT == ActionState) &&
- (INSTALLSTATE_LOCAL == InstallState || INSTALLSTATE_SOURCE == InstallState);
-}
-
-static BOOL
-IsUninstalling(_In_ INSTALLSTATE InstallState, _In_ INSTALLSTATE ActionState)
-{
- return (INSTALLSTATE_ABSENT == ActionState || INSTALLSTATE_REMOVED == ActionState) &&
- (INSTALLSTATE_LOCAL == InstallState || INSTALLSTATE_SOURCE == InstallState);
-}
-
-static UINT64
-ParseVersion(_In_ const TCHAR *Version)
-{
- ULONG Major = 0, Minor = 0, Revision = 0, Build = 0;
- _stscanf_s(Version, TEXT("%u.%u.%u.%u"), &Major, &Minor, &Revision, &Build);
- return ((UINT64)Major << 48) | ((UINT64)Minor << 32) | ((UINT64)Revision << 16) | ((UINT64)Build << 0);
-}
-
-_Success_(return )
-static BOOL
-Newer(_In_ MSIHANDLE Handle, _In_ BOOL SkipHashComparison, _Out_ TCHAR *InstallAction, _In_ SIZE_T InstallActionSize)
-{
- INT64 NewTime, OldTime;
- UINT64 NewVersion, OldVersion;
- TCHAR NewHash[0x100], OldHash[0x100], NewTimeString[0x100], OldTimeString[0x100], NewVersionString[0x100],
- OldVersionString[0x100];
- DWORD Size, Type;
- HKEY Key;
- BOOL Ret = TRUE;
-
- Size = _countof(NewHash);
- if (MsiGetProperty(Handle, PROPERTY_INSTALLER_HASH, NewHash, &Size) != ERROR_SUCCESS)
- return FALSE;
- Size = _countof(NewTimeString);
- if (MsiGetProperty(Handle, PROPERTY_INSTALLER_BUILDTIME, NewTimeString, &Size) != ERROR_SUCCESS)
- return FALSE;
- NewTime = _tstoll(NewTimeString);
- Size = _countof(NewVersionString);
- if (MsiGetProperty(Handle, PROPERTY_VERSION, NewVersionString, &Size) != ERROR_SUCCESS)
- return FALSE;
- NewVersion = ParseVersion(NewVersionString);
-
- _stprintf_s(
- InstallAction,
- InstallActionSize,
- ACTION_INSTALL ACTION_INSTALL_SEPERATORS,
- NewHash,
- NewTimeString,
- NewVersionString);
-
- if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WINTUN, 0, KEY_READ, &Key) != ERROR_SUCCESS)
- return TRUE;
- Size = sizeof(OldHash);
- if (RegQueryValueEx(Key, REGKEY_INSTALLER_HASH, NULL, &Type, (LPBYTE)OldHash, &Size) != ERROR_SUCCESS ||
- Type != REG_SZ)
- goto cleanup;
- Size = sizeof(OldTimeString);
- if (RegQueryValueEx(Key, REGKEY_INSTALLER_BUILDTIME, NULL, &Type, (LPBYTE)OldTimeString, &Size) != ERROR_SUCCESS ||
- Type != REG_SZ)
- goto cleanup;
- OldTime = _tstoll(OldTimeString);
- Size = sizeof(OldVersionString);
- if (RegQueryValueEx(Key, REGKEY_VERSION, NULL, &Type, (LPBYTE)OldVersionString, &Size) != ERROR_SUCCESS ||
- Type != REG_SZ)
- goto cleanup;
- OldVersion = ParseVersion(OldVersionString);
-
- Ret = NewVersion >= OldVersion && NewTime >= OldTime && (SkipHashComparison || _tcscmp(NewHash, OldHash));
-
-cleanup:
- RegCloseKey(Key);
- return Ret;
-}
-
-UINT __stdcall MsiEvaluate(MSIHANDLE Handle)
-{
- MsiHandle = Handle;
- SetLogger(MsiLogger);
- BOOL IsComInitialized = SUCCEEDED(CoInitialize(NULL));
- UINT Ret = ERROR_INSTALL_FAILURE;
- MSIHANDLE View = 0, Record = 0, Database = MsiGetActiveDatabase(Handle);
- if (!Database)
- goto cleanup;
- Ret = MsiDatabaseOpenView(
- Database, TEXT("SELECT `Component` FROM `Component` WHERE `ComponentId` = '" ANCHOR_COMPONENT "'"), &View);
- if (Ret != ERROR_SUCCESS)
- goto cleanup;
- Ret = MsiViewExecute(View, 0);
- if (Ret != ERROR_SUCCESS)
- goto cleanup;
- Ret = MsiViewFetch(View, &Record);
- if (Ret != ERROR_SUCCESS)
- goto cleanup;
- TCHAR ComponentName[0x1000];
- DWORD Size = _countof(ComponentName);
- Ret = MsiRecordGetString(Record, 1, ComponentName, &Size);
- if (Ret != ERROR_SUCCESS)
- goto cleanup;
- INSTALLSTATE InstallState, ActionState;
- Ret = MsiGetComponentState(Handle, ComponentName, &InstallState, &ActionState);
- if (Ret != ERROR_SUCCESS)
- goto cleanup;
- TCHAR InstallAction[0x400];
- if ((IsReInstalling(InstallState, ActionState) || IsInstalling(InstallState, ActionState)) &&
- Newer(Handle, IsReInstalling(InstallState, ActionState), InstallAction, _countof(InstallAction)))
- Ret = MsiSetProperty(Handle, PROCESS_ACTION, InstallAction);
- else if (IsUninstalling(InstallState, ActionState))
- Ret = MsiSetProperty(Handle, PROCESS_ACTION, ACTION_UNINSTALL);
- if (Ret != ERROR_SUCCESS)
- goto cleanup;
-
- Ret = MsiDoAction(Handle, TEXT("DisableRollback"));
-
-cleanup:
- if (View)
- MsiCloseHandle(View);
- if (Record)
- MsiCloseHandle(Record);
- if (Database)
- MsiCloseHandle(Database);
- if (IsComInitialized)
- CoUninitialize();
- return Ret;
-}
-
-static BOOL
-WriteRegKeys(_In_ TCHAR *Values)
-{
- TCHAR *Hash, *Time, *Version;
- Hash = Values;
- Time = _tcschr(Hash, ACTION_INSTALL_SEPERATOR);
- if (!Time)
- return FALSE;
- *Time++ = TEXT('\0');
- Version = _tcschr(Time, ACTION_INSTALL_SEPERATOR);
- if (!Version)
- return FALSE;
- *Version++ = TEXT('\0');
-
- HKEY Key;
- if (RegCreateKeyEx(
- HKEY_LOCAL_MACHINE, REGKEY_WINTUN, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &Key, NULL) !=
- ERROR_SUCCESS)
- return FALSE;
- BOOL Ret =
- RegSetValueEx(
- Key, REGKEY_INSTALLER_HASH, 0, REG_SZ, (LPBYTE)Hash, ((DWORD)_tcslen(Hash) + 1) * sizeof(*Hash)) ==
- ERROR_SUCCESS &&
- RegSetValueEx(
- Key, REGKEY_INSTALLER_BUILDTIME, 0, REG_SZ, (LPBYTE)Time, ((DWORD)_tcslen(Time) + 1) * sizeof(*Time)) ==
- ERROR_SUCCESS &&
- RegSetValueEx(
- Key, REGKEY_VERSION, 0, REG_SZ, (LPBYTE)Version, ((DWORD)_tcslen(Version) + 1) * sizeof(*Version)) ==
- ERROR_SUCCESS;
- RegCloseKey(Key);
- return Ret;
-}
-
-UINT __stdcall MsiProcess(MSIHANDLE Handle)
-{
- MsiHandle = Handle;
- SetLogger(MsiLogger);
- BOOL IsComInitialized = SUCCEEDED(CoInitialize(NULL));
- DWORD LastError = ERROR_SUCCESS;
- BOOL Ret = FALSE;
- TCHAR Value[0x1000], *RegValues;
- DWORD Size = _countof(Value);
- LastError = MsiGetProperty(Handle, TEXT("CustomActionData"), Value, &Size);
- if (LastError != ERROR_SUCCESS)
- goto cleanup;
- if ((RegValues = _tcschr(Value, ACTION_INSTALL_SEPERATOR)) != NULL)
- *RegValues++ = TEXT('\0');
- if (!_tcscmp(Value, ACTION_INSTALL))
- {
- Ret = InstallOrUpdate();
- if (RegValues && Ret)
- Ret = WriteRegKeys(RegValues);
- }
- else if (!_tcscmp(Value, ACTION_UNINSTALL))
- {
- Ret = Uninstall();
- if (Ret)
- RegDeleteKeyEx(HKEY_LOCAL_MACHINE, REGKEY_WINTUN, 0, 0);
- }
- else
- Ret = TRUE;
- LastError = GetLastError();
-cleanup:
- if (IsComInitialized)
- CoUninitialize();
- return Ret ? ERROR_SUCCESS : LastError ? LastError : ERROR_INSTALL_FAILED;
-}