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

Delta Between Two Patch Sets: Shared/AdblockPlusClient.cpp

Issue 10580043: Run a single FilterEngine instance in a separate process (Closed)
Left Patch Set: Created May 16, 2013, 5:29 a.m.
Right Patch Set: Addressed review issues Created May 23, 2013, 7:10 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 | « Shared/AdblockPlusClient.h ('k') | Shared/PluginFilter.cpp » ('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 #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
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
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 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld