Chromium 用户数据目录User Data 初始化过程c++

news2024/11/20 9:24:46

一、先说结论 User Data 路径优先级如下:

1、注册表中策略配置的路径。

   计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Chromium

    UserDataDir="xx_path"

2、命令行中的路径。

   --user-data-dir="xx_path"

3、默认用户路径

   %LOCALAPPDATA%/Chromium/User Data

二、接下来上源码分析过程

一、chrome\app\chrome_crash_reporter_client_win.cc

    //1、开始初始化user data目录
    std::wstring user_data_dir;
    if (process_type.empty())
      install_static::GetUserDataDirectory(&user_data_dir, nullptr);

// static
void ChromeCrashReporterClient::InitializeCrashReportingForProcess() {
  static ChromeCrashReporterClient* instance = nullptr;
  if (instance)
    return;

  instance = new ChromeCrashReporterClient();
  ANNOTATE_LEAKING_OBJECT_PTR(instance);

  std::wstring process_type = install_static::GetSwitchValueFromCommandLine(
      ::GetCommandLine(), install_static::kProcessType);
  // Don't set up Crashpad crash reporting in the Crashpad handler itself, nor
  // in the fallback crash handler for the Crashpad handler process.
  if (process_type != install_static::kCrashpadHandler &&
      process_type != install_static::kFallbackHandler) {
    crash_reporter::SetCrashReporterClient(instance);
    
    //1、开始初始化user data目录
    std::wstring user_data_dir;
    if (process_type.empty())
      install_static::GetUserDataDirectory(&user_data_dir, nullptr);

    // TODO(wfh): Add a DCHECK for success. See https://crbug.com/1329269.
    std::ignore = crash_reporter::InitializeCrashpadWithEmbeddedHandler(
        /*initial_client=*/process_type.empty(),
        install_static::WideToUTF8(process_type),
        install_static::WideToUTF8(user_data_dir), base::FilePath());
  }
}

二、第二步看install_static::GetUserDataDirectory(&user_data_dir, nullptr);实现

 在chrome\install_static\user_data_dir.cc中

