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

Unified Diff: src/shared/Communication.cpp

Issue 10786016: Moved all pipe functionality into a self-containing Communication::Pipe class (Closed)
Patch Set: Created June 3, 2013, 2:07 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/shared/Communication.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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");
+}
« no previous file with comments | « src/shared/Communication.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld