Windows install_static refactor.

This change introduces install_static::InstallDetails, a module-global
holder of details relating to the current install. It also more clearly
defines the concept of a primary install mode and one or more secondary
install modes (e.g., "Chrome SxS" for Google Chrome's canary channel).
Furthermore, it creates a clear boundary for brand-specific constants so
that Chromium and Google Chrome don't bleed into one another. See
chrome/install_static/README.md for more information.

BUG=373987
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.win:win10_chromium_x64_rel_ng

Committed: https://crrev.com/92bc27b8b101d2b300a7b3afd79265b3cfba1152
Review-Url: https://codereview.chromium.org/2422643002
Cr-Original-Commit-Position: refs/heads/master@{#430728}
Cr-Commit-Position: refs/heads/master@{#432270}
diff --git a/chrome/install_static/install_details.cc b/chrome/install_static/install_details.cc
new file mode 100644
index 0000000..c4d96a2
--- /dev/null
+++ b/chrome/install_static/install_details.cc
@@ -0,0 +1,91 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/install_static/install_details.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include <type_traits>
+
+#include "chrome/install_static/install_modes.h"
+#include "chrome/install_static/install_util.h"
+#include "chrome_elf/nt_registry/nt_registry.h"
+#include "components/version_info/version_info_values.h"
+
+namespace install_static {
+
+namespace {
+
+// The version is set at compile-time to a W.X.Y.Z value.
+constexpr char kProductVersion[] = PRODUCT_VERSION;
+
+// This module's instance (intentionally leaked at shutdown).
+InstallDetails* g_module_details = nullptr;
+
+}  // namespace
+
+std::wstring InstallDetails::GetClientStateKeyPath(bool binaries) const {
+  return binaries && multi_install()
+             ? GetBinariesClientStateKeyPath()
+             : install_static::GetClientStateKeyPath(app_guid());
+}
+
+std::wstring InstallDetails::GetClientStateMediumKeyPath(bool binaries) const {
+  return binaries && multi_install()
+             ? GetBinariesClientStateMediumKeyPath()
+             : install_static::GetClientStateMediumKeyPath(app_guid());
+}
+
+bool InstallDetails::VersionMismatch() const {
+  // Check the product version and the size of the mode structure.
+  return payload_->size != sizeof(Payload) ||
+         strcmp(payload_->product_version, &kProductVersion[0]) != 0 ||
+         payload_->mode->size != sizeof(InstallConstants);
+}
+
+// static
+const InstallDetails& InstallDetails::Get() {
+  assert(g_module_details);
+  return *g_module_details;
+}
+
+// static
+void InstallDetails::SetForProcess(
+    std::unique_ptr<PrimaryInstallDetails> details) {
+  assert(!details || !g_module_details);
+  // Tests may set then reset via null. In this case, delete the old instance.
+  delete g_module_details;
+  // Intentionally leaked at shutdown.
+  g_module_details = details.release();
+}
+
+// static
+const InstallDetails::Payload* InstallDetails::GetPayload() {
+  assert(g_module_details);
+  static_assert(std::is_pod<Payload>::value, "Payload must be a POD-struct");
+  static_assert(std::is_pod<InstallConstants>::value,
+                "InstallConstants must be a POD-struct");
+  return g_module_details->payload_;
+}
+
+// static
+void InstallDetails::InitializeFromPrimaryModule(
+    const wchar_t* primary_module_name) {
+  assert(!g_module_details);
+  using GetInstallDetailsPayloadFunction = const Payload*(__cdecl*)();
+  GetInstallDetailsPayloadFunction payload_getter =
+      reinterpret_cast<GetInstallDetailsPayloadFunction>(::GetProcAddress(
+          ::GetModuleHandle(primary_module_name), "GetInstallDetailsPayload"));
+  assert(payload_getter);
+  // Intentionally leaked at shutdown.
+  g_module_details = new InstallDetails(payload_getter());
+}
+
+PrimaryInstallDetails::PrimaryInstallDetails() : InstallDetails(&payload_) {
+  payload_.size = sizeof(payload_);
+  payload_.product_version = &kProductVersion[0];
+}
+
+}  // namespace install_static