| OLD | NEW |
| (Empty) |
| 1 // Copyright 2007-2009 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 // | |
| 16 // Defines SharedMemoryProxy to encapsulate marshaling and unmarshaling of | |
| 17 // IGoogleUpdate3 and other interface pointers across process boundaries. | |
| 18 // | |
| 19 // TODO(omaha): seems possible to make it general purpose and move it to common. | |
| 20 #ifndef OMAHA_GOOPDATE_GOOGLE_UPDATE_PROXY_H__ | |
| 21 #define OMAHA_GOOPDATE_GOOGLE_UPDATE_PROXY_H__ | |
| 22 | |
| 23 #include <atlbase.h> | |
| 24 #include <atlsecurity.h> | |
| 25 #include "base/basictypes.h" | |
| 26 #include "omaha/base/debug.h" | |
| 27 #include "omaha/base/error.h" | |
| 28 #include "omaha/base/logging.h" | |
| 29 #include "omaha/base/scoped_any.h" | |
| 30 #include "omaha/base/shared_memory_ptr.h" | |
| 31 #include "omaha/base/utils.h" | |
| 32 #include "omaha/base/vistautil.h" | |
| 33 | |
| 34 namespace omaha { | |
| 35 | |
| 36 // Constants | |
| 37 const size_t kMaxSizeInterfaceMarshalData = 256; | |
| 38 const TCHAR* const kBrowserHttpRequestShareName = _T("IBrowserRequest2_"); | |
| 39 | |
| 40 struct InterfaceMarshalData { | |
| 41 void InitializeSharedData(const CString&) { | |
| 42 SetZero(data_); | |
| 43 size_ = 0; | |
| 44 } | |
| 45 size_t size_; | |
| 46 uint8 data_[kMaxSizeInterfaceMarshalData]; | |
| 47 }; | |
| 48 | |
| 49 class SharedMemoryAttributes { | |
| 50 public: | |
| 51 SharedMemoryAttributes(const TCHAR* shared_memory_name, | |
| 52 const CSecurityDesc& security_attributes) | |
| 53 : shared_memory_name_(shared_memory_name), | |
| 54 security_attributes_(security_attributes) { | |
| 55 } | |
| 56 const CString& GetSharedMemoryName() { return shared_memory_name_; } | |
| 57 LPSECURITY_ATTRIBUTES GetSecurityAttributes() { | |
| 58 return &security_attributes_; | |
| 59 } | |
| 60 | |
| 61 private: | |
| 62 CString shared_memory_name_; | |
| 63 CSecurityAttributes security_attributes_; | |
| 64 DISALLOW_EVIL_CONSTRUCTORS(SharedMemoryAttributes); | |
| 65 }; | |
| 66 | |
| 67 extern SharedMemoryAttributes low_integrity_attributes; | |
| 68 extern SharedMemoryAttributes high_integrity_attributes; | |
| 69 | |
| 70 template <typename InterfaceType, typename LockType> | |
| 71 class SharedMemoryProxy { | |
| 72 public: | |
| 73 SharedMemoryProxy(bool read_only, SharedMemoryAttributes* attributes) | |
| 74 : shared_memory_ptr_(attributes->GetSharedMemoryName(), | |
| 75 attributes->GetSecurityAttributes(), | |
| 76 NULL, | |
| 77 read_only) { | |
| 78 CORE_LOG(L3, (_T("[SharedMemoryProxy::SharedMemoryProxy]"))); | |
| 79 } | |
| 80 | |
| 81 ~SharedMemoryProxy() { | |
| 82 CORE_LOG(L3, (_T("[SharedMemoryProxy::~SharedMemoryProxy]"))); | |
| 83 } | |
| 84 | |
| 85 HRESULT GetObject(InterfaceType** interface_ptr) { | |
| 86 ASSERT1(interface_ptr); | |
| 87 ASSERT1(*interface_ptr == NULL); | |
| 88 | |
| 89 CORE_LOG(L3, (_T("[SharedMemoryProxy::GetObject]"))); | |
| 90 | |
| 91 return UnmarshalInterface(interface_ptr); | |
| 92 } | |
| 93 | |
| 94 HRESULT RegisterObject(InterfaceType* interface_ptr) { | |
| 95 ASSERT1(interface_ptr); | |
| 96 CORE_LOG(L3, (_T("[SharedMemoryProxy::RegisterObject]"))); | |
| 97 | |
| 98 return MarshalInterface(interface_ptr); | |
| 99 } | |
| 100 | |
| 101 HRESULT RevokeObject() { | |
| 102 CORE_LOG(L3, (_T("[SharedMemoryProxy::RevokeObject]"))); | |
| 103 | |
| 104 if (!shared_memory_ptr_) { | |
| 105 OPT_LOG(LEVEL_ERROR, (_T("[Shared memory ptr error]"))); | |
| 106 return GOOPDATE_E_INVALID_SHARED_MEMORY_PTR; | |
| 107 } | |
| 108 | |
| 109 shared_memory_ptr_->size_ = 0; | |
| 110 SetZero(shared_memory_ptr_->data_); | |
| 111 | |
| 112 return S_OK; | |
| 113 } | |
| 114 | |
| 115 private: | |
| 116 // Helpers. | |
| 117 HRESULT MarshalInterface(InterfaceType* interface_ptr) { | |
| 118 CORE_LOG(L3, (_T("[SharedMemoryProxy::MarshalInterface]"))); | |
| 119 | |
| 120 if (!shared_memory_ptr_) { | |
| 121 OPT_LOG(LEVEL_ERROR, (_T("[Shared memory ptr error]"))); | |
| 122 return GOOPDATE_E_INVALID_SHARED_MEMORY_PTR; | |
| 123 } | |
| 124 | |
| 125 // Marshal the interface. | |
| 126 scoped_hglobal hglobal(::GlobalAlloc(GHND, 0)); | |
| 127 if (!valid(hglobal)) { | |
| 128 OPT_LOG(LEVEL_ERROR, (_T("[GlobalAlloc failed]"))); | |
| 129 return E_OUTOFMEMORY; | |
| 130 } | |
| 131 | |
| 132 CComPtr<IStream> stream; | |
| 133 HRESULT hr = ::CreateStreamOnHGlobal(get(hglobal), false, &stream); | |
| 134 if (FAILED(hr)) { | |
| 135 OPT_LOG(LEVEL_ERROR, (_T("[CreateStreamOnHGlobal failed][0x%08x]"), hr)); | |
| 136 return hr; | |
| 137 } | |
| 138 | |
| 139 // MSHLFLAGS_TABLEWEAK results in CO_E_OBJNOTREG if unmarshaling multiple | |
| 140 // times, so using MSHLFLAGS_TABLESTRONG. | |
| 141 hr = ::CoMarshalInterface(stream, | |
| 142 __uuidof(InterfaceType), | |
| 143 interface_ptr, | |
| 144 MSHCTX_LOCAL, | |
| 145 NULL, | |
| 146 MSHLFLAGS_TABLESTRONG); | |
| 147 if (FAILED(hr)) { | |
| 148 OPT_LOG(LEVEL_ERROR, (_T("[CoMarshalInterface failed][0x%08x]"), hr)); | |
| 149 return hr; | |
| 150 } | |
| 151 | |
| 152 // Copy out the marshaled data. | |
| 153 STATSTG stat = {0}; | |
| 154 hr = stream->Stat(&stat, STATFLAG_NONAME); | |
| 155 if (FAILED(hr)) { | |
| 156 OPT_LOG(LEVEL_ERROR, (_T("[IStream::Stat failed][0x%08x]"), hr)); | |
| 157 return hr; | |
| 158 } | |
| 159 int64 size = static_cast<int64>(stat.cbSize.QuadPart); | |
| 160 if (!size || size > kMaxSizeInterfaceMarshalData) { | |
| 161 OPT_LOG(LEVEL_ERROR, (_T("[Bad size][%I64d]"), size)); | |
| 162 return GOOPDATE_E_INVALID_INTERFACE_MARSHAL_SIZE; | |
| 163 } | |
| 164 | |
| 165 byte* data = reinterpret_cast<byte*>(::GlobalLock(get(hglobal))); | |
| 166 if (!data) { | |
| 167 return HRESULTFromLastError(); | |
| 168 } | |
| 169 memcpy(shared_memory_ptr_->data_, data, stat.cbSize.LowPart); | |
| 170 shared_memory_ptr_->size_ = stat.cbSize.LowPart; | |
| 171 | |
| 172 ::GlobalUnlock(get(hglobal)); | |
| 173 | |
| 174 return S_OK; | |
| 175 } | |
| 176 | |
| 177 HRESULT UnmarshalInterface(InterfaceType** interface_ptr) { | |
| 178 CORE_LOG(L3, (_T("[SharedMemoryProxy::UnmarshalInterface]"))); | |
| 179 | |
| 180 if (!shared_memory_ptr_) { | |
| 181 OPT_LOG(LEVEL_ERROR, (_T("[Shared memory ptr error]"))); | |
| 182 return GOOPDATE_E_INVALID_SHARED_MEMORY_PTR; | |
| 183 } | |
| 184 | |
| 185 size_t size = shared_memory_ptr_->size_; | |
| 186 if (!size || size > kMaxSizeInterfaceMarshalData) { | |
| 187 CORE_LOG(LEVEL_ERROR, (_T("[bad size][%d]"), size)); | |
| 188 return GOOPDATE_E_INVALID_INTERFACE_MARSHAL_SIZE; | |
| 189 } | |
| 190 | |
| 191 // Unmarshal the interface. | |
| 192 scoped_hglobal hglobal(::GlobalAlloc(GPTR, size)); | |
| 193 if (!valid(hglobal)) { | |
| 194 OPT_LOG(LEVEL_ERROR, (_T("[GlobalAlloc failed]"))); | |
| 195 return E_OUTOFMEMORY; | |
| 196 } | |
| 197 memcpy(get(hglobal), shared_memory_ptr_->data_, size); | |
| 198 | |
| 199 CComPtr<IStream> stream; | |
| 200 HRESULT hr = ::CreateStreamOnHGlobal(get(hglobal), false, &stream); | |
| 201 if (FAILED(hr)) { | |
| 202 OPT_LOG(LEVEL_ERROR, (_T("[CreateStreamOnHGlobal failed][0x%08x]"), hr)); | |
| 203 return hr; | |
| 204 } | |
| 205 | |
| 206 hr = ::CoUnmarshalInterface(stream, | |
| 207 __uuidof(InterfaceType), | |
| 208 reinterpret_cast<void **>(interface_ptr)); | |
| 209 if (FAILED(hr)) { | |
| 210 OPT_LOG(LEVEL_ERROR, (_T("[CoUnmarshalInterface failed][0x%08x]"), hr)); | |
| 211 return hr; | |
| 212 } | |
| 213 | |
| 214 return S_OK; | |
| 215 } | |
| 216 | |
| 217 SharedMemoryPtr<LockType, InterfaceMarshalData> shared_memory_ptr_; | |
| 218 DISALLOW_EVIL_CONSTRUCTORS(SharedMemoryProxy); | |
| 219 }; | |
| 220 | |
| 221 } // namespace omaha | |
| 222 | |
| 223 #endif // OMAHA_GOOPDATE_GOOGLE_UPDATE_PROXY_H__ | |
| 224 | |
| OLD | NEW |