6 #if !defined(NO_OS_DEPENDENCE) && defined(WINDOWS_PIPES_AVAILABLE)
12 #if defined(CRYPTOPP_WIN32_AVAILABLE)
13 # if ((WINVER >= 0x0602 ) || (_WIN32_WINNT >= 0x0602 ))
14 # include <synchapi.h>
15 # include <ioapiset.h>
16 # define USE_WINDOWS8_API
22 WindowsHandle::WindowsHandle(HANDLE h,
bool own)
27 WindowsHandle::~WindowsHandle()
42 bool WindowsHandle::HandleValid()
const
44 return m_h && m_h != INVALID_HANDLE_VALUE;
47 void WindowsHandle::AttachHandle(HANDLE h,
bool own)
57 HANDLE WindowsHandle::DetachHandle()
60 m_h = INVALID_HANDLE_VALUE;
65 void WindowsHandle::CloseHandle()
67 if (m_h != INVALID_HANDLE_VALUE)
70 m_h = INVALID_HANDLE_VALUE;
77 void WindowsPipe::HandleError(
const char *operation)
const
79 DWORD err = GetLastError();
80 throw Err(GetHandle(), operation, err);
83 WindowsPipe::Err::Err(HANDLE s,
const std::string& operation,
int error)
84 :
OS_Error(IO_ERROR,
"WindowsPipe: " + operation +
" operation failed with error 0x" +
IntToString(error, 16), operation, error)
91 WindowsPipeReceiver::WindowsPipeReceiver()
92 : m_resultPending(false), m_eofReceived(false)
94 m_event.AttachHandle(CreateEvent(NULL,
true,
false, NULL),
true);
95 CheckAndHandleError(
"CreateEvent", m_event.HandleValid());
96 memset(&m_overlapped, 0,
sizeof(m_overlapped));
97 m_overlapped.hEvent = m_event;
102 assert(!m_resultPending && !m_eofReceived);
104 const HANDLE h = GetHandle();
106 if (ReadFile(h, buf,
UnsignedMin((DWORD)128*1024, bufLen), &m_lastResult, &m_overlapped))
108 if (m_lastResult == 0)
109 m_eofReceived =
true;
113 switch (GetLastError())
116 CheckAndHandleError(
"ReadFile",
false);
117 case ERROR_BROKEN_PIPE:
118 case ERROR_HANDLE_EOF:
120 m_eofReceived =
true;
122 case ERROR_IO_PENDING:
123 m_resultPending =
true;
126 return !m_resultPending;
132 container.AddHandle(m_event,
CallStack(
"WindowsPipeReceiver::GetWaitObjects() - result pending", &callStack));
133 else if (!m_eofReceived)
134 container.SetNoWait(
CallStack(
"WindowsPipeReceiver::GetWaitObjects() - result ready", &callStack));
137 unsigned int WindowsPipeReceiver::GetReceiveResult()
141 #if defined(USE_WINDOWS8_API)
142 BOOL result = GetOverlappedResultEx(GetHandle(), &m_overlapped, &m_lastResult, INFINITE, FALSE);
144 BOOL result = GetOverlappedResult(GetHandle(), &m_overlapped, &m_lastResult, FALSE);
148 if (m_lastResult == 0)
149 m_eofReceived =
true;
153 switch (GetLastError())
156 CheckAndHandleError(
"GetOverlappedResult",
false);
157 case ERROR_BROKEN_PIPE:
158 case ERROR_HANDLE_EOF:
160 m_eofReceived =
true;
163 m_resultPending =
false;
170 WindowsPipeSender::WindowsPipeSender()
171 : m_resultPending(false), m_lastResult(0)
173 m_event.AttachHandle(CreateEvent(NULL,
true,
false, NULL),
true);
174 CheckAndHandleError(
"CreateEvent", m_event.HandleValid());
175 memset(&m_overlapped, 0,
sizeof(m_overlapped));
176 m_overlapped.hEvent = m_event;
179 void WindowsPipeSender::Send(
const byte* buf,
size_t bufLen)
182 const HANDLE h = GetHandle();
184 if (WriteFile(h, buf,
UnsignedMin((DWORD)128*1024, bufLen), &written, &m_overlapped))
186 m_resultPending =
false;
187 m_lastResult = written;
191 if (GetLastError() != ERROR_IO_PENDING)
192 CheckAndHandleError(
"WriteFile",
false);
194 m_resultPending =
true;
201 container.AddHandle(m_event,
CallStack(
"WindowsPipeSender::GetWaitObjects() - result pending", &callStack));
203 container.SetNoWait(
CallStack(
"WindowsPipeSender::GetWaitObjects() - result ready", &callStack));
206 unsigned int WindowsPipeSender::GetSendResult()
210 const HANDLE h = GetHandle();
211 #if defined(USE_WINDOWS8_API)
212 BOOL result = GetOverlappedResultEx(h, &m_overlapped, &m_lastResult, INFINITE, FALSE);
213 CheckAndHandleError(
"GetOverlappedResultEx", result);
215 BOOL result = GetOverlappedResult(h, &m_overlapped, &m_lastResult, FALSE);
216 CheckAndHandleError(
"GetOverlappedResult", result);
218 m_resultPending =
false;