| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/installer/util/self_reg_work_item.h" | 5 #include "chrome/installer/util/self_reg_work_item.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
| 10 #include "chrome/installer/util/logging_installer.h" | 10 #include "chrome/installer/util/logging_installer.h" |
| 11 | 11 |
| 12 // Default registration export names. | 12 // Default registration export names. |
| 13 const char kDefaultRegistrationEntryPoint[] = "DllRegisterServer"; | 13 const char kDefaultRegistrationEntryPoint[] = "DllRegisterServer"; |
| 14 const char kDefaultUnregistrationEntryPoint[] = "DllUnregisterServer"; | 14 const char kDefaultUnregistrationEntryPoint[] = "DllUnregisterServer"; |
| 15 | 15 |
| 16 // User-level registration export names. | 16 // User-level registration export names. |
| 17 const char kUserRegistrationEntryPoint[] = "DllRegisterUserServer"; | 17 const char kUserRegistrationEntryPoint[] = "DllRegisterUserServer"; |
| 18 const char kUserUnregistrationEntryPoint[] = "DllUnregisterUserServer"; | 18 const char kUserUnregistrationEntryPoint[] = "DllUnregisterUserServer"; |
| 19 | 19 |
| 20 SelfRegWorkItem::SelfRegWorkItem(const std::wstring& dll_path, | 20 SelfRegWorkItem::SelfRegWorkItem(const std::wstring& dll_path, |
| 21 bool do_register, | 21 bool do_register, |
| 22 bool user_level_registration) | 22 bool user_level_registration) |
| 23 : do_register_(do_register), dll_path_(dll_path), | 23 : do_register_(do_register), dll_path_(dll_path), |
| 24 user_level_registration_(user_level_registration) { | 24 user_level_registration_(user_level_registration) { |
| 25 } | 25 } |
| 26 | 26 |
| 27 SelfRegWorkItem::~SelfRegWorkItem() { | 27 SelfRegWorkItem::~SelfRegWorkItem() { |
| 28 } | 28 } |
| 29 | 29 |
| 30 // This is designed to unmux error codes that may be shoe-horned in to HRESULT |
| 31 // return codes by ORing a number into the top four bits of the facility code |
| 32 // Any number thus found will be returned in |error_code|. The "cleaned" |
| 33 // HRESULT is then returned. |
| 34 // |
| 35 // This only has an effect if the customer bit is set in the HRESULT, if it is |
| 36 // not set then *error_code will be unchanged and the original HRESULT is |
| 37 // returned. |
| 38 // |
| 39 // Note that this will do the wrong thing for high-valued facility codes. |
| 40 HRESULT UnMuxHRESULTErrorCode(HRESULT hr, int* error_code) { |
| 41 DCHECK(error_code); |
| 42 if (hr & (1 << 29)) { |
| 43 *error_code = (hr & 0x07800000) >> 23; |
| 44 return hr & 0xF87FFFFF; |
| 45 } |
| 46 |
| 47 return hr; |
| 48 } |
| 49 |
| 30 bool SelfRegWorkItem::RegisterDll(bool do_register) { | 50 bool SelfRegWorkItem::RegisterDll(bool do_register) { |
| 31 VLOG(1) << "COM " << (do_register ? "registration of " : "unregistration of ") | 51 VLOG(1) << "COM " << (do_register ? "registration of " : "unregistration of ") |
| 32 << dll_path_; | 52 << dll_path_; |
| 33 | 53 |
| 34 HMODULE dll_module = ::LoadLibraryEx(dll_path_.c_str(), NULL, | 54 HMODULE dll_module = ::LoadLibraryEx(dll_path_.c_str(), NULL, |
| 35 LOAD_WITH_ALTERED_SEARCH_PATH); | 55 LOAD_WITH_ALTERED_SEARCH_PATH); |
| 36 bool success = false; | 56 bool success = false; |
| 37 if (NULL != dll_module) { | 57 if (NULL != dll_module) { |
| 38 typedef HRESULT (WINAPI* RegisterFunc)(); | 58 typedef HRESULT (WINAPI* RegisterFunc)(); |
| 39 RegisterFunc register_server_func = NULL; | 59 RegisterFunc register_server_func = NULL; |
| 40 if (do_register) { | 60 if (do_register) { |
| 41 register_server_func = reinterpret_cast<RegisterFunc>( | 61 register_server_func = reinterpret_cast<RegisterFunc>( |
| 42 ::GetProcAddress(dll_module, user_level_registration_ ? | 62 ::GetProcAddress(dll_module, user_level_registration_ ? |
| 43 kUserRegistrationEntryPoint : kDefaultRegistrationEntryPoint)); | 63 kUserRegistrationEntryPoint : kDefaultRegistrationEntryPoint)); |
| 44 } else { | 64 } else { |
| 45 register_server_func = reinterpret_cast<RegisterFunc>( | 65 register_server_func = reinterpret_cast<RegisterFunc>( |
| 46 ::GetProcAddress(dll_module, user_level_registration_ ? | 66 ::GetProcAddress(dll_module, user_level_registration_ ? |
| 47 kUserUnregistrationEntryPoint : | 67 kUserUnregistrationEntryPoint : |
| 48 kDefaultUnregistrationEntryPoint)); | 68 kDefaultUnregistrationEntryPoint)); |
| 49 } | 69 } |
| 50 | 70 |
| 51 if (NULL != register_server_func) { | 71 if (NULL != register_server_func) { |
| 52 HRESULT hr = register_server_func(); | 72 HRESULT hr = register_server_func(); |
| 53 success = SUCCEEDED(hr); | 73 success = SUCCEEDED(hr); |
| 54 if (!success) { | 74 if (!success) { |
| 55 PLOG(ERROR) << "Failed to " << (do_register ? "register" : "unregister") | 75 int error_code = 0; |
| 56 << " DLL at " << dll_path_.c_str() << | 76 HRESULT unmuxed_hr = UnMuxHRESULTErrorCode(hr, &error_code); |
| 57 base::StringPrintf(" 0x%08X", hr); | 77 LOG(ERROR) << "Failed to " << (do_register ? "register" : "unregister") |
| 78 << " DLL at " << dll_path_.c_str() << ", hr=" |
| 79 << base::StringPrintf(" 0x%08X", unmuxed_hr) << ", code=" |
| 80 << error_code; |
| 58 } | 81 } |
| 59 } else { | 82 } else { |
| 60 LOG(ERROR) << "COM registration export function not found"; | 83 LOG(ERROR) << "COM registration export function not found"; |
| 61 } | 84 } |
| 62 ::FreeLibrary(dll_module); | 85 ::FreeLibrary(dll_module); |
| 63 } else { | 86 } else { |
| 64 PLOG(WARNING) << "Failed to load: " << dll_path_; | 87 PLOG(WARNING) << "Failed to load: " << dll_path_; |
| 65 } | 88 } |
| 66 return success; | 89 return success; |
| 67 } | 90 } |
| 68 | 91 |
| 69 bool SelfRegWorkItem::Do() { | 92 bool SelfRegWorkItem::Do() { |
| 70 bool success = RegisterDll(do_register_); | 93 bool success = RegisterDll(do_register_); |
| 71 if (ignore_failure_) | 94 if (ignore_failure_) |
| 72 success = true; | 95 success = true; |
| 73 return success; | 96 return success; |
| 74 } | 97 } |
| 75 | 98 |
| 76 void SelfRegWorkItem::Rollback() { | 99 void SelfRegWorkItem::Rollback() { |
| 77 if (!ignore_failure_) { | 100 if (!ignore_failure_) { |
| 78 RegisterDll(!do_register_); | 101 RegisterDll(!do_register_); |
| 79 } | 102 } |
| 80 } | 103 } |
| OLD | NEW |