diff options
| author | spycrab <spycrab@users.noreply.github.com> | 2019-03-07 19:09:35 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-03-07 19:09:35 +0100 |
| commit | db2542886a76a3d346fbdb019dec6b0afd53bd84 (patch) | |
| tree | a3dce03c9b5f5c4c98818cfd11b5083dbda67f51 /Source/Core/Updater/Main.cpp | |
| parent | 7d17163ce85f518e3951a39ab226a446c32a8e54 (diff) | |
| parent | 19bf2c166d9bc1647a3d055dbdeca87e8cdf5a06 (diff) | |
Merge pull request #7844 from spycrab/updatecommon_electric_boogaloo
UpdaterCommon: Move most of the programs here
Diffstat (limited to 'Source/Core/Updater/Main.cpp')
| -rw-r--r-- | Source/Core/Updater/Main.cpp | 203 |
1 files changed, 13 insertions, 190 deletions
diff --git a/Source/Core/Updater/Main.cpp b/Source/Core/Updater/Main.cpp index 35e868a7f1..0cb09cb966 100644 --- a/Source/Core/Updater/Main.cpp +++ b/Source/Core/Updater/Main.cpp @@ -4,36 +4,18 @@ #include <windows.h> #include <ShlObj.h> - -#include <OptionParser.h> -#include <array> -#include <optional> #include <shellapi.h> + #include <string> -#include <thread> #include <vector> -#include "Common/CommonPaths.h" -#include "Common/CommonTypes.h" -#include "Common/FileUtil.h" +#include "Common/StringUtil.h" #include "UpdaterCommon/UI.h" #include "UpdaterCommon/UpdaterCommon.h" namespace { -// Internal representation of options passed on the command-line. -struct Options -{ - std::string this_manifest_url; - std::string next_manifest_url; - std::string content_store_url; - std::string install_base_path; - std::optional<std::string> binary_to_restart; - std::optional<DWORD> parent_pid; - std::optional<std::string> log_file; -}; - std::vector<std::string> CommandLineToUtf8Argv(PCWSTR command_line) { int nargs; @@ -50,75 +32,6 @@ std::vector<std::string> CommandLineToUtf8Argv(PCWSTR command_line) LocalFree(tokenized); return argv; } - -std::optional<Options> ParseCommandLine(PCWSTR command_line) -{ - using optparse::OptionParser; - - OptionParser parser = OptionParser().prog("updater.exe").description("Dolphin Updater binary"); - - parser.add_option("--this-manifest-url") - .dest("this-manifest-url") - .help("URL to the update manifest for the currently installed version.") - .metavar("URL"); - parser.add_option("--next-manifest-url") - .dest("next-manifest-url") - .help("URL to the update manifest for the to-be-installed version.") - .metavar("URL"); - parser.add_option("--content-store-url") - .dest("content-store-url") - .help("Base URL of the content store where files to download are stored.") - .metavar("URL"); - parser.add_option("--install-base-path") - .dest("install-base-path") - .help("Base path of the Dolphin install to be updated.") - .metavar("PATH"); - parser.add_option("--binary-to-restart") - .dest("binary-to-restart") - .help("Binary to restart after the update is over.") - .metavar("PATH"); - parser.add_option("--log-file") - .dest("log-file") - .help("File where to log updater debug output.") - .metavar("PATH"); - parser.add_option("--parent-pid") - .dest("parent-pid") - .type("int") - .help("(optional) PID of the parent process. The updater will wait for this process to " - "complete before proceeding.") - .metavar("PID"); - - std::vector<std::string> argv = CommandLineToUtf8Argv(command_line); - optparse::Values options = parser.parse_args(argv); - - Options opts; - - // Required arguments. - std::vector<std::string> required{"this-manifest-url", "next-manifest-url", "content-store-url", - "install-base-path"}; - for (const auto& req : required) - { - if (!options.is_set(req)) - { - parser.print_help(); - return {}; - } - } - opts.this_manifest_url = options["this-manifest-url"]; - opts.next_manifest_url = options["next-manifest-url"]; - opts.content_store_url = options["content-store-url"]; - opts.install_base_path = options["install-base-path"]; - - // Optional arguments. - if (options.is_set("binary-to-restart")) - opts.binary_to_restart = options["binary-to-restart"]; - if (options.is_set("parent-pid")) - opts.parent_pid = (DWORD)options.get("parent-pid"); - if (options.is_set("log-file")) - opts.log_file = options["log-file"]; - - return opts; -} }; // namespace int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) @@ -132,58 +45,29 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine return 1; } - std::optional<Options> maybe_opts = ParseCommandLine(pCmdLine); - if (!maybe_opts) - return 1; - Options opts = std::move(*maybe_opts); - + // Test for write permissions bool need_admin = false; - if (opts.log_file) - { - log_fp = _wfopen(UTF8ToUTF16(*opts.log_file).c_str(), L"w"); - if (!log_fp) - { - log_fp = stderr; - // Failing to create the logfile for writing is a good indicator that we need administrator - // priviliges - need_admin = true; - } - else - atexit(FlushLog); - } - - fprintf(log_fp, "Updating from: %s\n", opts.this_manifest_url.c_str()); - fprintf(log_fp, "Updating to: %s\n", opts.next_manifest_url.c_str()); - fprintf(log_fp, "Install path: %s\n", opts.install_base_path.c_str()); + FILE* test_fh = fopen("Updater.log", "w"); - if (!File::IsDirectory(opts.install_base_path)) - { - FatalError("Cannot find install base path, or not a directory."); - return 1; - } - - if (opts.parent_pid) - { - fprintf(log_fp, "Waiting for parent PID %d to complete...\n", *opts.parent_pid); - HANDLE parent_handle = OpenProcess(SYNCHRONIZE, FALSE, *opts.parent_pid); - WaitForSingleObject(parent_handle, INFINITE); - CloseHandle(parent_handle); - fprintf(log_fp, "Completed! Proceeding with update.\n"); - } + if (test_fh == nullptr) + need_admin = true; + else + fclose(test_fh); if (need_admin) { if (IsUserAnAdmin()) { - FatalError("Failed to write to directory despite administrator priviliges."); + MessageBox(nullptr, L"Failed to write to directory despite administrator priviliges.", + L"Error", MB_ICONERROR); return 1; } wchar_t path[MAX_PATH]; if (GetModuleFileName(hInstance, path, sizeof(path)) == 0) { - FatalError("Failed to get updater filename."); + MessageBox(nullptr, L"Failed to get updater filename.", L"Error", MB_ICONERROR); return 1; } @@ -192,68 +76,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine return 0; } - std::thread thread(UI::MessageLoop); - thread.detach(); - - UI::SetDescription("Fetching and parsing manifests..."); - - Manifest this_manifest, next_manifest; - { - std::optional<Manifest> maybe_manifest = FetchAndParseManifest(opts.this_manifest_url); - if (!maybe_manifest) - { - FatalError("Could not fetch current manifest. Aborting."); - return 1; - } - this_manifest = std::move(*maybe_manifest); - - maybe_manifest = FetchAndParseManifest(opts.next_manifest_url); - if (!maybe_manifest) - { - FatalError("Could not fetch next manifest. Aborting."); - return 1; - } - next_manifest = std::move(*maybe_manifest); - } - - UI::SetDescription("Computing what to do..."); - - TodoList todo = ComputeActionsToDo(this_manifest, next_manifest); - todo.Log(); - - std::optional<std::string> maybe_temp_dir = FindOrCreateTempDir(opts.install_base_path); - if (!maybe_temp_dir) - return 1; - std::string temp_dir = std::move(*maybe_temp_dir); - - UI::SetDescription("Performing Update..."); - - bool ok = PerformUpdate(todo, opts.install_base_path, opts.content_store_url, temp_dir); - if (!ok) - FatalError("Failed to apply the update."); - - CleanUpTempDir(temp_dir, todo); - - UI::ResetCurrentProgress(); - UI::ResetTotalProgress(); - UI::SetCurrentMarquee(false); - UI::SetTotalMarquee(false); - UI::SetCurrentProgress(0, 1); - UI::SetTotalProgress(1, 1); - UI::SetDescription("Done!"); - - // Let the user process that we are done. - Sleep(1000); - - if (opts.binary_to_restart) - { - // Hack: Launching the updater over the explorer ensures that admin priviliges are dropped. Why? - // Ask Microsoft. - ShellExecuteW(nullptr, nullptr, L"explorer.exe", UTF8ToUTF16(*opts.binary_to_restart).c_str(), - nullptr, SW_SHOW); - } - - UI::Stop(); + std::vector<std::string> args = CommandLineToUtf8Argv(pCmdLine); - return !ok; + return RunUpdater(args) ? 0 : 1; } |
