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

一、先说结论 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;
}}  // namespacebool 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.xdnf.cn/news/1552409.html

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

相关文章

buuctf---->[WUSTCTF2020]level3

做题笔记。 无语。 下载 查壳。 64ida打开。 先运行一下程序: 用它这个程序 加密romantic >>> cm9tYW50aWH 我们去正常加密看看: 仔细对比你会发现点毛病。 看看ida: 这表看起来,很正常,默认的为什么会加密不…

Python批量下载PPT模块并实现自动解压

日常工作中,我们总是找不到合适的PPT模板而烦恼。即使有免费的网站可以下载,但是一个一个地去下载,然后再批量解压进行查看也非常的麻烦,有没有更好方法呢? 今天,我们利用Python来爬取一个网站上的PPT&…

Java学习-网络编程

目录 1. 网络通信基本概念 1.1 通信 1.2 网络 1.3 协议 1.4 网络通信 1.5 网络通信协议 1.6 TCP/IP协议 1.7 互联网 1.8 计算机网络 2. TCP与UDP协议 2.1 TCP 2.2 UDP 2.3 TCP的三次握手 2.4 为什么要三次握手 2.5 TCP四次挥手 2.6 为什么要四次挥手 3. HTTP1…

代码随想录算法训练营Day18 | 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

目录 530.二叉搜索树的最小绝对差 501.二叉搜索树中的众数 236. 二叉树的最近公共祖先 530.二叉搜索树的最小绝对差 题目 530. 二叉搜索树的最小绝对差 - 力扣(LeetCode) 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值…

python16_引号使用

引号使用 A "Im a teacher!" B I\m a teacher! C """Im a teacher!, I am a teacher!, "I am a teacher!" """def single_quote(s):return sdef double_quote(s):return sdef triple_quote(s):return sif __name__ &qu…

【Linux】进程+权限管理+软硬链接+其他命令

目录 1. man手册 2. find按文件名称 3. find按文件类型 4. date显示时间 5. cal显示日历 6. du文件大小 7. ln链接 8. 软连接,硬链接区别 9. 文本查找 10. wc统计文本(计算文件的Bytes数、字数或列数) 11. 查看文本内容: 1…

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

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

C语言、Eazy_x——井字棋

#include<graphics.h>char board_data[3][3] { { -,-,-},{ -,-,-},{ -,-,-}, };char current_piece o;//检测指定棋子玩家是否获胜 bool CheckWin(char c) {if (board_data[0][0] c && board_data[0][1] c && board_data[0][2] c)return true;if (…

数据结构-链表笔记

移除节点 203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val) { this.val val; }* ListNode(int val, ListN…

常见的VPS或者独立服务器的控制面板推荐

随着越来越多的企业和个人转向VPS和独立服务器以获得更高的性能和灵活性&#xff0c;选择合适的控制面板变得尤为重要。一个好的控制面板可以大大简化服务器管理&#xff0c;提高工作效率。本篇文章将介绍2024年最值得推荐的VPS控制面板&#xff0c;帮助您做出明智的选择。 1.…

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

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

TVS管工作原理:【图文讲解】

TVS(Transient Voltage Suppressor)二极管&#xff0c;又称为瞬态抑制二极管&#xff0c;是普遍使用的一种新型高效电路保护器件&#xff0c;它具有极快的响应时间&#xff08;亚纳秒级&#xff09;和相当高的浪涌吸收能力。当它的两端经受瞬间的高能量冲击时&#xff0c;TVS能…

每日OJ题_牛客_DP2跳台阶_动态规划_C++_Java

目录 牛客_DP2跳台阶_动态规划 题目解析 C代码 Java代码 牛客_DP2跳台阶_动态规划 跳台阶_牛客题霸_牛客网 题目解析 当前值只和数组的前两个值有关&#xff0c;在往前面的就无关了&#xff0c;所以没必要申请一个数组&#xff0c;直接使用两个变量即可&#xff0c;这样空…

【数据结构与算法】时间复杂度和空间复杂度例题

文章目录 时间复杂度常数阶时间O(1)对数阶时间O(logN)线性阶时间O(n)线性对数阶时间O(nlogN)平方阶时间O(n*n) 空间复杂度常量空间O(1)线性空间O(n)二维空间O(n*n)递归空间 时间复杂度 常数阶时间O(1) 代码在执行的时候&#xff0c;它消耗的时间并不随着某个变量的增长而增长…

pytorch之梯度累加

1.什么是梯度&#xff1f; 梯度可以理解为一个多变量函数的变化率&#xff0c;它告诉我们在某一点上&#xff0c;函数的输出如何随输入的变化而变化。更直观地说&#xff0c;梯度指示了最优化方向。 在机器学习中的作用&#xff1a;在训练模型时&#xff0c;我们的目标是最小…

LeetCode[中等] 279.完全平方

给你一个整数 n &#xff0c;返回 和为 n 的完全平方数的最少数量 。 完全平方数 是一个整数&#xff0c;其值等于另一个整数的平方&#xff1b;换句话说&#xff0c;其值等于一个整数自乘的积。例如&#xff0c;1、4、9 和 16 都是完全平方数&#xff0c;而 3 和 11 不是。 1…

数值计算的程序设计问题举例

### 数值计算的程序设计问题 #### 1. 结构静力分析计算 **涉及领域**&#xff1a;工程力学、建筑工程 **主要问题**&#xff1a;线性代数方程组&#xff08;Linear Algebraic Equations&#xff09; **解释说明**&#xff1a; 在结构静力分析中&#xff0c;我们需要解决复杂的…

Java项目实战II基于Java+Spring Boot+MySQL的购物推荐网站的设计与实现(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者 一、前言 随着互联网技术的飞速发展&#xff0c;电子商务已成为人们日常生活中不可或缺的一部分。然而&#xf…

自动驾驶系列—自动驾驶MCU架构全方位解析:从单核到多核的选型指南与应用实例

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

VIIRS 版本1(5000)数据于2024年6月17日停更,请转向VIIRS版本2(5200)

根据官网发布的消息&#xff0c;VIIRS版本1&#xff08;5000&#xff09;的多数数据产品于今日停止更新。需要VIIRS数据的朋友需要转向版本2数据了。 可见红外成像辐射计套件 (VIIRS) 第 1 版 (集合 1) 陆地数据产品于 2024 年 6 月 17 日终止生产。唯一的例外是双向反射分布函…