// 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/bind_status_callback_impl.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/platform_thread.h"
BSCBImpl::BSCBImpl() {
DVLOG(1) << __FUNCTION__ << me();
}
BSCBImpl::~BSCBImpl() {
DVLOG(1) << __FUNCTION__ << me();
}
std::string BSCBImpl::me() {
return base::StringPrintf(" obj=0x%08X", static_cast<BSCBImpl*>(this));
}
HRESULT BSCBImpl::DelegateQI(void* obj, REFIID iid, void** ret, DWORD cookie) {
BSCBImpl* me = reinterpret_cast<BSCBImpl*>(obj);
HRESULT hr = E_NOINTERFACE;
if (me->delegate_)
hr = me->delegate_.QueryInterface(iid, ret);
return hr;
}
void BSCBImpl::Initialize(IBindStatusCallback* original) {
DCHECK(!delegate_);
delegate_ = original;
}
HRESULT BSCBImpl::AttachToBind(IBindCtx* bind_ctx) {
HRESULT hr = S_OK;
hr = ::RegisterBindStatusCallback(bind_ctx, this, delegate_.Receive(), 0);
if (SUCCEEDED(hr)) {
bind_ctx_ = bind_ctx;
}
return hr;
}
HRESULT BSCBImpl::ReleaseBind() {
// AddRef ourselves while we release these objects as we might
// perish during this operation.
AddRef();
HRESULT hr = S_OK;
if (bind_ctx_) {
hr = ::RevokeBindStatusCallback(bind_ctx_, this);
}
delegate_.Release();
bind_ctx_.Release();
Release();
return hr;
}
// IServiceProvider
HRESULT BSCBImpl::QueryService(REFGUID service, REFIID iid, void** object) {
HRESULT hr = E_NOINTERFACE;
if (delegate_) {
base::win::ScopedComPtr<IServiceProvider> svc;
svc.QueryFrom(delegate_);
if (svc) {
hr = svc->QueryService(service, iid, object);
}
}
return hr;
}
// IBindStatusCallback
HRESULT BSCBImpl::OnStartBinding(DWORD reserved, IBinding* binding) {
DVLOG(1) << __FUNCTION__ << me()
<< base::StringPrintf(" tid=%i", base::PlatformThread::CurrentId());
HRESULT hr = S_OK;
if (delegate_)
hr = delegate_->OnStartBinding(reserved, binding);
return hr;
}
HRESULT BSCBImpl::GetPriority(LONG* priority) {
DVLOG(1) << __FUNCTION__ << me()
<< base::StringPrintf(" tid=%i", base::PlatformThread::CurrentId());
HRESULT hr = S_OK;
if (delegate_)
hr = delegate_->GetPriority(priority);
return hr;
}
HRESULT BSCBImpl::OnLowResource(DWORD reserved) {
DVLOG(1) << __FUNCTION__ << me()
<< base::StringPrintf(" tid=%i", base::PlatformThread::CurrentId());
HRESULT hr = S_OK;
if (delegate_)
hr = delegate_->OnLowResource(reserved);
return hr;
}
HRESULT BSCBImpl::OnProgress(ULONG progress, ULONG progress_max,
ULONG status_code, LPCWSTR status_text) {
DVLOG(1) << __FUNCTION__ << me()
<< base::StringPrintf(" status=%i tid=%i %ls", status_code,
base::PlatformThread::CurrentId(),
status_text);
HRESULT hr = S_OK;
if (delegate_)
delegate_->OnProgress(progress, progress_max, status_code, status_text);
return hr;
}
HRESULT BSCBImpl::OnStopBinding(HRESULT hresult, LPCWSTR error) {
DVLOG(1) << __FUNCTION__ << me()
<< base::StringPrintf(" hr=0x%08X '%ls' tid=%i", hresult, error,
base::PlatformThread::CurrentId());
HRESULT hr = S_OK;
if (delegate_)
delegate_->OnStopBinding(hresult, error);
return hr;
}
HRESULT BSCBImpl::GetBindInfo(DWORD* bindf, BINDINFO* bind_info) {
DVLOG(1) << __FUNCTION__ << me()
<< base::StringPrintf(" tid=%i", base::PlatformThread::CurrentId());
HRESULT hr = S_OK;
if (delegate_)
delegate_->GetBindInfo(bindf, bind_info);
return hr;
}
HRESULT BSCBImpl::OnDataAvailable(DWORD bscf, DWORD size,
FORMATETC* format_etc, STGMEDIUM* stgmed) {
DVLOG(1) << __FUNCTION__ << me()
<< base::StringPrintf(" tid=%i", base::PlatformThread::CurrentId());
HRESULT hr = S_OK;
if (delegate_)
hr = delegate_->OnDataAvailable(bscf, size, format_etc, stgmed);
return hr;
}
HRESULT BSCBImpl::OnObjectAvailable(REFIID iid, IUnknown* unk) {
DVLOG(1) << __FUNCTION__ << me()
<< base::StringPrintf(" tid=%i", base::PlatformThread::CurrentId());
HRESULT hr = S_OK;
if (delegate_)
delegate_->OnObjectAvailable(iid, unk);
return hr;
}
// IBindStatusCallbackEx
HRESULT BSCBImpl::GetBindInfoEx(DWORD* bindf, BINDINFO* bind_info,
DWORD* bindf2, DWORD* reserved) {
DVLOG(1) << __FUNCTION__ << me()
<< base::StringPrintf(" tid=%i", base::PlatformThread::CurrentId());
HRESULT hr = S_OK;
if (delegate_) {
base::win::ScopedComPtr<IBindStatusCallbackEx> bscbex;
bscbex.QueryFrom(delegate_);
if (bscbex)
hr = bscbex->GetBindInfoEx(bindf, bind_info, bindf2, reserved);
}
return hr;
}
HRESULT BSCBImpl::BeginningTransaction(LPCWSTR url, LPCWSTR headers,
DWORD reserved,
LPWSTR* additional_headers) {
DVLOG(1) << __FUNCTION__ << me()
<< base::StringPrintf(" tid=%i", base::PlatformThread::CurrentId());
HRESULT hr = S_OK;
if (delegate_) {
base::win::ScopedComPtr<IHttpNegotiate> http_negotiate;
http_negotiate.QueryFrom(delegate_);
if (http_negotiate) {
hr = http_negotiate->BeginningTransaction(url, headers, reserved,
additional_headers);
}
}
DLOG_IF(ERROR, FAILED(hr)) << __FUNCTION__;
return hr;
}
HRESULT BSCBImpl::OnResponse(DWORD response_code, LPCWSTR response_headers,
LPCWSTR request_headers,
LPWSTR* additional_headers) {
DVLOG(1) << __FUNCTION__ << me()
<< base::StringPrintf(" tid=%i", base::PlatformThread::CurrentId());
HRESULT hr = S_OK;
if (delegate_) {
base::win::ScopedComPtr<IHttpNegotiate> http_negotiate;
http_negotiate.QueryFrom(delegate_);
if (http_negotiate) {
hr = http_negotiate->OnResponse(response_code, response_headers,
request_headers, additional_headers);
}
}
return hr;
}
HRESULT BSCBImpl::GetRootSecurityId(BYTE* security_id, DWORD* security_id_size,
DWORD_PTR reserved) {
HRESULT hr = S_OK;
if (delegate_) {
base::win::ScopedComPtr<IHttpNegotiate2> http_negotiate;
http_negotiate.QueryFrom(delegate_);
if (http_negotiate) {
hr = http_negotiate->GetRootSecurityId(security_id, security_id_size,
reserved);
}
}
return hr;
}
HRESULT BSCBImpl::GetSerializedClientCertContext(BYTE** cert,
DWORD* cert_size) {
HRESULT hr = S_OK;
if (delegate_) {
base::win::ScopedComPtr<IHttpNegotiate3> http_negotiate;
http_negotiate.QueryFrom(delegate_);
if (http_negotiate) {
return http_negotiate->GetSerializedClientCertContext(cert, cert_size);
}
}
return hr;
}