Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: src/engine/Main.cpp

Issue 5447868882092032: Issue 1793 - check whether the frame is whitelisted before injecting CSS (Closed)
Left Patch Set: update Created Jan. 13, 2015, 3:20 p.m.
Right Patch Set: rebase and rename webBrowser to parentBrowser Created Nov. 30, 2015, 3:27 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/plugin/AdblockPlusClient.h » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH
4 *
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
7 * published by the Free Software Foundation.
8 *
9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #pragma comment(linker,"\"/manifestdependency:type='win32' \
19 name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
20 processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
21
1 #include <AdblockPlus.h> 22 #include <AdblockPlus.h>
2 #include <functional> 23 #include <functional>
3 #include <vector> 24 #include <vector>
25 #include <deque>
4 #include <thread> 26 #include <thread>
27 #include <mutex>
28 #include <condition_variable>
5 #include <Windows.h> 29 #include <Windows.h>
6 30
7 #include "../shared/AutoHandle.h" 31 #include "../shared/AutoHandle.h"
8 #include "../shared/Communication.h" 32 #include "../shared/Communication.h"
9 #include "../shared/Dictionary.h" 33 #include "../shared/Dictionary.h"
10 #include "../shared/Utils.h" 34 #include "../shared/Utils.h"
11 #include "../shared/Version.h" 35 #include "../shared/Version.h"
12 #include "../shared/CriticalSection.h" 36 #include "../shared/CriticalSection.h"
13 #include "../shared/IE_version.h" 37 #include "IeVersion.h"
14 #include "AdblockPlus.h" 38 #include "AdblockPlus.h"
15 #include "Debug.h" 39 #include "Debug.h"
16 #include "Updater.h" 40 #include "Updater.h"
41 #include "Registry.h"
42 #include "NotificationWindow.h"
17 43
18 namespace 44 namespace
19 { 45 {
46 struct ScopedAtlAxInitializer
47 {
48 ScopedAtlAxInitializer()
49 {
50 ATL::AtlAxWinInit();
51 }
52 ~ScopedAtlAxInitializer()
53 {
54 ATL::AtlAxWinTerm();
55 }
56 };
57
58 class ABPAtlModule : public ATL::CAtlExeModuleT<ABPAtlModule>
59 {
60 enum CustomMessages
61 {
62 TASK_POSTED = WM_USER + 1
63 };
64
65 public:
66 ABPAtlModule() : m_msgHWnd(nullptr)
67 {
68 }
69 void Finalize();
70 HRESULT PreMessageLoop(int showCmd) throw();
71 void RunMessageLoop() throw();
72 static HRESULT InitializeCom() throw()
73 {
74 // The default implementation initializes multithreaded version but
75 // in this case hosted ActiveX does not properly work.
76 return CoInitialize(nullptr);
77 }
78 private:
79 void onNewNotification(const AdblockPlus::NotificationPtr& notification);
80 void DispatchTask(std::function<void()>&& task);
81 void ProcessTasks();
82
83 ScopedAtlAxInitializer m_scopedAtlAxInit;
84 HWND m_msgHWnd;
85 std::recursive_mutex m_tasksMutex;
86 std::deque<std::function<void()>> m_tasks;
87 std::unique_ptr<NotificationBorderWindow> m_notificationWindow;
88 } _AtlModule;
89
20 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine; 90 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine;
21 std::auto_ptr<Updater> updater; 91 std::auto_ptr<Updater> updater;
22 int activeConnections = 0; 92 int activeConnections = 0;
23 CriticalSection activeConnectionsLock; 93 CriticalSection activeConnectionsLock;
24 HWND callbackWindow; 94 HWND callbackWindow;
25 95
26 bool IsWhitelisted(const std::string& urlArg, 96 // it's a helper for the function below.
27 const std::vector<std::string>& frameHierarchy, const std::string& type) 97 std::string GetWhitelistingFilter(const std::string& url, const std::string& p arent, AdblockPlus::FilterEngine::ContentType type)
28 { 98 {
29 auto IsWhitelisted = [&type](const std::string& url, const std::string& pare nt)->bool 99 AdblockPlus::FilterPtr match = filterEngine->Matches(url, type, parent);
30 { 100 if (match && match->GetType() == AdblockPlus::Filter::TYPE_EXCEPTION)
31 AdblockPlus::FilterPtr match = filterEngine->Matches(url, type, parent); 101 {
32 return match && match->GetType() == AdblockPlus::Filter::TYPE_EXCEPTION; 102 return match->GetProperty("text")->AsString();
33 }; 103 }
34 bool isWhitelisted = false; 104 return "";
Eric 2015/01/13 19:52:52 I dislike identifiers that differ only in capitali
sergei 2015/04/13 08:06:41 fixed
105 };
106
107 std::string GetWhitelistingFilter(const std::string& urlArg,
108 const std::vector<std::string>& frameHierarchy, AdblockPlus::FilterEngine::C ontentType type)
109 {
35 if (frameHierarchy.empty()) 110 if (frameHierarchy.empty())
36 { 111 {
37 isWhitelisted = IsWhitelisted(urlArg, ""); 112 return GetWhitelistingFilter(urlArg, "", type);
Eric 2015/01/13 19:52:52 We can simply return here and skip the subsequent
sergei 2015/04/13 08:06:41 fixed
38 } 113 }
39 else 114 auto frameIterator = frameHierarchy.begin();
40 { 115 std::string url = urlArg;
41 auto frame_ii = frameHierarchy.begin(); 116 do
Eric 2015/01/13 19:52:52 As much as I prefer underscores, ABP doesn't use t
sergei 2015/04/13 08:06:41 fixed
42 std::string parentUrl; 117 {
43 std::string url = urlArg; 118 std::string parentUrl = *frameIterator++;
44 while (!isWhitelisted && frame_ii != frameHierarchy.end()) 119 auto filterText = GetWhitelistingFilter(url, parentUrl, type);
Eric 2015/01/13 19:52:52 We only need the second term here.
sergei 2015/04/13 08:06:41 fixed
45 { 120 if (!filterText.empty())
46 parentUrl = *frame_ii; 121 {
47 isWhitelisted = IsWhitelisted(url, parentUrl); 122 return filterText;
Eric 2015/01/13 19:52:52 if (IsWhitelisted(...)) return true;
sergei 2015/04/13 08:06:41 fixed
48 url = parentUrl; 123 }
49 ++frame_ii; 124 url = parentUrl;
50 } 125 }
Eric 2015/01/13 19:52:52 Just return false if the loop terminates having re
sergei 2015/04/13 08:06:41 fixed
51 } 126 while (frameIterator != frameHierarchy.end());
52 return isWhitelisted; 127 return "";
53 }
54
55 void WriteStrings(Communication::OutputBuffer& response,
56 const std::vector<std::string>& strings)
57 {
58 int32_t count = static_cast<int32_t>(strings.size());
59 response << count;
60 for (int32_t i = 0; i < count; i++)
61 response << strings[i];
62 } 128 }
63 129
64 void WriteSubscriptions(Communication::OutputBuffer& response, 130 void WriteSubscriptions(Communication::OutputBuffer& response,
65 const std::vector<AdblockPlus::SubscriptionPtr>& subscriptions) 131 const std::vector<AdblockPlus::SubscriptionPtr>& subscriptions)
66 { 132 {
67 int32_t count = static_cast<int32_t>(subscriptions.size()); 133 int32_t count = static_cast<int32_t>(subscriptions.size());
68 response << count; 134 response << count;
69 for (int32_t i = 0; i < count; i++) 135 for (int32_t i = 0; i < count; i++)
70 { 136 {
71 AdblockPlus::SubscriptionPtr subscription = subscriptions[i]; 137 AdblockPlus::SubscriptionPtr subscription = subscriptions[i];
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 { 177 {
112 Communication::OutputBuffer response; 178 Communication::OutputBuffer response;
113 179
114 Communication::ProcType procedure; 180 Communication::ProcType procedure;
115 request >> procedure; 181 request >> procedure;
116 switch (procedure) 182 switch (procedure)
117 { 183 {
118 case Communication::PROC_MATCHES: 184 case Communication::PROC_MATCHES:
119 { 185 {
120 std::string url; 186 std::string url;
121 std::string type; 187 using namespace AdblockPlus;
122 std::string documentUrl; 188 std::string documentUrl;
189 int32_t type;
123 request >> url >> type >> documentUrl; 190 request >> url >> type >> documentUrl;
124 referrerMapping.Add(url, documentUrl); 191 referrerMapping.Add(url, documentUrl);
125 AdblockPlus::FilterPtr filter = filterEngine->Matches(url, type, referre rMapping.BuildReferrerChain(documentUrl)); 192 auto contentType = static_cast<FilterEngine::ContentType>(type);
126 response << (filter && filter->GetType() != AdblockPlus::Filter::TYPE_EX CEPTION); 193 FilterPtr filter = filterEngine->Matches(url, contentType, referrerMappi ng.BuildReferrerChain(documentUrl));
194 response << (filter && filter->GetType() != Filter::TYPE_EXCEPTION);
127 break; 195 break;
128 } 196 }
129 case Communication::PROC_GET_ELEMHIDE_SELECTORS: 197 case Communication::PROC_GET_ELEMHIDE_SELECTORS:
130 { 198 {
131 std::string domain; 199 std::string domain;
132 request >> domain; 200 request >> domain;
133 WriteStrings(response, filterEngine->GetElementHidingSelectors(domain)); 201 response << filterEngine->GetElementHidingSelectors(domain);
134 break; 202 break;
135 } 203 }
136 case Communication::PROC_AVAILABLE_SUBSCRIPTIONS: 204 case Communication::PROC_AVAILABLE_SUBSCRIPTIONS:
137 { 205 {
138 WriteSubscriptions(response, filterEngine->FetchAvailableSubscriptions() ); 206 WriteSubscriptions(response, filterEngine->FetchAvailableSubscriptions() );
139 break; 207 break;
140 } 208 }
141 case Communication::PROC_LISTED_SUBSCRIPTIONS: 209 case Communication::PROC_LISTED_SUBSCRIPTIONS:
142 { 210 {
143 WriteSubscriptions(response, filterEngine->GetListedSubscriptions()); 211 WriteSubscriptions(response, filterEngine->GetListedSubscriptions());
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 const size_t prefixLen = strlen(prefix); 276 const size_t prefixLen = strlen(prefix);
209 const size_t suffixLen = strlen(suffix); 277 const size_t suffixLen = strlen(suffix);
210 if (!text.compare(0, prefixLen, prefix) && 278 if (!text.compare(0, prefixLen, prefix) &&
211 !text.compare(text.size() - suffixLen, suffixLen, suffix)) 279 !text.compare(text.size() - suffixLen, suffixLen, suffix))
212 { 280 {
213 domains.push_back(text.substr(prefixLen, text.size() - prefixLen - suffixLen)); 281 domains.push_back(text.substr(prefixLen, text.size() - prefixLen - suffixLen));
214 } 282 }
215 } 283 }
216 } 284 }
217 285
218 WriteStrings(response, domains); 286 response << domains;
219 break; 287 break;
220 } 288 }
221 case Communication::PROC_IS_WHITELISTED_URL: 289 case Communication::PROC_GET_WHITELISTING_FITER:
222 { 290 {
223 std::string url; 291 std::string url;
224 request >> url; 292 request >> url;
225 std::vector<std::string> frameHierarchy; 293 std::vector<std::string> frameHierarchy;
226 request >> frameHierarchy; 294 request >> frameHierarchy;
227 response << IsWhitelisted(url, frameHierarchy, "DOCUMENT");; 295 response << GetWhitelistingFilter(url, frameHierarchy, AdblockPlus::Filt erEngine::CONTENT_TYPE_DOCUMENT);
228 break; 296 break;
229 } 297 }
230 case Communication::PROC_IS_ELEMHIDE_WHITELISTED_ON_URL: 298 case Communication::PROC_IS_ELEMHIDE_WHITELISTED_ON_URL:
231 { 299 {
232 std::string url; 300 std::string url;
233 request >> url; 301 request >> url;
234 std::vector<std::string> frameHierarchy; 302 std::vector<std::string> frameHierarchy;
235 request >> frameHierarchy; 303 request >> frameHierarchy;
236 response << IsWhitelisted(url, frameHierarchy, "ELEMHIDE"); 304 response << !GetWhitelistingFilter(url, frameHierarchy, AdblockPlus::Fil terEngine::CONTENT_TYPE_ELEMHIDE).empty();
237 break; 305 break;
238 } 306 }
239 case Communication::PROC_ADD_FILTER: 307 case Communication::PROC_ADD_FILTER:
240 { 308 {
241 std::string text; 309 std::string text;
242 request >> text; 310 request >> text;
243 311
244 filterEngine->GetFilter(text)->AddToList(); 312 filterEngine->GetFilter(text)->AddToList();
245 break; 313 break;
246 } 314 }
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 486
419 Debug("Client disconnected " + threadString); 487 Debug("Client disconnected " + threadString);
420 488
421 { 489 {
422 CriticalSection::Lock lock(activeConnectionsLock); 490 CriticalSection::Lock lock(activeConnectionsLock);
423 activeConnections--; 491 activeConnections--;
424 if (activeConnections < 1) 492 if (activeConnections < 1)
425 { 493 {
426 Debug("No connections left, shutting down the engine"); 494 Debug("No connections left, shutting down the engine");
427 activeConnections = 0; 495 activeConnections = 0;
496
497 // The following exit(0) calls the destructor of _AtlModule from the
498 // current thread which results in the disaster because there is a
499 // running message loop as well as there can be alive notification
500 // window which holds v8::Value as well as m_tasks can hold v8::Value
501 // but JS Engine is destroyed before _AtlModule. BTW, various free
502 // running threads like Timeout also cause the crash because the engine
503 // is already destroyed.
504 _AtlModule.Finalize();
428 exit(0); 505 exit(0);
429 } 506 }
430 } 507 }
431 508
432 } 509 }
433 510
434 void OnUpdateAvailable(AdblockPlus::JsValueList& params) 511 void OnUpdateAvailable(AdblockPlus::JsValueList& params)
435 { 512 {
436 if (params.size() < 1) 513 if (params.size() < 1)
437 { 514 {
438 Debug("updateAvailable event missing URL"); 515 Debug("updateAvailable event missing URL");
439 return; 516 return;
440 } 517 }
441 updateAvailable = true; 518 updateAvailable = true;
442 519
443 updater->Update(params[0]->AsString()); 520 updater->Update(params[0]->AsString());
444 } 521 }
445 } 522
523 std::wstring PreconfigurationValueFromRegistry(const std::wstring& preconfigNa me)
524 {
525 try
526 {
527 AdblockPlus::RegistryKey regKey(HKEY_CURRENT_USER, L"Software\\AdblockPlus ");
528 return regKey.value_wstring(preconfigName);
529 }
530 catch (const std::runtime_error&)
531 {
532 return L"";
533 }
534 }
446 535
447 std::auto_ptr<AdblockPlus::FilterEngine> CreateFilterEngine(const std::wstring& locale) 536 std::auto_ptr<AdblockPlus::FilterEngine> CreateFilterEngine(const std::wstring& locale)
448 { 537 {
449 AdblockPlus::AppInfo appInfo; 538 AdblockPlus::AppInfo appInfo;
450 appInfo.version = ToUtf8String(IEPLUGIN_VERSION); 539 appInfo.version = ToUtf8String(IEPLUGIN_VERSION);
451 appInfo.name = "adblockplusie"; 540 appInfo.name = "adblockplusie";
452 #ifdef _WIN64 541 #ifdef _WIN64
453 appInfo.application = "msie64"; 542 appInfo.application = "msie64";
454 #else 543 #else
455 appInfo.application = "msie32"; 544 appInfo.application = "msie32";
456 #endif 545 #endif
457 appInfo.applicationVersion = ToUtf8String(AdblockPlus::IE::InstalledVersionStr ing()); 546 appInfo.applicationVersion = ToUtf8String(AdblockPlus::IE::InstalledVersionStr ing());
458 appInfo.locale = ToUtf8String(locale); 547 appInfo.locale = ToUtf8String(locale);
459 #ifdef ADBLOCK_PLUS_TEST_MODE 548 #ifdef ADBLOCK_PLUS_TEST_MODE
460 appInfo.developmentBuild = true; 549 appInfo.developmentBuild = true;
461 #else 550 #else
462 appInfo.developmentBuild = false; 551 appInfo.developmentBuild = false;
463 #endif 552 #endif
464 553
465 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::New(appInfo); 554 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::New(appInfo);
466 jsEngine->SetEventCallback("updateAvailable", &OnUpdateAvailable); 555 jsEngine->SetEventCallback("updateAvailable", &OnUpdateAvailable);
467 556
468 std::string dataPath = ToUtf8String(GetAppDataPath()); 557 std::string dataPath = ToUtf8String(GetAppDataPath());
469 dynamic_cast<AdblockPlus::DefaultFileSystem*>(jsEngine->GetFileSystem().get()) ->SetBasePath(dataPath); 558 dynamic_cast<AdblockPlus::DefaultFileSystem*>(jsEngine->GetFileSystem().get()) ->SetBasePath(dataPath);
470 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine(new AdblockPlus::FilterE ngine(jsEngine)); 559 std::map<std::string, AdblockPlus::JsValuePtr> preconfig;
560 preconfig["disable_auto_updates"] = jsEngine->NewValue(
561 PreconfigurationValueFromRegistry(L"disable_auto_updates") == L"true");
562 preconfig["suppress_first_run_page"] = jsEngine->NewValue(
563 PreconfigurationValueFromRegistry(L"suppress_first_run_page") == L"true");
564 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine(new AdblockPlus::FilterE ngine(jsEngine, preconfig));
471 return filterEngine; 565 return filterEngine;
472 } 566 }
473 567
474 int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 568 void ABPAtlModule::Finalize()
569 {
570 std::condition_variable cv;
571 std::mutex cvMutex;
572 std::unique_lock<std::mutex> lock(cvMutex);
573 DispatchTask([&cvMutex, &cv, this]
574 {
575 if (m_notificationWindow)
576 {
577 m_notificationWindow->SendMessage(WM_CLOSE);
578 }
579 SendMessage(m_msgHWnd, WM_QUIT, 0, 0);
580 {
581 std::lock_guard<std::recursive_mutex> lock(m_tasksMutex);
582 m_tasks.clear();
583 }
584 std::unique_lock<std::mutex> lock(cvMutex);
585 cv.notify_one();
586 });
587 cv.wait(lock);
588 }
589
590 HRESULT ABPAtlModule::PreMessageLoop(int showCmd) throw()
591 {
592 const std::wstring className = L"ABPEngineMessageWindow";
593 WNDCLASS wc;
594 wc.style = 0;
595 wc.lpfnWndProc = DefWindowProcW;
596 wc.cbClsExtra = 0;
597 wc.cbWndExtra = 0;
598 wc.hInstance = ATL::_AtlBaseModule.GetModuleInstance();
599 wc.hIcon = nullptr;
600 wc.hCursor = nullptr;
601 wc.hbrBackground = nullptr;
602 wc.lpszMenuName = nullptr;
603 wc.lpszClassName = className.c_str();
604 ATOM atom = RegisterClass(&wc);
605 if (!atom)
606 {
607 DebugLastError("Cannot register class for message only window");
608 return E_FAIL;
609 }
610 m_msgHWnd = CreateWindowW(className.c_str(),
611 nullptr, // window name
612 0, // style
613 0, 0, 0, 0, // geometry (x, y, w, h)
614 HWND_MESSAGE, // parent
615 nullptr, // menu handle
616 wc.hInstance,
617 0); // windows creation data.
618 if (!m_msgHWnd)
619 {
620 DebugLastError("Cannot create message only window");
621 return E_FAIL;
622 }
623
624 filterEngine->SetShowNotificationCallback([this](const AdblockPlus::Notificati onPtr& notification)
625 {
626 if (!notification)
627 {
628 return;
629 }
630 DispatchTask([notification, this]
631 {
632 onNewNotification(notification);
633 });
634 });
635
636 HRESULT retValue = __super::PreMessageLoop(showCmd);
637 // __super::PreMessageLoop returns S_FALSE because there is nothing to
638 // register but S_OK is required to run message loop.
639 return FAILED(retValue) ? retValue : S_OK;
640 }
641
642 void ABPAtlModule::RunMessageLoop() throw()
643 {
644 MSG msg = {};
645 while (GetMessage(&msg, /*hwnd*/nullptr, /*msgFilterMin*/0, /*msgFilterMax*/0) )
646 {
647 if (msg.hwnd == m_msgHWnd && msg.message == CustomMessages::TASK_POSTED)
648 {
649 ProcessTasks();
650 }
651 TranslateMessage(&msg);
652 DispatchMessage(&msg);
653 }
654 }
655
656 void ABPAtlModule::onNewNotification(const AdblockPlus::NotificationPtr& notific ation)
657 {
658 m_notificationWindow.reset(new NotificationBorderWindow(*notification, GetExeD ir() + L"html\\templates\\"));
659 m_notificationWindow->SetOnDestroyed([notification, this]
660 {
661 notification->MarkAsShown();
662 m_notificationWindow.reset();
663 });
664 m_notificationWindow->SetOnLinkClicked([](const std::wstring& url)
665 {
666 ATL::CComPtr<IWebBrowser2> webBrowser;
667 if (SUCCEEDED(webBrowser.CoCreateInstance(__uuidof(InternetExplorer))) && we bBrowser)
668 {
669 ATL::CComVariant emptyVariant;
670 webBrowser->Navigate(ATL::CComBSTR(url.c_str()), &emptyVariant, &emptyVari ant, &emptyVariant, &emptyVariant);
671 webBrowser->put_Visible(VARIANT_TRUE);
672 }
673 });
674 m_notificationWindow->Create(/*parent window*/nullptr);
675 if (m_notificationWindow->operator HWND() != nullptr)
676 {
677 m_notificationWindow->ShowWindow(SW_SHOWNOACTIVATE);
678 m_notificationWindow->UpdateWindow();
679 }
680 }
681
682 void ABPAtlModule::DispatchTask(std::function<void()>&& task)
683 {
684 {
685 std::lock_guard<std::recursive_mutex> lock(m_tasksMutex);
686 m_tasks.emplace_back(std::move(task));
687 }
688 PostMessageW(m_msgHWnd, CustomMessages::TASK_POSTED, 0, 0);
689 }
690
691 void ABPAtlModule::ProcessTasks()
692 {
693 std::lock_guard<std::recursive_mutex> lock(m_tasksMutex);
694 while(!m_tasks.empty())
695 {
696 auto task = *m_tasks.begin();
697 m_tasks.pop_front();
698 if (task)
699 task();
700 }
701 }
702
703 } // namespace {
704
705 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int cmdShow)
475 { 706 {
476 AutoHandle mutex(CreateMutexW(0, false, L"AdblockPlusEngine")); 707 AutoHandle mutex(CreateMutexW(0, false, L"AdblockPlusEngine"));
477 if (!mutex) 708 if (!mutex)
478 { 709 {
479 DebugLastError("CreateMutex failed"); 710 DebugLastError("CreateMutex failed");
480 return 1; 711 return 1;
481 } 712 }
482 713
483 if (GetLastError() == ERROR_ALREADY_EXISTS) 714 if (GetLastError() == ERROR_ALREADY_EXISTS)
484 { 715 {
485 DebugLastError("Named pipe exists, another engine instance appears to be run ning"); 716 DebugLastError("Named pipe exists, another engine instance appears to be run ning");
486 return 1; 717 return 1;
487 } 718 }
488 719
489 int argc; 720 int argc;
490 LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc); 721 LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
491 std::wstring locale(argc >= 2 ? argv[1] : L""); 722 std::wstring locale(argc >= 2 ? argv[1] : L"");
492 LocalFree(argv); 723 LocalFree(argv);
493 Dictionary::Create(locale); 724 Dictionary::Create(locale);
494 filterEngine = CreateFilterEngine(locale); 725 filterEngine = CreateFilterEngine(locale);
495 updater.reset(new Updater(filterEngine->GetJsEngine())); 726 updater.reset(new Updater(filterEngine->GetJsEngine()));
496 727
497 for (;;) 728 std::thread communicationThread([]
498 { 729 {
499 try 730 for (;;)
500 { 731 {
501 auto pipe = std::make_shared<Communication::Pipe>(Communication::pipeName, Communication::Pipe::MODE_CREATE); 732 try
502 733 {
503 // TODO: we should wait for the finishing of the thread before exiting fro m this function. 734 auto pipe = std::make_shared<Communication::Pipe>(Communication::pipeNam e, Communication::Pipe::MODE_CREATE);
504 // It works now in most cases because the browser waits for the response i n the pipe, and the 735
505 // thread has time to finish while this response is being processed and th e browser is 736 // TODO: we should wait for the finishing of the thread before exiting f rom this function.
506 // disposing all its stuff. 737 // It works now in most cases because the browser waits for the response in the pipe, and the
507 std::thread([pipe]() 738 // thread has time to finish while this response is being processed and the browser is
508 { 739 // disposing all its stuff.
509 ClientThread(pipe.get()); 740 std::thread([pipe]()
510 }).detach(); 741 {
511 } 742 ClientThread(pipe.get());
512 catch(const std::system_error& ex) 743 }).detach();
513 { 744 }
514 DebugException(ex); 745 catch(const std::system_error& ex)
515 return 1; 746 {
516 } 747 DebugException(ex);
517 catch (const std::runtime_error& e) 748 return 1;
518 { 749 }
519 DebugException(e); 750 catch (const std::runtime_error& e)
520 return 1; 751 {
521 } 752 DebugException(e);
522 } 753 return 1;
523 754 }
524 return 0; 755 }
756 });
757
758 int retValue = _AtlModule.WinMain(cmdShow);
759 if (communicationThread.joinable())
760 {
761 communicationThread.join();
762 }
763
764 return retValue;
525 } 765 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld