1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/component_updater/component_updater_paths.h"
6 
7 #include "base/lazy_instance.h"
8 #include "base/path_service.h"
9 
10 namespace component_updater {
11 
12 namespace {
13 
14 // This key gives the root directory of all the component installations.
15 static int g_components_preinstalled_root_key = -1;
16 static int g_components_preinstalled_root_key_alt = -1;
17 static int g_components_user_root_key = -1;
18 
19 }  // namespace
20 
21 const base::FilePath::CharType kSupervisedUserWhitelistDirName[] =
22     FILE_PATH_LITERAL("SupervisedUserWhitelists");
23 
PathProvider(int key,base::FilePath * result)24 bool PathProvider(int key, base::FilePath* result) {
25   DCHECK_GT(g_components_user_root_key, 0);
26   DCHECK_GT(g_components_preinstalled_root_key, 0);
27 
28   // Early exit here to prevent a potential infinite loop when we retrieve
29   // the path for g_components_*_root_key.
30   if (key < PATH_START || key > PATH_END)
31     return false;
32 
33   switch (key) {
34     case DIR_COMPONENT_PREINSTALLED:
35       return base::PathService::Get(g_components_preinstalled_root_key, result);
36     case DIR_COMPONENT_PREINSTALLED_ALT:
37       return base::PathService::Get(g_components_preinstalled_root_key_alt,
38                                     result);
39     case DIR_COMPONENT_USER:
40       return base::PathService::Get(g_components_user_root_key, result);
41   }
42 
43   base::FilePath cur;
44   if (!base::PathService::Get(g_components_user_root_key, &cur))
45     return false;
46 
47   switch (key) {
48     case DIR_COMPONENT_CLD2:
49       cur = cur.Append(FILE_PATH_LITERAL("CLD"));
50       break;
51     case DIR_RECOVERY_BASE:
52       cur = cur.Append(FILE_PATH_LITERAL("recovery"));
53       break;
54     case DIR_SWIFT_SHADER:
55       cur = cur.Append(FILE_PATH_LITERAL("SwiftShader"));
56       break;
57     case DIR_SUPERVISED_USER_ALLOWLISTS:
58       cur = cur.Append(kSupervisedUserWhitelistDirName);
59       break;
60     default:
61       return false;
62   }
63 
64   *result = cur;
65   return true;
66 }
67 
68 // This cannot be done as a static initializer sadly since Visual Studio will
69 // eliminate this object file if there is no direct entry point into it.
RegisterPathProvider(int components_preinstalled_root_key,int components_preinstalled_root_key_alt,int components_user_root_key)70 void RegisterPathProvider(int components_preinstalled_root_key,
71                           int components_preinstalled_root_key_alt,
72                           int components_user_root_key) {
73   DCHECK_EQ(g_components_preinstalled_root_key, -1);
74   DCHECK_EQ(g_components_preinstalled_root_key_alt, -1);
75   DCHECK_EQ(g_components_user_root_key, -1);
76   DCHECK_GT(components_preinstalled_root_key, 0);
77   DCHECK_GT(components_preinstalled_root_key_alt, 0);
78   DCHECK_GT(components_user_root_key, 0);
79   DCHECK(components_preinstalled_root_key < PATH_START ||
80          components_preinstalled_root_key > PATH_END);
81   DCHECK(components_preinstalled_root_key_alt < PATH_START ||
82          components_preinstalled_root_key_alt > PATH_END);
83   DCHECK(components_user_root_key < PATH_START ||
84          components_user_root_key > PATH_END);
85 
86   g_components_preinstalled_root_key = components_preinstalled_root_key;
87   g_components_preinstalled_root_key_alt = components_preinstalled_root_key_alt;
88   g_components_user_root_key = components_user_root_key;
89   base::PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
90 }
91 
92 }  // namespace component_updater
93