| OLD | NEW |
| (Empty) |
| 1 // Copyright 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 // This class allows for implementing two dual interfaces, ReadOnly being a | |
| 17 // read-only dual interface, and ReadWrite being a read-write dual interface. | |
| 18 // Based on the value returned from is_read_only(), the ReadOnly or the | |
| 19 // ReadWrite dual interface is exposed at runtime. | |
| 20 // | |
| 21 // An ATL class needs to | |
| 22 // (a) derive from DualInterfaceSwitch | |
| 23 // | |
| 24 // (b) implement the is_read_only() method. For instance: | |
| 25 // bool is_read_only() { return is_read_only_; } | |
| 26 // | |
| 27 // (c) add entries similar to below for the dual interfaces as well as IDispatch | |
| 28 // to the COM map: | |
| 29 // BEGIN_COM_MAP(AppData) | |
| 30 // COM_INTERFACE_ENTRY2(IUnknown, IAppData) | |
| 31 // COM_INTERFACE_ENTRY_FUNC(__uuidof(IAppDataReadOnly), 0, DualInterfaceQI) | |
| 32 // COM_INTERFACE_ENTRY_FUNC(__uuidof(IAppData), 0, DualInterfaceQI) | |
| 33 // COM_INTERFACE_ENTRY_FUNC(__uuidof(IDispatch), 0, DualInterfaceQI) | |
| 34 // END_COM_MAP() | |
| 35 | |
| 36 #ifndef OMAHA_BASE_DUAL_INTERFACE_SWITCH_H_ | |
| 37 #define OMAHA_BASE_DUAL_INTERFACE_SWITCH_H_ | |
| 38 | |
| 39 #include <windows.h> | |
| 40 #include <atlbase.h> | |
| 41 #include "base/basictypes.h" | |
| 42 #include "omaha/base/debug.h" | |
| 43 | |
| 44 namespace omaha { | |
| 45 | |
| 46 template <class T, class ReadOnly, REFIID iid_read_only, | |
| 47 class ReadWrite, REFIID iid_read_write> | |
| 48 class ATL_NO_VTABLE DualInterfaceSwitch : public ReadOnly, | |
| 49 public ReadWrite { | |
| 50 protected: | |
| 51 // DualInterfaceQI gives out either the ReadOnly or ReadWrite interface | |
| 52 // pointer, based on the value of is_read_only() that class T implements. | |
| 53 // The signature of this function has to be | |
| 54 // HRESULT WINAPI func(void* pv, REFIID riid, LPVOID* ppv, DWORD dw); | |
| 55 // for it to work with COM_INTERFACE_ENTRY_FUNC. | |
| 56 static HRESULT WINAPI DualInterfaceQI(void* p, | |
| 57 REFIID riid, | |
| 58 LPVOID* v, | |
| 59 DWORD) { | |
| 60 // Ensure that ReadOnly and ReadWrite are derived from IDispatch. | |
| 61 ASSERT1(static_cast<IDispatch*>(reinterpret_cast<ReadOnly*>(1))); | |
| 62 ASSERT1(static_cast<IDispatch*>(reinterpret_cast<ReadWrite*>(1))); | |
| 63 | |
| 64 if (riid != iid_read_only && | |
| 65 riid != iid_read_write && | |
| 66 riid != __uuidof(IDispatch)) { | |
| 67 // Returning S_FALSE allows COM map processing to continue. Another entry | |
| 68 // in the COM map might match the interface requested. | |
| 69 return S_FALSE; | |
| 70 } | |
| 71 | |
| 72 T* t = reinterpret_cast<T*>(p); | |
| 73 if (t->is_read_only() && riid == iid_read_write) { | |
| 74 return S_FALSE; | |
| 75 } | |
| 76 | |
| 77 t->AddRef(); | |
| 78 if (t->is_read_only() || riid == iid_read_only) { | |
| 79 *v = static_cast<ReadOnly*>(t); | |
| 80 return S_OK; | |
| 81 } | |
| 82 | |
| 83 *v = static_cast<ReadWrite*>(t); | |
| 84 return S_OK; | |
| 85 } | |
| 86 }; | |
| 87 | |
| 88 } // namespace omaha | |
| 89 | |
| 90 #endif // OMAHA_BASE_DUAL_INTERFACE_SWITCH_H_ | |
| OLD | NEW |