namespace install_static {

namespace {

std::wstring* g_user_data_dir;
std::wstring* g_invalid_user_data_dir;

// Retrieves a registry policy for the user data directory from the registry, if
// one is set. If there's none set in either HKLM or HKCU, |user_data_dir| will
// be unmodified.
void GetUserDataDirFromRegistryPolicyIfSet(const InstallConstants& mode,
                                           std::wstring* user_data_dir) {
  assert(user_data_dir);
  std::wstring policies_path = L"SOFTWARE\\Policies\\";
  AppendChromeInstallSubDirectory(mode, false /* !include_suffix */,
                                  &policies_path);

  std::wstring value;

  constexpr wchar_t kUserDataDirRegistryKeyName[] = L"UserDataDir";

  // First, try HKLM.
  if (nt::QueryRegValueSZ(nt::HKLM, nt::NONE, policies_path.c_str(),
                          kUserDataDirRegistryKeyName, &value)) {
    *user_data_dir = ExpandPathVariables(value);
    return;
  }

  // Second, try HKCU.
  if (nt::QueryRegValueSZ(nt::HKCU, nt::NONE, policies_path.c_str(),
                          kUserDataDirRegistryKeyName, &value)) {
    *user_data_dir = ExpandPathVariables(value);
    return;
  }
}

std::wstring MakeAbsoluteFilePath(const std::wstring& input) {
  wchar_t file_path[MAX_PATH];
  if (!_wfullpath(file_path, input.c_str(), _countof(file_path)))
    return std::wstring();
  return file_path;
}

// The same as GetUserDataDirectory(), but directly queries the global command
// line object for the --user-data-dir flag. This is the more commonly used
// function, where GetUserDataDirectory() is used primiarily for testing.
bool GetUserDataDirectoryUsingProcessCommandLine(
    const InstallConstants& mode,
    std::wstring* result,
    std::wstring* invalid_supplied_directory) {
  return GetUserDataDirectoryImpl(
      GetSwitchValueFromCommandLine(::GetCommandLine(), kUserDataDirSwitch),
      mode, result, invalid_supplied_directory);
}

// Populates |result| with the default User Data directory for the current
// user. Returns false if all attempts at locating a User Data directory fail.
// TODO(ananta)
// http://crbug.com/604923
// Unify this with the Browser Distribution code.
bool GetDefaultUserDataDirectory(const InstallConstants& mode,
                                 std::wstring* result) {
  // This environment variable should be set on Windows Vista and later
  // (https://msdn.microsoft.com/library/windows/desktop/dd378457.aspx).
  std::wstring user_data_dir = GetEnvironmentString(L"LOCALAPPDATA");

  if (user_data_dir.empty()) {
    // LOCALAPPDATA was not set; fallback to the temporary files path.
    DWORD size = ::GetTempPath(0, nullptr);
    if (!size)
      return false;
    user_data_dir.resize(size + 1);
    size = ::GetTempPath(size + 1, &user_data_dir[0]);
    if (!size || size >= user_data_dir.size())
      return false;
    user_data_dir.resize(size);
  }

  result->swap(user_data_dir);
  if ((*result)[result->length() - 1] != L'\\')
    result->push_back(L'\\');
  AppendChromeInstallSubDirectory(mode, true /* include_suffix */, result);
  result->push_back(L'\\');
  result->append(L"User Data");
  return true;
}

}  // namespace

bool GetUserDataDirectoryImpl(
    const std::wstring& user_data_dir_from_command_line,
    const InstallConstants& mode,
    std::wstring* result,
    std::wstring* invalid_supplied_directory) {
  std::wstring user_data_dir = user_data_dir_from_command_line;
  
  //从注册表中读取路径
  GetUserDataDirFromRegistryPolicyIfSet(mode, &user_data_dir);

  // On Windows, trailing separators leave Chrome in a bad state. See
  // crbug.com/464616.
  while (!user_data_dir.empty() &&
         (user_data_dir.back() == '\\' || user_data_dir.back() == '/')) {
    user_data_dir.pop_back();
  }

  bool got_valid_directory =
      !user_data_dir.empty() && RecursiveDirectoryCreate(user_data_dir);
  if (!got_valid_directory) {
    *invalid_supplied_directory = user_data_dir;
    //从%LOCALAPPDATA%/Chromium/User Data 中读取
    got_valid_directory = GetDefaultUserDataDirectory(mode, &user_data_dir);
  }

  // The Chrome implementation CHECKs() here in the browser process. We
  // don't as this function is used to initialize crash reporting, so
  // we would get no report of this failure.
  assert(got_valid_directory);
  if (!got_valid_directory)
    return false;

  *result = MakeAbsoluteFilePath(user_data_dir);
  return true;
}

bool GetUserDataDirectory(std::wstring* user_data_dir,
                          std::wstring* invalid_user_data_dir) {
  if (!g_user_data_dir) {
    g_user_data_dir = new std::wstring();
    g_invalid_user_data_dir = new std::wstring();
    //从命令行中解析路径
    if (!GetUserDataDirectoryUsingProcessCommandLine(
            InstallDetails::Get().mode(), g_user_data_dir,
            g_invalid_user_data_dir)) {
      return false;
    }
    assert(!g_user_data_dir->empty());
  }
  *user_data_dir = *g_user_data_dir;
  if (invalid_user_data_dir)
    *invalid_user_data_dir = *g_invalid_user_data_dir;
  return true;
}

}  // namespace install_static

调用堆栈:

GetUserDataDirectory->GetUserDataDirectoryUsingProcessCommandLine->

GetUserDataDirectoryImpl->GetSwitchValueFromCommandLine->GetUserDataDirFromRegistryPolicyIfSet->GetDefaultUserDataDirectory

   

三、最后将初始化的g_user_data_dir路径设置到   

chrome\app\chrome_main_delegate.cc

CHECK(base::PathService::OverrideAndCreateIfNeeded(
        chrome::DIR_USER_DATA, user_data_dir, false, true));中,

