23 #elif defined(_MSC_VER)
32 #include "../tapctl/basic.h"
33 #include "../tapctl/error.h"
34 #include "../tapctl/tap.h"
52 #pragma comment(lib, "advapi32.lib")
53 #pragma comment(lib, "iphlpapi.lib")
54 #pragma comment(lib, "shell32.lib")
55 #pragma comment(lib, "shlwapi.lib")
56 #pragma comment(lib, "version.lib")
64 #define MSICA_ADAPTER_TICK_SIZE (16*1024)
66 #define FILE_NEED_REBOOT L".ovpn_need_reboot"
67 #define CMP_OVPN_DCO_INF L"CMP_ovpn_dco.inf"
68 #define ACTION_ADD_DRIVER L"AddDriver"
69 #define ACTION_DELETE_DRIVER L"DeleteDriver"
70 #define ACTION_NOOP L"Noop"
71 #define FILE_OVPN_DCO_INF L"ovpn-dco.inf"
72 #define OVPN_DCO_HWID L"ovpn-dco"
87 _In_ MSIHANDLE hInstall,
93 uiResult = MsiSetProperty(hInstall, szProperty, szSequence);
95 if (uiResult != ERROR_SUCCESS)
97 SetLastError(uiResult);
101 return ERROR_SUCCESS;
115 _debug_popup(
_In_z_ LPCSTR szFunctionName)
117 TCHAR szTitle[0x100], szMessage[0x100+MAX_PATH], szProcessPath[MAX_PATH];
121 _stprintf_s(szTitle, _countof(szTitle), TEXT(
"%hs v%") TEXT(
PRIsLPTSTR),
125 GetModuleFileName(NULL, szProcessPath, _countof(szProcessPath));
126 LPCTSTR szProcessName = _tcsrchr(szProcessPath, TEXT(
'\\'));
127 szProcessName = szProcessName ? szProcessName + 1 : szProcessPath;
131 szMessage, _countof(szMessage),
132 TEXT(
"The %") TEXT(
PRIsLPTSTR) TEXT(
" process (PID: %u) has started to execute the %hs")
133 TEXT(
" custom action.\r\n")
135 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")
137 TEXT(
"If you are not debugging this custom action, you can safely ignore this message."),
139 GetCurrentProcessId(),
142 MessageBox(NULL, szMessage, szTitle, MB_OK);
145 #define debug_popup(f) _debug_popup(f)
147 #define debug_popup(f)
167 SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
168 if (hSCManager == NULL)
170 uiResult = GetLastError();
176 SC_HANDLE hService = OpenService(hSCManager, TEXT(
"OpenVPNService"), SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);
177 if (hService == NULL)
179 uiResult = GetLastError();
180 if (uiResult == ERROR_SERVICE_DOES_NOT_EXIST)
183 goto cleanup_OpenSCManager;
186 goto cleanup_OpenSCManager;
190 SERVICE_STATUS_PROCESS ssp;
192 if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&ssp,
sizeof(ssp), &dwBufSize))
194 switch (ssp.dwCurrentState)
196 case SERVICE_START_PENDING:
197 case SERVICE_RUNNING:
198 case SERVICE_STOP_PENDING:
199 case SERVICE_PAUSE_PENDING:
201 case SERVICE_CONTINUE_PENDING:
204 TCHAR szPID[10 + 1 ];
206 szPID, _countof(szPID),
210 uiResult = MsiSetProperty(hInstall, TEXT(
"OPENVPNSERVICE"), szPID);
211 if (uiResult != ERROR_SUCCESS)
213 SetLastError(uiResult);
218 goto cleanup_OpenService;
225 uiResult = GetLastError();
232 BYTE _buffer_8k[8192];
233 LPQUERY_SERVICE_CONFIG pQsc = (LPQUERY_SERVICE_CONFIG)_buffer_8k;
234 dwBufSize =
sizeof(_buffer_8k);
235 if (!QueryServiceConfig(hService, pQsc, dwBufSize, &dwBufSize))
237 uiResult = GetLastError();
238 msg(
M_NONFATAL |
M_ERRNO,
"%s: QueryServiceStatusEx(\"QueryServiceConfig\") failed", __FUNCTION__);
239 goto cleanup_OpenService;
242 if (pQsc->dwStartType <= SERVICE_AUTO_START)
245 uiResult = MsiSetProperty(hInstall, TEXT(
"OPENVPNSERVICE"), pQsc->lpBinaryPathName);
246 if (uiResult != ERROR_SUCCESS)
248 SetLastError(uiResult);
250 goto cleanup_OpenService;
254 uiResult = ERROR_SUCCESS;
257 CloseServiceHandle(hService);
258 cleanup_OpenSCManager:
259 CloseServiceHandle(hSCManager);
266 _In_ MSIHANDLE hInstall,
267 _In_z_ LPCTSTR szzHardwareIDs,
268 _In_z_ LPCTSTR szAdaptersPropertyName,
269 _In_z_ LPCTSTR szActiveAdaptersPropertyName)
276 if (uiResult != ERROR_SUCCESS)
280 else if (pAdapterList == NULL)
287 PIP_ADAPTER_ADDRESSES pAdapterAdresses = NULL;
288 ULONG ulAdapterAdressesSize = 16*1024;
289 for (
size_t iteration = 0; iteration < 2; iteration++)
291 pAdapterAdresses = (PIP_ADAPTER_ADDRESSES)malloc(ulAdapterAdressesSize);
292 if (pAdapterAdresses == NULL)
294 msg(
M_NONFATAL,
"%s: malloc(%u) failed", __FUNCTION__, ulAdapterAdressesSize);
295 uiResult = ERROR_OUTOFMEMORY;
goto cleanup_pAdapterList;
298 ULONG ulResult = GetAdaptersAddresses(
300 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,
303 &ulAdapterAdressesSize);
305 if (ulResult == ERROR_SUCCESS)
310 free(pAdapterAdresses);
311 if (ulResult != ERROR_BUFFER_OVERFLOW)
313 SetLastError(ulResult);
315 uiResult = ulResult;
goto cleanup_pAdapterList;
320 size_t adapter_count = 0;
328 szAdapters = (LPTSTR)malloc(adapter_count * (38 + 1 ) *
sizeof(TCHAR)),
329 szAdaptersTail = szAdapters;
330 if (szAdapters == NULL)
332 msg(
M_FATAL,
"%s: malloc(%u) failed", __FUNCTION__, adapter_count * (38 + 1 ) *
sizeof(TCHAR));
333 uiResult = ERROR_OUTOFMEMORY;
goto cleanup_pAdapterAdresses;
337 szAdaptersActive = (LPTSTR)malloc(adapter_count * (38 + 1 ) *
sizeof(TCHAR)),
338 szAdaptersActiveTail = szAdaptersActive;
339 if (szAdaptersActive == NULL)
341 msg(
M_FATAL,
"%s: malloc(%u) failed", __FUNCTION__, adapter_count * (38 + 1 ) *
sizeof(TCHAR));
342 uiResult = ERROR_OUTOFMEMORY;
goto cleanup_szAdapters;
348 LPOLESTR szAdapterId = NULL;
349 StringFromIID((REFIID)&pAdapter->guid, &szAdapterId);
352 if (szAdapters < szAdaptersTail)
354 *(szAdaptersTail++) = TEXT(
';');
356 memcpy(szAdaptersTail, szAdapterId, 38 *
sizeof(TCHAR));
357 szAdaptersTail += 38;
360 for (PIP_ADAPTER_ADDRESSES p = pAdapterAdresses; p; p = p->Next)
362 OLECHAR szId[38 + 1 ];
364 if (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, p->AdapterName, -1, szId, _countof(szId)) > 0
365 && SUCCEEDED(IIDFromString(szId, &
guid))
366 && memcmp(&
guid, &pAdapter->guid,
sizeof(GUID)) == 0)
368 if (p->OperStatus == IfOperStatusUp)
371 if (szAdaptersActive < szAdaptersActiveTail)
373 *(szAdaptersActiveTail++) = TEXT(
';');
375 memcpy(szAdaptersActiveTail, szAdapterId, 38 *
sizeof(TCHAR));
376 szAdaptersActiveTail += 38;
381 CoTaskMemFree(szAdapterId);
383 szAdaptersTail [0] = 0;
384 szAdaptersActiveTail[0] = 0;
387 uiResult = MsiSetProperty(hInstall, szAdaptersPropertyName, szAdapters);
388 if (uiResult != ERROR_SUCCESS)
390 SetLastError(uiResult);
391 msg(
M_NONFATAL |
M_ERRNO,
"%s: MsiSetProperty(\"%s\") failed", __FUNCTION__, szAdaptersPropertyName);
392 goto cleanup_szAdaptersActive;
394 uiResult = MsiSetProperty(hInstall, szActiveAdaptersPropertyName, szAdaptersActive);
395 if (uiResult != ERROR_SUCCESS)
397 SetLastError(uiResult);
398 msg(
M_NONFATAL |
M_ERRNO,
"%s: MsiSetProperty(\"%s\") failed", __FUNCTION__, szActiveAdaptersPropertyName);
399 goto cleanup_szAdaptersActive;
402 cleanup_szAdaptersActive:
403 free(szAdaptersActive);
406 cleanup_pAdapterAdresses:
407 free(pAdapterAdresses);
408 cleanup_pAdapterList:
417 #pragma comment(linker, DLLEXP_EXPORT)
422 BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
430 TEXT(
"TAPWINDOWS6ADAPTERS"),
431 TEXT(
"ACTIVETAPWINDOWS6ADAPTERS"));
434 TEXT(
"Wintun") TEXT(
"\0"),
435 TEXT(
"WINTUNADAPTERS"),
436 TEXT(
"ACTIVEWINTUNADAPTERS"));
439 TEXT(
"ovpn-dco") TEXT(
"\0"),
440 TEXT(
"OVPNDCOAPTERS"),
441 TEXT(
"ACTIVEOVPNDCOADAPTERS"));
443 if (bIsCoInitialized)
447 return ERROR_SUCCESS;
455 #pragma comment(linker, DLLEXP_EXPORT)
457 UNREFERENCED_PARAMETER(hInstall);
462 HWND hWnd = FindWindow(TEXT(
"OpenVPN-GUI"), NULL);
466 SendMessage(hWnd, WM_CLOSE, 0, 0);
470 return ERROR_SUCCESS;
478 #pragma comment(linker, DLLEXP_EXPORT)
484 BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
489 MSIHANDLE hRecord = MsiCreateRecord(1);
492 uiResult = ERROR_INVALID_HANDLE;
494 goto cleanup_CoInitialize;
496 uiResult = MsiRecordSetString(hRecord, 0, TEXT(
"\"[#bin.openvpn_gui.exe]\""));
497 if (uiResult != ERROR_SUCCESS)
499 SetLastError(uiResult);
501 goto cleanup_MsiCreateRecord;
505 TCHAR szStackBuf[MAX_PATH];
506 DWORD dwPathSize = _countof(szStackBuf);
507 LPTSTR szPath = szStackBuf;
508 uiResult = MsiFormatRecord(hInstall, hRecord, szPath, &dwPathSize);
509 if (uiResult == ERROR_MORE_DATA)
512 szPath = (LPTSTR)malloc((++dwPathSize) *
sizeof(TCHAR));
515 msg(
M_FATAL,
"%s: malloc(%u) failed", __FUNCTION__, dwPathSize *
sizeof(TCHAR));
516 uiResult = ERROR_OUTOFMEMORY;
goto cleanup_MsiCreateRecord;
519 uiResult = MsiFormatRecord(hInstall, hRecord, szPath, &dwPathSize);
521 if (uiResult != ERROR_SUCCESS)
523 SetLastError(uiResult);
525 goto cleanup_malloc_szPath;
529 SHELLEXECUTEINFO sei = {
530 .cbSize =
sizeof(SHELLEXECUTEINFO),
531 .fMask = SEE_MASK_FLAG_NO_UI,
533 .nShow = SW_SHOWNORMAL
535 if (!ShellExecuteEx(&sei))
537 uiResult = GetLastError();
539 goto cleanup_malloc_szPath;
542 uiResult = ERROR_SUCCESS;
544 cleanup_malloc_szPath:
545 if (szPath != szStackBuf)
549 cleanup_MsiCreateRecord:
550 MsiCloseHandle(hRecord);
551 cleanup_CoInitialize:
552 if (bIsCoInitialized)
584 _In_z_ LPCTSTR szDisplayName,
585 _In_z_ LPCTSTR szHardwareId,
591 if (dwResult != ERROR_SUCCESS)
599 if (pAdapterOther == NULL)
602 TCHAR szArgument[10 + MAX_PATH + 1 + MAX_PATH + 1 ];
606 szArgument, _countof(szArgument),
607 TEXT(
"create=\"%.*s|%.*s\""),
608 MAX_PATH, szDisplayName,
609 MAX_PATH, szHardwareId);
616 szArgument, _countof(szArgument),
617 TEXT(
"deleteN=\"%.*s\""),
618 MAX_PATH, szDisplayName);
625 else if (_tcsicmp(szDisplayName, pAdapterOther->szName) == 0)
628 for (LPCTSTR hwid = pAdapterOther->szzHardwareIDs;; hwid += _tcslen(hwid) + 1)
633 msg(
M_NONFATAL,
"%s: Adapter with name \"%" PRIsLPTSTR "\" already exists", __FUNCTION__, pAdapterOther->szName);
634 dwResult = ERROR_ALREADY_EXISTS;
635 goto cleanup_pAdapterList;
637 else if (_tcsicmp(hwid, szHardwareId) == 0)
647 cleanup_pAdapterList:
685 _In_z_ LPCTSTR szDisplayName,
692 if (dwResult != ERROR_SUCCESS)
700 if (_tcsicmp(szDisplayName, pAdapter->szName) == 0)
703 TCHAR szArgument[8 + 38 + 1 ];
704 if (seqCommit && seqRollback)
708 szArgument, _countof(szArgument),
715 szArgument, _countof(szArgument),
722 szArgument, _countof(szArgument),
731 szArgument, _countof(szArgument),
751 #pragma comment(linker, DLLEXP_EXPORT)
757 BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
767 seqUninstallRollback;
776 bool bRollbackEnabled = MsiEvaluateCondition(hInstall, TEXT(
"RollbackDisabled")) != MSICONDITION_TRUE;
779 MSIHANDLE hDatabase = MsiGetActiveDatabase(hInstall);
782 msg(
M_NONFATAL,
"%s: MsiGetActiveDatabase failed", __FUNCTION__);
783 uiResult = ERROR_INVALID_HANDLE;
784 goto cleanup_exec_seq;
788 switch (MsiDatabaseIsTablePersistent(hDatabase, TEXT(
"TUNTAPAdapter")))
790 case MSICONDITION_FALSE:
791 case MSICONDITION_TRUE:
break;
794 uiResult = ERROR_SUCCESS;
795 goto cleanup_hDatabase;
799 MSIHANDLE hViewST = 0;
800 LPCTSTR szQuery = TEXT(
"SELECT `Adapter`,`DisplayName`,`Condition`,`Component_`,`HardwareId` FROM `TUNTAPAdapter`");
801 uiResult = MsiDatabaseOpenView(hDatabase, szQuery, &hViewST);
802 if (uiResult != ERROR_SUCCESS)
804 SetLastError(uiResult);
806 goto cleanup_hDatabase;
810 uiResult = MsiViewExecute(hViewST, 0);
811 if (uiResult != ERROR_SUCCESS)
813 SetLastError(uiResult);
815 goto cleanup_hViewST;
819 MSIHANDLE hRecordProg = MsiCreateRecord(2);
822 uiResult = ERROR_INVALID_HANDLE;
824 goto cleanup_hViewST_close;
830 MSIHANDLE hRecord = 0;
831 uiResult = MsiViewFetch(hViewST, &hRecord);
832 if (uiResult == ERROR_NO_MORE_ITEMS)
834 uiResult = ERROR_SUCCESS;
837 else if (uiResult != ERROR_SUCCESS)
839 SetLastError(uiResult);
841 goto cleanup_hRecordProg;
844 INSTALLSTATE iInstalled, iAction;
847 LPTSTR szValue = NULL;
849 if (uiResult != ERROR_SUCCESS)
851 goto cleanup_hRecord;
855 uiResult = MsiGetComponentState(hInstall, szValue, &iInstalled, &iAction);
856 if (uiResult != ERROR_SUCCESS)
858 SetLastError(uiResult);
861 goto cleanup_hRecord;
867 LPTSTR szDisplayName = NULL;
869 if (uiResult != ERROR_SUCCESS)
871 goto cleanup_hRecord;
874 LPTSTR szDisplayNameEx = _tcschr(szDisplayName, TEXT(
'|'));
875 szDisplayNameEx = szDisplayNameEx != NULL ? szDisplayNameEx + 1 : szDisplayName;
878 TCHAR szzHardwareIDs[0x100] = { 0 };
880 LPTSTR szHwId = NULL;
882 if (uiResult != ERROR_SUCCESS)
884 goto cleanup_szDisplayName;
886 memcpy_s(szzHardwareIDs,
sizeof(szzHardwareIDs) - 2*
sizeof(TCHAR) , szHwId, _tcslen(szHwId)*
sizeof(TCHAR));
890 if (iAction > INSTALLSTATE_BROKEN)
894 if (iAction >= INSTALLSTATE_LOCAL)
897 LPTSTR szValue = NULL;
899 if (uiResult != ERROR_SUCCESS)
901 goto cleanup_szDisplayName;
908 #pragma GCC diagnostic push
909 #pragma GCC diagnostic ignored "-Wswitch"
911 switch (MsiEvaluateCondition(hInstall, szValue))
913 case MSICONDITION_FALSE:
915 goto cleanup_szDisplayName;
917 case MSICONDITION_ERROR:
918 uiResult = ERROR_INVALID_FIELD;
921 goto cleanup_szDisplayName;
924 #pragma GCC diagnostic pop
931 bRollbackEnabled ? &seqInstallRollback : NULL,
934 &iTicks) != ERROR_SUCCESS)
936 uiResult = ERROR_INSTALL_FAILED;
937 goto cleanup_szDisplayName;
949 bRollbackEnabled ? &seqUninstallCommit : NULL,
950 bRollbackEnabled ? &seqUninstallRollback : NULL,
958 MsiRecordSetInteger(hRecordProg, 1, 3 );
959 MsiRecordSetInteger(hRecordProg, 2, iTicks);
960 if (MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL)
962 uiResult = ERROR_INSTALL_USEREXIT;
963 goto cleanup_szDisplayName;
967 cleanup_szDisplayName:
970 MsiCloseHandle(hRecord);
971 if (uiResult != ERROR_SUCCESS)
973 goto cleanup_hRecordProg;
978 TCHAR tmpDir[MAX_PATH];
979 GetTempPath(MAX_PATH, tmpDir);
981 TCHAR str[MAX_PATH + 7];
982 _stprintf_s(str, _countof(str), TEXT(
"tmpdir=%") TEXT(
PRIsLPTSTR), tmpDir);
991 if ((uiResult =
setup_sequence(hInstall, TEXT(
"InstallTUNTAPAdapters" ), &seqInstall )) != ERROR_SUCCESS
992 || (uiResult =
setup_sequence(hInstall, TEXT(
"InstallTUNTAPAdaptersCommit" ), &seqInstallCommit )) != ERROR_SUCCESS
993 || (uiResult =
setup_sequence(hInstall, TEXT(
"InstallTUNTAPAdaptersRollback" ), &seqInstallRollback )) != ERROR_SUCCESS
994 || (uiResult =
setup_sequence(hInstall, TEXT(
"UninstallTUNTAPAdapters" ), &seqUninstall )) != ERROR_SUCCESS
995 || (uiResult =
setup_sequence(hInstall, TEXT(
"UninstallTUNTAPAdaptersCommit" ), &seqUninstallCommit )) != ERROR_SUCCESS
996 || (uiResult =
setup_sequence(hInstall, TEXT(
"UninstallTUNTAPAdaptersRollback"), &seqUninstallRollback)) != ERROR_SUCCESS)
998 goto cleanup_hRecordProg;
1001 uiResult = ERROR_SUCCESS;
1003 cleanup_hRecordProg:
1004 MsiCloseHandle(hRecordProg);
1005 cleanup_hViewST_close:
1006 MsiViewClose(hViewST);
1008 MsiCloseHandle(hViewST);
1010 MsiCloseHandle(hDatabase);
1018 if (bIsCoInitialized)
1060 WCHAR path[MAX_PATH];
1063 msg(
M_WARN,
"%s: Reboot required, create reboot indication file \"%ls\"", __FUNCTION__, path);
1065 HANDLE file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1066 if (file == INVALID_HANDLE_VALUE)
1080 #pragma comment(linker, DLLEXP_EXPORT)
1086 BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
1087 WCHAR tmpDir[MAX_PATH] = {0};
1091 BOOL bIsCleanup = MsiGetMode(hInstall, MSIRUNMODE_COMMIT) || MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK);
1094 LPWSTR szSequence = NULL;
1095 uiResult =
msi_get_string(hInstall, L
"CustomActionData", &szSequence);
1096 if (uiResult != ERROR_SUCCESS)
1098 goto cleanup_CoInitialize;
1101 LPWSTR *szArg = CommandLineToArgvW(szSequence, &nArgs);
1104 uiResult = GetLastError();
1106 goto cleanup_szSequence;
1110 MSIHANDLE hRecordProg = MsiCreateRecord(3);
1111 MsiRecordSetInteger(hRecordProg, 1, 1);
1112 MsiRecordSetInteger(hRecordProg, 2, 1);
1113 MsiRecordSetInteger(hRecordProg, 3, 0);
1114 MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg);
1117 MsiRecordSetInteger(hRecordProg, 1, 2);
1118 MsiRecordSetInteger(hRecordProg, 3, 0);
1120 BOOL bRebootRequired = FALSE;
1122 for (
int i = 1 ; i < nArgs; ++i)
1124 DWORD dwResult = ERROR_SUCCESS;
1126 if (wcsncmp(szArg[i], L
"create=", 7) == 0)
1129 LPWSTR szName = szArg[i] + 7;
1130 LPWSTR szHardwareId = wcschr(szName, L
'|');
1131 if (szHardwareId == NULL)
1133 goto invalid_argument;
1135 szHardwareId[0] = 0;
1140 MSIHANDLE hRecord = MsiCreateRecord(4);
1141 MsiRecordSetString(hRecord, 1, TEXT(
"Creating adapter"));
1142 MsiRecordSetString(hRecord, 2, szName);
1143 MsiRecordSetString(hRecord, 3, szHardwareId);
1144 int iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord);
1145 MsiCloseHandle(hRecord);
1146 if (iResult == IDCANCEL)
1148 uiResult = ERROR_INSTALL_USEREXIT;
1154 dwResult =
tap_create_adapter(NULL, NULL, szHardwareId, &bRebootRequired, &guidAdapter);
1155 if (dwResult == ERROR_SUCCESS)
1162 else if (wcsncmp(szArg[i], L
"deleteN=", 8) == 0)
1165 LPCWSTR szName = szArg[i] + 8;
1169 MSIHANDLE hRecord = MsiCreateRecord(3);
1170 MsiRecordSetString(hRecord, 1, TEXT(
"Deleting adapter"));
1171 MsiRecordSetString(hRecord, 2, szName);
1172 int iResult = MsiProcessMessage(hInstall, INSTALLMESSAGE_ACTIONDATA, hRecord);
1173 MsiCloseHandle(hRecord);
1174 if (iResult == IDCANCEL)
1176 uiResult = ERROR_INSTALL_USEREXIT;
1184 if (dwResult == ERROR_SUCCESS)
1187 for (
struct tap_adapter_node *pAdapter = pAdapterList; pAdapter != NULL; pAdapter = pAdapter->
pNext)
1189 if (_tcsicmp(
szName, pAdapter->szName) == 0)
1200 else if (wcsncmp(szArg[i], L
"delete=", 7) == 0)
1206 goto invalid_argument;
1210 else if (wcsncmp(szArg[i], L
"enable=", 7) == 0)
1216 goto invalid_argument;
1220 else if (wcsncmp(szArg[i], L
"disable=", 8) == 0)
1226 goto invalid_argument;
1230 else if (wcsncmp(szArg[i], L
"tmpdir=", 7) == 0)
1232 wcscpy_s(tmpDir, _countof(tmpDir), szArg[i] + 7);
1236 goto invalid_argument;
1239 if (dwResult != ERROR_SUCCESS && !bIsCleanup )
1241 uiResult = ERROR_INSTALL_FAILURE;
1247 if (MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL)
1249 dwResult = ERROR_INSTALL_USEREXIT;
1256 msg(
M_NONFATAL,
"%s: Ignoring invalid argument: %ls", __FUNCTION__, szArg[i]);
1260 if (bRebootRequired && wcslen(tmpDir) > 0)
1264 MsiCloseHandle(hRecordProg);
1268 cleanup_CoInitialize:
1269 if (bIsCoInitialized)
1280 #pragma comment(linker, DLLEXP_EXPORT)
1285 BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
1290 WCHAR tempPath[MAX_PATH];
1291 GetTempPathW(MAX_PATH, tempPath);
1294 WCHAR path[MAX_PATH];
1296 WIN32_FIND_DATA data = { 0 };
1297 HANDLE searchHandle = FindFirstFileW(path, &data);
1298 if (searchHandle != INVALID_HANDLE_VALUE)
1300 msg(
M_WARN,
"%s: Reboot file exists, schedule reboot", __FUNCTION__);
1302 FindClose(searchHandle);
1305 MsiSetMode(hInstall, MSIRUNMODE_REBOOTATEND, TRUE);
1308 if (bIsCoInitialized)
1312 return ERROR_SUCCESS;
1318 return INSTALLSTATE_LOCAL == ActionState || INSTALLSTATE_SOURCE == ActionState
1319 || (INSTALLSTATE_DEFAULT == ActionState
1320 && (INSTALLSTATE_LOCAL == InstallState || INSTALLSTATE_SOURCE == InstallState));
1326 return (INSTALLSTATE_LOCAL == ActionState || INSTALLSTATE_SOURCE == ActionState
1327 || INSTALLSTATE_DEFAULT == ActionState)
1328 && (INSTALLSTATE_LOCAL == InstallState || INSTALLSTATE_SOURCE == InstallState);
1334 return (INSTALLSTATE_ABSENT == ActionState || INSTALLSTATE_REMOVED == ActionState)
1335 && (INSTALLSTATE_LOCAL == InstallState || INSTALLSTATE_SOURCE == InstallState);
1342 #pragma comment(linker, DLLEXP_EXPORT)
1348 BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
1352 INSTALLSTATE InstallState, ActionState;
1353 ret = MsiGetComponentStateW(hInstall,
CMP_OVPN_DCO_INF, &InstallState, &ActionState);
1354 if (ret != ERROR_SUCCESS)
1362 WCHAR tempPath[MAX_PATH];
1363 GetTempPathW(MAX_PATH, tempPath);
1365 WCHAR pathToInf[MAX_PATH];
1366 DWORD pathLen = _countof(pathToInf);
1367 ret = MsiGetPropertyW(hInstall, L
"OVPNDCO", pathToInf, &pathLen);
1368 if (ret != ERROR_SUCCESS)
1375 WCHAR action[0x400];
1386 swprintf_s(action, _countof(action), L
"%s||",
ACTION_NOOP);
1389 ret = MsiSetPropertyW(hInstall, L
"OvpnDcoProcess", action);
1392 if (bIsCoInitialized)
1402 wcscpy_s(publishedName, len, L
"");
1411 if (!SetupDiBuildDriverInfoList(devInfoSet, NULL, SPDIT_CLASSDRIVER))
1414 goto cleanupDeviceInfoSet;
1416 for (DWORD idx = 0;; ++idx)
1418 SP_DRVINFO_DATA_W drvInfo = { .cbSize =
sizeof(drvInfo) };
1419 if (!SetupDiEnumDriverInfoW(devInfoSet, NULL, SPDIT_CLASSDRIVER, idx, &drvInfo))
1421 if (GetLastError() == ERROR_NO_MORE_ITEMS)
1426 goto cleanupDriverInfoList;
1429 if (SetupDiGetDriverInfoDetailW(devInfoSet, NULL, &drvInfo, NULL, 0, &size) || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
1432 goto cleanupDriverInfoList;
1434 PSP_DRVINFO_DETAIL_DATA_W drvDetails = calloc(1, size);
1437 msg(
M_NONFATAL,
"%s: calloc(1, %u) failed", __FUNCTION__, size);
1438 goto cleanupDriverInfoList;
1440 drvDetails->cbSize =
sizeof(*drvDetails);
1441 if (!SetupDiGetDriverInfoDetailW(devInfoSet, NULL, &drvInfo, drvDetails, size, &size))
1445 goto cleanupDriverInfoList;
1447 if (wcscmp(hwid, drvDetails->HardwareID) == 0)
1449 PathStripPathW(drvDetails->InfFileName);
1450 wcscpy_s(publishedName, len, drvDetails->InfFileName);
1458 cleanupDriverInfoList:
1459 SetupDiDestroyDriverInfoList(devInfoSet, NULL, SPDIT_CLASSDRIVER);
1460 cleanupDeviceInfoSet:
1461 SetupDiDestroyDeviceInfoList(devInfoSet);
1471 if (ret != ERROR_SUCCESS)
1473 msg(
M_NONFATAL,
"%s",
"Failed to get adapter list: %d", __FUNCTION__, ret);
1477 BOOL rebootRequired = FALSE;
1478 for (
struct tap_adapter_node *pAdapter = pAdapterList; pAdapter != NULL; pAdapter = pAdapter->
pNext)
1484 WCHAR publishedName[MAX_PATH] = { 0 };
1487 if (!SetupUninstallOEMInfW(publishedName, 0, NULL))
1489 msg(
M_NONFATAL |
M_ERRNO,
"%s: SetupUninstallOEMInfW(\"%ls\") failed", __FUNCTION__, publishedName);
1503 if (!SetupCopyOEMInfW(pathToInf, NULL, SPOST_PATH, 0, NULL, 0, NULL, NULL))
1510 BOOL rebootRequired = FALSE;
1511 if (!UpdateDriverForPlugAndPlayDevicesW(NULL,
OVPN_DCO_HWID, pathToInf, INSTALLFLAG_NONINTERACTIVE | INSTALLFLAG_FORCE, &rebootRequired))
1514 if (GetLastError() != ERROR_NO_SUCH_DEVINST)
1530 #pragma comment(linker, DLLEXP_EXPORT)
1536 BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
1540 LPWSTR customData = NULL;
1541 ret =
msi_get_string(hInstall, L
"CustomActionData", &customData);
1542 if (ret != ERROR_SUCCESS)
1548 WCHAR action[0x400] = { 0 };
1549 WCHAR pathToInf[MAX_PATH] = { 0 };
1550 WCHAR pathToTmp[MAX_PATH] = { 0 };
1553 WCHAR *token = wcstok_s(customData, L
"|", &
pos);
1560 wcscpy_s(action, _countof(action), token);
1564 wcscpy_s(pathToInf, _countof(pathToInf), token);
1568 wcscpy_s(pathToTmp, _countof(pathToTmp), token);
1571 token = wcstok_s(NULL, L
"|", &
pos);
1585 if (bIsCoInitialized)