// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/installer/util/self_reg_work_item.h"

#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "chrome/installer/util/logging_installer.h"

// Default registration export names.
const char kDefaultRegistrationEntryPoint[] = "DllRegisterServer";
const char kDefaultUnregistrationEntryPoint[] = "DllUnregisterServer";

// User-level registration export names.
const char kUserRegistrationEntryPoint[] = "DllRegisterUserServer";
const char kUserUnregistrationEntryPoint[] = "DllUnregisterUserServer";

SelfRegWorkItem::SelfRegWorkItem(const std::wstring& dll_path,
                                 bool do_register,
                                 bool user_level_registration)
    : do_register_(do_register), dll_path_(dll_path),
      user_level_registration_(user_level_registration) {
}

SelfRegWorkItem::~SelfRegWorkItem() {
}

// This is designed to unmux error codes that may be shoe-horned in to HRESULT
// return codes by ORing a number into the top four bits of the facility code
// Any number thus found will be returned in |error_code|. The "cleaned"
// HRESULT is then returned.
//
// This only has an effect if the customer bit is set in the HRESULT, if it is
// not set then *error_code will be unchanged and the original HRESULT is
// returned.
//
// Note that this will do the wrong thing for high-valued facility codes.
HRESULT UnMuxHRESULTErrorCode(HRESULT hr, int* error_code) {
  DCHECK(error_code);
  if (hr & (1 << 29)) {
    *error_code = (hr & 0x07800000) >> 23;
    return hr & 0xF87FFFFF;
  }

  return hr;
}

bool SelfRegWorkItem::RegisterDll(bool do_register) {
  VLOG(1) << "COM " << (do_register ? "registration of " : "unregistration of ")
          << dll_path_;

  HMODULE dll_module = ::LoadLibraryEx(dll_path_.c_str(), NULL,
                                       LOAD_WITH_ALTERED_SEARCH_PATH);
  bool success = false;
  if (NULL != dll_module) {
    typedef HRESULT (WINAPI* RegisterFunc)();
    RegisterFunc register_server_func = NULL;
    if (do_register) {
      register_server_func = reinterpret_cast<RegisterFunc>(
          ::GetProcAddress(dll_module, user_level_registration_ ?
              kUserRegistrationEntryPoint : kDefaultRegistrationEntryPoint));
    } else {
      register_server_func = reinterpret_cast<RegisterFunc>(
          ::GetProcAddress(dll_module, user_level_registration_ ?
              kUserUnregistrationEntryPoint :
              kDefaultUnregistrationEntryPoint));
    }

    if (NULL != register_server_func) {
      HRESULT hr = register_server_func();
      success = SUCCEEDED(hr);
      if (!success) {
        int error_code = 0;
        HRESULT unmuxed_hr = UnMuxHRESULTErrorCode(hr, &error_code);
        LOG(ERROR) << "Failed to " << (do_register ? "register" : "unregister")
                   << " DLL at " << dll_path_.c_str() << ", hr="
                   << base::StringPrintf(" 0x%08X", unmuxed_hr) << ", code="
                   << error_code;
      }
    } else {
      LOG(ERROR) << "COM registration export function not found";
    }
    ::FreeLibrary(dll_module);
  } else {
    PLOG(WARNING) << "Failed to load: " << dll_path_;
  }
  return success;
}

bool SelfRegWorkItem::Do() {
  bool success = RegisterDll(do_register_);
  if (ignore_failure_)
    success = true;
  return success;
}

void SelfRegWorkItem::Rollback() {
  if (!ignore_failure_) {
    RegisterDll(!do_register_);
  }
}