// Initializes the user data dir. Must be called before InitializeLocalState().
void InitializeUserDataDir(base::CommandLine* command_line) {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
  // In debug builds of Lacros, we keep track of when the user data dir
  // is initialized, to ensure the cryptohome is not accessed before login
  // when prelaunching at login screen.
  chromeos::lacros_paths::SetInitializedUserDataDir();
#endif
#if BUILDFLAG(IS_WIN)
  // Reach out to chrome_elf for the truth on the user data directory.
  // Note that in tests, this links to chrome_elf_test_stubs.
  wchar_t user_data_dir_buf[MAX_PATH], invalid_user_data_dir_buf[MAX_PATH];

  // In tests this may return false, implying the user data dir should be unset.
  if (GetUserDataDirectoryThunk(user_data_dir_buf, std::size(user_data_dir_buf),
                                invalid_user_data_dir_buf,
                                std::size(invalid_user_data_dir_buf))) {
    base::FilePath user_data_dir(user_data_dir_buf);
    if (invalid_user_data_dir_buf[0] != 0) {
      chrome::SetInvalidSpecifiedUserDataDir(
          base::FilePath(invalid_user_data_dir_buf));
      command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
    }
    //将user data路径存储到path缓存中
    CHECK(base::PathService::OverrideAndCreateIfNeeded(
        chrome::DIR_USER_DATA, user_data_dir, false, true));
  }

这样

  base::FilePath user_data_dir;

  base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);

就可以读取其中的路径了。

      

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2182965.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在使用visual studio 2022,运行程序时弹窗:“ 此任务要求应用程序具有提升的权限“

系列文章目录 文章目录 系列文章目录前言一、问题原因二、解决方法1.第一种解决方法2.第二种解决方法 前言 在使用visual studio 2022,运行程序时弹窗:" 此任务要求应用程序具有提升的权限",每次都要再次点击“使用其他凭证重新启…

【LeetCode HOT 100】详细题解之二叉树篇

【LeetCode HOT 100】详细题解之二叉树篇 94 二叉树的中序遍历方法一:递归方法二:迭代 104 二叉树的最大深度方法一:递归方法二:迭代 226 翻转二叉树方法一:递归方法二:迭代 101 对称二叉树方法一&#xff…

麦克斯韦方程组的独立方程与辅助方程

第四个方程可以由第一个方程得到。注意哈密顿算符求散度是对空间求偏导,也就是xyz,而麦克斯韦方程组中的矢量除了xyz还有t也是自变量。 方程1推出方程4(用到求微分的换顺序) 方程2推出方程3,用到电流面密度和电荷体密…

python调用opencv报错“module ‘cv2‘ has no attribute ‘namedWindow‘”

之前电脑上使用pip install安装过opencv相关的python模块,不过后续学习opencv时主要使用OpenCVSharp在VS2022中创建项目测试。今天学习过程中突然想用python试试,不过运行下面代码时报错“module ‘cv2’ has no attribute namedWindow”。 import cv2c…

单调队列与单调栈<2>——单调栈

单调栈的定义 单调递增栈 栈中元素从栈底到栈顶是递增的。 单调递减栈 栈中元素从栈底到栈顶是递减的。 单调栈的核心内容 我们从左到右遍历元素,构造单调栈(从栈顶到栈底递增或减):在 i 从左往右遍历的过程中,我…

【高频SQL基础50题】16-20

