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
3 // found in the LICENSE file.
5 #include "chrome/installer/util/self_reg_work_item.h"
7 #include "base/logging.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h"
10 #include "chrome/installer/util/logging_installer.h"
12 // Default registration export names.
13 const char kDefaultRegistrationEntryPoint
[] = "DllRegisterServer";
14 const char kDefaultUnregistrationEntryPoint
[] = "DllUnregisterServer";
16 // User-level registration export names.
17 const char kUserRegistrationEntryPoint
[] = "DllRegisterUserServer";
18 const char kUserUnregistrationEntryPoint
[] = "DllUnregisterUserServer";
20 SelfRegWorkItem::SelfRegWorkItem(const std::wstring
& dll_path
,
22 bool user_level_registration
)
23 : do_register_(do_register
), dll_path_(dll_path
),
24 user_level_registration_(user_level_registration
) {
27 SelfRegWorkItem::~SelfRegWorkItem() {
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.
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
39 // Note that this will do the wrong thing for high-valued facility codes.
40 HRESULT
UnMuxHRESULTErrorCode(HRESULT hr
, int* error_code
) {
43 *error_code
= (hr
& 0x07800000) >> 23;
44 return hr
& 0xF87FFFFF;
50 bool SelfRegWorkItem::RegisterDll(bool do_register
) {
51 VLOG(1) << "COM " << (do_register
? "registration of " : "unregistration of ")
54 HMODULE dll_module
= ::LoadLibraryEx(dll_path_
.c_str(), NULL
,
55 LOAD_WITH_ALTERED_SEARCH_PATH
);
57 if (NULL
!= dll_module
) {
58 typedef HRESULT (WINAPI
* RegisterFunc
)();
59 RegisterFunc register_server_func
= NULL
;
61 register_server_func
= reinterpret_cast<RegisterFunc
>(
62 ::GetProcAddress(dll_module
, user_level_registration_
?
63 kUserRegistrationEntryPoint
: kDefaultRegistrationEntryPoint
));
65 register_server_func
= reinterpret_cast<RegisterFunc
>(
66 ::GetProcAddress(dll_module
, user_level_registration_
?
67 kUserUnregistrationEntryPoint
:
68 kDefaultUnregistrationEntryPoint
));
71 if (NULL
!= register_server_func
) {
72 HRESULT hr
= register_server_func();
73 success
= SUCCEEDED(hr
);
76 HRESULT unmuxed_hr
= UnMuxHRESULTErrorCode(hr
, &error_code
);
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="
83 LOG(ERROR
) << "COM registration export function not found";
85 ::FreeLibrary(dll_module
);
87 PLOG(WARNING
) << "Failed to load: " << dll_path_
;
92 bool SelfRegWorkItem::Do() {
93 bool success
= RegisterDll(do_register_
);
99 void SelfRegWorkItem::Rollback() {
100 if (!ignore_failure_
) {
101 RegisterDll(!do_register_
);