// Copyright 2007-2009 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
//
// Defines SharedMemoryProxy to encapsulate marshaling and unmarshaling of
// IGoogleUpdate3 and other interface pointers across process boundaries.
//
// TODO(omaha): seems possible to make it general purpose and move it to common.
#ifndef OMAHA_GOOPDATE_GOOGLE_UPDATE_PROXY_H__
#define OMAHA_GOOPDATE_GOOGLE_UPDATE_PROXY_H__

#include <atlbase.h>
#include <atlsecurity.h>
#include "base/basictypes.h"
#include "omaha/base/debug.h"
#include "omaha/base/error.h"
#include "omaha/base/logging.h"
#include "omaha/base/scoped_any.h"
#include "omaha/base/shared_memory_ptr.h"
#include "omaha/base/utils.h"
#include "omaha/base/vistautil.h"

namespace omaha {

// Constants
const size_t kMaxSizeInterfaceMarshalData = 256;
const TCHAR* const kBrowserHttpRequestShareName = _T("IBrowserRequest2_");

struct InterfaceMarshalData {
  void InitializeSharedData(const CString&) {
    SetZero(data_);
    size_ = 0;
  }
  size_t size_;
  uint8 data_[kMaxSizeInterfaceMarshalData];
};

class SharedMemoryAttributes {
 public:
  SharedMemoryAttributes(const TCHAR* shared_memory_name,
                         const CSecurityDesc& security_attributes)
      : shared_memory_name_(shared_memory_name),
        security_attributes_(security_attributes) {
  }
  const CString& GetSharedMemoryName() { return shared_memory_name_; }
  LPSECURITY_ATTRIBUTES GetSecurityAttributes() {
    return &security_attributes_;
  }

 private:
  CString shared_memory_name_;
  CSecurityAttributes security_attributes_;
  DISALLOW_EVIL_CONSTRUCTORS(SharedMemoryAttributes);
};

extern SharedMemoryAttributes low_integrity_attributes;
extern SharedMemoryAttributes high_integrity_attributes;

template <typename InterfaceType, typename LockType>
class SharedMemoryProxy {
 public:
  SharedMemoryProxy(bool read_only, SharedMemoryAttributes* attributes)
      : shared_memory_ptr_(attributes->GetSharedMemoryName(),
                           attributes->GetSecurityAttributes(),
                           NULL,
                           read_only) {
    CORE_LOG(L3, (_T("[SharedMemoryProxy::SharedMemoryProxy]")));
  }

  ~SharedMemoryProxy() {
    CORE_LOG(L3, (_T("[SharedMemoryProxy::~SharedMemoryProxy]")));
  }

  HRESULT GetObject(InterfaceType** interface_ptr) {
    ASSERT1(interface_ptr);
    ASSERT1(*interface_ptr == NULL);

    CORE_LOG(L3, (_T("[SharedMemoryProxy::GetObject]")));

    return UnmarshalInterface(interface_ptr);
  }

  HRESULT RegisterObject(InterfaceType* interface_ptr) {
    ASSERT1(interface_ptr);
    CORE_LOG(L3, (_T("[SharedMemoryProxy::RegisterObject]")));

    return MarshalInterface(interface_ptr);
  }

  HRESULT RevokeObject() {
    CORE_LOG(L3, (_T("[SharedMemoryProxy::RevokeObject]")));

    if (!shared_memory_ptr_) {
      OPT_LOG(LEVEL_ERROR, (_T("[Shared memory ptr error]")));
      return GOOPDATE_E_INVALID_SHARED_MEMORY_PTR;
    }

    shared_memory_ptr_->size_ = 0;
    SetZero(shared_memory_ptr_->data_);

    return S_OK;
  }

