OLD | NEW |
1 #include <Windows.h> | 1 #include <Windows.h> |
2 #include <Lmcons.h> | 2 #include <Lmcons.h> |
3 #include <Sddl.h> | 3 #include <Sddl.h> |
4 | 4 |
5 #include "Communication.h" | 5 #include "Communication.h" |
6 | 6 |
7 namespace | 7 namespace |
8 { | 8 { |
9 const int bufferSize = 1024; | 9 const int bufferSize = 1024; |
10 | 10 |
(...skipping 30 matching lines...) Expand all Loading... |
41 } | 41 } |
42 else | 42 else |
43 hasType = false; | 43 hasType = false; |
44 } | 44 } |
45 | 45 |
46 Communication::PipeConnectionError::PipeConnectionError() | 46 Communication::PipeConnectionError::PipeConnectionError() |
47 : std::runtime_error(AppendErrorCode("Unable to connect to a named pipe")) | 47 : std::runtime_error(AppendErrorCode("Unable to connect to a named pipe")) |
48 { | 48 { |
49 } | 49 } |
50 | 50 |
| 51 Communication::PipeBusyError::PipeBusyError() |
| 52 : std::runtime_error("Timeout while trying to connect to a named pipe, pipe is
busy") |
| 53 { |
| 54 } |
| 55 |
51 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod
e mode) | 56 Communication::Pipe::Pipe(const std::wstring& pipeName, Communication::Pipe::Mod
e mode) |
52 { | 57 { |
53 pipe = INVALID_HANDLE_VALUE; | 58 pipe = INVALID_HANDLE_VALUE; |
54 if (mode == MODE_CREATE) | 59 if (mode == MODE_CREATE) |
55 { | 60 { |
56 SECURITY_ATTRIBUTES sa; | 61 SECURITY_ATTRIBUTES sa; |
57 memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); | 62 memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES)); |
58 sa.nLength = sizeof(SECURITY_ATTRIBUTES); | 63 sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
59 | 64 |
60 // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb625958
.aspx | 65 // Low mandatory label. See http://msdn.microsoft.com/en-us/library/bb625958
.aspx |
61 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; | 66 LPCWSTR accessControlEntry = L"S:(ML;;NW;;;LW)"; |
62 PSECURITY_DESCRIPTOR securitydescriptor; | 67 PSECURITY_DESCRIPTOR securitydescriptor; |
63 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDD
L_REVISION_1, &securitydescriptor, 0); | 68 ConvertStringSecurityDescriptorToSecurityDescriptorW(accessControlEntry, SDD
L_REVISION_1, &securitydescriptor, 0); |
64 | 69 |
65 sa.lpSecurityDescriptor = securitydescriptor; | 70 sa.lpSecurityDescriptor = securitydescriptor; |
66 sa.bInheritHandle = TRUE; | 71 sa.bInheritHandle = TRUE; |
67 | 72 |
68 pipe = CreateNamedPipeW (pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MES
SAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, | 73 pipe = CreateNamedPipeW (pipeName.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MES
SAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, |
69 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSi
ze, 0, &sa); | 74 PIPE_UNLIMITED_INSTANCES, bufferSize, bufferSi
ze, 0, &sa); |
70 LocalFree(securitydescriptor); | 75 LocalFree(securitydescriptor); |
71 } | 76 } |
72 else | 77 else |
73 { | 78 { |
74 if (WaitNamedPipeW(pipeName.c_str(), 5000)) | 79 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPE
N_EXISTING, 0, 0); |
| 80 if (pipe == INVALID_HANDLE_VALUE && GetLastError() == ERROR_PIPE_BUSY) |
| 81 { |
| 82 if (!WaitNamedPipeW(pipeName.c_str(), 5000)) |
| 83 throw PipeBusyError(); |
| 84 |
75 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O
PEN_EXISTING, 0, 0); | 85 pipe = CreateFileW(pipeName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, O
PEN_EXISTING, 0, 0); |
| 86 } |
76 } | 87 } |
77 | 88 |
78 if (pipe == INVALID_HANDLE_VALUE) | 89 if (pipe == INVALID_HANDLE_VALUE) |
79 throw PipeConnectionError(); | 90 throw PipeConnectionError(); |
80 | 91 |
81 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; | 92 DWORD pipeMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; |
82 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) | 93 if (!SetNamedPipeHandleState(pipe, &pipeMode, 0, 0)) |
83 throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastE
rror()); | 94 throw std::runtime_error("SetNamedPipeHandleState failed: error " + GetLastE
rror()); |
84 | 95 |
85 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) | 96 if (mode == MODE_CREATE && !ConnectNamedPipe(pipe, 0)) |
(...skipping 26 matching lines...) Expand all Loading... |
112 return Communication::InputBuffer(stream.str()); | 123 return Communication::InputBuffer(stream.str()); |
113 } | 124 } |
114 | 125 |
115 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) | 126 void Communication::Pipe::WriteMessage(Communication::OutputBuffer& message) |
116 { | 127 { |
117 DWORD bytesWritten; | 128 DWORD bytesWritten; |
118 std::string data = message.Get(); | 129 std::string data = message.Get(); |
119 if (!WriteFile(pipe, data.c_str(), data.length(), &bytesWritten, 0)) | 130 if (!WriteFile(pipe, data.c_str(), data.length(), &bytesWritten, 0)) |
120 throw std::runtime_error("Failed to write to pipe"); | 131 throw std::runtime_error("Failed to write to pipe"); |
121 } | 132 } |
OLD | NEW |