| OLD | NEW |
| 1 #include "..\engine\stdafx.h" | 1 #include <Windows.h> |
| 2 | |
| 3 #include <Lmcons.h> | 2 #include <Lmcons.h> |
| 3 #include <Sddl.h> |
| 4 | 4 |
| 5 #include "Communication.h" | 5 #include "Communication.h" |
| 6 | 6 |
| 7 namespace | 7 namespace |
| 8 { | 8 { |
| 9 std::string AppendErrorCode(const std::string& message) |
| 10 { |
| 11 std::stringstream stream; |
| 12 stream << message << " (Error code: " << GetLastError() << ")"; |
| 13 return stream.str(); |
| 14 } |
| 15 |
| 9 std::wstring GetUserName() | 16 std::wstring GetUserName() |
| 10 { | 17 { |
| 11 const DWORD maxLength = UNLEN + 1; | 18 const DWORD maxLength = UNLEN + 1; |
| 12 std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]); | 19 std::auto_ptr<wchar_t> buffer(new wchar_t[maxLength]); |
| 13 DWORD length = maxLength; | 20 DWORD length = maxLength; |
| 14 if (!::GetUserName(buffer.get(), &length)) | 21 if (!::GetUserNameW(buffer.get(), &length)) |
| 15 { | 22 throw std::runtime_error(AppendErrorCode("Failed to get the current user's
name")); |
| 16 std::stringstream stream; | |
| 17 stream << "Failed to get the current user's name (Error code: " << GetLast
Error() << ")"; | |
| 18 throw std::runtime_error("Failed to get the current user's name"); | |
| 19 } | |
| 20 return std::wstring(buffer.get(), length); | 23 return std::wstring(buffer.get(), length); |
| 21 } | 24 } |
| 22 } | 25 } |
| 23 | 26 |
| 24 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_"
+ GetUserName(); | 27 const std::wstring Communication::pipeName = L"\\\\.\\pipe\\adblockplusengine_"
+ GetUserName(); |
| 25 | 28 |
| 26 Communication::InputBuffer Communication::ReadMessage(HANDLE pipe) | 29 Communication::PipeConnectionError::PipeConnectionError() |
| 30 : std::runtime_error(AppendErrorCode("Unable to connect to a named pipe")) |
| 31 { |
| 32 } |
| 33 |
| 34 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod
e mode) |
| 35 { |
| 36 pipe = INVALID_HANDLE_VALUE; |
| 37 if (mode == MODE_CREATE) |
| 38 { |
| 39 SECURITY_ATTRIBUTES sa; |
| 40 memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); |
| 41 sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
| 42 |
| 43 // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb625958
.aspx |
| 44 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; |
| 45 PSECURITY_DESCRIPTOR securitydescriptor; |
| 46 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDD
L_REVISION_1, &securitydescriptor, 0); |
| 47 |
| 48 sa.lpSecurityDescriptor = securitydescriptor; |
| 49 sa.bInheritHandle = TRUE; |
| 50 |
| 51 pipe = CreateNamedPipeW (pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MES
SAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, |
| 52 PIPE_UNLIMITED_INSTANCES, Communication::buffe
rSize, Communication::bufferSize, 0, &sa); |
| 53 LocalFree(securitydescriptor); |
| 54 } |
| 55 else |
| 56 { |
| 57 if (WaitNamedPipeW(pipeName.c_str(), 5000)) |
| 58 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O
PEN_EXISTING, 0, 0); |
| 59 } |
| 60 |
| 61 if (pipe == INVALID_HANDLE_VALUE) |
| 62 throw PipeConnectionError(); |
| 63 |
| 64 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; |
| 65 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) |
| 66 throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastE
rror()); |
| 67 |
| 68 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) |
| 69 throw std::runtime_error("Client failed to connect: error " + GetLastError()
); |
| 70 } |
| 71 |
| 72 Communication::Pipe::~Pipe() |
| 73 { |
| 74 CloseHandle(pipe); |
| 75 } |
| 76 |
| 77 Communication::InputBuffer Communication::Pipe::ReadMessage() |
| 27 { | 78 { |
| 28 std::stringstream stream; | 79 std::stringstream stream; |
| 29 std::auto_ptr<char> buffer(new char[bufferSize]); | 80 std::auto_ptr<char> buffer(new char[bufferSize]); |
| 30 bool doneReading = false; | 81 bool doneReading = false; |
| 31 while (!doneReading) | 82 while (!doneReading) |
| 32 { | 83 { |
| 33 DWORD bytesRead; | 84 DWORD bytesRead; |
| 34 if (ReadFile(pipe, buffer.get(), bufferSize * sizeof(char), &bytesRead, 0)) | 85 if (ReadFile(pipe, buffer.get(), bufferSize * sizeof(char), &bytesRead, 0)) |
| 35 doneReading = true; | 86 doneReading = true; |
| 36 else if (GetLastError() != ERROR_MORE_DATA) | 87 else if (GetLastError() != ERROR_MORE_DATA) |
| 37 { | 88 { |
| 38 std::stringstream stream; | 89 std::stringstream stream; |
| 39 stream << "Error reading from pipe: " << GetLastError(); | 90 stream << "Error reading from pipe: " << GetLastError(); |
| 40 throw std::runtime_error(stream.str()); | 91 throw std::runtime_error(stream.str()); |
| 41 } | 92 } |
| 42 stream << std::string(buffer.get(), bytesRead); | 93 stream << std::string(buffer.get(), bytesRead); |
| 43 } | 94 } |
| 44 return Communication::InputBuffer(stream.str()); | 95 return Communication::InputBuffer(stream.str()); |
| 45 } | 96 } |
| 46 | 97 |
| 47 void Communication::WriteMessage(HANDLE pipe, Communication::OutputBuffer& messa
ge) | 98 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) |
| 48 { | 99 { |
| 49 DWORD bytesWritten; | 100 DWORD bytesWritten; |
| 50 std::string data = message.Get(); | 101 std::string data = message.Get(); |
| 51 if (!WriteFile(pipe, data.c_str(), data.length(), &bytesWritten, 0)) | 102 if (!WriteFile(pipe, data.c_str(), data.length(), &bytesWritten, 0)) |
| 52 throw std::runtime_error("Failed to write to pipe"); | 103 throw std::runtime_error("Failed to write to pipe"); |
| 53 } | 104 } |
| OLD | NEW |