 private:
  // Helpers.
  HRESULT MarshalInterface(InterfaceType* interface_ptr) {
    CORE_LOG(L3, (_T("[SharedMemoryProxy::MarshalInterface]")));

    if (!shared_memory_ptr_) {
      OPT_LOG(LEVEL_ERROR, (_T("[Shared memory ptr error]")));
      return GOOPDATE_E_INVALID_SHARED_MEMORY_PTR;
    }

    // Marshal the interface.
    scoped_hglobal hglobal(::GlobalAlloc(GHND, 0));
    if (!valid(hglobal)) {
      OPT_LOG(LEVEL_ERROR, (_T("[GlobalAlloc failed]")));
      return E_OUTOFMEMORY;
    }

    CComPtr<IStream> stream;
    HRESULT hr = ::CreateStreamOnHGlobal(get(hglobal), false, &stream);
    if (FAILED(hr)) {
      OPT_LOG(LEVEL_ERROR, (_T("[CreateStreamOnHGlobal failed][0x%08x]"), hr));
      return hr;
    }

    // MSHLFLAGS_TABLEWEAK results in CO_E_OBJNOTREG if unmarshaling multiple
    // times, so using MSHLFLAGS_TABLESTRONG.
    hr = ::CoMarshalInterface(stream,
                              __uuidof(InterfaceType),
                              interface_ptr,
                              MSHCTX_LOCAL,
                              NULL,
                              MSHLFLAGS_TABLESTRONG);
    if (FAILED(hr)) {
      OPT_LOG(LEVEL_ERROR, (_T("[CoMarshalInterface failed][0x%08x]"), hr));
      return hr;
    }

    // Copy out the marshaled data.
    STATSTG stat = {0};
    hr = stream->Stat(&stat, STATFLAG_NONAME);
    if (FAILED(hr)) {
      OPT_LOG(LEVEL_ERROR, (_T("[IStream::Stat failed][0x%08x]"), hr));
      return hr;
    }
    int64 size = static_cast<int64>(stat.cbSize.QuadPart);
    if (!size || size > kMaxSizeInterfaceMarshalData) {
      OPT_LOG(LEVEL_ERROR, (_T("[Bad size][%I64d]"), size));
      return GOOPDATE_E_INVALID_INTERFACE_MARSHAL_SIZE;
    }

    byte* data = reinterpret_cast<byte*>(::GlobalLock(get(hglobal)));
    if (!data) {
      return HRESULTFromLastError();
    }
    memcpy(shared_memory_ptr_->data_, data, stat.cbSize.LowPart);
    shared_memory_ptr_->size_ = stat.cbSize.LowPart;

    ::GlobalUnlock(get(hglobal));

    return S_OK;
  }

  HRESULT UnmarshalInterface(InterfaceType** interface_ptr) {
    CORE_LOG(L3, (_T("[SharedMemoryProxy::UnmarshalInterface]")));

    if (!shared_memory_ptr_) {
      OPT_LOG(LEVEL_ERROR, (_T("[Shared memory ptr error]")));
      return GOOPDATE_E_INVALID_SHARED_MEMORY_PTR;
    }

    size_t size = shared_memory_ptr_->size_;
    if (!size || size > kMaxSizeInterfaceMarshalData) {
      CORE_LOG(LEVEL_ERROR, (_T("[bad size][%d]"), size));
      return GOOPDATE_E_INVALID_INTERFACE_MARSHAL_SIZE;
    }

    // Unmarshal the interface.
    scoped_hglobal hglobal(::GlobalAlloc(GPTR, size));
    if (!valid(hglobal)) {
      OPT_LOG(LEVEL_ERROR, (_T("[GlobalAlloc failed]")));
      return E_OUTOFMEMORY;
    }
    memcpy(get(hglobal), shared_memory_ptr_->data_, size);

    CComPtr<IStream> stream;
    HRESULT hr = ::CreateStreamOnHGlobal(get(hglobal), false, &stream);
    if (FAILED(hr)) {
      OPT_LOG(LEVEL_ERROR, (_T("[CreateStreamOnHGlobal failed][0x%08x]"), hr));
      return hr;
    }

    hr = ::CoUnmarshalInterface(stream,
                                __uuidof(InterfaceType),
                                reinterpret_cast<void **>(interface_ptr));
    if (FAILED(hr)) {
      OPT_LOG(LEVEL_ERROR, (_T("[CoUnmarshalInterface failed][0x%08x]"), hr));
      return hr;
    }

    return S_OK;
  }

  SharedMemoryPtr<LockType, InterfaceMarshalData> shared_memory_ptr_;
  DISALLOW_EVIL_CONSTRUCTORS(SharedMemoryProxy);
};

}  // namespace omaha

#endif  // OMAHA_GOOPDATE_GOOGLE_UPDATE_PROXY_H__

