// Copyright (c) 2012 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_frame/buggy_bho_handling.h"

#include <algorithm>

#include "base/logging.h"
#include "base/process/memory.h"
#include "base/win/scoped_comptr.h"
#include "chrome_frame/exception_barrier.h"
#include "chrome_frame/function_stub.h"
#include "chrome_frame/pin_module.h"
#include "chrome_frame/utils.h"
#include "chrome_frame/vtable_patch_manager.h"

namespace buggy_bho {

base::ThreadLocalPointer<BuggyBhoTls> BuggyBhoTls::s_bad_object_tls_;

struct ModuleAndVersion {
  const char* module_name_;
  const uint32 major_version_;
  const uint32 minor_version_;
};

const ModuleAndVersion kBuggyModules[] = {
  { "askbar.dll", 4, 1 },  // troublemaker: 4.1.0.5.
  { "gbieh.dll", 3, 8 },  // troublemaker: 3.8.14.12
  { "gbiehcef.dll", 3, 8 },  // troublemaker: 3.8.11.23
  { "alot.dll", 2, 5 },  // troublemaker: 2.5.12000.509
  { "ctbr.dll", 5, 1 },  // troublemaker: 5.1.0.95
  { "srchbxex.dll", 1, 2 },  // troublemaker: 1.2.123.0
  { "iedvtool32.dll", 8, 0 },  // troublemaker: 8.0.0.4
  { "mst164.dll", 9, 1 },  // troublemaker: 9.1.3700.1
  { "deposit_ie_com.dll", 0, 1  },  // troublemaker: 0.1.0.72
  { "rpshell32.dll", 6, 0 },  // troublemaker: 6.0.6000.1389
  { "msgsres.dll", 6, 0 },  // troublemaker: 6.0.6000.1389
  { "limewireinttb.dll", 4, 1  },  // troublemaker: 4.1.1.1000
  { "pxsecure.dll", 3, 0  },  // troublemaker: 3.0.5.220

  // These BHOs seem to be out of the same buggy BHO factory
  { "tbabso.dll", 4, 5 },  // troublemaker: 4.5.156.0
  { "tbabs0.dll.dll", 4, 5 },  // troublemaker: 4.5.156.0
  { "tbbes0.dll", 4, 5 },  // troublemaker: 4.5.153.0
  { "tbfre0.dll", 4, 5 },  // troublemaker: 4.5.181.1
  { "tbmypl.dll", 4, 5 },  // troublemaker: 4.5.181.3
  { "tbmul1.dll", 4, 5 },  // troublemaker: 4.5.181.1
  { "tbdow1.dll", 4, 5 },  // troublemaker: 4.5.167.0
  { "tbfree.dll", 4, 5 },  // troublemaker: 4.5.178.0

  // Viruses?
  { "msgsc2.dll", 0xffff, 0xffff },  // troublemaker: 1.2.3000.1
  { "essclis.dll", 0xffff, 0xffff },  // troublemaker: 4.3.1800.2
  { "snagwb.dll", 0xffff, 0xffff },  // troublemaker: 2.6.0.28
};

bool IsBuggyBho(HMODULE mod) {
  DCHECK(mod);

  char path[MAX_PATH * 2] = {0};
  ::GetModuleFileNameA(mod, path, arraysize(path));
  const char* file_name = ::PathFindFileNameA(path);
  for (size_t i = 0; i < arraysize(kBuggyModules); ++i) {
    if (lstrcmpiA(file_name, kBuggyModules[i].module_name_) == 0) {
      uint32 version = 0;
      GetModuleVersion(mod, &version, NULL);
      const ModuleAndVersion& buggy = kBuggyModules[i];
      if (HIWORD(version) < buggy.major_version_ ||
          (HIWORD(version) == buggy.major_version_ &&
           LOWORD(version) <= buggy.minor_version_)) {
        return true;
      }
    }
  }

  return false;
}

BuggyBhoTls::BuggyBhoTls()
    : patched_(false) {
  DCHECK(s_bad_object_tls_.Get() == NULL);
  s_bad_object_tls_.Set(this);
}

BuggyBhoTls::~BuggyBhoTls() {
  DCHECK(BuggyBhoTls::GetInstance() == this);
  s_bad_object_tls_.Set(NULL);
}

void BuggyBhoTls::AddBuggyObject(IDispatch* obj) {
  bad_objects_.push_back(obj);
}

bool BuggyBhoTls::ShouldSkipInvoke(IDispatch* obj) const {
  DCHECK(web_browser2_ != NULL);
  if (IsChromeFrameDocument(web_browser2_)) {
    return std::find(bad_objects_.begin(), bad_objects_.end(), obj) !=
           bad_objects_.end();
  }
  return false;
}

// static
BuggyBhoTls* BuggyBhoTls::GetInstance() {
  BuggyBhoTls* tls_instance = s_bad_object_tls_.Get();
  if (!tls_instance) {
    tls_instance = new BuggyBhoTls();
    DCHECK(s_bad_object_tls_.Get() != NULL);
  }
  return tls_instance;
}

// static
void BuggyBhoTls::DestroyInstance() {
  BuggyBhoTls* tls_instance = s_bad_object_tls_.Get();
  if (tls_instance) {
    delete tls_instance;
    DCHECK(s_bad_object_tls_.Get() == NULL);
  }
}

HRESULT BuggyBhoTls::PatchBuggyBHOs(IWebBrowser2* browser) {
  if (patched_)
    return S_FALSE;

  DCHECK(browser);
  DCHECK(web_browser2_ == NULL);

  base::win::ScopedComPtr<IConnectionPointContainer> cpc;
  HRESULT hr = cpc.QueryFrom(browser);
  if (SUCCEEDED(hr)) {
    const GUID sinks[] = { DIID_DWebBrowserEvents2, DIID_DWebBrowserEvents };
    for (size_t i = 0; i < arraysize(sinks); ++i) {
      base::win::ScopedComPtr<IConnectionPoint> cp;
      cpc->FindConnectionPoint(sinks[i], cp.Receive());
      if (cp) {
        base::win::ScopedComPtr<IEnumConnections> connections;
        cp->EnumConnections(connections.Receive());
        if (connections) {
          CONNECTDATA cd = {0};
          DWORD fetched = 0;
          while (connections->Next(1, &cd, &fetched) == S_OK && fetched) {
            PatchIfBuggy(cd.pUnk, sinks[i]);
            cd.pUnk->Release();
            fetched = 0;
          }
        }
      }
    }
  }
  patched_ = true;
  web_browser2_ = browser;
  return hr;
}

bool BuggyBhoTls::PatchIfBuggy(IUnknown* unk, const IID& diid) {
  DCHECK(unk);
  PROC* methods = *reinterpret_cast<PROC**>(unk);
  HMODULE mod = base::GetModuleFromAddress(methods[0]);
  if (!IsBuggyBho(mod))
    return false;

  base::win::ScopedComPtr<IDispatch> disp;
  HRESULT hr = unk->QueryInterface(diid,
      reinterpret_cast<void**>(disp.Receive()));
  if (FAILED(hr))  // Sometimes only IDispatch QI is supported
    hr = disp.QueryFrom(unk);
  DCHECK(SUCCEEDED(hr));

  if (SUCCEEDED(hr)) {
    const int kInvokeIndex = 6;
    DCHECK(static_cast<IUnknown*>(disp) == unk);
    if (SUCCEEDED(PatchInvokeMethod(&methods[kInvokeIndex]))) {
      AddBuggyObject(disp);
    }
  }
  return false;
}

// static
STDMETHODIMP BuggyBhoTls::BuggyBhoInvoke(InvokeFunc original, IDispatch* me,
                                         DISPID dispid, REFIID riid, LCID lcid,
                                         WORD flags, DISPPARAMS* params,
                                         VARIANT* result, EXCEPINFO* ei,
                                         UINT* err) {
  DVLOG(1) << __FUNCTION__;

  DCHECK(BuggyBhoTls::GetInstance())
      << "You must first have an instance of BuggyBhoTls on this thread";
  if (BuggyBhoTls::GetInstance() &&
      BuggyBhoTls::GetInstance()->ShouldSkipInvoke(me)) {
    // Ignore this call and avoid the bug.
    // TODO(tommi): Maybe we should check a specific list of DISPIDs too?
    return S_OK;
  }

  // No need to report crashes in those known-to-be-buggy DLLs.
  ExceptionBarrierReportOnlyModule barrier;
  return original(me, dispid, riid, lcid, flags, params, result, ei, err);
}

// static
HRESULT BuggyBhoTls::PatchInvokeMethod(PROC* invoke) {
  CCritSecLock lock(_pAtlModule->m_csStaticDataInitAndTypeInfo.m_sec, true);

  FunctionStub* stub = FunctionStub::FromCode(*invoke);
  if (stub)
    return S_FALSE;

  DWORD flags = 0;
  if (!::VirtualProtect(invoke, sizeof(PROC), PAGE_EXECUTE_READWRITE, &flags))
    return AtlHresultFromLastError();

  HRESULT hr = S_OK;

  stub = FunctionStub::Create(reinterpret_cast<uintptr_t>(*invoke),
                              BuggyBhoInvoke);
  if (!stub) {
    hr = E_OUTOFMEMORY;
  } else {
    if (!vtable_patch::internal::ReplaceFunctionPointer(
            reinterpret_cast<void**>(invoke), stub->code(),
            reinterpret_cast<void*>(stub->argument()))) {
      hr = E_UNEXPECTED;
      FunctionStub::Destroy(stub);
    } else {
      chrome_frame::PinModule();  // No backing out now.
      ::FlushInstructionCache(::GetCurrentProcess(), invoke, sizeof(PROC));
    }
  }
  ::VirtualProtect(invoke, sizeof(PROC), flags, &flags);
  return hr;
}

}  // end namespace buggy_bho
