#include "base/base_paths.h"
#include "base/check.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/process/process.h"
#include "base/test/launcher/unit_test_launcher.h"
#include "base/test/test_suite.h"
#include "base/test/test_switches.h"
#include "build/build_config.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/updater/constants.h"
#include "chrome/updater/test/integration_test_commands.h"
#include "chrome/updater/test/test_scope.h"
#include "chrome/updater/test/unit_test_util.h"
#include "chrome/updater/updater_branding.h"
#include "chrome/updater/updater_scope.h"
#include "third_party/abseil-cpp/absl/cleanup/cleanup.h"
#if BUILDFLAG(IS_WIN)
#include <shlobj.h>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <string>
#include "base/path_service.h"
#include "base/win/registry.h"
#include "base/win/scoped_com_initializer.h"
#include "chrome/installer/util/scoped_token_privilege.h"
#include "chrome/updater/util/win_util.h"
namespace {
void FixExecutionPriorities() {
const HANDLE process = ::GetCurrentProcess();
const DWORD priority_class = ::GetPriorityClass(process);
if (priority_class == NORMAL_PRIORITY_CLASS) {
return;
}
::SetPriorityClass(process, NORMAL_PRIORITY_CLASS);
static const auto set_process_information_fn =
reinterpret_cast<decltype(&::SetProcessInformation)>(::GetProcAddress(
::GetModuleHandle(L"Kernel32.dll"), "SetProcessInformation"));
if (!set_process_information_fn) {
return;
}
MEMORY_PRIORITY_INFORMATION memory_priority = {};
memory_priority.MemoryPriority = MEMORY_PRIORITY_NORMAL;
set_process_information_fn(process, ProcessMemoryPriority, &memory_priority,
sizeof(memory_priority));
::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_NORMAL);
}
class ScopedSymbolPath {
public:
explicit ScopedSymbolPath(bool is_system)
: is_system_(is_system),
rootkey_(is_system ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER),
subkey_(is_system ? L"SYSTEM\\CurrentControlSet\\Control\\Session "
L"Manager\\Environment"
: L"Environment") {
base::FilePath out_dir;
base::PathService::Get(base::DIR_EXE, &out_dir);
const std::wstring symbol_path = out_dir.value();
if (::GetEnvironmentVariable(kNtSymbolPathEnVar, nullptr, 0) == 0) {
::SetEnvironmentVariable(kNtSymbolPathEnVar, symbol_path.c_str());
}
base::win::RegKey reg_key(rootkey_, subkey_.c_str(), KEY_READ | KEY_WRITE);
if (reg_key.Valid() && !reg_key.HasValue(kNtSymbolPathEnVar)) {
is_owned = reg_key.WriteValue(kNtSymbolPathEnVar, symbol_path.c_str()) ==
ERROR_SUCCESS;
if (!is_owned) {
return;
}
BroadcastEnvironmentChange();
VLOG(0) << "Symbol path for " << (is_system_ ? "system" : "user")
<< " set to: " << symbol_path;
}
}
~ScopedSymbolPath() {
if (!is_owned) {
return;
}
base::win::RegKey reg_key(rootkey_, subkey_.c_str(), KEY_WRITE);
if (reg_key.Valid()) {
reg_key.DeleteValue(kNtSymbolPathEnVar);
BroadcastEnvironmentChange();
}
}
private:
static void BroadcastEnvironmentChange() {
constexpr int kTimeOutMilliSeconds = 100;
DWORD_PTR result = 0;
::SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0,
reinterpret_cast<LPARAM>(L"Environment"), SMTO_NORMAL,
kTimeOutMilliSeconds, &result);
}
static constexpr wchar_t kNtSymbolPathEnVar[] = L"_NT_ALT_SYMBOL_PATH";
const bool is_system_ = false;
const HKEY rootkey_ = nullptr;
const std::wstring subkey_;
bool is_owned = false;
};
}
#endif
namespace {
void MaybeIncreaseTestTimeouts(int argc, char** argv) { … }
void SkipFallbackNetworkFetcher() { … }
}
int main(int argc, char** argv) { … }