OLD | NEW |
| (Empty) |
1 // Copyright 2010 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 #ifndef OMAHA_GOOPDATE_COM_PROXY_H_ | |
17 #define OMAHA_GOOPDATE_COM_PROXY_H_ | |
18 | |
19 #include <atlbase.h> | |
20 #include <atlcom.h> | |
21 #include <atlctl.h> | |
22 #include "base/basictypes.h" | |
23 #include "omaha/base/atlregmapex.h" | |
24 #include "omaha/base/debug.h" | |
25 #include "omaha/base/logging.h" | |
26 #include "omaha/base/scope_guard.h" | |
27 #include "omaha/common/goopdate_utils.h" | |
28 #include "omaha/goopdate/google_update_ps_resource.h" | |
29 #include "goopdate/omaha3_idl.h" | |
30 | |
31 namespace omaha { | |
32 | |
33 // All[*] coclasses in omaha3_idl.idl do the following: | |
34 // * Derive from StdMarshalInfo. | |
35 // * Construct StdMarshalInfo(is_machine). | |
36 // * Add a COM_INTERFACE_ENTRY(IStdMarshalInfo) | |
37 // | |
38 // [*] The proxy classes GoogleComProxy[XXX]Class, being proxies, do not follow | |
39 // the steps above. In addition, the CurrentStateClass has a custom marshaler | |
40 // and does not follow the steps above. | |
41 // | |
42 const IID kIIDsToRegister[] = { | |
43 __uuidof(IGoogleUpdate3), | |
44 __uuidof(IAppBundle), | |
45 __uuidof(IApp), | |
46 __uuidof(IAppVersion), | |
47 __uuidof(IPackage), | |
48 __uuidof(ICurrentState), | |
49 | |
50 __uuidof(IRegistrationUpdateHook), | |
51 | |
52 __uuidof(IGoogleUpdate3Web), | |
53 __uuidof(IGoogleUpdate3WebSecurity), | |
54 __uuidof(IAppBundleWeb), | |
55 __uuidof(IAppWeb), | |
56 __uuidof(IAppVersionWeb), | |
57 __uuidof(ICoCreateAsync), | |
58 __uuidof(ICoCreateAsyncStatus), | |
59 __uuidof(ICredentialDialog), | |
60 | |
61 // Omaha2 IIDs: | |
62 __uuidof(IBrowserHttpRequest2), | |
63 __uuidof(IProcessLauncher), | |
64 __uuidof(IProgressWndEvents), | |
65 __uuidof(IJobObserver), | |
66 __uuidof(IGoogleUpdate), | |
67 __uuidof(IGoogleUpdateCore), | |
68 }; | |
69 | |
70 struct ComProxyMode { | |
71 static bool is_machine() { | |
72 return goopdate_utils::IsRunningFromOfficialGoopdateDir(true); | |
73 } | |
74 | |
75 static const GUID& class_id() { | |
76 return is_machine() ? __uuidof(GoogleComProxyMachineClass) : | |
77 __uuidof(GoogleComProxyUserClass); | |
78 } | |
79 | |
80 static const GUID ps_clsid() { | |
81 if (is_machine()) { | |
82 GUID proxy_clsid = PROXY_CLSID_IS_MACHINE; | |
83 return proxy_clsid; | |
84 } else { | |
85 GUID proxy_clsid = PROXY_CLSID_IS_USER; | |
86 return proxy_clsid; | |
87 } | |
88 } | |
89 | |
90 static const TCHAR* const hk_root() { | |
91 return is_machine() ? _T("HKLM") : _T("HKCU"); | |
92 } | |
93 }; | |
94 | |
95 #pragma warning(push) | |
96 | |
97 // C4640: construction of local static object is not thread-safe | |
98 #pragma warning(disable : 4640) | |
99 | |
100 // C4505: unreferenced IUnknown local functions have been removed | |
101 #pragma warning(disable : 4505) | |
102 | |
103 class ATL_NO_VTABLE ComProxy | |
104 : public CComObjectRootEx<CComMultiThreadModel>, | |
105 public CComCoClass<ComProxy>, | |
106 public IUnknown { | |
107 public: | |
108 ComProxy() { | |
109 CORE_LOG(L2, (_T("[ComProxy::ComProxy]"))); | |
110 } | |
111 | |
112 DECLARE_GET_CONTROLLING_UNKNOWN() | |
113 DECLARE_REGISTRY_RESOURCEID_EX(IDR_COM_PROXY_RGS); | |
114 | |
115 #pragma warning(push) | |
116 // Construction of local static object is not thread-safe | |
117 #pragma warning(disable:4640) | |
118 BEGIN_REGISTRY_MAP() | |
119 REGMAP_ENTRY(_T("HKROOT"), ComProxyMode::hk_root()) | |
120 REGMAP_ENTRY(_T("CLSID"), ComProxyMode::class_id()) | |
121 END_REGISTRY_MAP() | |
122 #pragma warning(pop) | |
123 | |
124 BEGIN_COM_MAP(ComProxy) | |
125 COM_INTERFACE_ENTRY(IUnknown) | |
126 COM_INTERFACE_ENTRY_FUNC(__uuidof(IClientSecurity), 0, QueryInternal) | |
127 COM_INTERFACE_ENTRY_FUNC(__uuidof(IMultiQI), 0, QueryInternal) | |
128 COM_INTERFACE_ENTRY_AGGREGATE_BLIND(proxy_manager_.p) | |
129 END_COM_MAP() | |
130 | |
131 static HRESULT WINAPI QueryInternal(void* ptr, REFIID iid, | |
132 void** retval, DWORD_PTR) { | |
133 ASSERT1(ptr); | |
134 ASSERT1(retval); | |
135 CORE_LOG(L2, (_T("[ComProxy::QueryInternal][%s]"), GuidToString(iid))); | |
136 | |
137 ComProxy* this_ptr = reinterpret_cast<ComProxy*>(ptr); | |
138 return this_ptr->proxy_internal_unknown_->QueryInternalInterface(iid, | |
139 retval); | |
140 } | |
141 | |
142 HRESULT FinalConstruct() { | |
143 CORE_LOG(L2, (_T("[ComProxy::FinalConstruct]"))); | |
144 | |
145 HRESULT hr = RegisterProxyStubs(); | |
146 if (FAILED(hr)) { | |
147 CORE_LOG(LE, (_T("[RegisterProxyStubs failed][0x%x]"), hr)); | |
148 // If explicit registration failed, the registry-based proxy lookup | |
149 // mechanism may still work. Fall through. | |
150 } | |
151 | |
152 hr = ::CoGetStdMarshalEx(GetControllingUnknown(), | |
153 SMEXF_HANDLER, | |
154 &proxy_manager_); | |
155 if (FAILED(hr)) { | |
156 CORE_LOG(LE, (_T("[::CoGetStdMarshalEx failed][0x%x]"), hr)); | |
157 return hr; | |
158 } | |
159 | |
160 return proxy_manager_.QueryInterface(&proxy_internal_unknown_); | |
161 } | |
162 | |
163 void FinalRelease() { | |
164 CORE_LOG(L2, (_T("[ComProxy::FinalRelease]"))); | |
165 } | |
166 | |
167 static HRESULT RegisterProxyStubs() { | |
168 static LLock lock; | |
169 static bool is_registered = false; | |
170 | |
171 __mutexScope(lock); | |
172 | |
173 if (is_registered) { | |
174 return S_OK; | |
175 } | |
176 | |
177 CORE_LOG(L2, (_T("[ComProxy::RegisterProxyStubs][Registering][%d]"), | |
178 ComProxyMode::is_machine())); | |
179 | |
180 const GUID ps_clsid = ComProxyMode::ps_clsid(); | |
181 for (size_t i = 0; i < arraysize(kIIDsToRegister); ++i) { | |
182 HRESULT hr = ::CoRegisterPSClsid(kIIDsToRegister[i], ps_clsid); | |
183 if (FAILED(hr)) { | |
184 CORE_LOG(LE, (_T("[::CoRegisterPSClsid failed][%s][%s][0x%x]"), | |
185 GuidToString(kIIDsToRegister[i]), GuidToString(ps_clsid), hr)); | |
186 return hr; | |
187 } | |
188 } | |
189 | |
190 is_registered = true; | |
191 return S_OK; | |
192 } | |
193 | |
194 protected: | |
195 virtual ~ComProxy() { | |
196 CORE_LOG(L2, (_T("[ComProxy::~ComProxy]"))); | |
197 } | |
198 | |
199 CComPtr<IUnknown> proxy_manager_; | |
200 CComPtr<IInternalUnknown> proxy_internal_unknown_; | |
201 | |
202 DISALLOW_COPY_AND_ASSIGN(ComProxy); | |
203 }; | |
204 | |
205 #pragma warning(pop) | |
206 | |
207 class StdMarshalInfo : public IStdMarshalInfo { | |
208 public: | |
209 explicit StdMarshalInfo(bool is_machine) : is_machine_(is_machine) { | |
210 CORE_LOG(L6, (_T("[StdMarshalInfo::StdMarshalInfo][%d]"), is_machine)); | |
211 | |
212 VERIFY1(SUCCEEDED(ComProxy::RegisterProxyStubs())); | |
213 } | |
214 | |
215 // IStdMarshalInfo. | |
216 STDMETHODIMP GetClassForHandler(DWORD context, void* ptr, CLSID* clsid) { | |
217 UNREFERENCED_PARAMETER(context); | |
218 UNREFERENCED_PARAMETER(ptr); | |
219 | |
220 *clsid = is_machine_ ? __uuidof(GoogleComProxyMachineClass) : | |
221 __uuidof(GoogleComProxyUserClass); | |
222 return S_OK; | |
223 } | |
224 | |
225 private: | |
226 bool is_machine_; | |
227 | |
228 DISALLOW_COPY_AND_ASSIGN(StdMarshalInfo); | |
229 }; | |
230 | |
231 } // namespace omaha | |
232 | |
233 #endif // OMAHA_GOOPDATE_COM_PROXY_H_ | |
234 | |
OLD | NEW |