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 : dll_path_(dll_path
),
24 do_register_(do_register
),
25 user_level_registration_(user_level_registration
) {
28 SelfRegWorkItem::~SelfRegWorkItem() {
31 // This is designed to unmux error codes that may be shoe-horned in to HRESULT
32 // return codes by ORing a number into the top four bits of the facility code
33 // Any number thus found will be returned in |error_code|. The "cleaned"
34 // HRESULT is then returned.
36 // This only has an effect if the customer bit is set in the HRESULT, if it is
37 // not set then *error_code will be unchanged and the original HRESULT is
40 // Note that this will do the wrong thing for high-valued facility codes.
41 HRESULT
UnMuxHRESULTErrorCode(HRESULT hr
, int* error_code
) {
44 *error_code
= (hr
& 0x07800000) >> 23;
45 return hr
& 0xF87FFFFF;
51 bool SelfRegWorkItem::RegisterDll(bool do_register
) {
52 VLOG(1) << "COM " << (do_register
? "registration of " : "unregistration of ")
55 HMODULE dll_module
= ::LoadLibraryEx(dll_path_
.c_str(), NULL
,
56 LOAD_WITH_ALTERED_SEARCH_PATH
);
58 if (NULL
!= dll_module
) {
59 typedef HRESULT (WINAPI
* RegisterFunc
)();
60 RegisterFunc register_server_func
= NULL
;
62 register_server_func
= reinterpret_cast<RegisterFunc
>(
63 ::GetProcAddress(dll_module
, user_level_registration_
?
64 kUserRegistrationEntryPoint
: kDefaultRegistrationEntryPoint
));
66 register_server_func
= reinterpret_cast<RegisterFunc
>(
67 ::GetProcAddress(dll_module
, user_level_registration_
?
68 kUserUnregistrationEntryPoint
:
69 kDefaultUnregistrationEntryPoint
));
72 if (NULL
!= register_server_func
) {
73 HRESULT hr
= register_server_func();
74 success
= SUCCEEDED(hr
);
77 HRESULT unmuxed_hr
= UnMuxHRESULTErrorCode(hr
, &error_code
);
78 LOG(ERROR
) << "Failed to " << (do_register
? "register" : "unregister")
79 << " DLL at " << dll_path_
.c_str() << ", hr="
80 << base::StringPrintf(" 0x%08X", unmuxed_hr
) << ", code="
84 LOG(ERROR
) << "COM registration export function not found";
86 ::FreeLibrary(dll_module
);
88 PLOG(WARNING
) << "Failed to load: " << dll_path_
;
93 bool SelfRegWorkItem::Do() {
94 bool success
= RegisterDll(do_register_
);
100 void SelfRegWorkItem::Rollback() {
101 if (!ignore_failure_
) {
102 RegisterDll(!do_register_
);