Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: base/registry_hive.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/registry_hive.h ('k') | base/registry_monitor_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2004-2009 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15
16 #include "omaha/base/registry_hive.h"
17 #include "omaha/base/accounts.h"
18 #include "omaha/base/reg_key.h"
19 #include "omaha/base/safe_format.h"
20 #include "omaha/base/string.h"
21 #include "omaha/base/system.h"
22 #include "omaha/base/user_info.h"
23 #include "omaha/base/utils.h"
24
25 namespace omaha {
26
27 RegistryHive::RegistryHive()
28 : hive_holding_key_(NULL) {
29 }
30
31 RegistryHive::~RegistryHive() {
32 if ( !hive_name_.IsEmpty() ) {
33 UnloadHive();
34 }
35 }
36
37 // Loads hive for requested SID. SID should be in format "S-X-X....."
38 // name is a name under which the hive will be added to the HKEY_USERS,
39 // you could use persons name here. This parameter should not have '\\'
40 // characters!
41 // It is not recommended to load more than one hive at once - LoadHive,
42 // manipulate hive, UnloadHive, and then work on the next one.
43 //
44 // Hive could be already loaded: you logged out from other user but system
45 // had open key in your current user. In that case I open hive_holding_key_ to
46 // prevent system from unloading hive and do not load/unload hive - the system
47 // will do it.
48 HRESULT RegistryHive::LoadHive(TCHAR const * sid, TCHAR const *name) {
49 ASSERT1(sid);
50 ASSERT1(name);
51 ASSERT1(hive_name_.IsEmpty());
52 ASSERT1(String_FindChar(name, _T('\\')) == -1);
53
54 CString profile_key;
55 CString hive_path;
56
57 // Need set SE_RESTORE_NAME/SE_BACKUP_NAME priveleges to current process
58 // otherwise loading of the hive will fail
59 RET_IF_FAILED(System::AdjustPrivilege(SE_RESTORE_NAME, true));
60 RET_IF_FAILED(System::AdjustPrivilege(SE_BACKUP_NAME, true));
61
62 SafeCStringFormat(&profile_key, kProfileKeyFormat, sid);
63
64 if ( FAILED(RegKey::GetValue(profile_key, kProfilePathValue, &hive_path)) ) {
65 return E_FAIL;
66 }
67
68
69 wchar_t temporary_buffer[MAX_PATH];
70 DWORD ret = ExpandEnvironmentStrings(hive_path, temporary_buffer, MAX_PATH);
71
72 if ( !ret || ret >= MAX_PATH ) {
73 return E_FAIL;
74 }
75 hive_path = temporary_buffer;
76
77 hive_path.Append(_T("\\"));
78 hive_path.Append(kHiveName);
79
80 hive_name_ = name;
81
82 LONG res = RegLoadKey(HKEY_USERS, hive_name_, hive_path);
83
84 if ( ERROR_SHARING_VIOLATION == res ) {
85 // It is quite possible that the hive is still held by system.
86 hive_name_ = sid;
87
88 // if it is the case, this call will succeeed, and the system will not
89 // unload the hive while there are outstanding keys opened.
90 res = RegOpenKeyEx(HKEY_USERS,
91 hive_name_,
92 0,
93 KEY_ALL_ACCESS,
94 &hive_holding_key_);
95 }
96
97 return (res == ERROR_SUCCESS) ? S_OK : E_FAIL;
98 }
99
100 // Loads hive for requested SID, but only if the SID is another user
101 // (since we don't need to do anything if the sid is ours)
102 HRESULT RegistryHive::LoadHive(TCHAR const * user_sid) {
103 ASSERT1(user_sid != NULL);
104 bool other_user = false;
105
106 // Determine if the SID passed in is really another user
107 CString current_user_sid;
108 HRESULT hr = omaha::user_info::GetProcessUser(NULL, NULL, &current_user_sid);
109 if (FAILED(hr)) {
110 UTIL_LOG(LE, (_T("[RegistryHive::LoadHive - failed to get current user")));
111 return hr;
112 }
113
114 // user_sid is the current user - no need to load the hive
115 if (lstrcmpi(current_user_sid, user_sid) == 0)
116 return S_FALSE;
117
118 // Get info on the sid we're being asked to load for
119 CString name;
120 CString domain;
121 SID_NAME_USE user_type;
122 hr = accounts::GetUserInfo(user_sid, &name, &domain, &user_type);
123 if ( FAILED(hr) || user_type != SidTypeUser ) {
124 // Either Sid no longer exists or Sid is not a user Sid
125 // (There is other possibility: Sid could be for roaming profile on domain
126 // which is currently down, but we do not support roaming profiles)
127 return FAILED(hr) ? hr : E_FAIL;
128 }
129
130 hr = LoadHive(user_sid, name); // Use user name as a temporary key name.
131 if ( FAILED(hr) ) {
132 // Hive no longer present.
133 return E_FAIL;
134 }
135
136 return S_OK;
137 }
138
139
140 // Unloads and saves loaded hive
141 HRESULT RegistryHive::UnloadHive() {
142 if (hive_name_.IsEmpty())
143 return S_OK;
144
145 LONG res;
146 if ( hive_holding_key_ ) {
147 res = RegCloseKey(hive_holding_key_);
148 hive_holding_key_ = NULL;
149 // no need to unload hive. System will do it.
150 } else {
151 res = RegUnLoadKey(HKEY_USERS, hive_name_);
152 }
153 hive_name_.Empty();
154 return (res == ERROR_SUCCESS) ? S_OK : E_FAIL;
155 }
156
157 // Does it recursively. The name should be relative to HKEY_CURRENT_USER.
158 HRESULT RegistryHive::DeleteUserKey(TCHAR const * key_name) {
159 ASSERT(key_name && *key_name, (L""));
160 if ( !key_name || !*key_name ) {
161 return E_FAIL;
162 }
163 CString key(key_name);
164 ExpandKeyName(&key);
165
166 if ( !RegKey::SafeKeyNameForDeletion(key) ) {
167 return E_FAIL;
168 }
169
170 return RegKey::DeleteKey(key);
171 }
172
173 void RegistryHive::ExpandKeyName(CString * str) {
174 ASSERT1(str);
175
176 // If we haven't loaded another user's hive, use HKCU instead of
177 // HKEY_USERS
178 CString key_name;
179 if (hive_name_.IsEmpty()) {
180 key_name = _T("HKCU\\");
181 } else {
182 key_name = _T("HKEY_USERS\\");
183 key_name.Append(hive_name_ + _T("\\"));
184 }
185
186 key_name.Append(*str);
187 *str = key_name;
188 }
189
190 // Load a user registry
191 int LoadUserRegistry(const TCHAR* user_sid,
192 ProcessUserRegistryFunc* handler,
193 LONG_PTR param) {
194 ASSERT1(user_sid && *user_sid);
195 ASSERT1(handler);
196
197 // Get current user SID
198 CString curr_user_sid;
199 HRESULT hr = omaha::user_info::GetProcessUser(NULL, NULL, &curr_user_sid);
200 if (FAILED(hr)) {
201 UTIL_LOG(LE, (_T("[LoadUserRegistry - can't get current user][0x%x]"), hr));
202 return 0;
203 }
204
205 // Is current user?
206 bool other_user = curr_user_sid.CompareNoCase(user_sid) != 0;
207
208 // Get the hive for this user
209 RegistryHive user_hive;
210 if (other_user) {
211 // Get the info about this user
212 SID_NAME_USE user_type = SidTypeInvalid;
213 CString name, domain;
214 hr = accounts::GetUserInfo(user_sid, &name, &domain, &user_type);
215 if (FAILED(hr) || user_type != SidTypeUser) {
216 // Either SID no longer exists or SID is not a user Sid
217 // (There is other possibility: SID could be for roaming profile on domain
218 // which is currently down, but we do not support roaming profiles)
219 UTIL_LOG(LEVEL_WARNING,
220 (_T("[LoadUserRegistry - SID %s invalid or unsupported][0x%x]"),
221 user_sid, hr));
222 return 0;
223 }
224
225 // Load the hive
226 hr = user_hive.LoadHive(user_sid, domain + _T("_") + name);
227 if (FAILED(hr)) {
228 // Hive no longer present.
229 UTIL_LOG(LW, (_T("[LoadUserRegistry]")
230 _T("[hive not present for %s][0x%x]"), user_sid, hr));
231 return 0;
232 }
233 }
234
235 // Get the registry key path
236 CString user_reg_path;
237 user_hive.ExpandKeyName(&user_reg_path);
238
239 // Call the handler
240 int res = (*handler)(user_sid, user_reg_path, param);
241
242 // Unload the hive
243 if (other_user) {
244 hr = user_hive.UnloadHive();
245 if (FAILED(hr)) {
246 UTIL_LOG(LE, (_T("[LoadUserRegistry]")
247 _T("[failed to save hive for %s][0x%x]"), user_sid, hr));
248 }
249 }
250
251 return res;
252 }
253
254 // Enumerate all user registries
255 void EnumerateAllUserRegistries(ProcessUserRegistryFunc* handler,
256 LONG_PTR param) {
257 ASSERT1(handler);
258
259 CSimpleArray<CString> sid_array;
260 accounts::GetAllUserSids(&sid_array);
261 for (int i = 0 ; i < sid_array.GetSize() ; ++i) {
262 if (LoadUserRegistry(sid_array[i], handler, param)) {
263 return;
264 }
265 }
266 }
267
268 } // namespace omaha
269
OLDNEW
« no previous file with comments | « base/registry_hive.h ('k') | base/registry_monitor_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698