Left: | ||
Right: |
OLD | NEW |
---|---|
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2015 Eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 | 121 |
122 HRESULT CPluginClass::FinalConstruct() | 122 HRESULT CPluginClass::FinalConstruct() |
123 { | 123 { |
124 return S_OK; | 124 return S_OK; |
125 } | 125 } |
126 | 126 |
127 void CPluginClass::FinalRelease() | 127 void CPluginClass::FinalRelease() |
128 { | 128 { |
129 s_criticalSectionBrowser.Lock(); | 129 s_criticalSectionBrowser.Lock(); |
130 { | 130 { |
131 m_webBrowser2.Release(); | 131 m_webBrowser2.Release(); |
Eric
2015/03/06 15:58:04
Explicit release.
| |
132 } | 132 } |
133 s_criticalSectionBrowser.Unlock(); | 133 s_criticalSectionBrowser.Unlock(); |
134 } | 134 } |
135 | 135 |
136 | 136 |
137 // This method tries to get a 'connection point' from the stored browser, which can be | 137 // This method tries to get a 'connection point' from the stored browser, which can be |
138 // used to attach or detach from the stream of browser events | 138 // used to attach or detach from the stream of browser events |
139 CComPtr<IConnectionPoint> CPluginClass::GetConnectionPoint() | 139 CComPtr<IConnectionPoint> CPluginClass::GetConnectionPoint() |
140 { | 140 { |
141 CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pContaine r(GetBrowser()); | 141 CComQIPtr<IConnectionPointContainer, &IID_IConnectionPointContainer> pContaine r(GetBrowser()); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
226 return 0; | 226 return 0; |
227 if (!((CPluginClass*)thisPtr)->InitObject(true)) | 227 if (!((CPluginClass*)thisPtr)->InitObject(true)) |
228 { | 228 { |
229 ((CPluginClass*)thisPtr)->Unadvice(); | 229 ((CPluginClass*)thisPtr)->Unadvice(); |
230 } | 230 } |
231 | 231 |
232 return 0; | 232 return 0; |
233 } | 233 } |
234 | 234 |
235 | 235 |
236 | 236 /* |
237 // This gets called when a new browser window is created (which also triggers th e | 237 * IE calls this when it creates a new browser window or tab, immediately after it also |
238 // creation of this object). The pointer passed in should be to a IWebBrowser2 | 238 * creates the object. The argument 'unknownSite' in is the OLE "site" of the ob ject, |
239 // interface that represents the browser for the window. | 239 * which is an IWebBrowser2 interface associated with the window/tab. |
240 // it is also called when a tab is closed, this unknownSite will be null | 240 * |
241 // so we should handle that it is called this way several times during a session | 241 * IE also ordinarily calls this again when its window/tab is closed, in which c ase |
242 * 'unknownSite' will be null. Extraordinarily, this is sometimes _not_ called w hen IE | |
243 * is shutting down. Thus 'SetSite(nullptr)' has some similarities with a destru ctor, | |
244 * but it is not a proper substitute for one. | |
sergei
2015/03/09 10:23:50
I'm not sure that we need this comment except the
Eric
2015/03/09 13:31:29
I was just rewriting the comment, mostly, with the
Oleksandr
2015/03/10 08:38:26
I am pretty sure it _is_ called every time when IE
Oleksandr
2015/03/10 08:42:04
https://msdn.microsoft.com/en-us/library/bb250489(
| |
245 */ | |
242 STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) | 246 STDMETHODIMP CPluginClass::SetSite(IUnknown* unknownSite) |
243 { | 247 { |
244 CPluginSettings* settings = CPluginSettings::GetInstance(); | 248 try |
249 { | |
250 if (unknownSite) | |
251 { | |
245 | 252 |
246 MULTIPLE_VERSIONS_CHECK(); | 253 DEBUG_GENERAL(L"========================================================== ======================\nNEW TAB UI\n============================================ ====================================") |
247 | 254 |
248 if (unknownSite) | 255 HRESULT hr = ::CoInitialize(NULL); |
249 { | 256 if (FAILED(hr)) |
257 { | |
258 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT, "Class::SetSite - CoInitialize"); | |
259 } | |
250 | 260 |
251 DEBUG_GENERAL(L"============================================================ ====================\nNEW TAB UI\n============================================== ==================================") | 261 s_criticalSectionBrowser.Lock(); |
262 { | |
263 m_webBrowser2 = unknownSite; | |
Eric
2015/03/06 15:58:04
Assigned to m_webBrowser2 here, declared as CComQI
sergei
2015/03/06 16:07:19
Here `AddRef` is called.
| |
264 } | |
265 s_criticalSectionBrowser.Unlock(); | |
252 | 266 |
253 HRESULT hr = ::CoInitialize(NULL); | 267 //register the mimefilter |
254 if (FAILED(hr)) | 268 //and only mimefilter |
255 { | 269 //on some few computers the mimefilter does not get properly registered wh en it is done on another thread |
256 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_COINIT, " Class::SetSite - CoInitialize"); | |
257 } | |
258 | 270 |
259 s_criticalSectionBrowser.Lock(); | 271 s_criticalSectionLocal.Lock(); |
260 { | 272 { |
261 m_webBrowser2 = unknownSite; | 273 // Always register on startup, then check if we need to unregister in a separate thread |
262 } | 274 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
263 s_criticalSectionBrowser.Unlock(); | 275 s_asyncWebBrowser2 = unknownSite; |
276 s_instances.insert(this); | |
277 } | |
278 s_criticalSectionLocal.Unlock(); | |
264 | 279 |
265 //register the mimefilter | 280 try |
266 //and only mimefilter | 281 { |
267 //on some few computers the mimefilter does not get properly registered when it is done on another thread | 282 // Check if loaded as BHO |
283 if (GetBrowser()) | |
sergei
2015/03/09 10:23:50
We don't need this comment now.
Eric
2015/03/09 13:31:29
We don't need this particular comment, but we'll n
Eric
2015/03/17 10:41:07
Done.
| |
284 { | |
285 DEBUG_GENERAL("Loaded as BHO"); | |
286 CComPtr<IConnectionPoint> pPoint = GetConnectionPoint(); | |
287 if (pPoint) | |
288 { | |
289 HRESULT hr = pPoint->Advise((IDispatch*)this, &m_nConnectionID); | |
290 if (SUCCEEDED(hr)) | |
291 { | |
292 m_isAdviced = true; | |
268 | 293 |
269 s_criticalSectionLocal.Lock(); | 294 try |
270 { | 295 { |
271 // Always register on startup, then check if we need to unregister in a se parate thread | 296 std::thread startInitObjectThread(StartInitObject, this); |
272 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); | 297 startInitObjectThread.detach(); // TODO: but actually we should wait for the thread in the dtr. |
273 s_asyncWebBrowser2 = unknownSite; | 298 } |
274 s_instances.insert(this); | 299 catch (const std::system_error& ex) |
275 } | 300 { |
276 s_criticalSectionLocal.Unlock(); | 301 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAI N_THREAD_CREATE_PROCESS, |
277 | 302 "Class::Thread - Failed to create StartInitObject thread"); |
278 try | 303 } |
279 { | 304 } |
280 // Check if loaded as BHO | 305 else |
281 if (GetBrowser()) | |
282 { | |
283 DEBUG_GENERAL("Loaded as BHO"); | |
284 CComPtr<IConnectionPoint> pPoint = GetConnectionPoint(); | |
285 if (pPoint) | |
286 { | |
287 HRESULT hr = pPoint->Advise((IDispatch*)this, &m_nConnectionID); | |
288 if (SUCCEEDED(hr)) | |
289 { | |
290 m_isAdviced = true; | |
291 | |
292 try | |
293 { | 306 { |
294 std::thread startInitObjectThread(StartInitObject, this); | 307 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_A DVICE, "Class::SetSite - Advice"); |
295 startInitObjectThread.detach(); // TODO: but actually we should wa it for the thread in the dtr. | |
296 } | 308 } |
297 catch (const std::system_error& ex) | |
298 { | |
299 DEBUG_SYSTEM_EXCEPTION(ex, PLUGIN_ERROR_THREAD, PLUGIN_ERROR_MAIN_ THREAD_CREATE_PROCESS, | |
300 "Class::Thread - Failed to create StartInitObject thread"); | |
301 } | |
302 } | |
303 else | |
304 { | |
305 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_ADV ICE, "Class::SetSite - Advice"); | |
306 } | 309 } |
307 } | 310 } |
308 } | 311 } |
309 else // Check if loaded as toolbar handler | 312 catch (const std::runtime_error& ex) |
310 { | 313 { |
311 DEBUG_GENERAL("Loaded as toolbar handler"); | 314 DEBUG_EXCEPTION(ex); |
312 CComPtr<IServiceProvider> pServiceProvider; | 315 Unadvice(); |
316 } | |
317 } | |
318 else | |
319 { | |
320 // Unadvice | |
321 Unadvice(); | |
313 | 322 |
314 HRESULT hr = unknownSite->QueryInterface(&pServiceProvider); | 323 // Destroy window |
315 if (SUCCEEDED(hr)) | 324 if (m_pWndProcStatus) |
325 { | |
326 ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWn dProcStatus); | |
327 | |
328 m_pWndProcStatus = NULL; | |
329 } | |
330 | |
331 if (m_hPaneWnd) | |
332 { | |
333 DestroyWindow(m_hPaneWnd); | |
334 m_hPaneWnd = NULL; | |
335 } | |
336 | |
337 m_hTabWnd = NULL; | |
338 m_hStatusBarWnd = NULL; | |
339 | |
340 // Remove instance from the list, shutdown threads | |
341 HANDLE hMainThread = NULL; | |
342 HANDLE hTabThread = NULL; | |
343 | |
344 s_criticalSectionLocal.Lock(); | |
345 { | |
346 s_instances.erase(this); | |
347 | |
348 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::Ge tCurrentThreadId()); | |
349 if (it != s_threadInstances.end()) | |
316 { | 350 { |
317 if (pServiceProvider) | 351 s_threadInstances.erase(it); |
318 { | |
319 s_criticalSectionBrowser.Lock(); | |
320 { | |
321 HRESULT hr = pServiceProvider->QueryService(IID_IWebBrowserApp, &m _webBrowser2); | |
322 if (SUCCEEDED(hr)) | |
323 { | |
324 if (m_webBrowser2) | |
325 { | |
326 InitObject(false); | |
327 } | |
328 } | |
329 else | |
330 { | |
331 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE _QUERY_BROWSER, "Class::SetSite - QueryService (IID_IWebBrowserApp)"); | |
332 } | |
333 } | |
334 s_criticalSectionBrowser.Unlock(); | |
335 } | |
336 } | 352 } |
337 else | 353 if (s_instances.empty()) |
338 { | 354 { |
339 DEBUG_ERROR_LOG(hr, PLUGIN_ERROR_SET_SITE, PLUGIN_ERROR_SET_SITE_QUERY _SERVICE_PROVIDER, "Class::SetSite - QueryInterface (service provider)"); | 355 // TODO: Explicitly releasing a resource when a container becomes empt y looks like a job better suited for shared_ptr |
356 CPluginClientFactory::ReleaseMimeFilterClientInstance(); | |
340 } | 357 } |
341 } | 358 } |
342 } | 359 s_criticalSectionLocal.Unlock(); |
343 catch (const std::runtime_error& ex) | |
344 { | |
345 DEBUG_EXCEPTION(ex); | |
346 Unadvice(); | |
347 } | |
348 } | |
349 else | |
350 { | |
351 // Unadvice | |
352 Unadvice(); | |
353 | 360 |
354 // Destroy window | 361 // Release browser interface |
355 if (m_pWndProcStatus) | 362 s_criticalSectionBrowser.Lock(); |
356 { | 363 { |
357 ::SetWindowLongPtr(m_hStatusBarWnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)m_pWndP rocStatus); | 364 m_webBrowser2.Release(); |
Eric
2015/03/06 15:58:04
Explicit release here.
sergei
2015/03/06 16:07:19
So, since `AddRef` is called and `m_webBrowser2` i
Eric
2015/03/06 16:27:22
Calling 'Release' through 'CComPtr' apparently als
| |
365 } | |
366 s_criticalSectionBrowser.Unlock(); | |
358 | 367 |
359 m_pWndProcStatus = NULL; | 368 DEBUG_GENERAL("=========================================================== =====================\nNEW TAB UI - END\n======================================= =========================================") |
369 | |
370 ::CoUninitialize(); | |
360 } | 371 } |
361 | 372 |
362 if (m_hPaneWnd) | 373 IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite); |
363 { | |
364 DestroyWindow(m_hPaneWnd); | |
365 m_hPaneWnd = NULL; | |
366 } | |
367 | |
368 m_hTabWnd = NULL; | |
369 m_hStatusBarWnd = NULL; | |
370 | |
371 // Remove instance from the list, shutdown threads | |
372 HANDLE hMainThread = NULL; | |
373 HANDLE hTabThread = NULL; | |
374 | |
375 s_criticalSectionLocal.Lock(); | |
376 { | |
377 s_instances.erase(this); | |
378 | |
379 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::GetC urrentThreadId()); | |
380 if (it != s_threadInstances.end()) | |
381 { | |
382 s_threadInstances.erase(it); | |
383 } | |
384 if (s_instances.empty()) | |
385 { | |
386 // TODO: Explicitly releasing a resource when a container becomes empty looks like a job better suited for shared_ptr | |
387 CPluginClientFactory::ReleaseMimeFilterClientInstance(); | |
388 } | |
389 } | |
390 s_criticalSectionLocal.Unlock(); | |
391 | |
392 // Release browser interface | |
393 s_criticalSectionBrowser.Lock(); | |
394 { | |
395 m_webBrowser2.Release(); | |
396 } | |
397 s_criticalSectionBrowser.Unlock(); | |
398 | |
399 DEBUG_GENERAL("============================================================= ===================\nNEW TAB UI - END\n========================================= =======================================") | |
400 | |
401 ::CoUninitialize(); | |
402 } | 374 } |
403 | 375 catch (...) |
404 return IObjectWithSiteImpl<CPluginClass>::SetSite(unknownSite); | 376 { |
377 } | |
378 return S_OK; | |
405 } | 379 } |
406 | 380 |
407 bool CPluginClass::IsStatusBarEnabled() | 381 bool CPluginClass::IsStatusBarEnabled() |
408 { | 382 { |
409 DEBUG_GENERAL("IsStatusBarEnabled start"); | 383 DEBUG_GENERAL("IsStatusBarEnabled start"); |
410 HKEY pHkey; | 384 HKEY pHkey; |
411 HKEY pHkeySub; | 385 HKEY pHkeySub; |
412 RegOpenCurrentUser(KEY_QUERY_VALUE, &pHkey); | 386 RegOpenCurrentUser(KEY_QUERY_VALUE, &pHkey); |
413 DWORD truth = 1; | 387 DWORD truth = 1; |
414 DWORD truthSize = sizeof(truth); | 388 DWORD truthSize = sizeof(truth); |
(...skipping 1471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1886 } | 1860 } |
1887 } | 1861 } |
1888 } | 1862 } |
1889 | 1863 |
1890 hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); | 1864 hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); |
1891 } | 1865 } |
1892 | 1866 |
1893 return hTabWnd; | 1867 return hTabWnd; |
1894 | 1868 |
1895 } | 1869 } |
OLD | NEW |