// 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_frame/buggy_bho_handling.h"

#include "base/logging.h"
#include "base/win/scoped_comptr.h"

#include "chrome_frame/exception_barrier.h"
#include "chrome_frame/function_stub.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 = 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 {
      PinModule();  // No backing out now.
      ::FlushInstructionCache(::GetCurrentProcess(), invoke, sizeof(PROC));
    }
  }
  ::VirtualProtect(invoke, sizeof(PROC), flags, &flags);
  return hr;
}

}  // end namespace buggy_bho
