Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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 #include "PluginUtil.h" |
12 | 12 |
13 #include "AdblockPlusClient.h" | 13 #include "AdblockPlusClient.h" |
14 | 14 |
15 namespace | 15 namespace |
16 { | 16 { |
17 // TODO: pipeName, bufferSize, AutoHandle, ReadMessage, WriteMessage, MarshalS trings and UnmarshalStrings are | 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. | 18 // duplicated in AdblockPlusEngine. We should find a way to reuse them. |
19 | 19 |
20 const std::wstring pipeName = L"\\\\.\\pipe\\adblockplusengine"; | 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 (); | |
21 const int bufferSize = 1024; | 35 const int bufferSize = 1024; |
22 | 36 |
23 class AutoHandle | 37 class AutoHandle |
24 { | 38 { |
25 public: | 39 public: |
26 AutoHandle() | 40 AutoHandle() |
27 { | 41 { |
28 } | 42 } |
29 | 43 |
30 AutoHandle(HANDLE handle) : handle(handle) | 44 AutoHandle(HANDLE handle) : handle(handle) |
31 { | 45 { |
32 } | 46 } |
33 | 47 |
34 ~AutoHandle() | 48 ~AutoHandle() |
35 { | 49 { |
36 CloseHandle(handle); | 50 CloseHandle(handle); |
37 } | 51 } |
38 | 52 |
39 HANDLE get() | 53 HANDLE get() |
40 { | 54 { |
41 return handle; | 55 return handle; |
42 } | 56 } |
43 | 57 |
44 private: | 58 private: |
45 HANDLE handle; | 59 HANDLE handle; |
46 static int references; | |
47 | 60 |
48 AutoHandle(const AutoHandle& autoHandle); | 61 AutoHandle(const AutoHandle& autoHandle); |
49 AutoHandle& operator=(const AutoHandle& autoHandle); | 62 AutoHandle& operator=(const AutoHandle& autoHandle); |
50 }; | 63 }; |
51 | 64 |
52 std::string MarshalStrings(const std::vector<std::string>& strings) | 65 std::string MarshalStrings(const std::vector<std::string>& strings) |
53 { | 66 { |
54 // TODO: This is some pretty hacky marshalling, replace it with something mo re robust | 67 // TODO: This is some pretty hacky marshalling, replace it with something mo re robust |
55 std::string marshalledStrings; | 68 std::string marshalledStrings; |
56 for (std::vector<std::string>::const_iterator it = strings.begin(); it != st rings.end(); it++) | 69 for (std::vector<std::string>::const_iterator it = strings.begin(); it != st rings.end(); it++) |
57 marshalledStrings += *it + ';'; | 70 marshalledStrings += *it + ';'; |
58 return marshalledStrings; | 71 return marshalledStrings; |
59 } | 72 } |
60 | 73 |
61 std::vector<std::string> UnmarshalStrings(const std::string& message) | 74 std::vector<std::string> UnmarshalStrings(const std::string& message) |
62 { | 75 { |
63 std::stringstream stream(message); | 76 std::stringstream stream(message); |
64 std::vector<std::string> strings; | 77 std::vector<std::string> strings; |
65 std::string string; | 78 std::string string; |
66 while (std::getline(stream, string, ';')) | 79 while (std::getline(stream, string, ';')) |
67 strings.push_back(string); | 80 strings.push_back(string); |
68 return strings; | 81 return strings; |
69 } | 82 } |
70 | 83 |
71 std::string ReadMessage(HANDLE pipe) | 84 std::string ReadMessage(HANDLE pipe) |
72 { | 85 { |
73 std::stringstream stream; | 86 std::stringstream stream; |
74 std::auto_ptr<char> buffer(new char[bufferSize]); | 87 std::auto_ptr<char> buffer(new char[bufferSize]); |
75 bool hasError; | 88 bool doneReading = false; |
76 do | 89 while (!doneReading) |
77 { | 90 { |
78 DWORD bytesRead; | 91 DWORD bytesRead; |
79 hasError = !ReadFile(pipe, buffer.get(), bufferSize * sizeof(char), &bytes Read, 0); | 92 if (ReadFile(pipe, buffer.get(), bufferSize * sizeof(char), &bytesRead, 0) ) |
80 if (hasError && GetLastError() != ERROR_MORE_DATA) | 93 doneReading = true; |
94 else if (GetLastError() != ERROR_MORE_DATA) | |
81 { | 95 { |
82 std::stringstream stream; | 96 std::stringstream stream; |
83 stream << "Error reading from pipe: " << GetLastError(); | 97 stream << "Error reading from pipe: " << GetLastError(); |
84 throw std::runtime_error(stream.str()); | 98 throw std::runtime_error(stream.str()); |
85 } | 99 } |
86 stream << std::string(buffer.get(), bytesRead); | 100 stream << std::string(buffer.get(), bytesRead); |
87 } while (hasError); | 101 } |
88 return stream.str(); | 102 return stream.str(); |
89 } | 103 } |
90 | 104 |
91 void WriteMessage(HANDLE pipe, const std::string& message) | 105 void WriteMessage(HANDLE pipe, const std::string& message) |
92 { | 106 { |
93 DWORD bytesWritten; | 107 DWORD bytesWritten; |
94 if (!WriteFile(pipe, message.c_str(), message.length(), &bytesWritten, 0)) | 108 if (!WriteFile(pipe, message.c_str(), message.length(), &bytesWritten, 0)) |
95 throw std::runtime_error("Failed to write to pipe"); | 109 throw std::runtime_error("Failed to write to pipe"); |
96 } | 110 } |
97 | 111 |
98 HANDLE OpenPipe(const std::wstring& name) | 112 HANDLE OpenPipe(const std::wstring& name) |
99 { | 113 { |
100 if (WaitNamedPipe(name.c_str(), 5000)) | 114 if (WaitNamedPipe(name.c_str(), 5000)) |
101 return CreateFile(name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_E XISTING, 0, 0); | 115 return CreateFile(name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_E XISTING, 0, 0); |
102 return INVALID_HANDLE_VALUE; | 116 return INVALID_HANDLE_VALUE; |
103 } | 117 } |
104 | 118 |
105 void SpawnAdblockPlusEngine() | 119 void SpawnAdblockPlusEngine() |
106 { | 120 { |
107 std::wstring engineExecutablePath = DllDir() + L"AdblockPlusEngine.exe"; | 121 std::wstring engineExecutablePath = DllDir() + L"AdblockPlusEngine.exe"; |
108 STARTUPINFO startupInfo = {}; | 122 STARTUPINFO startupInfo = {}; |
109 PROCESS_INFORMATION processInformation = {}; | 123 PROCESS_INFORMATION processInformation = {}; |
110 | 124 |
111 HANDLE token; | 125 HANDLE token; |
112 OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token); | 126 OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ADJUST_DEFAULT | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &token); |
113 HANDLE newToken; | 127 HANDLE newToken; |
114 DuplicateTokenEx(token, 0, 0, SecurityImpersonation, TokenPrimary, &newToken ); | 128 DuplicateTokenEx(token, 0, 0, SecurityImpersonation, TokenPrimary, &newToken ); |
115 | 129 |
116 if (!CreateProcessAsUser(newToken, 0, const_cast<wchar_t*>(engineExecutableP ath.c_str()), 0, 0, 0, 0, 0, 0, | 130 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)) | 131 &startupInfo, &processInformation)) |
118 { | 132 { |
119 DWORD error = GetLastError(); | 133 DWORD error = GetLastError(); |
120 throw std::runtime_error("Failed to start Adblock Plus Engine"); | 134 throw std::runtime_error("Failed to start Adblock Plus Engine"); |
121 } | 135 } |
136 | |
137 CloseHandle(processInformation.hProcess); | |
138 CloseHandle(processInformation.hThread); | |
122 } | 139 } |
123 | 140 |
124 HANDLE OpenAdblockPlusEnginePipe() | 141 HANDLE OpenAdblockPlusEnginePipe() |
125 { | 142 { |
126 try | 143 try |
127 { | 144 { |
128 HANDLE pipe = OpenPipe(pipeName); | 145 HANDLE pipe = OpenPipe(pipeName); |
129 if (pipe == INVALID_HANDLE_VALUE) | 146 if (pipe == INVALID_HANDLE_VALUE) |
130 { | 147 { |
131 SpawnAdblockPlusEngine(); | 148 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 | 149 |
133 int timeout = 5000; | 150 int timeout = 10000; |
134 while ((pipe = OpenPipe(pipeName)) == INVALID_HANDLE_VALUE) | 151 while ((pipe = OpenPipe(pipeName)) == INVALID_HANDLE_VALUE) |
135 { | 152 { |
136 const int step = 10; | 153 const int step = 10; |
137 Sleep(step); | 154 Sleep(step); |
138 timeout -= step; | 155 timeout -= step; |
139 if (timeout <= 0) | 156 if (timeout <= 0) |
140 throw std::runtime_error("Unable to open Adblock Plus Engine pipe"); | 157 throw std::runtime_error("Unable to open Adblock Plus Engine pipe"); |
141 } | 158 } |
142 } | 159 } |
143 | 160 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
278 cbData = 50; | 295 cbData = 50; |
279 status = RegQueryValueEx(hKey, L"Version", NULL, &type, (BYTE*)version, &cbDat a); | 296 status = RegQueryValueEx(hKey, L"Version", NULL, &type, (BYTE*)version, &cbDat a); |
280 if (status != 0) | 297 if (status != 0) |
281 { | 298 { |
282 return 0; | 299 return 0; |
283 } | 300 } |
284 RegCloseKey(hKey); | 301 RegCloseKey(hKey); |
285 return (int)(version[0] - 48); | 302 return (int)(version[0] - 48); |
286 } | 303 } |
287 | 304 |
288 std::string CallAdblockPlusEngineProcedure(const std::string& name, const std::v ector<std::string>& args) | 305 std::string CallAdblockPlusEngineProcedure(const std::vector<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 { | 306 { |
290 AutoHandle pipe(OpenAdblockPlusEnginePipe()); | 307 AutoHandle pipe(OpenAdblockPlusEnginePipe()); |
291 std::vector<std::string> strings; | 308 WriteMessage(pipe.get(), MarshalStrings(args)); |
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()); | 309 return ReadMessage(pipe.get()); |
297 } | 310 } |
298 | 311 |
299 bool CAdblockPlusClient::Matches(const std::string& url, const std::string& cont entType, const std::string& domain) | 312 bool CAdblockPlusClient::Matches(const std::string& url, const std::string& cont entType, const std::string& domain) |
300 { | 313 { |
301 std::vector<std::string> args; | 314 std::vector<std::string> args; |
315 args.push_back("Matches"); | |
302 args.push_back(url); | 316 args.push_back(url); |
303 args.push_back(contentType); | 317 args.push_back(contentType); |
304 args.push_back(domain); | 318 args.push_back(domain); |
305 | 319 |
306 try | 320 try |
307 { | 321 { |
308 std::string response = CallAdblockPlusEngineProcedure("Matches", args); | 322 std::string response = CallAdblockPlusEngineProcedure(args); |
309 return response == "1"; | 323 return response == "1"; |
310 } | 324 } |
311 catch (const std::exception& e) | 325 catch (const std::exception& e) |
312 { | 326 { |
313 DEBUG_GENERAL(e.what()); | 327 DEBUG_GENERAL(e.what()); |
314 return false; | 328 return false; |
315 } | 329 } |
316 } | 330 } |
317 | 331 |
318 std::vector<std::string> CAdblockPlusClient::GetElementHidingSelectors(std::stri ng domain) | 332 std::vector<std::string> CAdblockPlusClient::GetElementHidingSelectors(std::stri ng domain) |
319 { | 333 { |
320 std::vector<std::string> args; | 334 std::vector<std::string> args; |
335 args.push_back("GetElementHidingSelectors"); | |
321 args.push_back(domain); | 336 args.push_back(domain); |
322 | 337 |
323 try | 338 try |
324 { | 339 { |
325 std::string response = CallAdblockPlusEngineProcedure("GetElementHidingSelec tors", args); | 340 std::string response = CallAdblockPlusEngineProcedure(args); |
326 return UnmarshalStrings(response); | 341 return UnmarshalStrings(response); |
327 } | 342 } |
328 catch (const std::exception& e) | 343 catch (const std::exception& e) |
329 { | 344 { |
330 DEBUG_GENERAL(e.what()); | 345 DEBUG_GENERAL(e.what()); |
331 return std::vector<std::string>(); | 346 return std::vector<std::string>(); |
332 } | 347 } |
333 } | 348 } |
334 | 349 |
335 std::vector<AdblockPlus::SubscriptionPtr> CAdblockPlusClient::FetchAvailableSubs criptions() | 350 std::vector<AdblockPlus::SubscriptionPtr> CAdblockPlusClient::FetchAvailableSubs criptions() |
(...skipping 18 matching lines...) Expand all Loading... | |
354 { | 369 { |
355 //TODO: implement this | 370 //TODO: implement this |
356 return std::vector<AdblockPlus::SubscriptionPtr>(); | 371 return std::vector<AdblockPlus::SubscriptionPtr>(); |
357 } | 372 } |
358 | 373 |
359 AdblockPlus::SubscriptionPtr CAdblockPlusClient::GetSubscription(std::string url ) | 374 AdblockPlus::SubscriptionPtr CAdblockPlusClient::GetSubscription(std::string url ) |
360 { | 375 { |
361 //TODO: imlement this | 376 //TODO: imlement this |
362 return AdblockPlus::SubscriptionPtr(); | 377 return AdblockPlus::SubscriptionPtr(); |
363 } | 378 } |
LEFT | RIGHT |