#define MSICA_ADAPTER_TICK_SIZE (16*1024) /** Amount of tick space to reserve for one TAP/TUN adapter creation/deletition. */
+#define FILE_NEED_REBOOT L".ovpn_need_reboot"
/**
* Joins an argument sequence and sets it to the MSI property.
}
}
+ /* save path to user's temp dir to be used later by deferred actions */
+ TCHAR tmpDir[MAX_PATH];
+ GetTempPath(MAX_PATH, tmpDir);
+
+ TCHAR str[MAX_PATH + 7];
+ _stprintf_s(str, _countof(str), TEXT("tmpdir=%") TEXT(PRIsLPTSTR), tmpDir);
+ msica_arg_seq_add_tail(&seqInstall, str);
+ msica_arg_seq_add_tail(&seqInstallCommit, str);
+ msica_arg_seq_add_tail(&seqInstallRollback, str);
+ msica_arg_seq_add_tail(&seqUninstall, str);
+ msica_arg_seq_add_tail(&seqUninstallCommit, str);
+ msica_arg_seq_add_tail(&seqUninstallRollback, str);
+
/* Store deferred custom action parameters. */
if ((uiResult = setup_sequence(hInstall, TEXT("InstallTUNTAPAdapters" ), &seqInstall )) != ERROR_SUCCESS
|| (uiResult = setup_sequence(hInstall, TEXT("InstallTUNTAPAdaptersCommit" ), &seqInstallCommit )) != ERROR_SUCCESS
}
+/**
+ * Create empty file in user's temp directory. The existence of this file
+ * is checked in the end of installation by ScheduleReboot immediate custom action
+ * which schedules reboot.
+ *
+ * @param szTmpDir path to user's temp dirctory
+ *
+ */
+static void
+CreateRebootFile(_In_z_ LPCWSTR szTmpDir)
+{
+ TCHAR path[MAX_PATH];
+ swprintf_s(path, _countof(path), L"%s%s", szTmpDir, FILE_NEED_REBOOT);
+
+ msg(M_WARN, "%s: Reboot required, create reboot indication file \"%" PRIsLPTSTR "\"", __FUNCTION__, path);
+
+ HANDLE file = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (file == INVALID_HANDLE_VALUE)
+ {
+ msg(M_NONFATAL | M_ERRNO, "%s: CreateFile(\"%" PRIsLPTSTR "\") failed", __FUNCTION__, path);
+ }
+ else
+ {
+ CloseHandle(file);
+ }
+}
+
UINT __stdcall
ProcessDeferredAction(_In_ MSIHANDLE hInstall)
{
UINT uiResult;
BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
+ WCHAR tmpDir[MAX_PATH] = {0};
OPENVPNMSICA_SAVE_MSI_SESSION(hInstall);
}
dwResult = tap_enable_adapter(NULL, &guid, FALSE, &bRebootRequired);
}
+ else if (wcsncmp(szArg[i], L"tmpdir=", 7) == 0)
+ {
+ wcscpy_s(tmpDir, _countof(tmpDir), szArg[i] + 7);
+ }
else
{
goto invalid_argument;
}
cleanup:
- if (bRebootRequired)
+ if (bRebootRequired && wcslen(tmpDir) > 0)
{
- MsiSetMode(hInstall, MSIRUNMODE_REBOOTATEND, TRUE);
+ CreateRebootFile(tmpDir);
}
MsiCloseHandle(hRecordProg);
LocalFree(szArg);
}
return uiResult;
}
+
+UINT __stdcall
+CheckAndScheduleReboot(_In_ MSIHANDLE hInstall)
+{
+#ifdef _MSC_VER
+#pragma comment(linker, DLLEXP_EXPORT)
+#endif
+
+ debug_popup(TEXT(__FUNCTION__));
+
+ UINT ret = ERROR_SUCCESS;
+ BOOL bIsCoInitialized = SUCCEEDED(CoInitialize(NULL));
+
+ OPENVPNMSICA_SAVE_MSI_SESSION(hInstall);
+
+ /* get user-specific temp path, to where we create reboot indication file */
+ TCHAR tempPath[MAX_PATH];
+ GetTempPath(MAX_PATH, tempPath);
+
+ /* check if reboot file exists */
+ TCHAR path[MAX_PATH];
+ _stprintf_s(path, _countof(path), L"%s%s", tempPath, FILE_NEED_REBOOT);
+ WIN32_FIND_DATA data = { 0 };
+ HANDLE searchHandle = FindFirstFile(path, &data);
+ if (searchHandle != INVALID_HANDLE_VALUE)
+ {
+ msg(M_WARN, "%s: Reboot file exists, schedule reboot", __FUNCTION__);
+
+ FindClose(searchHandle);
+ DeleteFile(path);
+
+ MsiSetMode(hInstall, MSIRUNMODE_REBOOTATEND, TRUE);
+ }
+
+ if (bIsCoInitialized)
+ {
+ CoUninitialize();
+ }
+ return ret;
+}