Commit 7d293530 authored by Roger Tawa's avatar Roger Tawa Committed by Commit Bot

Update some organic brand codes for enterprise installs.

Bug: 874558
Change-Id: I09dbdacde63bf0f9fc771b214ca5ee021fdada19
Reviewed-on: https://chromium-review.googlesource.com/1178889Reviewed-by: default avatarGabriel Charette <gab@chromium.org>
Reviewed-by: default avatarGreg Thompson <grt@chromium.org>
Commit-Queue: Roger Tawa <rogerta@chromium.org>
Cr-Commit-Position: refs/heads/master@{#585832}
parent af3c256b
......@@ -100,6 +100,8 @@ static_library("test_support") {
"scoped_mock_clock_override.h",
"scoped_mock_time_message_loop_task_runner.cc",
"scoped_mock_time_message_loop_task_runner.h",
"scoped_os_info_override_win.cc",
"scoped_os_info_override_win.h",
"scoped_path_override.cc",
"scoped_path_override.h",
"scoped_task_environment.cc",
......
// Copyright 2018 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 "base/test/scoped_os_info_override_win.h"
#include <windows.h>
#include "base/win/windows_version.h"
namespace base {
namespace test {
ScopedOSInfoOverride::ScopedOSInfoOverride(Type type)
: original_info_(base::win::OSInfo::GetInstance()),
overriding_info_(CreateInfoOfType(type)) {
*base::win::OSInfo::GetInstanceStorage() = overriding_info_.get();
}
ScopedOSInfoOverride::~ScopedOSInfoOverride() {
*base::win::OSInfo::GetInstanceStorage() = original_info_;
}
// static
ScopedOSInfoOverride::UniqueOsInfo ScopedOSInfoOverride::CreateInfoOfType(
Type type) {
_OSVERSIONINFOEXW version_info = {sizeof(version_info)};
_SYSTEM_INFO system_info = {};
int os_type = 0;
switch (type) {
case Type::kWin10Pro:
case Type::kWin10Home:
version_info.dwMajorVersion = 10;
version_info.dwMinorVersion = 0;
version_info.dwBuildNumber = 15063;
version_info.wServicePackMajor = 0;
version_info.wServicePackMinor = 0;
version_info.szCSDVersion[0] = 0;
version_info.wProductType = VER_NT_WORKSTATION;
version_info.wSuiteMask = VER_SUITE_PERSONAL;
system_info.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64;
system_info.dwNumberOfProcessors = 1;
system_info.dwAllocationGranularity = 8;
os_type =
type == Type::kWin10Home ? PRODUCT_HOME_BASIC : PRODUCT_PROFESSIONAL;
break;
}
return UniqueOsInfo(new base::win::OSInfo(version_info, system_info, os_type),
&ScopedOSInfoOverride::deleter);
}
// static
void ScopedOSInfoOverride::deleter(base::win::OSInfo* info) {
delete info;
}
} // namespace test
} // namespace base
// Copyright 2018 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.
#ifndef BASE_TEST_SCOPED_OS_INFO_OVERRIDE_WIN_H_
#define BASE_TEST_SCOPED_OS_INFO_OVERRIDE_WIN_H_
#include <memory>
#include "base/macros.h"
namespace base {
namespace win {
class OSInfo;
} // namespace win
} // namespace base
namespace base {
namespace test {
// Helper class to override info returned by base::win::OSInfo::GetIntance()
// for the lifetime of this object. Upon destruction, the original info at time
// of object creation is restored.
class ScopedOSInfoOverride {
public:
// Types of windows machines that can be used for overriding. Add new
// machine types as needed.
enum class Type {
kWin10Pro,
kWin10Home,
};
explicit ScopedOSInfoOverride(Type type);
~ScopedOSInfoOverride();
private:
using UniqueOsInfo =
std::unique_ptr<base::win::OSInfo, void (*)(base::win::OSInfo*)>;
static UniqueOsInfo CreateInfoOfType(Type type);
// The OSInfo taken by this instance at construction and restored at
// destruction.
base::win::OSInfo* original_info_;
// The OSInfo owned by this scoped object and which overrides
// base::win::OSInfo::GetIntance() for the lifespan of the object.
UniqueOsInfo overriding_info_;
// Because the dtor of OSInfo is private, a custom deleter is needed to use
// unique_ptr.
static void deleter(base::win::OSInfo* info);
DISALLOW_COPY_AND_ASSIGN(ScopedOSInfoOverride);
};
} // namespace test
} // namespace base
#endif // BASE_TEST_SCOPED_OS_INFO_OVERRIDE_WIN_H_
......@@ -121,6 +121,36 @@ bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
return false;
}
bool* GetDomainEnrollmentStateStorage() {
static bool state = IsOS(OS_DOMAINMEMBER);
return &state;
}
bool* GetRegisteredWithManagementStateStorage() {
static bool state = []() {
ScopedNativeLibrary library(
FilePath(FILE_PATH_LITERAL("MDMRegistration.dll")));
if (!library.is_valid())
return false;
using IsDeviceRegisteredWithManagementFunction =
decltype(&::IsDeviceRegisteredWithManagement);
IsDeviceRegisteredWithManagementFunction
is_device_registered_with_management_function =
reinterpret_cast<IsDeviceRegisteredWithManagementFunction>(
library.GetFunctionPointer("IsDeviceRegisteredWithManagement"));
if (!is_device_registered_with_management_function)
return false;
BOOL is_managed = FALSE;
HRESULT hr =
is_device_registered_with_management_function(&is_managed, 0, nullptr);
return SUCCEEDED(hr) && is_managed;
}();
return &state;
}
} // namespace
// Uses the Windows 10 WRL API's to query the current system state. The API's
......@@ -529,44 +559,17 @@ bool IsDeviceUsedAsATablet(std::string* reason) {
return is_tablet;
}
enum DomainEnrollmentState {UNKNOWN = -1, NOT_ENROLLED, ENROLLED};
static volatile long int g_domain_state = UNKNOWN;
bool IsEnrolledToDomain() {
// Doesn't make any sense to retry inside a user session because joining a
// domain will only kick in on a restart.
if (g_domain_state == UNKNOWN) {
::InterlockedCompareExchange(&g_domain_state,
IsOS(OS_DOMAINMEMBER) ?
ENROLLED : NOT_ENROLLED,
UNKNOWN);
}
return *GetDomainEnrollmentStateStorage();
}
return g_domain_state == ENROLLED;
// This function is deprecated, prefer class ScopedDomainStateForTesting.
void SetDomainStateForTesting(bool state) {
*GetDomainEnrollmentStateStorage() = state;
}
bool IsDeviceRegisteredWithManagement() {
static bool is_device_registered_with_management = []() {
ScopedNativeLibrary library(
FilePath(FILE_PATH_LITERAL("MDMRegistration.dll")));
if (!library.is_valid())
return false;
using IsDeviceRegisteredWithManagementFunction =
decltype(&::IsDeviceRegisteredWithManagement);
IsDeviceRegisteredWithManagementFunction
is_device_registered_with_management_function =
reinterpret_cast<IsDeviceRegisteredWithManagementFunction>(
library.GetFunctionPointer("IsDeviceRegisteredWithManagement"));
if (!is_device_registered_with_management_function)
return false;
BOOL is_managed = false;
HRESULT hr =
is_device_registered_with_management_function(&is_managed, 0, nullptr);
return SUCCEEDED(hr) && is_managed;
}();
return is_device_registered_with_management;
return *GetRegisteredWithManagementStateStorage();
}
bool IsEnterpriseManaged() {
......@@ -579,10 +582,6 @@ bool IsEnterpriseManaged() {
return IsEnrolledToDomain();
}
void SetDomainStateForTesting(bool state) {
g_domain_state = state ? ENROLLED : NOT_ENROLLED;
}
bool IsUser32AndGdi32Available() {
static auto is_user32_and_gdi32_available = []() {
// If win32k syscalls aren't disabled, then user32 and gdi32 are available.
......@@ -705,5 +704,25 @@ void EnableHighDPISupport() {
}
}
ScopedDomainStateForTesting::ScopedDomainStateForTesting(bool state)
: initial_state_(IsEnrolledToDomain()) {
*GetDomainEnrollmentStateStorage() = state;
}
ScopedDomainStateForTesting::~ScopedDomainStateForTesting() {
*GetDomainEnrollmentStateStorage() = initial_state_;
}
ScopedDeviceRegisteredWithManagementForTesting::
ScopedDeviceRegisteredWithManagementForTesting(bool state)
: initial_state_(IsDeviceRegisteredWithManagement()) {
*GetRegisteredWithManagementStateStorage() = state;
}
ScopedDeviceRegisteredWithManagementForTesting::
~ScopedDeviceRegisteredWithManagementForTesting() {
*GetRegisteredWithManagementStateStorage() = initial_state_;
}
} // namespace win
} // namespace base
......@@ -29,6 +29,7 @@
#include <vector>
#include "base/base_export.h"
#include "base/macros.h"
#include "base/strings/string16.h"
struct IPropertyStore;
......@@ -164,6 +165,7 @@ BASE_EXPORT bool IsEnterpriseManaged();
// Used by tests to mock any wanted state. Call with |state| set to true to
// simulate being in a domain and false otherwise.
// This function is deprecated, prefer class ScopedDomainStateForTesting below.
BASE_EXPORT void SetDomainStateForTesting(bool state);
// Returns true if the current process can make USER32 or GDI32 calls such as
......@@ -192,6 +194,30 @@ BASE_EXPORT bool IsProcessPerMonitorDpiAware();
// Enable high-DPI support for the current process.
BASE_EXPORT void EnableHighDPISupport();
// Allows changing the domain enrolled state for the life time of the object.
// The original state is restored upon destruction.
class BASE_EXPORT ScopedDomainStateForTesting {
public:
ScopedDomainStateForTesting(bool state);
~ScopedDomainStateForTesting();
private:
bool initial_state_;
DISALLOW_COPY_AND_ASSIGN(ScopedDomainStateForTesting);
};
// Allows changing the management registration state for the life time of the
// object. The original state is restored upon destruction.
class BASE_EXPORT ScopedDeviceRegisteredWithManagementForTesting {
public:
ScopedDeviceRegisteredWithManagementForTesting(bool state);
~ScopedDeviceRegisteredWithManagementForTesting();
private:
bool initial_state_;
DISALLOW_COPY_AND_ASSIGN(ScopedDeviceRegisteredWithManagementForTesting);
};
} // namespace win
} // namespace base
......
......@@ -120,29 +120,45 @@ int GetUBR() {
} // namespace
// static
OSInfo* OSInfo::GetInstance() {
OSInfo** OSInfo::GetInstanceStorage() {
// Note: we don't use the Singleton class because it depends on AtExitManager,
// and it's convenient for other modules to use this classs without it. This
// pattern is copied from gurl.cc.
static OSInfo* info;
if (!info) {
OSInfo* new_info = new OSInfo();
if (InterlockedCompareExchangePointer(
reinterpret_cast<PVOID*>(&info), new_info, NULL)) {
delete new_info;
// and it's convenient for other modules to use this class without it.
static OSInfo* info = []() {
_OSVERSIONINFOEXW version_info = {sizeof(version_info)};
::GetVersionEx(reinterpret_cast<_OSVERSIONINFOW*>(&version_info));
_SYSTEM_INFO system_info = {};
::GetNativeSystemInfo(&system_info);
DWORD os_type = 0;
if (version_info.dwMajorVersion == 6 || version_info.dwMajorVersion == 10) {
// Only present on Vista+.
GetProductInfoPtr get_product_info =
reinterpret_cast<GetProductInfoPtr>(::GetProcAddress(
::GetModuleHandle(L"kernel32.dll"), "GetProductInfo"));
get_product_info(version_info.dwMajorVersion, version_info.dwMinorVersion,
0, 0, &os_type);
}
}
return info;
return new OSInfo(version_info, system_info, os_type);
}();
return &info;
}
OSInfo::OSInfo()
// static
OSInfo* OSInfo::GetInstance() {
return *GetInstanceStorage();
}
OSInfo::OSInfo(const _OSVERSIONINFOEXW& version_info,
const _SYSTEM_INFO& system_info,
int os_type)
: version_(VERSION_PRE_XP),
kernel32_version_(VERSION_PRE_XP),
got_kernel32_version_(false),
architecture_(OTHER_ARCHITECTURE),
wow64_status_(GetWOW64StatusForProcess(GetCurrentProcess())) {
OSVERSIONINFOEX version_info = { sizeof version_info };
::GetVersionEx(reinterpret_cast<OSVERSIONINFO*>(&version_info));
version_number_.major = version_info.dwMajorVersion;
version_number_.minor = version_info.dwMinorVersion;
version_number_.build = version_info.dwBuildNumber;
......@@ -153,8 +169,6 @@ OSInfo::OSInfo()
service_pack_.minor = version_info.wServicePackMinor;
service_pack_str_ = base::WideToUTF8(version_info.szCSDVersion);
SYSTEM_INFO system_info = {};
::GetNativeSystemInfo(&system_info);
switch (system_info.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_INTEL: architecture_ = X86_ARCHITECTURE; break;
case PROCESSOR_ARCHITECTURE_AMD64: architecture_ = X64_ARCHITECTURE; break;
......@@ -163,16 +177,8 @@ OSInfo::OSInfo()
processors_ = system_info.dwNumberOfProcessors;
allocation_granularity_ = system_info.dwAllocationGranularity;
GetProductInfoPtr get_product_info;
DWORD os_type;
if (version_info.dwMajorVersion == 6 || version_info.dwMajorVersion == 10) {
// Only present on Vista+.
get_product_info = reinterpret_cast<GetProductInfoPtr>(
::GetProcAddress(::GetModuleHandle(L"kernel32.dll"), "GetProductInfo"));
get_product_info(version_info.dwMajorVersion, version_info.dwMinorVersion,
0, 0, &os_type);
switch (os_type) {
case PRODUCT_CLUSTER_SERVER:
case PRODUCT_DATACENTER_SERVER:
......
......@@ -13,6 +13,14 @@
#include "base/macros.h"
typedef void* HANDLE;
struct _OSVERSIONINFOEXW;
struct _SYSTEM_INFO;
namespace base {
namespace test {
class ScopedOSInfoOverride;
} // namespace test
} // namespace base
namespace base {
namespace win {
......@@ -116,7 +124,12 @@ class BASE_EXPORT OSInfo {
static WOW64Status GetWOW64StatusForProcess(HANDLE process_handle);
private:
OSInfo();
friend class base::test::ScopedOSInfoOverride;
static OSInfo** GetInstanceStorage();
OSInfo(const _OSVERSIONINFOEXW& version_info,
const _SYSTEM_INFO& system_info,
int os_type);
~OSInfo();
Version version_;
......
......@@ -31,6 +31,8 @@
#include "base/strings/utf_string_conversions.h"
#include "base/version.h"
#include "base/win/registry.h"
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "chrome/install_static/install_details.h"
#include "chrome/install_static/install_modes.h"
#include "chrome/install_static/install_util.h"
......@@ -638,6 +640,52 @@ void AddVersionKeyWorkItems(HKEY root,
true); // overwrite version
}
void AddUpdateBrandCodeWorkItem(const InstallerState& installer_state,
WorkItemList* install_list) {
// Only update specific brand codes needed for enterprise.
base::string16 brand;
if (!GoogleUpdateSettings::GetBrand(&brand))
return;
base::string16 new_brand = GetUpdatedBrandCode(brand);
if (new_brand.empty())
return;
// Only update if this machine is:
// - domain joined, or
// - registered with MDM and is not windows home edition
bool is_enterprise_version =
base::win::OSInfo::GetInstance()->version_type() != base::win::SUITE_HOME;
if (!(base::win::IsEnrolledToDomain() ||
(base::win::IsDeviceRegisteredWithManagement() &&
is_enterprise_version))) {
return;
}
BrowserDistribution* browser_dist = installer_state.product().distribution();
DCHECK(browser_dist);
install_list->AddSetRegValueWorkItem(
installer_state.root_key(), browser_dist->GetStateKey(), KEY_WOW64_32KEY,
google_update::kRegRLZBrandField, new_brand, true);
}
base::string16 GetUpdatedBrandCode(const base::string16& brand_code) {
// Brand codes to be remapped on enterprise installs.
static constexpr struct EnterpriseBrandRemapping {
const wchar_t* old_brand;
const wchar_t* new_brand;
} kEnterpriseBrandRemapping[] = {
{L"GGLS", L"GCEU"},
{L"GGRV", L"GCEV"},
};
for (auto mapping : kEnterpriseBrandRemapping) {
if (brand_code == mapping.old_brand)
return mapping.new_brand;
}
return base::string16();
}
bool AppendPostInstallTasks(const InstallerState& installer_state,
const base::FilePath& setup_path,
const base::Version* current_version,
......@@ -857,6 +905,8 @@ void AddInstallWorkItems(const InstallationState& original_state,
// Migrate usagestats back to Chrome.
AddMigrateUsageStatsWorkItems(installer_state, install_list);
AddUpdateBrandCodeWorkItem(installer_state, install_list);
// Append the tasks that run after the installation.
AppendPostInstallTasks(installer_state,
setup_path,
......
......@@ -46,6 +46,16 @@ void AddVersionKeyWorkItems(HKEY root,
bool add_language_identifier,
WorkItemList* list);
// Updates the RLZ brand code or distribution tag. This is called by the
// installer to update deprecated, organic enterprise brand codes.
void AddUpdateBrandCodeWorkItem(const InstallerState& installer_state,
WorkItemList* install_list);
// Checks to see if the given brand code is one that should be updated if
// the current install is considered an enterprise install. If so the updated
// brand code is returned, otherwise an empty string is returned.
base::string16 GetUpdatedBrandCode(const base::string16& brand_code);
// After a successful copying of all the files, this function is called to
// do a few post install tasks:
// - Handle the case of in-use-update by updating "opv" (old version) key or
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment