30#include "../tapctl/basic.h"
31#include "../tapctl/error.h"
32#include "../tapctl/tap.h"
50#pragma comment(lib, "advapi32.lib")
51#pragma comment(lib, "iphlpapi.lib")
52#pragma comment(lib, "shell32.lib")
53#pragma comment(lib, "shlwapi.lib")
54#pragma comment(lib, "version.lib")
63#define MSICA_ADAPTER_TICK_SIZE (16 * 1024)
65#define FILE_NEED_REBOOT L".ovpn_need_reboot"
67#define OPENVPN_CONNECT_ADAPTER_SUBSTR L"OpenVPN Connect"
82 _In_ MSIHANDLE hInstall,
88 uiResult = MsiSetProperty(hInstall, szProperty, szSequence);
90 if (uiResult != ERROR_SUCCESS)
94 SetLastError(uiResult);
112_debug_popup(
_In_z_ LPCSTR szFunctionName)
114 TCHAR szTitle[0x100], szMessage[0x100+MAX_PATH], szProcessPath[MAX_PATH];
118 _stprintf_s(szTitle, _countof(szTitle), TEXT(
"%hs v%") TEXT(
PRIsLPTSTR),
119 szFunctionName, TEXT(PACKAGE_VERSION));
122 GetModuleFileName(NULL, szProcessPath, _countof(szProcessPath));
123 LPCTSTR szProcessName = _tcsrchr(szProcessPath, TEXT(
'\\'));
124 szProcessName = szProcessName ? szProcessName + 1 : szProcessPath;
128 szMessage, _countof(szMessage),
129 TEXT(
"The %") TEXT(
PRIsLPTSTR) TEXT(
" process (PID: %u) has started to execute the %hs")
130 TEXT(
" custom action.\r\n")
132 TEXT(
"If you would like to debug the custom action, attach a debugger to this process and set breakpoints before dismissing this dialog.\r\n")
134 TEXT(
"If you are not debugging this custom action, you can safely ignore this message."),
136 GetCurrentProcessId(),
139 MessageBox(NULL, szMessage, szTitle, MB_OK);
142#define debug_popup(f) _debug_popup(f)
144#define debug_popup(f)
149 _In_ MSIHANDLE hInstall,
150 _In_z_ LPCTSTR szzHardwareIDs,
151 _In_z_ LPCTSTR szAdaptersPropertyName,
152 _In_z_ LPCTSTR szActiveAdaptersPropertyName)
159 if (uiResult != ERROR_SUCCESS)
163 else if (pAdapterList == NULL)
170 PIP_ADAPTER_ADDRESSES pAdapterAdresses = NULL;
171 ULONG ulAdapterAdressesSize = 16*1024;
172 for (
size_t iteration = 0; iteration < 2; iteration++)
174 pAdapterAdresses = (PIP_ADAPTER_ADDRESSES)malloc(ulAdapterAdressesSize);
175 if (pAdapterAdresses == NULL)
177 msg(
M_NONFATAL,
"%s: malloc(%u) failed", __FUNCTION__, ulAdapterAdressesSize);
178 uiResult = ERROR_OUTOFMEMORY;
goto cleanup_pAdapterList;
181 ULONG ulResult = GetAdaptersAddresses(
183 GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME | GAA_FLAG_INCLUDE_ALL_INTERFACES,
186 &ulAdapterAdressesSize);
188 if (ulResult == ERROR_SUCCESS)
193 free(pAdapterAdresses);
194 if (ulResult != ERROR_BUFFER_OVERFLOW)
196 SetLastError(ulResult);
198 uiResult = ulResult;
goto cleanup_pAdapterList;
203 size_t adapter_count = 0;
211 szAdapters = (LPTSTR)malloc(adapter_count * (38 + 1 ) *
sizeof(TCHAR)),
212 szAdaptersTail = szAdapters;
213 if (szAdapters == NULL)
215 msg(
M_FATAL,
"%s: malloc(%u) failed", __FUNCTION__, adapter_count * (38 + 1 ) *
sizeof(TCHAR));
216 uiResult = ERROR_OUTOFMEMORY;
goto cleanup_pAdapterAdresses;
220 szAdaptersActive = (LPTSTR)malloc(adapter_count * (38 + 1 ) *
sizeof(TCHAR)),
221 szAdaptersActiveTail = szAdaptersActive;
222 if (szAdaptersActive == NULL)
224 msg(
M_FATAL,
"%s: malloc(%u) failed", __FUNCTION__, adapter_count * (38 + 1 ) *
sizeof(TCHAR));
225 uiResult = ERROR_OUTOFMEMORY;
goto cleanup_szAdapters;
233 msg(
M_WARN,
"%s: skip OpenVPN Connect adapter '%ls'", __FUNCTION__, pAdapter->szName);
238 LPOLESTR szAdapterId = NULL;
239 StringFromIID((REFIID)&pAdapter->guid, &szAdapterId);
242 if (szAdapters < szAdaptersTail)
244 *(szAdaptersTail++) = TEXT(
';');
246 memcpy(szAdaptersTail, szAdapterId, 38 *
sizeof(TCHAR));
247 szAdaptersTail += 38;
250 for (PIP_ADAPTER_ADDRESSES p = pAdapterAdresses; p; p = p->Next)
252 OLECHAR szId[38 + 1 ];
254 if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, p->AdapterName, -1, szId, _countof(szId)) > 0
255 && SUCCEEDED(IIDFromString(szId, &
guid))
256 && memcmp(&
guid, &pAdapter->guid,
sizeof(GUID)) == 0)
258 if (p->OperStatus == IfOperStatusUp)
261 if (szAdaptersActive < szAdaptersActiveTail)
263 *(szAdaptersActiveTail++) = TEXT(
';');
265 memcpy(szAdaptersActiveTail, szAdapterId, 38 *
sizeof(TCHAR));
266 szAdaptersActiveTail += 38;
271 CoTaskMemFree(szAdapterId);
273 szAdaptersTail [0] = 0;
274 szAdaptersActiveTail[0] = 0;
277 uiResult = MsiSetProperty(hInstall, szAdaptersPropertyName, szAdapters);
278 if (uiResult != ERROR_SUCCESS)
280 SetLastError(uiResult);
281 msg(
M_NONFATAL |
M_ERRNO,
"%s: MsiSetProperty(\"%s\") failed", __FUNCTION__, szAdaptersPropertyName);
282 goto cleanup_szAdaptersActive;
284 uiResult = MsiSetProperty(hInstall, szActiveAdaptersPropertyName, szAdaptersActive);
285 if (uiResult != ERROR_SUCCESS)
287 SetLastError(uiResult);
288 msg(
M_NONFATAL |
M_ERRNO,
"%s: MsiSetProperty(\"%s\") failed", __FUNCTION__, szActiveAdaptersPropertyName);
289 goto cleanup_szAdaptersActive;
292cleanup_szAdaptersActive:
293 free(szAdaptersActive);
296cleanup_pAdapterAdresses:
297 free(pAdapterAdresses);
307#pragma comment(linker, DLLEXP_EXPORT)
312 BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
318 TEXT(
"root\\") TEXT(TAP_WIN_COMPONENT_ID) TEXT(
"\0") TEXT(TAP_WIN_COMPONENT_ID) TEXT(
"\0"),
319 TEXT(
"TAPWINDOWS6ADAPTERS"),
320 TEXT(
"ACTIVETAPWINDOWS6ADAPTERS"));
323 TEXT(
"Wintun") TEXT(
"\0"),
324 TEXT(
"WINTUNADAPTERS"),
325 TEXT(
"ACTIVEWINTUNADAPTERS"));
328 TEXT(
"ovpn-dco") TEXT(
"\0"),
329 TEXT(
"OVPNDCOADAPTERS"),
330 TEXT(
"ACTIVEOVPNDCOADAPTERS"));
332 if (bIsCoInitialized)
336 return ERROR_SUCCESS;
344#pragma comment(linker, DLLEXP_EXPORT)
346 UNREFERENCED_PARAMETER(hInstall);
351 HWND hWnd = FindWindow(TEXT(
"OpenVPN-GUI"), NULL);
355 SendMessage(hWnd, WM_CLOSE, 0, 0);
359 return ERROR_SUCCESS;
367#pragma comment(linker, DLLEXP_EXPORT)
373 BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
378 MSIHANDLE hRecord = MsiCreateRecord(1);
381 uiResult = ERROR_INVALID_HANDLE;
383 goto cleanup_CoInitialize;
385 uiResult = MsiRecordSetString(hRecord, 0, TEXT(
"\"[#bin.openvpn_gui.exe]\""));
386 if (uiResult != ERROR_SUCCESS)
388 SetLastError(uiResult);
390 goto cleanup_MsiCreateRecord;
394 TCHAR szStackBuf[MAX_PATH];
395 DWORD dwPathSize = _countof(szStackBuf);
396 LPTSTR szPath = szStackBuf;
397 uiResult = MsiFormatRecord(hInstall, hRecord, szPath, &dwPathSize);
398 if (uiResult == ERROR_MORE_DATA)
401 szPath = (LPTSTR)malloc((++dwPathSize) *
sizeof(TCHAR));
404 msg(
M_FATAL,
"%s: malloc(%u) failed", __FUNCTION__, dwPathSize *
sizeof(TCHAR));
405 uiResult = ERROR_OUTOFMEMORY;
goto cleanup_MsiCreateRecord;
408 uiResult = MsiFormatRecord(hInstall, hRecord, szPath, &dwPathSize);
410 if (uiResult != ERROR_SUCCESS)
412 SetLastError(uiResult);
414 goto cleanup_malloc_szPath;
418 SHELLEXECUTEINFO sei = {
419 .cbSize =
sizeof(SHELLEXECUTEINFO),
420 .fMask = SEE_MASK_FLAG_NO_UI,
422 .nShow = SW_SHOWNORMAL
424 if (!ShellExecuteEx(&sei))
426 uiResult = GetLastError();
428 goto cleanup_malloc_szPath;
431 uiResult = ERROR_SUCCESS;
433cleanup_malloc_szPath:
434 if (szPath != szStackBuf)
438cleanup_MsiCreateRecord:
439 MsiCloseHandle(hRecord);
441 if (bIsCoInitialized)
473 _In_z_ LPCTSTR szDisplayName,
474 _In_z_ LPCTSTR szHardwareId,
480 if (dwResult != ERROR_SUCCESS)
488 if (pAdapterOther == NULL)
491 TCHAR szArgument[10 + MAX_PATH + 1 + MAX_PATH + 1 ];
495 szArgument, _countof(szArgument),
496 TEXT(
"create=\"%.*s|%.*s\""),
497 MAX_PATH, szDisplayName,
498 MAX_PATH, szHardwareId);
505 szArgument, _countof(szArgument),
506 TEXT(
"deleteN=\"%.*s\""),
507 MAX_PATH, szDisplayName);
514 else if (_tcsicmp(szDisplayName, pAdapterOther->szName) == 0)
517 for (LPCTSTR hwid = pAdapterOther->szzHardwareIDs;; hwid += _tcslen(hwid) + 1)
522 msg(
M_NONFATAL,
"%s: Adapter with name \"%" PRIsLPTSTR "\" already exists", __FUNCTION__, pAdapterOther->szName);
523 dwResult = ERROR_ALREADY_EXISTS;
524 goto cleanup_pAdapterList;
526 else if (_tcsicmp(hwid, szHardwareId) == 0)
574 _In_z_ LPCTSTR szDisplayName,
581 if (dwResult != ERROR_SUCCESS)
589 if (_tcsicmp(szDisplayName, pAdapter->szName) == 0)
592 TCHAR szArgument[8 + 38 + 1 ];
593 if (seqCommit && seqRollback)
597 szArgument, _countof(szArgument),
604 szArgument, _countof(szArgument),
611 szArgument, _countof(szArgument),
620 szArgument, _countof(szArgument),
640#pragma comment(linker, DLLEXP_EXPORT)
646 BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
656 seqUninstallRollback;
665 bool bRollbackEnabled = MsiEvaluateCondition(hInstall, TEXT(
"RollbackDisabled")) != MSICONDITION_TRUE;
668 MSIHANDLE hDatabase = MsiGetActiveDatabase(hInstall);
671 msg(
M_NONFATAL,
"%s: MsiGetActiveDatabase failed", __FUNCTION__);
672 uiResult = ERROR_INVALID_HANDLE;
673 goto cleanup_exec_seq;
677 switch (MsiDatabaseIsTablePersistent(hDatabase, TEXT(
"TUNTAPAdapter")))
679 case MSICONDITION_FALSE:
680 case MSICONDITION_TRUE:
break;
683 uiResult = ERROR_SUCCESS;
684 goto cleanup_hDatabase;
688 MSIHANDLE hViewST = 0;
689 LPCTSTR szQuery = TEXT(
"SELECT `Adapter`,`DisplayName`,`Condition`,`Component_`,`HardwareId` FROM `TUNTAPAdapter`");
690 uiResult = MsiDatabaseOpenView(hDatabase, szQuery, &hViewST);
691 if (uiResult != ERROR_SUCCESS)
693 SetLastError(uiResult);
695 goto cleanup_hDatabase;
699 uiResult = MsiViewExecute(hViewST, 0);
700 if (uiResult != ERROR_SUCCESS)
702 SetLastError(uiResult);
704 goto cleanup_hViewST;
708 MSIHANDLE hRecordProg = MsiCreateRecord(2);
711 uiResult = ERROR_INVALID_HANDLE;
713 goto cleanup_hViewST_close;
719 MSIHANDLE hRecord = 0;
720 uiResult = MsiViewFetch(hViewST, &hRecord);
721 if (uiResult == ERROR_NO_MORE_ITEMS)
723 uiResult = ERROR_SUCCESS;
726 else if (uiResult != ERROR_SUCCESS)
728 SetLastError(uiResult);
730 goto cleanup_hRecordProg;
733 INSTALLSTATE iInstalled, iAction;
736 LPTSTR szValue = NULL;
738 if (uiResult != ERROR_SUCCESS)
740 goto cleanup_hRecord;
744 uiResult = MsiGetComponentState(hInstall, szValue, &iInstalled, &iAction);
745 if (uiResult != ERROR_SUCCESS)
747 SetLastError(uiResult);
750 goto cleanup_hRecord;
756 LPTSTR szDisplayName = NULL;
758 if (uiResult != ERROR_SUCCESS)
760 goto cleanup_hRecord;
763 LPTSTR szDisplayNameEx = _tcschr(szDisplayName, TEXT(
'|'));
764 szDisplayNameEx = szDisplayNameEx != NULL ? szDisplayNameEx + 1 : szDisplayName;
767 TCHAR szzHardwareIDs[0x100] = { 0 };
769 LPTSTR szHwId = NULL;
771 if (uiResult != ERROR_SUCCESS)
773 goto cleanup_szDisplayName;
775 memcpy_s(szzHardwareIDs,
sizeof(szzHardwareIDs) - 2*
sizeof(TCHAR) , szHwId, _tcslen(szHwId)*
sizeof(TCHAR));
779 if (iAction > INSTALLSTATE_BROKEN)
783 if (iAction >= INSTALLSTATE_LOCAL)
786 LPTSTR szValue = NULL;
788 if (uiResult != ERROR_SUCCESS)
790 goto cleanup_szDisplayName;
792#if defined(__GNUC__) || defined(__clang__)
797#pragma GCC diagnostic push
798#pragma GCC diagnostic ignored "-Wswitch"
800 switch (MsiEvaluateCondition(hInstall, szValue))
802 case MSICONDITION_FALSE:
804 goto cleanup_szDisplayName;
806 case MSICONDITION_ERROR:
807 uiResult = ERROR_INVALID_FIELD;
810 goto cleanup_szDisplayName;
812#if defined(__GNUC__) || defined(__clang__)
813#pragma GCC diagnostic pop
820 bRollbackEnabled ? &seqInstallRollback : NULL,
823 &iTicks) != ERROR_SUCCESS)
825 uiResult = ERROR_INSTALL_FAILED;
826 goto cleanup_szDisplayName;
838 bRollbackEnabled ? &seqUninstallCommit : NULL,
839 bRollbackEnabled ? &seqUninstallRollback : NULL,
847 MsiRecordSetInteger(hRecordProg, 1, 3 );
848 MsiRecordSetInteger(hRecordProg, 2, iTicks);
849 if (MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL)
851 uiResult = ERROR_INSTALL_USEREXIT;
852 goto cleanup_szDisplayName;
856cleanup_szDisplayName:
859 MsiCloseHandle(hRecord);
860 if (uiResult != ERROR_SUCCESS)
862 goto cleanup_hRecordProg;
867 TCHAR tmpDir[MAX_PATH];
868 GetTempPath(MAX_PATH, tmpDir);
870 TCHAR str[MAX_PATH + 7];
871 _stprintf_s(str, _countof(str), TEXT(
"tmpdir=%") TEXT(
PRIsLPTSTR), tmpDir);
880 if ((uiResult =
setup_sequence(hInstall, TEXT(
"InstallTUNTAPAdapters" ), &seqInstall )) != ERROR_SUCCESS
881 || (uiResult =
setup_sequence(hInstall, TEXT(
"InstallTUNTAPAdaptersCommit" ), &seqInstallCommit )) != ERROR_SUCCESS
882 || (uiResult =
setup_sequence(hInstall, TEXT(
"InstallTUNTAPAdaptersRollback" ), &seqInstallRollback )) != ERROR_SUCCESS
883 || (uiResult =
setup_sequence(hInstall, TEXT(
"UninstallTUNTAPAdapters" ), &seqUninstall )) != ERROR_SUCCESS
884 || (uiResult =
setup_sequence(hInstall, TEXT(
"UninstallTUNTAPAdaptersCommit" ), &seqUninstallCommit )) != ERROR_SUCCESS
885 || (uiResult =
setup_sequence(hInstall, TEXT(
"UninstallTUNTAPAdaptersRollback"), &seqUninstallRollback)) != ERROR_SUCCESS)
887 goto cleanup_hRecordProg;
890 uiResult = ERROR_SUCCESS;
893 MsiCloseHandle(hRecordProg);
894cleanup_hViewST_close:
895 MsiViewClose(hViewST);
897 MsiCloseHandle(hViewST);
899 MsiCloseHandle(hDatabase);
907 if (bIsCoInitialized)
949 WCHAR path[MAX_PATH];
952 msg(
M_WARN,
"%s: Reboot required, create reboot indication file \"%ls\"", __FUNCTION__, path);
954 HANDLE file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
955 if (file == INVALID_HANDLE_VALUE)
969#pragma comment(linker, DLLEXP_EXPORT)
975 BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
976 WCHAR tmpDir[MAX_PATH] = {0};
980 BOOL bIsCleanup = MsiGetMode(hInstall, MSIRUNMODE_COMMIT) || MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK);
983 LPWSTR szSequence = NULL;
984 uiResult =
msi_get_string(hInstall, L
"CustomActionData", &szSequence);
985 if (uiResult != ERROR_SUCCESS)
987 goto cleanup_CoInitialize;
990 LPWSTR *szArg = CommandLineToArgvW(szSequence, &nArgs);
993 uiResult = GetLastError();
995 goto cleanup_szSequence;
999 MSIHANDLE hRecordProg = MsiCreateRecord(3);
1000 MsiRecordSetInteger(hRecordProg, 1, 1);
1001 MsiRecordSetInteger(hRecordProg, 2, 1);
1002 MsiRecordSetInteger(hRecordProg, 3, 0);
1003 MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg);
1006 MsiRecordSetInteger(hRecordProg, 1, 2);
1007 MsiRecordSetInteger(hRecordProg, 3, 0);
1009 BOOL bRebootRequired = FALSE;
1011 for (
int i = 1 ; i < nArgs; ++i)
1013 DWORD dwResult = ERROR_SUCCESS;
1015 if (wcsncmp(szArg[i], L
"create=", 7) == 0)
1018 LPWSTR szName = szArg[i] + 7;
1019 LPWSTR szHardwareId = wcschr(szName, L
'|');
1020 if (szHardwareId == NULL)
1022 goto invalid_argument;
1024 szHardwareId[0] = 0;
1029 MSIHANDLE hRecord = MsiCreateRecord(4);
1030 MsiRecordSetString(hRecord, 1, TEXT(
"Creating adapter"));
1031 MsiRecordSetString(hRecord, 2, szName);
1032 MsiRecordSetString(hRecord, 3, szHardwareId);
1033 int iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord);
1034 MsiCloseHandle(hRecord);
1035 if (iResult == IDCANCEL)
1037 uiResult = ERROR_INSTALL_USEREXIT;
1043 dwResult =
tap_create_adapter(NULL, NULL, szHardwareId, &bRebootRequired, &guidAdapter);
1044 if (dwResult == ERROR_SUCCESS)
1051 else if (wcsncmp(szArg[i], L
"deleteN=", 8) == 0)
1054 LPCWSTR szName = szArg[i] + 8;
1058 MSIHANDLE hRecord = MsiCreateRecord(3);
1059 MsiRecordSetString(hRecord, 1, TEXT(
"Deleting adapter"));
1060 MsiRecordSetString(hRecord, 2, szName);
1061 int iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord);
1062 MsiCloseHandle(hRecord);
1063 if (iResult == IDCANCEL)
1065 uiResult = ERROR_INSTALL_USEREXIT;
1073 if (dwResult == ERROR_SUCCESS)
1076 for (
struct tap_adapter_node *pAdapter = pAdapterList; pAdapter != NULL; pAdapter = pAdapter->
pNext)
1078 if (_tcsicmp(
szName, pAdapter->szName) == 0)
1089 else if (wcsncmp(szArg[i], L
"delete=", 7) == 0)
1095 goto invalid_argument;
1099 else if (wcsncmp(szArg[i], L
"enable=", 7) == 0)
1105 goto invalid_argument;
1109 else if (wcsncmp(szArg[i], L
"disable=", 8) == 0)
1115 goto invalid_argument;
1119 else if (wcsncmp(szArg[i], L
"tmpdir=", 7) == 0)
1121 wcscpy_s(tmpDir, _countof(tmpDir), szArg[i] + 7);
1125 goto invalid_argument;
1128 if (dwResult != ERROR_SUCCESS && !bIsCleanup )
1130 uiResult = ERROR_INSTALL_FAILURE;
1136 if (MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL)
1138 dwResult = ERROR_INSTALL_USEREXIT;
1145 msg(
M_NONFATAL,
"%s: Ignoring invalid argument: %ls", __FUNCTION__, szArg[i]);
1149 if (bRebootRequired && wcslen(tmpDir) > 0)
1153 MsiCloseHandle(hRecordProg);
1157cleanup_CoInitialize:
1158 if (bIsCoInitialized)
1169#pragma comment(linker, DLLEXP_EXPORT)
1174 BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
1179 WCHAR tempPath[MAX_PATH];
1180 GetTempPathW(MAX_PATH, tempPath);
1183 WCHAR path[MAX_PATH];
1185 WIN32_FIND_DATA data = { 0 };
1186 HANDLE searchHandle = FindFirstFileW(path, &data);
1187 if (searchHandle != INVALID_HANDLE_VALUE)
1189 msg(
M_WARN,
"%s: Reboot file exists, schedule reboot", __FUNCTION__);
1191 FindClose(searchHandle);
1194 MsiSetMode(hInstall, MSIRUNMODE_REBOOTATEND, TRUE);
1197 if (bIsCoInitialized)
1201 return ERROR_SUCCESS;
void msica_arg_seq_free(_Inout_ struct msica_arg_seq *seq)
Frees argument sequence.
void msica_arg_seq_add_tail(_Inout_ struct msica_arg_seq *seq, _Inout_ LPCTSTR argument)
Appends argument to the end of the argument sequence.
void msica_arg_seq_init(_Inout_ struct msica_arg_seq *seq)
Initializes argument sequence.
void msica_arg_seq_add_head(_Inout_ struct msica_arg_seq *seq, _In_z_ LPCTSTR argument)
Inserts argument to the beginning of the argument sequence.
LPTSTR msica_arg_seq_join(_In_ const struct msica_arg_seq *seq)
Join arguments of the argument sequence into a space delimited string.
UINT msi_get_string(_In_ MSIHANDLE hInstall, _In_z_ LPCTSTR szName, _Out_ LPTSTR *pszValue)
Gets MSI property value.
UINT msi_format_field(_In_ MSIHANDLE hInstall, _In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ LPTSTR *pszValue)
Formats MSI record field.
UINT msi_get_record_string(_In_ MSIHANDLE hRecord, _In_ unsigned int iField, _Out_ LPTSTR *pszValue)
Gets MSI record string value.
UINT __stdcall CheckAndScheduleReboot(_In_ MSIHANDLE hInstall)
Schedule reboot after installation if reboot indication file is found in user's temp directory.
static void find_adapters(_In_ MSIHANDLE hInstall, _In_z_ LPCTSTR szzHardwareIDs, _In_z_ LPCTSTR szAdaptersPropertyName, _In_z_ LPCTSTR szActiveAdaptersPropertyName)
#define OPENVPN_CONNECT_ADAPTER_SUBSTR
UINT __stdcall FindSystemInfo(_In_ MSIHANDLE hInstall)
Determines Windows information:
UINT __stdcall ProcessDeferredAction(_In_ MSIHANDLE hInstall)
Perform scheduled deferred action.
static DWORD schedule_adapter_delete(_Inout_ struct msica_arg_seq *seq, _Inout_opt_ struct msica_arg_seq *seqCommit, _Inout_opt_ struct msica_arg_seq *seqRollback, _In_z_ LPCTSTR szDisplayName, _In_z_ LPCTSTR szzHardwareIDs, _Inout_ int *iTicks)
Schedules adapter deletion.
#define MSICA_ADAPTER_TICK_SIZE
Local constants.
UINT __stdcall CloseOpenVPNGUI(_In_ MSIHANDLE hInstall)
Find OpenVPN GUI window and send it a WM_CLOSE message.
UINT __stdcall StartOpenVPNGUI(_In_ MSIHANDLE hInstall)
Launches OpenVPN GUI.
static DWORD schedule_adapter_create(_Inout_ struct msica_arg_seq *seq, _Inout_opt_ struct msica_arg_seq *seqRollback, _In_z_ LPCTSTR szDisplayName, _In_z_ LPCTSTR szHardwareId, _Inout_ int *iTicks)
Schedules adapter creation.
static BOOL parse_guid(_In_z_ LPCWSTR szArg, _Out_ GUID *guid)
Parses string encoded GUID.
static void CreateRebootFile(_In_z_ LPCWSTR szTmpDir)
Create empty file in user's temp directory.
UINT __stdcall EvaluateTUNTAPAdapters(_In_ MSIHANDLE hInstall)
Evaluate the TUNTAPAdapter table of the MSI package database and prepare a list of TAP adapters to in...
static UINT setup_sequence(_In_ MSIHANDLE hInstall, _In_z_ LPCTSTR szProperty, _In_ struct msica_arg_seq *seq)
Joins an argument sequence and sets it to the MSI property.
#define OPENVPNMSICA_SAVE_MSI_SESSION(hInstall)
Set MSI session handle in thread local storage.
Network adapter list node.
struct tap_adapter_node * pNext
Pointer to next adapter.
LPTSTR szzHardwareIDs
Device hardware ID(s)
LPTSTR szName
Adapter name.
DWORD tap_create_adapter(_In_opt_ HWND hwndParent, _In_opt_ LPCTSTR szDeviceDescription, _In_ LPCTSTR szHwId, _Inout_ LPBOOL pbRebootRequired, _Out_ LPGUID pguidAdapter)
Creates a TUN/TAP adapter.
DWORD tap_set_adapter_name(_In_ LPCGUID pguidAdapter, _In_ LPCTSTR szName, _In_ BOOL bSilent)
Sets adapter name.
DWORD tap_list_adapters(_In_opt_ HWND hwndParent, _In_opt_ LPCTSTR szzHwIDs, _Out_ struct tap_adapter_node **ppAdapter)
Creates a list of existing network adapters.
DWORD tap_delete_adapter(_In_opt_ HWND hwndParent, _In_ LPCGUID pguidAdapter, _Inout_ LPBOOL pbRebootRequired)
Deletes an adapter.
void tap_free_adapter_list(_In_ struct tap_adapter_node *pAdapterList)
Frees a list of network adapters.
DWORD tap_enable_adapter(_In_opt_ HWND hwndParent, _In_ LPCGUID pguidAdapter, _In_ BOOL bEnable, _Inout_ LPBOOL pbRebootRequired)
Enables or disables an adapter.
#define PRIGUID_PARAM_REF(g)
static int cleanup(void **state)