day by day. 目录 1.进店却未进行过交易的顾客 2.项目员工 I 3.销售分析III 4. 判断三角形 5. 电影评分 1.进店却未进行过交易的顾客 连接题。 思路:根据trans表中的visit_id号在 visits表中排除,再将剩下的合并相同客户(累加visit…

300Kg载重履带式无人车底盘定制开发技术详解

关于300Kg载重履带式无人车底盘的定制开发技术,可以从以下几个方面进行详细解析: 一、总体设计思路 300Kg载重履带式无人车底盘的定制开发,旨在打造一款承载能力强、行驶稳定、适应复杂地形的无人运输平台。设计过程中需充分考虑动力系统的…

【C++ 前缀和 数论】1590. 使数组和能被 P 整除|2038

本文涉及的基础知识点 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 质数、最大公约数、菲蜀定理 LeetCode 1590. 使数组和能被 P 整除 给你一个正整数数组 nums,请你移除 最短 子数组(可以为 空)&am…

麒麟系统文件扩展名所表示的文件种类

图 1 .conf 配置文件,如图2; 图 2 .Deb 安装包,如图3; 图 3 .sh 可执行程序,如图4; 图 4 .tar或者.gz 压缩包,如图5; 图 5 .bin 二进制文件,如图6; 图 6…

android compose ScrollableTabRow indicator 指示器设置宽度

.requiredWidth(30.dp) Box(modifier Modifier.background(Color.LightGray).fillMaxWidth()) {ScrollableTabRow(selectedTabIndex selectedTabIndex, // 默认选中第一个标签containerColor ColorPageBg,edgePadding 1.dp, // 内容与边缘的距离indicator { tabPositions…

房地产政策持续利好,龙湖“好房子”新品观萃入市受市场认可

《港湾商业观察》王璐 经过疫情以来持续调整的房地产市场,外界预期,在政策利好效应带动下,行业将稳健向前。 9月26日,中央政治局会议对房地产的表述内容释放出极强的政策宽松信号。会议首次明确提出,“要促进房地产市…

解决QWidget及内部控件只能放大不能缩小的问题

在设计可缩放控件的时候,你可能会与到这种情况: 缩放 控件只能放大,不能缩小。。。是不是很头痛?让我来猜猜原因:你是不是让子类控件的大小设置地跟父类控件大小一样大?没错这就是原因所在。 用上面一行替换…

pdf怎么盖章不覆盖文字

pdf怎么盖章不覆盖文字?在PDF上盖章而不覆盖文字,可以按照以下步骤操作: 使用福昕PDF编辑器 下载安装:从福昕软件官网下载并安装福昕PDF编辑器。打开文档:用福昕PDF编辑器打开需要盖章的PDF文档。访问图章工具&#…

[网络]抓包工具介绍 tcpdump

一、tcpdump tcpdump是一款基于命令行的网络抓包工具,可以捕获并分析传输到和从网络接口流入和流出的数据包。 1.1 安装 tcpdump 通常已经预装在大多数 Linux 发行版中。如果没有安装,可以使用包管理器 进行安装。例如 Ubuntu,可以使用以下…

Ps:将画板导出到 PDF

菜单:文件/导出/将画板导出到 PDF Export/Artboards to PDF 将画板导出到 PDF Artboards to PDF命令用于将 Photoshop 的画板导出为 PDF 文件,提供了多种导出选项,可以控制文件的压缩、是否嵌入颜色配置文件、文件命名以及页面顺序等。它适用…

电力、电子、电气、电器,怎么说明白?

从学科划分的角度讲 电力、电子和电器都属于电气工程学科。电气工程一词来源于日本,其中的“气”来源于西方外文翻译(西方工业之初,动力机械均由蒸汽轮机驱动,后来用与发电,故"电气"开始乏指工业动力,现在电…

高效便捷,体验不一样的韩语翻译神器

嘿,大家好啊!今天想跟大家聊聊我用过的几款翻译神器,特别是它们在翻译韩语时的那些小感受。作为一个偶尔需要啃啃韩语资料或者跟韩国朋友聊天的普通人,我真心觉得这些翻译工具简直就是我的救星! 一、福昕在线翻译 网址…

Unity网络开发记录(五):二进制传输消息类

消息类 前篇所写的CS模型只能传输字符串,在本篇文章中,尝试在服务端一次传输多种类型的数据,并在客户端接收到信息之后进行解析显示 为了实现对不同类型的数据传输,需要将不同类型的数据都转换成二进制的形式在网络中进行传输。所…

爬虫——爬虫理论+request模块

一、爬虫理论 爬虫——请求网站并提取数据的自动化程序 网络爬虫(又被称为网页蜘蛛,网络机器人)就是模拟客户端发送网络请求,接收请求响应,一种按照一定的规则,自动的抓取互联网信息的程序。 原则上&…

通信工程学习:什么是HTTP超文本传输协议

HTTP:超文本传输协议 HTTP(Hyper Text Transfer Protocol),即超文本传输协议,是互联网上应用最为广泛的一种网络协议,它位于TCP/IP四层模型当中的应用层。以下是关于HTTP协议的详细解释: 一、H…