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

Side by Side Diff: src/engine/main.cpp

Issue 10774005: Avoid duplication between AdblockPlus and AdblockPlusEngine (Closed)
Patch Set: Created May 24, 2013, 3:48 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 #include <AdblockPlus.h> 1 #include "stdafx.h"
2 #include <iostream> 2
3 #include <Lmcons.h> 3 #include "../shared/AutoHandle.h"
4 #include <ShlObj.h> 4 #include "../shared/Communication.h"
Wladimir Palant 2013/05/27 09:51:55 I wonder whether we should add an include director
Oleksandr 2013/05/27 15:32:26 Include directories are generally used for third-p
5 #include <sstream>
6 #include <vector>
7 #include <Windows.h>
8 #include <Sddl.h>
9 5
10 namespace 6 namespace
11 { 7 {
12 std::wstring GetUserName()
13 {
14 const DWORD maxLength = UNLEN + 1;
15 std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]);
16 DWORD length = maxLength;
17 if (!::GetUserName(buffer.get(), &length))
18 {
19 std::stringstream stream;
20 stream << "Failed to get the current user's name (Error code: " << GetLast Error() << ")";
21 throw std::runtime_error("Failed to get the current user's name");
22 }
23 return std::wstring(buffer.get(), length);
24 }
25
26 const std::wstring pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName ();
27 const int bufferSize = 1024;
28 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine; 8 std::auto_ptr<AdblockPlus::FilterEngine> filterEngine;
29 9
30 class AutoHandle
31 {
32 public:
33 AutoHandle()
34 {
35 }
36
37 AutoHandle(HANDLE handle) : handle(handle)
38 {
39 }
40
41 ~AutoHandle()
42 {
43 CloseHandle(handle);
44 }
45
46 HANDLE get()
47 {
48 return handle;
49 }
50
51 private:
52 HANDLE handle;
53
54 AutoHandle(const AutoHandle& autoHandle);
55 AutoHandle& operator=(const AutoHandle& autoHandle);
56 };
57
58 void Log(const std::string& message) 10 void Log(const std::string& message)
59 { 11 {
60 // TODO: Log to a log file 12 // TODO: Log to a log file
61 MessageBoxA(0, ("AdblockPlusEngine: " + message).c_str(), "", MB_OK); 13 MessageBoxA(0, ("AdblockPlusEngine: " + message).c_str(), "", MB_OK);
62 } 14 }
63 15
64 void LogLastError(const std::string& message) 16 void LogLastError(const std::string& message)
65 { 17 {
66 std::stringstream stream; 18 std::stringstream stream;
67 stream << message << " (Error code: " << GetLastError() << ")"; 19 stream << message << " (Error code: " << GetLastError() << ")";
68 Log(stream.str()); 20 Log(stream.str());
69 } 21 }
70 22
71 void LogException(const std::exception& exception) 23 void LogException(const std::exception& exception)
72 { 24 {
73 Log(std::string("An exception occurred: ") + exception.what()); 25 Log(std::string("An exception occurred: ") + exception.what());
74 } 26 }
75 27
76 std::string MarshalStrings(const std::vector<std::string>& strings)
77 {
78 // TODO: This is some pretty hacky marshalling, replace it with something mo re robust
79 std::string marshalledStrings;
80 for (std::vector<std::string>::const_iterator it = strings.begin(); it != st rings.end(); it++)
81 marshalledStrings += *it + ';';
82 return marshalledStrings;
83 }
84
85 std::vector<std::string> UnmarshalStrings(const std::string& message)
86 {
87 std::stringstream stream(message);
88 std::vector<std::string> strings;
89 std::string string;
90 while (std::getline(stream, string, ';'))
91 strings.push_back(string);
92 return strings;
93 }
94
95 std::string ToUtf8String(std::wstring str) 28 std::string ToUtf8String(std::wstring str)
96 { 29 {
97 size_t length = str.size(); 30 size_t length = str.size();
98 if (length == 0) 31 if (length == 0)
99 return std::string(); 32 return std::string();
100 33
101 DWORD utf8StringLength = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), length , 0, 0, 0, 0); 34 DWORD utf8StringLength = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), length , 0, 0, 0, 0);
102 if (utf8StringLength == 0) 35 if (utf8StringLength == 0)
103 throw std::runtime_error("Failed to determine the required buffer size"); 36 throw std::runtime_error("Failed to determine the required buffer size");
104 37
105 std::string utf8String(utf8StringLength, '\0'); 38 std::string utf8String(utf8StringLength, '\0');
106 WideCharToMultiByte(CP_UTF8, 0, str.c_str(), length, &utf8String[0], utf8Str ingLength, 0, 0); 39 WideCharToMultiByte(CP_UTF8, 0, str.c_str(), length, &utf8String[0], utf8Str ingLength, 0, 0);
107 return utf8String; 40 return utf8String;
108 } 41 }
109 42
110 std::string ReadMessage(HANDLE pipe)
111 {
112 std::stringstream stream;
113 std::auto_ptr<char> buffer(new char[bufferSize]);
114 bool doneReading = false;
115 while (!doneReading)
116 {
117 DWORD bytesRead;
118 if (ReadFile(pipe, buffer.get(), bufferSize * sizeof(char), &bytesRead, 0) )
119 doneReading = true;
120 else if (GetLastError() != ERROR_MORE_DATA)
121 {
122 std::stringstream stream;
123 stream << "Error reading from pipe: " << GetLastError();
124 throw std::runtime_error(stream.str());
125 }
126 stream << std::string(buffer.get(), bytesRead);
127 }
128 return stream.str();
129 }
130
131 void WriteMessage(HANDLE pipe, const std::string& message)
132 {
133 DWORD bytesWritten;
134 if (!WriteFile(pipe, message.c_str(), message.length(), &bytesWritten, 0))
135 throw std::runtime_error("Failed to write to pipe");
136 }
137
138 std::string HandleRequest(const std::vector<std::string>& strings) 43 std::string HandleRequest(const std::vector<std::string>& strings)
139 { 44 {
140 std::string procedureName = strings[0]; 45 std::string procedureName = strings[0];
141 if (procedureName == "Matches") 46 if (procedureName == "Matches")
142 return filterEngine->Matches(strings[1], strings[2], strings[3]) ? "1" : " 0"; 47 return filterEngine->Matches(strings[1], strings[2], strings[3]) ? "1" : " 0";
143 if (procedureName == "GetElementHidingSelectors") 48 if (procedureName == "GetElementHidingSelectors")
144 return MarshalStrings(filterEngine->GetElementHidingSelectors(strings[1])) ; 49 return Communication::MarshalStrings(filterEngine->GetElementHidingSelecto rs(strings[1]));
145 return ""; 50 return "";
146 } 51 }
147 52
148 DWORD WINAPI ClientThread(LPVOID param) 53 DWORD WINAPI ClientThread(LPVOID param)
149 { 54 {
150 HANDLE pipe = static_cast<HANDLE>(param); 55 HANDLE pipe = static_cast<HANDLE>(param);
151 56
152 try 57 try
153 { 58 {
154 std::string message = ReadMessage(pipe); 59 std::string message = Communication::ReadMessage(pipe);
155 std::vector<std::string> strings = UnmarshalStrings(message); 60 std::vector<std::string> strings = Communication::UnmarshalStrings(message );
156 std::string response = HandleRequest(strings); 61 std::string response = HandleRequest(strings);
157 WriteMessage(pipe, response); 62 Communication::WriteMessage(pipe, response);
158 } 63 }
159 catch (const std::exception& e) 64 catch (const std::exception& e)
160 { 65 {
161 LogException(e); 66 LogException(e);
162 } 67 }
163 68
164 // TODO: Keep the pipe open until the client disconnects 69 // TODO: Keep the pipe open until the client disconnects
165 FlushFileBuffers(pipe); 70 FlushFileBuffers(pipe);
166 DisconnectNamedPipe(pipe); 71 DisconnectNamedPipe(pipe);
167 CloseHandle(pipe); 72 CloseHandle(pipe);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 127
223 // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb625958.a spx 128 // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb625958.a spx
224 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; 129 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)";
225 PSECURITY_DESCRIPTOR securitydescriptor; 130 PSECURITY_DESCRIPTOR securitydescriptor;
226 ConvertStringSecurityDescriptorToSecurityDescriptor(accessControlEntry, SDDL_R EVISION_1, &securitydescriptor, 0); 131 ConvertStringSecurityDescriptorToSecurityDescriptor(accessControlEntry, SDDL_R EVISION_1, &securitydescriptor, 0);
227 132
228 sa.lpSecurityDescriptor = securitydescriptor; 133 sa.lpSecurityDescriptor = securitydescriptor;
229 sa.bInheritHandle = TRUE; 134 sa.bInheritHandle = TRUE;
230 135
231 HANDLE pipe = CreateNamedPipe(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_ MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 136 HANDLE pipe = CreateNamedPipe(pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_ MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
232 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize , 0, &sa); 137 PIPE_UNLIMITED_INSTANCES, Communication::bufferS ize, Communication::bufferSize, 0, &sa);
233 LocalFree(securitydescriptor); 138 LocalFree(securitydescriptor);
234 return pipe; 139 return pipe;
235 } 140 }
236 141
237 int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 142 int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
238 { 143 {
239 // TODO: Attempt to create the pipe first, and exit immediately if this 144 // TODO: Attempt to create the pipe first, and exit immediately if this
240 // fails. Since multiple instances of the engine could be running, 145 // fails. Since multiple instances of the engine could be running,
241 // this may need named mutices to avoid race conditions. 146 // this may need named mutices to avoid race conditions.
242 // Note that as soon as the pipe is created first, we can reduce the 147 // Note that as soon as the pipe is created first, we can reduce the
243 // client timeout after CreateProcess(), but should increase the one 148 // client timeout after CreateProcess(), but should increase the one
244 // in WaitNamedPipe(). 149 // in WaitNamedPipe().
245 150
246 filterEngine = CreateFilterEngine(); 151 filterEngine = CreateFilterEngine();
247 152
248 for (;;) 153 for (;;)
249 { 154 {
250 HANDLE pipe = CreatePipe(pipeName); 155 HANDLE pipe = CreatePipe(Communication::pipeName);
251 if (pipe == INVALID_HANDLE_VALUE) 156 if (pipe == INVALID_HANDLE_VALUE)
252 { 157 {
253 LogLastError("CreateNamedPipe failed"); 158 LogLastError("CreateNamedPipe failed");
254 return 1; 159 return 1;
255 } 160 }
256 161
257 if (!ConnectNamedPipe(pipe, 0)) 162 if (!ConnectNamedPipe(pipe, 0))
258 { 163 {
259 LogLastError("Client failed to connect"); 164 LogLastError("Client failed to connect");
260 CloseHandle(pipe); 165 CloseHandle(pipe);
261 continue; 166 continue;
262 } 167 }
263 168
264 // TODO: Count established connections, kill the engine when none are left 169 // TODO: Count established connections, kill the engine when none are left
265 170
266 AutoHandle thread(CreateThread(0, 0, ClientThread, static_cast<LPVOID>(pipe) , 0, 0)); 171 AutoHandle thread(CreateThread(0, 0, ClientThread, static_cast<LPVOID>(pipe) , 0, 0));
267 if (!thread.get()) 172 if (!thread.get())
268 { 173 {
269 LogLastError("CreateThread failed"); 174 LogLastError("CreateThread failed");
270 return 1; 175 return 1;
271 } 176 }
272 } 177 }
273 178
274 return 0; 179 return 0;
275 } 180 }
OLDNEW
« no previous file with comments | « AdblockPlusPlugin.vcxproj ('k') | src/engine/stdafx.h » ('j') | src/shared/AutoHandle.cpp » ('J')

Powered by Google App Engine
This is Rietveld