当前位置: 首页 > article >正文

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;
}

}  // 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.kler.cn/news/327910.html

相关文章:

  • Apache POI快速入门
  • leetcode刷题day31|贪心算法Part05重叠区间问题(56. 合并区间、738.单调递增的数字、968.监控二叉树)
  • Unity NetCode 客户端连接不上服务器,局域网模式 Failed to connect to server.
  • 【微信小程序开发】入门Day2 —— 从视图逻辑到配置请求全方位解析
  • 遍历递归数结构,修改里的disabled值
  • 【JVM】基础篇
  • 2024ICPC网络赛2记录:CK
  • 企业数字化转型指南:基于TOGAF框架的系统化战略解读
  • Junit 5 - 理解Mockito,提高UT 覆盖率
  • 景联文科技精准数据标注:优化智能标注平台,打造智能未来
  • LiveQing视频点播流媒体RTMP推流服务功能-支持电子放大拉框放大直播视频拉框放大录像视频流拉框放大电子放大
  • 【Redis技术进阶之路】「原理分析系列开篇」探索事件驱动枚型与数据特久化原理实现(数据持久化的实现AOF)
  • linux远程桌面:xrdp 安装失败
  • Android 长按文本弹出输入框
  • 《野蛮时代》数据分析项目实战——报告
  • 基于muduo库实现protobuf协议的通信详解
  • 叶绿素透射反射率与波长
  • pr2024安装包及新手入门讲解
  • Qt::WA_TranslucentBackground
  • 成都睿明智科技有限公司抖音开店怎么样?
  • 社交内容电商中的新机遇:2+1链动模式AI智能名片商城小程序
  • 10款好用的开源 HarmonyOS 工具库
  • 7-1.Android SQLite 之 SQLiteDatabase 简单编码模板(SQLiteDatabase 使用、SQL 语句编写)
  • 矩阵系统源码搭建的具体步骤,支持oem,源码搭建
  • Redis的基础通用命令
  • 3D Gaussian Splatting 学习笔记
  • VTK 与 OpenCV 的区别和各自的特点
  • 【笔记】X射线的衍射方向
  • golang学习笔记26-管道(Channel)【重要】
  • mock数据,不使用springboot的单元测试