Index: base/registry_hive.cc |
diff --git a/base/registry_hive.cc b/base/registry_hive.cc |
deleted file mode 100644 |
index 006d4cfc913eeeedf6967a3967eab01fdb28cc6b..0000000000000000000000000000000000000000 |
--- a/base/registry_hive.cc |
+++ /dev/null |
@@ -1,269 +0,0 @@ |
-// Copyright 2004-2009 Google Inc. |
-// |
-// Licensed under the Apache License, Version 2.0 (the "License"); |
-// you may not use this file except in compliance with the License. |
-// You may obtain a copy of the License at |
-// |
-// http://www.apache.org/licenses/LICENSE-2.0 |
-// |
-// Unless required by applicable law or agreed to in writing, software |
-// distributed under the License is distributed on an "AS IS" BASIS, |
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
-// See the License for the specific language governing permissions and |
-// limitations under the License. |
-// ======================================================================== |
- |
-#include "omaha/base/registry_hive.h" |
-#include "omaha/base/accounts.h" |
-#include "omaha/base/reg_key.h" |
-#include "omaha/base/safe_format.h" |
-#include "omaha/base/string.h" |
-#include "omaha/base/system.h" |
-#include "omaha/base/user_info.h" |
-#include "omaha/base/utils.h" |
- |
-namespace omaha { |
- |
-RegistryHive::RegistryHive() |
- : hive_holding_key_(NULL) { |
-} |
- |
-RegistryHive::~RegistryHive() { |
- if ( !hive_name_.IsEmpty() ) { |
- UnloadHive(); |
- } |
-} |
- |
-// Loads hive for requested SID. SID should be in format "S-X-X....." |
-// name is a name under which the hive will be added to the HKEY_USERS, |
-// you could use persons name here. This parameter should not have '\\' |
-// characters! |
-// It is not recommended to load more than one hive at once - LoadHive, |
-// manipulate hive, UnloadHive, and then work on the next one. |
-// |
-// Hive could be already loaded: you logged out from other user but system |
-// had open key in your current user. In that case I open hive_holding_key_ to |
-// prevent system from unloading hive and do not load/unload hive - the system |
-// will do it. |
-HRESULT RegistryHive::LoadHive(TCHAR const * sid, TCHAR const *name) { |
- ASSERT1(sid); |
- ASSERT1(name); |
- ASSERT1(hive_name_.IsEmpty()); |
- ASSERT1(String_FindChar(name, _T('\\')) == -1); |
- |
- CString profile_key; |
- CString hive_path; |
- |
- // Need set SE_RESTORE_NAME/SE_BACKUP_NAME priveleges to current process |
- // otherwise loading of the hive will fail |
- RET_IF_FAILED(System::AdjustPrivilege(SE_RESTORE_NAME, true)); |
- RET_IF_FAILED(System::AdjustPrivilege(SE_BACKUP_NAME, true)); |
- |
- SafeCStringFormat(&profile_key, kProfileKeyFormat, sid); |
- |
- if ( FAILED(RegKey::GetValue(profile_key, kProfilePathValue, &hive_path)) ) { |
- return E_FAIL; |
- } |
- |
- |
- wchar_t temporary_buffer[MAX_PATH]; |
- DWORD ret = ExpandEnvironmentStrings(hive_path, temporary_buffer, MAX_PATH); |
- |
- if ( !ret || ret >= MAX_PATH ) { |
- return E_FAIL; |
- } |
- hive_path = temporary_buffer; |
- |
- hive_path.Append(_T("\\")); |
- hive_path.Append(kHiveName); |
- |
- hive_name_ = name; |
- |
- LONG res = RegLoadKey(HKEY_USERS, hive_name_, hive_path); |
- |
- if ( ERROR_SHARING_VIOLATION == res ) { |
- // It is quite possible that the hive is still held by system. |
- hive_name_ = sid; |
- |
- // if it is the case, this call will succeeed, and the system will not |
- // unload the hive while there are outstanding keys opened. |
- res = RegOpenKeyEx(HKEY_USERS, |
- hive_name_, |
- 0, |
- KEY_ALL_ACCESS, |
- &hive_holding_key_); |
- } |
- |
- return (res == ERROR_SUCCESS) ? S_OK : E_FAIL; |
-} |
- |
-// Loads hive for requested SID, but only if the SID is another user |
-// (since we don't need to do anything if the sid is ours) |
-HRESULT RegistryHive::LoadHive(TCHAR const * user_sid) { |
- ASSERT1(user_sid != NULL); |
- bool other_user = false; |
- |
- // Determine if the SID passed in is really another user |
- CString current_user_sid; |
- HRESULT hr = omaha::user_info::GetProcessUser(NULL, NULL, ¤t_user_sid); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[RegistryHive::LoadHive - failed to get current user"))); |
- return hr; |
- } |
- |
- // user_sid is the current user - no need to load the hive |
- if (lstrcmpi(current_user_sid, user_sid) == 0) |
- return S_FALSE; |
- |
- // Get info on the sid we're being asked to load for |
- CString name; |
- CString domain; |
- SID_NAME_USE user_type; |
- hr = accounts::GetUserInfo(user_sid, &name, &domain, &user_type); |
- if ( FAILED(hr) || user_type != SidTypeUser ) { |
- // Either Sid no longer exists or Sid is not a user Sid |
- // (There is other possibility: Sid could be for roaming profile on domain |
- // which is currently down, but we do not support roaming profiles) |
- return FAILED(hr) ? hr : E_FAIL; |
- } |
- |
- hr = LoadHive(user_sid, name); // Use user name as a temporary key name. |
- if ( FAILED(hr) ) { |
- // Hive no longer present. |
- return E_FAIL; |
- } |
- |
- return S_OK; |
-} |
- |
- |
-// Unloads and saves loaded hive |
-HRESULT RegistryHive::UnloadHive() { |
- if (hive_name_.IsEmpty()) |
- return S_OK; |
- |
- LONG res; |
- if ( hive_holding_key_ ) { |
- res = RegCloseKey(hive_holding_key_); |
- hive_holding_key_ = NULL; |
- // no need to unload hive. System will do it. |
- } else { |
- res = RegUnLoadKey(HKEY_USERS, hive_name_); |
- } |
- hive_name_.Empty(); |
- return (res == ERROR_SUCCESS) ? S_OK : E_FAIL; |
-} |
- |
-// Does it recursively. The name should be relative to HKEY_CURRENT_USER. |
-HRESULT RegistryHive::DeleteUserKey(TCHAR const * key_name) { |
- ASSERT(key_name && *key_name, (L"")); |
- if ( !key_name || !*key_name ) { |
- return E_FAIL; |
- } |
- CString key(key_name); |
- ExpandKeyName(&key); |
- |
- if ( !RegKey::SafeKeyNameForDeletion(key) ) { |
- return E_FAIL; |
- } |
- |
- return RegKey::DeleteKey(key); |
-} |
- |
-void RegistryHive::ExpandKeyName(CString * str) { |
- ASSERT1(str); |
- |
- // If we haven't loaded another user's hive, use HKCU instead of |
- // HKEY_USERS |
- CString key_name; |
- if (hive_name_.IsEmpty()) { |
- key_name = _T("HKCU\\"); |
- } else { |
- key_name = _T("HKEY_USERS\\"); |
- key_name.Append(hive_name_ + _T("\\")); |
- } |
- |
- key_name.Append(*str); |
- *str = key_name; |
-} |
- |
-// Load a user registry |
-int LoadUserRegistry(const TCHAR* user_sid, |
- ProcessUserRegistryFunc* handler, |
- LONG_PTR param) { |
- ASSERT1(user_sid && *user_sid); |
- ASSERT1(handler); |
- |
- // Get current user SID |
- CString curr_user_sid; |
- HRESULT hr = omaha::user_info::GetProcessUser(NULL, NULL, &curr_user_sid); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[LoadUserRegistry - can't get current user][0x%x]"), hr)); |
- return 0; |
- } |
- |
- // Is current user? |
- bool other_user = curr_user_sid.CompareNoCase(user_sid) != 0; |
- |
- // Get the hive for this user |
- RegistryHive user_hive; |
- if (other_user) { |
- // Get the info about this user |
- SID_NAME_USE user_type = SidTypeInvalid; |
- CString name, domain; |
- hr = accounts::GetUserInfo(user_sid, &name, &domain, &user_type); |
- if (FAILED(hr) || user_type != SidTypeUser) { |
- // Either SID no longer exists or SID is not a user Sid |
- // (There is other possibility: SID could be for roaming profile on domain |
- // which is currently down, but we do not support roaming profiles) |
- UTIL_LOG(LEVEL_WARNING, |
- (_T("[LoadUserRegistry - SID %s invalid or unsupported][0x%x]"), |
- user_sid, hr)); |
- return 0; |
- } |
- |
- // Load the hive |
- hr = user_hive.LoadHive(user_sid, domain + _T("_") + name); |
- if (FAILED(hr)) { |
- // Hive no longer present. |
- UTIL_LOG(LW, (_T("[LoadUserRegistry]") |
- _T("[hive not present for %s][0x%x]"), user_sid, hr)); |
- return 0; |
- } |
- } |
- |
- // Get the registry key path |
- CString user_reg_path; |
- user_hive.ExpandKeyName(&user_reg_path); |
- |
- // Call the handler |
- int res = (*handler)(user_sid, user_reg_path, param); |
- |
- // Unload the hive |
- if (other_user) { |
- hr = user_hive.UnloadHive(); |
- if (FAILED(hr)) { |
- UTIL_LOG(LE, (_T("[LoadUserRegistry]") |
- _T("[failed to save hive for %s][0x%x]"), user_sid, hr)); |
- } |
- } |
- |
- return res; |
-} |
- |
-// Enumerate all user registries |
-void EnumerateAllUserRegistries(ProcessUserRegistryFunc* handler, |
- LONG_PTR param) { |
- ASSERT1(handler); |
- |
- CSimpleArray<CString> sid_array; |
- accounts::GetAllUserSids(&sid_array); |
- for (int i = 0 ; i < sid_array.GetSize() ; ++i) { |
- if (LoadUserRegistry(sid_array[i], handler, param)) { |
- return; |
- } |
- } |
-} |
- |
-} // namespace omaha |
- |