gecko-dev/toolkit/xre/LauncherRegistryInfo.h
Toshihito Kikuchi ee1f6d7a78 Bug 1529593 - Make LauncherRegistryInfo delay write to the registry. r=aklotz
We have the `LauncherRegistryInfo` class to check the launcher process was
launched successfully on Windows by comparing the timestamps in the registry
when each process was launched.

The problem was when the process is launched from an elevated process, we
relaunch a new launcher process via shell after we updated the launcher's
timestamp.  As a result, `LauncherRegistryInfo` unexpectedly disabled the
launcher process even though there was nothing wrong.

A proposed fix is to introduce delay-write to the `LauncherRegistryInfo`.  With
this, `LauncherRegistryInfo::Check` modifies only the image timestamp. To update
the launcher/browser timestamps, we need to call `LauncherRegistryInfo::Commit`.
When we ask shell to relaunch a new process, we hold back commit, delegating it
to the new process.

There is another consideration needed.  If something fails during `LauncherMain`,
we call `DisableDueToFailure()` to disable the launcher until the image timestamp
is changed.  In such a case, we should not change the stored timestamps even
though commit is attempted.  The problem is we use a different instance to call
`DisableDueToFailure()` in `HandleLauncherError`.  To deal with this design,
`LauncherRegistryInfo` has a static boolean to indicate disablement happens or not.

Differential Revision: https://phabricator.services.mozilla.com/D44928

--HG--
extra : moz-landing-system : lando
2019-10-14 17:14:54 +00:00

100 lines
3.1 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
#ifndef mozilla_LauncherRegistryInfo_h
#define mozilla_LauncherRegistryInfo_h
#include "mozilla/Maybe.h"
#include "mozilla/WinHeaderOnlyUtils.h"
#include "nsWindowsHelpers.h"
#include <string>
/**
* We use std::wstring here because this code must be usable within both the
* launcher process and Gecko itself.
*/
namespace mozilla {
class LauncherRegistryInfo final {
public:
enum class ProcessType { Launcher, Browser };
enum class EnabledState {
Enabled,
FailDisabled,
ForceDisabled,
};
enum class CheckOption {
Default,
Force,
};
LauncherRegistryInfo() : mBinPath(GetFullBinaryPath().get()) {}
~LauncherRegistryInfo() { Abort(); }
LauncherVoidResult ReflectPrefToRegistry(const bool aEnable);
LauncherResult<EnabledState> IsEnabled();
LauncherResult<bool> IsTelemetryEnabled();
LauncherVoidResult ReflectTelemetryPrefToRegistry(const bool aEnable);
LauncherResult<ProcessType> Check(
const ProcessType aDesiredType,
const CheckOption aOption = CheckOption::Default);
LauncherVoidResult DisableDueToFailure();
LauncherVoidResult Commit();
void Abort();
private:
enum class Disposition { CreatedNew, OpenedExisting };
private:
// This flag is to prevent the disabled state from being accidentally
// re-enabled by another instance.
static bool sAllowCommit;
static EnabledState GetEnabledState(const Maybe<uint64_t>& aLauncherTs,
const Maybe<uint64_t>& aBrowserTs);
LauncherResult<Disposition> Open();
LauncherVoidResult WriteLauncherStartTimestamp(uint64_t aValue);
LauncherVoidResult WriteBrowserStartTimestamp(uint64_t aValue);
LauncherVoidResult WriteImageTimestamp(DWORD aTimestamp);
LauncherResult<bool> ClearLauncherStartTimestamp();
LauncherResult<bool> ClearBrowserStartTimestamp();
LauncherVoidResult ClearStartTimestamps();
LauncherResult<Maybe<DWORD>> GetSavedImageTimestamp();
LauncherResult<Maybe<uint64_t>> GetLauncherStartTimestamp();
LauncherResult<Maybe<uint64_t>> GetBrowserStartTimestamp();
const std::wstring& ResolveLauncherValueName();
const std::wstring& ResolveBrowserValueName();
const std::wstring& ResolveImageTimestampValueName();
const std::wstring& ResolveTelemetryValueName();
private:
Maybe<uint64_t> mLauncherTimestampToWrite;
Maybe<uint64_t> mBrowserTimestampToWrite;
nsAutoRegKey mRegKey;
std::wstring mBinPath;
std::wstring mImageValueName;
std::wstring mBrowserValueName;
std::wstring mLauncherValueName;
std::wstring mTelemetryValueName;
static const wchar_t kLauncherSubKeyPath[];
static const wchar_t kLauncherSuffix[];
static const wchar_t kBrowserSuffix[];
static const wchar_t kImageTimestampSuffix[];
static const wchar_t kTelemetrySuffix[];
};
} // namespace mozilla
#endif // mozilla_LauncherRegistryInfo_h