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 |