15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/bind_context_info.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/utils.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is non const due to API expectations
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static wchar_t* kBindContextInfo = L"_CHROMEFRAME_BIND_CONTEXT_INFO_";
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BindContextInfo member definitions.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BindContextInfo::BindContextInfo()
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : no_cache_(false),
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome_request_(false),
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_switching_(false) {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BindContextInfo::~BindContextInfo() {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT BindContextInfo::Initialize(IBindCtx* bind_ctx) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bind_ctx);
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!ftm_);
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = CoCreateFreeThreadedMarshaler(GetUnknown(), ftm_.Receive());
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(ftm_);
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SUCCEEDED(hr)) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = bind_ctx->RegisterObjectParam(kBindContextInfo, GetUnknown());
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(SUCCEEDED(hr)) << "Failed to initialize BindContextInfo";
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT BindContextInfo::FromBindContext(IBindCtx* bind_context,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         BindContextInfo** info) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(info);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!bind_context) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return E_POINTER;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::ScopedComPtr<IUnknown> context;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HRESULT hr = bind_context->GetObjectParam(kBindContextInfo,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            context.Receive());
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (context) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::win::ScopedComPtr<IBindContextInfoInternal> internal;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = internal.QueryFrom(context);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (SUCCEEDED(hr)) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = internal->GetCppObject(reinterpret_cast<void**>(info));
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DCHECK_EQ(hr, S_OK);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DLOG_IF(ERROR, *info != static_cast<BindContextInfo*>(internal.get()))
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << "marshalling took place!";
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(FAILED(hr));
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CComObject<BindContextInfo>* bind_context_info = NULL;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    hr = CComObject<BindContextInfo>::CreateInstance(&bind_context_info);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(bind_context_info != NULL);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bind_context_info) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bind_context_info->AddRef();
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hr = bind_context_info->Initialize(bind_context);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (FAILED(hr)) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bind_context_info->Release();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *info = bind_context_info;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return hr;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BindContextInfo::SetToSwitch(IStream* cache) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  is_switching_ = true;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if  (!no_cache_) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cache_ = cache;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RewindStream(cache_);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring BindContextInfo::GetUrl() {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_prot_data()) {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return prot_data_->url();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::wstring();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88