Left: | ||
Right: |
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: pipeName, bufferSize, AutoHandle, ReadMessage, WriteMessage, MarshalS trings and UnmarshalStrings are | |
18 // duplicated in AdblockPlusEngine. We should find a way to reuse them. | |
19 | |
20 const std::wstring pipeName = L"\\\\.\\pipe\\adblockplusengine"; | |
21 const int bufferSize = 1024; | |
22 | |
23 class AutoHandle | |
24 { | |
25 public: | |
26 AutoHandle() | |
27 { | |
28 } | |
29 | |
30 AutoHandle(HANDLE handle) : handle(handle) | |
31 { | |
32 } | |
33 | |
34 ~AutoHandle() | |
35 { | |
36 CloseHandle(handle); | |
37 } | |
38 | |
39 HANDLE get() | |
40 { | |
41 return handle; | |
42 } | |
43 | |
44 private: | |
45 HANDLE handle; | |
46 static int references; | |
47 | |
48 AutoHandle(const AutoHandle& autoHandle); | |
49 AutoHandle& operator=(const AutoHandle& autoHandle); | |
50 }; | |
51 | |
52 std::string MarshalStrings(const std::vector<std::string>& strings) | |
53 { | |
54 // TODO: This is some pretty hacky marshalling, replace it with something mo re robust | |
55 std::string marshalledStrings; | |
56 for (std::vector<std::string>::const_iterator it = strings.begin(); it != st rings.end(); it++) | |
57 marshalledStrings += *it + ';'; | |
58 return marshalledStrings; | |
59 } | |
60 | |
61 std::vector<std::string> UnmarshalStrings(const std::string& message) | |
62 { | |
63 std::stringstream stream(message); | |
64 std::vector<std::string> strings; | |
65 std::string string; | |
66 while (std::getline(stream, string, ';')) | |
67 strings.push_back(string); | |
68 return strings; | |
69 } | |
70 | |
71 std::string ReadMessage(HANDLE pipe) | |
72 { | |
73 std::stringstream stream; | |
74 std::auto_ptr<char> buffer(new char[bufferSize]); | |
75 bool hasError; | |
76 do | |
77 { | |
78 DWORD bytesRead; | |
79 hasError = !ReadFile(pipe, buffer.get(), bufferSize * sizeof(char), &bytes Read, 0); | |
80 if (hasError && GetLastError() != ERROR_MORE_DATA) | |
81 { | |
82 std::stringstream stream; | |
83 stream << "Error reading from pipe: " << GetLastError(); | |
84 throw std::runtime_error(stream.str()); | |
85 } | |
86 stream << std::string(buffer.get(), bytesRead); | |
87 } while (hasError); | |
88 return stream.str(); | |
89 } | |
90 | |
91 void WriteMessage(HANDLE pipe, const std::string& message) | |
92 { | |
93 DWORD bytesWritten; | |
94 if (!WriteFile(pipe, message.c_str(), message.length(), &bytesWritten, 0)) | |
95 throw std::runtime_error("Failed to write to pipe"); | |
96 } | |
97 | |
98 HANDLE OpenPipe(const std::wstring& name) | |
99 { | |
100 if (WaitNamedPipe(name.c_str(), 5000)) | |
101 return CreateFile(name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_E XISTING, 0, 0); | |
102 return INVALID_HANDLE_VALUE; | |
103 } | |
104 | |
105 void SpawnAdblockPlusEngine() | |
106 { | |
107 std::wstring engineExecutablePath = DllDir() + L"AdblockPlusEngine.exe"; | |
108 STARTUPINFO startupInfo = {}; | |
109 PROCESS_INFORMATION processInformation = {}; | |
110 | |
111 HANDLE token; | |
112 OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token); | |
113 HANDLE newToken; | |
114 DuplicateTokenEx(token, 0, 0, SecurityImpersonation, TokenPrimary, &newToken ); | |
115 | |
116 if (!CreateProcessAsUser(newToken, 0, const_cast<wchar_t*>(engineExecutableP ath.c_str()), 0, 0, 0, 0, 0, 0, | |
Wladimir Palant
2013/05/16 11:52:16
You are leaking the handles created here: "Handles
Felix Dahlke
2013/05/23 12:31:20
Done.
| |
117 &startupInfo, &processInformation)) | |
118 { | |
119 DWORD error = GetLastError(); | |
120 throw std::runtime_error("Failed to start Adblock Plus Engine"); | |
121 } | |
122 } | |
123 | |
124 HANDLE OpenAdblockPlusEnginePipe() | |
125 { | |
126 try | |
127 { | |
128 HANDLE pipe = OpenPipe(pipeName); | |
129 if (pipe == INVALID_HANDLE_VALUE) | |
130 { | |
131 SpawnAdblockPlusEngine(); | |
Wladimir Palant
2013/05/16 11:52:16
I can't say that I like the logic here, timing ass
Oleksandr
2013/05/16 13:23:22
The documentation says "If no instances of the spe
Felix Dahlke
2013/05/17 09:11:36
Yes, Oleksandr is right. We are using WaitNamedPip
Wladimir Palant
2013/05/17 10:35:02
Ok, I wonder whether we can wait for pipe creation
| |
132 | |
133 int timeout = 5000; | |
134 while ((pipe = OpenPipe(pipeName)) == INVALID_HANDLE_VALUE) | |
135 { | |
136 const int step = 10; | |
137 Sleep(step); | |
138 timeout -= step; | |
139 if (timeout <= 0) | |
140 throw std::runtime_error("Unable to open Adblock Plus Engine pipe"); | |
141 } | |
142 } | |
143 | |
144 DWORD mode = PIPE_READMODE_MESSAGE; | |
145 if (!SetNamedPipeHandleState(pipe, &mode, 0, 0)) | |
146 throw std::runtime_error("SetNamedPipeHandleState failed"); | |
147 | |
148 return pipe; | |
149 } | |
150 catch(std::exception e) | |
151 { | |
152 DEBUG_GENERAL(e.what()); | |
153 return INVALID_HANDLE_VALUE; | |
154 } | |
155 } | |
156 } | |
14 | 157 |
15 CAdblockPlusClient* CAdblockPlusClient::s_instance = NULL; | 158 CAdblockPlusClient* CAdblockPlusClient::s_instance = NULL; |
16 | 159 |
17 | |
18 CAdblockPlusClient::CAdblockPlusClient() : CPluginClientBase() | 160 CAdblockPlusClient::CAdblockPlusClient() : CPluginClientBase() |
19 { | 161 { |
20 try | 162 m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter()); |
21 { | 163 } |
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 | 164 |
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() | 165 CAdblockPlusClient::~CAdblockPlusClient() |
41 { | 166 { |
42 s_instance = NULL; | 167 s_instance = NULL; |
43 } | 168 } |
44 | 169 |
45 | 170 |
46 CAdblockPlusClient* CAdblockPlusClient::GetInstance() | 171 CAdblockPlusClient* CAdblockPlusClient::GetInstance() |
47 { | 172 { |
48 CAdblockPlusClient* instance = NULL; | 173 CAdblockPlusClient* instance = NULL; |
49 | 174 |
50 s_criticalSectionLocal.Lock(); | 175 s_criticalSectionLocal.Lock(); |
51 { | 176 { |
52 if (!s_instance) | 177 if (!s_instance) |
53 { | 178 { |
54 CAdblockPlusClient* client = new CAdblockPlusClient(); | 179 CAdblockPlusClient* client = new CAdblockPlusClient(); |
55 | 180 |
56 s_instance = client; | 181 s_instance = client; |
57 } | 182 } |
58 | 183 |
59 instance = s_instance; | 184 instance = s_instance; |
60 } | 185 } |
61 s_criticalSectionLocal.Unlock(); | 186 s_criticalSectionLocal.Unlock(); |
62 | 187 |
63 return instance; | 188 return instance; |
64 } | 189 } |
65 | 190 |
66 AdblockPlus::FilterEngine* CAdblockPlusClient::GetFilterEngine() | |
67 { | |
68 return filterEngine.get(); | |
69 } | |
70 | 191 |
71 bool CAdblockPlusClient::ShouldBlock(CString src, int contentType, const CString & domain, bool addDebug) | 192 bool CAdblockPlusClient::ShouldBlock(CString src, int contentType, const CString & domain, bool addDebug) |
72 { | 193 { |
73 bool isBlocked = false; | 194 bool isBlocked = false; |
74 | 195 |
75 bool isCached = false; | 196 bool isCached = false; |
76 | 197 |
77 CPluginSettings* settings = CPluginSettings::GetInstance(); | 198 CPluginSettings* settings = CPluginSettings::GetInstance(); |
78 | 199 |
79 m_criticalSectionCache.Lock(); | 200 m_criticalSectionCache.Lock(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
156 BYTE version[50]; | 277 BYTE version[50]; |
157 cbData = 50; | 278 cbData = 50; |
158 status = RegQueryValueEx(hKey, L"Version", NULL, &type, (BYTE*)version, &cbDat a); | 279 status = RegQueryValueEx(hKey, L"Version", NULL, &type, (BYTE*)version, &cbDat a); |
159 if (status != 0) | 280 if (status != 0) |
160 { | 281 { |
161 return 0; | 282 return 0; |
162 } | 283 } |
163 RegCloseKey(hKey); | 284 RegCloseKey(hKey); |
164 return (int)(version[0] - 48); | 285 return (int)(version[0] - 48); |
165 } | 286 } |
287 | |
288 std::string CallAdblockPlusEngineProcedure(const std::string& name, const std::v ector<std::string>& args) | |
Wladimir Palant
2013/05/16 11:52:16
Why combine the parameters here? It's a private he
Wladimir Palant
2013/05/23 14:25:01
This comment doesn't seem to be addressed.
Felix Dahlke
2013/05/23 19:10:44
Oops, seems I missed this. Addressed now, you're r
| |
289 { | |
290 AutoHandle pipe(OpenAdblockPlusEnginePipe()); | |
291 std::vector<std::string> strings; | |
292 strings.push_back(name); | |
293 for (std::vector<std::string>::const_iterator it = args.begin(); it != args.en d(); it++) | |
294 strings.push_back(*it); | |
295 WriteMessage(pipe.get(), MarshalStrings(strings)); | |
296 return ReadMessage(pipe.get()); | |
297 } | |
298 | |
299 bool CAdblockPlusClient::Matches(const std::string& url, const std::string& cont entType, const std::string& domain) | |
300 { | |
301 std::vector<std::string> args; | |
302 args.push_back(url); | |
303 args.push_back(contentType); | |
304 args.push_back(domain); | |
305 | |
306 try | |
307 { | |
308 std::string response = CallAdblockPlusEngineProcedure("Matches", args); | |
309 return response == "1"; | |
310 } | |
311 catch (const std::exception& e) | |
312 { | |
313 DEBUG_GENERAL(e.what()); | |
314 return false; | |
315 } | |
316 } | |
317 | |
318 std::vector<std::string> CAdblockPlusClient::GetElementHidingSelectors(std::stri ng domain) | |
319 { | |
320 std::vector<std::string> args; | |
321 args.push_back(domain); | |
322 | |
323 try | |
324 { | |
325 std::string response = CallAdblockPlusEngineProcedure("GetElementHidingSelec tors", args); | |
326 return UnmarshalStrings(response); | |
327 } | |
328 catch (const std::exception& e) | |
329 { | |
330 DEBUG_GENERAL(e.what()); | |
331 return std::vector<std::string>(); | |
332 } | |
333 } | |
334 | |
335 std::vector<AdblockPlus::SubscriptionPtr> CAdblockPlusClient::FetchAvailableSubs criptions() | |
336 { | |
337 //TODO: implement this | |
338 return std::vector<AdblockPlus::SubscriptionPtr>(); | |
339 } | |
340 | |
341 std::vector<AdblockPlus::FilterPtr> CAdblockPlusClient::GetListedFilters() | |
342 { | |
343 //TODO: implement this | |
344 return std::vector<AdblockPlus::FilterPtr>(); | |
345 } | |
346 | |
347 AdblockPlus::FilterPtr CAdblockPlusClient::GetFilter(std::string text) | |
348 { | |
349 //TODO: implement this | |
350 return AdblockPlus::FilterPtr(); | |
351 } | |
352 | |
353 std::vector<AdblockPlus::SubscriptionPtr> CAdblockPlusClient::GetListedSubscript ions() | |
354 { | |
355 //TODO: implement this | |
356 return std::vector<AdblockPlus::SubscriptionPtr>(); | |
357 } | |
358 | |
359 AdblockPlus::SubscriptionPtr CAdblockPlusClient::GetSubscription(std::string url ) | |
360 { | |
361 //TODO: imlement this | |
362 return AdblockPlus::SubscriptionPtr(); | |
363 } | |
OLD | NEW |