Index: src/shared/Communication.cpp |
=================================================================== |
--- a/src/shared/Communication.cpp |
+++ b/src/shared/Communication.cpp |
@@ -1,104 +1,121 @@ |
-#include <Windows.h> |
-#include <Lmcons.h> |
-#include <Sddl.h> |
- |
-#include "Communication.h" |
- |
-namespace |
-{ |
- std::string AppendErrorCode(const std::string& message) |
- { |
- std::stringstream stream; |
- stream << message << " (Error code: " << GetLastError() << ")"; |
- return stream.str(); |
- } |
- |
- std::wstring GetUserName() |
- { |
- const DWORD maxLength = UNLEN + 1; |
- std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]); |
- DWORD length = maxLength; |
- if (!::GetUserNameW(buffer.get(), &length)) |
- throw std::runtime_error(AppendErrorCode("Failed to get the current user's name")); |
- return std::wstring(buffer.get(), length); |
- } |
-} |
- |
-const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName(); |
- |
-Communication::PipeConnectionError::PipeConnectionError() |
- : std::runtime_error(AppendErrorCode("Unable to connect to a named pipe")) |
-{ |
-} |
- |
-Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mode mode) |
-{ |
- pipe = INVALID_HANDLE_VALUE; |
- if (mode == MODE_CREATE) |
- { |
- SECURITY_ATTRIBUTES sa; |
- memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); |
- sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
- |
- // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb625958.aspx |
- LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; |
- PSECURITY_DESCRIPTOR securitydescriptor; |
- ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDDL_REVISION_1, &securitydescriptor, 0); |
- |
- sa.lpSecurityDescriptor = securitydescriptor; |
- sa.bInheritHandle = TRUE; |
- |
- pipe = CreateNamedPipeW (pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, |
- PIPE_UNLIMITED_INSTANCES, Communication::bufferSize, Communication::bufferSize, 0, &sa); |
- LocalFree(securitydescriptor); |
- } |
- else |
- { |
- if (WaitNamedPipeW(pipeName.c_str(), 5000)) |
- pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); |
- } |
- |
- if (pipe == INVALID_HANDLE_VALUE) |
- throw PipeConnectionError(); |
- |
- DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; |
- if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) |
- throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastError()); |
- |
- if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) |
- throw std::runtime_error("Client failed to connect: error " + GetLastError()); |
-} |
- |
-Communication::Pipe::~Pipe() |
-{ |
- CloseHandle(pipe); |
-} |
- |
-Communication::InputBuffer Communication::Pipe::ReadMessage() |
-{ |
- std::stringstream stream; |
- std::auto_ptr<char> buffer(new char[bufferSize]); |
- bool doneReading = false; |
- while (!doneReading) |
- { |
- DWORD bytesRead; |
- if (ReadFile(pipe, buffer.get(), bufferSize * sizeof(char), &bytesRead, 0)) |
- doneReading = true; |
- else if (GetLastError() != ERROR_MORE_DATA) |
- { |
- std::stringstream stream; |
- stream << "Error reading from pipe: " << GetLastError(); |
- throw std::runtime_error(stream.str()); |
- } |
- stream << std::string(buffer.get(), bytesRead); |
- } |
- return Communication::InputBuffer(stream.str()); |
-} |
- |
-void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) |
-{ |
- DWORD bytesWritten; |
- std::string data = message.Get(); |
- if (!WriteFile(pipe, data.c_str(), data.length(), &bytesWritten, 0)) |
- throw std::runtime_error("Failed to write to pipe"); |
-} |
+#include <Windows.h> |
+#include <Lmcons.h> |
+#include <Sddl.h> |
+ |
+#include "Communication.h" |
+ |
+namespace |
+{ |
+ const int bufferSize = 1024; |
+ |
+ std::string AppendErrorCode(const std::string& message) |
+ { |
+ std::stringstream stream; |
+ stream << message << " (Error code: " << GetLastError() << ")"; |
+ return stream.str(); |
+ } |
+ |
+ std::wstring GetUserName() |
+ { |
+ const DWORD maxLength = UNLEN + 1; |
+ std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]); |
+ DWORD length = maxLength; |
+ if (!::GetUserNameW(buffer.get(), &length)) |
+ throw std::runtime_error(AppendErrorCode("Failed to get the current user's name")); |
+ return std::wstring(buffer.get(), length); |
+ } |
+} |
+ |
+const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_" + GetUserName(); |
+ |
+void Communication::InputBuffer::CheckType(Communication::ValueType expectedType) |
+{ |
+ if (!hasType) |
+ ReadBinary(currentType); |
+ |
+ if (currentType != expectedType) |
+ { |
+ // Make sure we don't attempt to read the type again |
+ hasType = true; |
+ throw new std::runtime_error("Unexpected type found in input buffer"); |
+ } |
+ else |
+ hasType = false; |
+} |
+ |
+Communication::PipeConnectionError::PipeConnectionError() |
+ : std::runtime_error(AppendErrorCode("Unable to connect to a named pipe")) |
+{ |
+} |
+ |
+Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mode mode) |
+{ |
+ pipe = INVALID_HANDLE_VALUE; |
+ if (mode == MODE_CREATE) |
+ { |
+ SECURITY_ATTRIBUTES sa; |
+ memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); |
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
+ |
+ // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb625958.aspx |
+ LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; |
+ PSECURITY_DESCRIPTOR securitydescriptor; |
+ ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDDL_REVISION_1, &securitydescriptor, 0); |
+ |
+ sa.lpSecurityDescriptor = securitydescriptor; |
+ sa.bInheritHandle = TRUE; |
+ |
+ pipe = CreateNamedPipeW (pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, |
+ PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSize, 0, &sa); |
+ LocalFree(securitydescriptor); |
+ } |
+ else |
+ { |
+ if (WaitNamedPipeW(pipeName.c_str(), 5000)) |
+ pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); |
+ } |
+ |
+ if (pipe == INVALID_HANDLE_VALUE) |
+ throw PipeConnectionError(); |
+ |
+ DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; |
+ if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) |
+ throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastError()); |
+ |
+ if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) |
+ throw std::runtime_error("Client failed to connect: error " + GetLastError()); |
+} |
+ |
+Communication::Pipe::~Pipe() |
+{ |
+ CloseHandle(pipe); |
+} |
+ |
+Communication::InputBuffer Communication::Pipe::ReadMessage() |
+{ |
+ std::stringstream stream; |
+ std::auto_ptr<char> buffer(new char[bufferSize]); |
+ bool doneReading = false; |
+ while (!doneReading) |
+ { |
+ DWORD bytesRead; |
+ if (ReadFile(pipe, buffer.get(), bufferSize * sizeof(char), &bytesRead, 0)) |
+ doneReading = true; |
+ else if (GetLastError() != ERROR_MORE_DATA) |
+ { |
+ std::stringstream stream; |
+ stream << "Error reading from pipe: " << GetLastError(); |
+ throw std::runtime_error(stream.str()); |
+ } |
+ stream << std::string(buffer.get(), bytesRead); |
+ } |
+ return Communication::InputBuffer(stream.str()); |
+} |
+ |
+void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) |
+{ |
+ DWORD bytesWritten; |
+ std::string data = message.Get(); |
+ if (!WriteFile(pipe, data.c_str(), data.length(), &bytesWritten, 0)) |
+ throw std::runtime_error("Failed to write to pipe"); |
+} |