OLD | NEW |
1 #include "PluginStdAfx.h" | 1 #include "PluginStdAfx.h" |
2 | 2 |
3 #include "PluginSettings.h" | 3 #include "PluginSettings.h" |
4 #include "PluginSystem.h" | 4 #include "PluginSystem.h" |
5 #include "PluginFilter.h" | 5 #include "PluginFilter.h" |
6 #include "PluginClientFactory.h" | 6 #include "PluginClientFactory.h" |
7 #include "PluginDictionary.h" | 7 #include "PluginDictionary.h" |
8 #include "PluginHttpRequest.h" | 8 #include "PluginHttpRequest.h" |
9 #include "PluginMutex.h" | 9 #include "PluginMutex.h" |
10 #include "PluginClass.h" | 10 #include "PluginClass.h" |
| 11 #include "PluginUtil.h" |
11 | 12 |
12 #include "AdblockPlusClient.h" | 13 #include "AdblockPlusClient.h" |
13 | 14 |
| 15 namespace |
| 16 { |
| 17 // TODO: GetUserName, pipeName, bufferSize, AutoHandle, ReadMessage, WriteMess
age, MarshalStrings and UnmarshalStrings are |
| 18 // duplicated in AdblockPlusEngine. We should find a way to reuse them. |
| 19 |
| 20 std::wstring GetUserName() |
| 21 { |
| 22 const DWORD maxLength = UNLEN + 1; |
| 23 std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]); |
| 24 DWORD length = maxLength; |
| 25 if (!::GetUserName(buffer.get(), &length)) |
| 26 { |
| 27 std::stringstream stream; |
| 28 stream << "Failed to get the current user's name (Error code: " << GetLast
Error() << ")"; |
| 29 throw std::runtime_error("Failed to get the current user's name"); |
| 30 } |
| 31 return std::wstring(buffer.get(), length); |
| 32 } |
| 33 |
| 34 const std::wstring pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName
(); |
| 35 const int bufferSize = 1024; |
| 36 |
| 37 class AutoHandle |
| 38 { |
| 39 public: |
| 40 AutoHandle() |
| 41 { |
| 42 } |
| 43 |
| 44 AutoHandle(HANDLE handle) : handle(handle) |
| 45 { |
| 46 } |
| 47 |
| 48 ~AutoHandle() |
| 49 { |
| 50 CloseHandle(handle); |
| 51 } |
| 52 |
| 53 HANDLE get() |
| 54 { |
| 55 return handle; |
| 56 } |
| 57 |
| 58 private: |
| 59 HANDLE handle; |
| 60 |
| 61 AutoHandle(const AutoHandle& autoHandle); |
| 62 AutoHandle& operator=(const AutoHandle& autoHandle); |
| 63 }; |
| 64 |
| 65 std::string MarshalStrings(const std::vector<std::string>& strings) |
| 66 { |
| 67 // TODO: This is some pretty hacky marshalling, replace it with something mo
re robust |
| 68 std::string marshalledStrings; |
| 69 for (std::vector<std::string>::const_iterator it = strings.begin(); it != st
rings.end(); it++) |
| 70 marshalledStrings += *it + ';'; |
| 71 return marshalledStrings; |
| 72 } |
| 73 |
| 74 std::vector<std::string> UnmarshalStrings(const std::string& message) |
| 75 { |
| 76 std::stringstream stream(message); |
| 77 std::vector<std::string> strings; |
| 78 std::string string; |
| 79 while (std::getline(stream, string, ';')) |
| 80 strings.push_back(string); |
| 81 return strings; |
| 82 } |
| 83 |
| 84 std::string ReadMessage(HANDLE pipe) |
| 85 { |
| 86 std::stringstream stream; |
| 87 std::auto_ptr<char> buffer(new char[bufferSize]); |
| 88 bool doneReading = false; |
| 89 while (!doneReading) |
| 90 { |
| 91 DWORD bytesRead; |
| 92 if (ReadFile(pipe, buffer.get(), bufferSize * sizeof(char), &bytesRead, 0)
) |
| 93 doneReading = true; |
| 94 else if (GetLastError() != ERROR_MORE_DATA) |
| 95 { |
| 96 std::stringstream stream; |
| 97 stream << "Error reading from pipe: " << GetLastError(); |
| 98 throw std::runtime_error(stream.str()); |
| 99 } |
| 100 stream << std::string(buffer.get(), bytesRead); |
| 101 } |
| 102 return stream.str(); |
| 103 } |
| 104 |
| 105 void WriteMessage(HANDLE pipe, const std::string& message) |
| 106 { |
| 107 DWORD bytesWritten; |
| 108 if (!WriteFile(pipe, message.c_str(), message.length(), &bytesWritten, 0)) |
| 109 throw std::runtime_error("Failed to write to pipe"); |
| 110 } |
| 111 |
| 112 HANDLE OpenPipe(const std::wstring& name) |
| 113 { |
| 114 if (WaitNamedPipe(name.c_str(), 5000)) |
| 115 return CreateFile(name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_E
XISTING, 0, 0); |
| 116 return INVALID_HANDLE_VALUE; |
| 117 } |
| 118 |
| 119 void SpawnAdblockPlusEngine() |
| 120 { |
| 121 std::wstring engineExecutablePath = DllDir() + L"AdblockPlusEngine.exe"; |
| 122 STARTUPINFO startupInfo = {}; |
| 123 PROCESS_INFORMATION processInformation = {}; |
| 124 |
| 125 HANDLE token; |
| 126 OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT
| TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token); |
| 127 HANDLE newToken; |
| 128 DuplicateTokenEx(token, 0, 0, SecurityImpersonation, TokenPrimary, &newToken
); |
| 129 |
| 130 if (!CreateProcessAsUser(newToken, 0, const_cast<wchar_t*>(engineExecutableP
ath.c_str()), 0, 0, 0, 0, 0, 0, |
| 131 &startupInfo, &processInformation)) |
| 132 { |
| 133 DWORD error = GetLastError(); |
| 134 throw std::runtime_error("Failed to start Adblock Plus Engine"); |
| 135 } |
| 136 |
| 137 CloseHandle(processInformation.hProcess); |
| 138 CloseHandle(processInformation.hThread); |
| 139 } |
| 140 |
| 141 HANDLE OpenAdblockPlusEnginePipe() |
| 142 { |
| 143 try |
| 144 { |
| 145 HANDLE pipe = OpenPipe(pipeName); |
| 146 if (pipe == INVALID_HANDLE_VALUE) |
| 147 { |
| 148 SpawnAdblockPlusEngine(); |
| 149 |
| 150 int timeout = 10000; |
| 151 while ((pipe = OpenPipe(pipeName)) == INVALID_HANDLE_VALUE) |
| 152 { |
| 153 const int step = 10; |
| 154 Sleep(step); |
| 155 timeout -= step; |
| 156 if (timeout <= 0) |
| 157 throw std::runtime_error("Unable to open Adblock Plus Engine pipe"); |
| 158 } |
| 159 } |
| 160 |
| 161 DWORD mode = PIPE_READMODE_MESSAGE; |
| 162 if (!SetNamedPipeHandleState(pipe, &mode, 0, 0)) |
| 163 throw std::runtime_error("SetNamedPipeHandleState failed"); |
| 164 |
| 165 return pipe; |
| 166 } |
| 167 catch(std::exception e) |
| 168 { |
| 169 DEBUG_GENERAL(e.what()); |
| 170 return INVALID_HANDLE_VALUE; |
| 171 } |
| 172 } |
| 173 } |
14 | 174 |
15 CAdblockPlusClient* CAdblockPlusClient::s_instance = NULL; | 175 CAdblockPlusClient* CAdblockPlusClient::s_instance = NULL; |
16 | 176 |
17 | |
18 CAdblockPlusClient::CAdblockPlusClient() : CPluginClientBase() | 177 CAdblockPlusClient::CAdblockPlusClient() : CPluginClientBase() |
19 { | 178 { |
20 try | 179 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter()); |
21 { | 180 } |
22 DEBUG_GENERAL("Building client"); | |
23 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter()); | |
24 AdblockPlus::AppInfo appInfo; | |
25 appInfo.name = "adblockplusie"; | |
26 appInfo.version = CT2CA(_T(IEPLUGIN_VERSION), CP_UTF8); | |
27 appInfo.platform = "msie"; | |
28 | |
29 DEBUG_GENERAL(L"Building engine"); | |
30 | 181 |
31 JsEnginePtr jsEngine(AdblockPlus::JsEngine::New(appInfo)); | |
32 filterEngine = std::auto_ptr<AdblockPlus::FilterEngine>(new AdblockPlus::Fil
terEngine(jsEngine)); | |
33 | |
34 } | |
35 catch(std::exception ex) | |
36 { | |
37 DEBUG_GENERAL(ex.what()); | |
38 } | |
39 } | |
40 CAdblockPlusClient::~CAdblockPlusClient() | 182 CAdblockPlusClient::~CAdblockPlusClient() |
41 { | 183 { |
42 s_instance = NULL; | 184 s_instance = NULL; |
43 } | 185 } |
44 | 186 |
45 | 187 |
46 CAdblockPlusClient* CAdblockPlusClient::GetInstance() | 188 CAdblockPlusClient* CAdblockPlusClient::GetInstance() |
47 { | 189 { |
48 CAdblockPlusClient* instance = NULL; | 190 CAdblockPlusClient* instance = NULL; |
49 | 191 |
50 s_criticalSectionLocal.Lock(); | 192 s_criticalSectionLocal.Lock(); |
51 { | 193 { |
52 if (!s_instance) | 194 if (!s_instance) |
53 { | 195 { |
54 CAdblockPlusClient* client = new CAdblockPlusClient(); | 196 CAdblockPlusClient* client = new CAdblockPlusClient(); |
55 | 197 |
56 s_instance = client; | 198 s_instance = client; |
57 } | 199 } |
58 | 200 |
59 instance = s_instance; | 201 instance = s_instance; |
60 } | 202 } |
61 s_criticalSectionLocal.Unlock(); | 203 s_criticalSectionLocal.Unlock(); |
62 | 204 |
63 return instance; | 205 return instance; |
64 } | 206 } |
65 | 207 |
66 AdblockPlus::FilterEngine* CAdblockPlusClient::GetFilterEngine() | |
67 { | |
68 return filterEngine.get(); | |
69 } | |
70 | 208 |
71 bool CAdblockPlusClient::ShouldBlock(CString src, int contentType, const CString
& domain, bool addDebug) | 209 bool CAdblockPlusClient::ShouldBlock(CString src, int contentType, const CString
& domain, bool addDebug) |
72 { | 210 { |
73 bool isBlocked = false; | 211 bool isBlocked = false; |
74 | 212 |
75 bool isCached = false; | 213 bool isCached = false; |
76 | 214 |
77 CPluginSettings* settings = CPluginSettings::GetInstance(); | 215 CPluginSettings* settings = CPluginSettings::GetInstance(); |
78 | 216 |
79 m_criticalSectionCache.Lock(); | 217 m_criticalSectionCache.Lock(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 BYTE version[50]; | 294 BYTE version[50]; |
157 cbData = 50; | 295 cbData = 50; |
158 status = RegQueryValueEx(hKey, L"Version", NULL, &type, (BYTE*)version, &cbDat
a); | 296 status = RegQueryValueEx(hKey, L"Version", NULL, &type, (BYTE*)version, &cbDat
a); |
159 if (status != 0) | 297 if (status != 0) |
160 { | 298 { |
161 return 0; | 299 return 0; |
162 } | 300 } |
163 RegCloseKey(hKey); | 301 RegCloseKey(hKey); |
164 return (int)(version[0] - 48); | 302 return (int)(version[0] - 48); |
165 } | 303 } |
| 304 |
| 305 std::string CallAdblockPlusEngineProcedure(const std::vector<std::string>& args) |
| 306 { |
| 307 AutoHandle pipe(OpenAdblockPlusEnginePipe()); |
| 308 WriteMessage(pipe.get(), MarshalStrings(args)); |
| 309 return ReadMessage(pipe.get()); |
| 310 } |
| 311 |
| 312 bool CAdblockPlusClient::Matches(const std::string& url, const std::string& cont
entType, const std::string& domain) |
| 313 { |
| 314 std::vector<std::string> args; |
| 315 args.push_back("Matches"); |
| 316 args.push_back(url); |
| 317 args.push_back(contentType); |
| 318 args.push_back(domain); |
| 319 |
| 320 try |
| 321 { |
| 322 std::string response = CallAdblockPlusEngineProcedure(args); |
| 323 return response == "1"; |
| 324 } |
| 325 catch (const std::exception& e) |
| 326 { |
| 327 DEBUG_GENERAL(e.what()); |
| 328 return false; |
| 329 } |
| 330 } |
| 331 |
| 332 std::vector<std::string> CAdblockPlusClient::GetElementHidingSelectors(std::stri
ng domain) |
| 333 { |
| 334 std::vector<std::string> args; |
| 335 args.push_back("GetElementHidingSelectors"); |
| 336 args.push_back(domain); |
| 337 |
| 338 try |
| 339 { |
| 340 std::string response = CallAdblockPlusEngineProcedure(args); |
| 341 return UnmarshalStrings(response); |
| 342 } |
| 343 catch (const std::exception& e) |
| 344 { |
| 345 DEBUG_GENERAL(e.what()); |
| 346 return std::vector<std::string>(); |
| 347 } |
| 348 } |
| 349 |
| 350 std::vector<AdblockPlus::SubscriptionPtr> CAdblockPlusClient::FetchAvailableSubs
criptions() |
| 351 { |
| 352 //TODO: implement this |
| 353 return std::vector<AdblockPlus::SubscriptionPtr>(); |
| 354 } |
| 355 |
| 356 std::vector<AdblockPlus::FilterPtr> CAdblockPlusClient::GetListedFilters() |
| 357 { |
| 358 //TODO: implement this |
| 359 return std::vector<AdblockPlus::FilterPtr>(); |
| 360 } |
| 361 |
| 362 AdblockPlus::FilterPtr CAdblockPlusClient::GetFilter(std::string text) |
| 363 { |
| 364 //TODO: implement this |
| 365 return AdblockPlus::FilterPtr(); |
| 366 } |
| 367 |
| 368 std::vector<AdblockPlus::SubscriptionPtr> CAdblockPlusClient::GetListedSubscript
ions() |
| 369 { |
| 370 //TODO: implement this |
| 371 return std::vector<AdblockPlus::SubscriptionPtr>(); |
| 372 } |
| 373 |
| 374 AdblockPlus::SubscriptionPtr CAdblockPlusClient::GetSubscription(std::string url
) |
| 375 { |
| 376 //TODO: imlement this |
| 377 return AdblockPlus::SubscriptionPtr(); |
| 378 } |
OLD | NEW |