Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

winpipes.cpp

00001 // winpipes.cpp - written and placed in the public domain by Wei Dai 00002 00003 #include "pch.h" 00004 #include "winpipes.h" 00005 00006 #ifdef WINDOWS_PIPES_AVAILABLE 00007 00008 #include "wait.h" 00009 00010 NAMESPACE_BEGIN(CryptoPP) 00011 00012 WindowsHandle::WindowsHandle(HANDLE h, bool own) 00013 : m_h(h), m_own(own) 00014 { 00015 } 00016 00017 WindowsHandle::~WindowsHandle() 00018 { 00019 if (m_own) 00020 { 00021 try 00022 { 00023 CloseHandle(); 00024 } 00025 catch (...) 00026 { 00027 } 00028 } 00029 } 00030 00031 bool WindowsHandle::HandleValid() const 00032 { 00033 return m_h && m_h != INVALID_HANDLE_VALUE; 00034 } 00035 00036 void WindowsHandle::AttachHandle(HANDLE h, bool own) 00037 { 00038 if (m_own) 00039 CloseHandle(); 00040 00041 m_h = h; 00042 m_own = own; 00043 HandleChanged(); 00044 } 00045 00046 HANDLE WindowsHandle::DetachHandle() 00047 { 00048 HANDLE h = m_h; 00049 m_h = INVALID_HANDLE_VALUE; 00050 HandleChanged(); 00051 return h; 00052 } 00053 00054 void WindowsHandle::CloseHandle() 00055 { 00056 if (m_h != INVALID_HANDLE_VALUE) 00057 { 00058 ::CloseHandle(m_h); 00059 m_h = INVALID_HANDLE_VALUE; 00060 HandleChanged(); 00061 } 00062 } 00063 00064 // ******************************************************** 00065 00066 void WindowsPipe::HandleError(const char *operation) const 00067 { 00068 DWORD err = GetLastError(); 00069 throw Err(GetHandle(), operation, err); 00070 } 00071 00072 WindowsPipe::Err::Err(HANDLE s, const std::string& operation, int error) 00073 : OS_Error(IO_ERROR, "WindowsPipe: " + operation + " operation failed with error 0x" + IntToString(error, 16), operation, error) 00074 , m_h(s) 00075 { 00076 } 00077 00078 // ************************************************************* 00079 00080 WindowsPipeReceiver::WindowsPipeReceiver() 00081 : m_resultPending(false), m_eofReceived(false) 00082 { 00083 m_event.AttachHandle(CreateEvent(NULL, true, false, NULL), true); 00084 CheckAndHandleError("CreateEvent", m_event.HandleValid()); 00085 memset(&m_overlapped, 0, sizeof(m_overlapped)); 00086 m_overlapped.hEvent = m_event; 00087 } 00088 00089 void WindowsPipeReceiver::Receive(byte* buf, unsigned int bufLen) 00090 { 00091 assert(!m_resultPending && !m_eofReceived); 00092 00093 HANDLE h = GetHandle(); 00094 if (ReadFile(h, buf, bufLen, &m_lastResult, &m_overlapped)) 00095 { 00096 if (m_lastResult == 0) 00097 m_eofReceived = true; 00098 } 00099 else 00100 { 00101 switch (GetLastError()) 00102 { 00103 default: 00104 CheckAndHandleError("ReadFile", false); 00105 case ERROR_BROKEN_PIPE: 00106 case ERROR_HANDLE_EOF: 00107 m_lastResult = 0; 00108 m_eofReceived = true; 00109 break; 00110 case ERROR_IO_PENDING: 00111 m_resultPending = true; 00112 } 00113 } 00114 } 00115 00116 void WindowsPipeReceiver::GetWaitObjects(WaitObjectContainer &container) 00117 { 00118 if (m_resultPending) 00119 container.AddHandle(m_event); 00120 else if (!m_eofReceived) 00121 container.SetNoWait(); 00122 } 00123 00124 unsigned int WindowsPipeReceiver::GetReceiveResult() 00125 { 00126 if (m_resultPending) 00127 { 00128 HANDLE h = GetHandle(); 00129 if (GetOverlappedResult(h, &m_overlapped, &m_lastResult, false)) 00130 { 00131 if (m_lastResult == 0) 00132 m_eofReceived = true; 00133 } 00134 else 00135 { 00136 switch (GetLastError()) 00137 { 00138 default: 00139 CheckAndHandleError("GetOverlappedResult", false); 00140 case ERROR_BROKEN_PIPE: 00141 case ERROR_HANDLE_EOF: 00142 m_lastResult = 0; 00143 m_eofReceived = true; 00144 } 00145 } 00146 m_resultPending = false; 00147 } 00148 return m_lastResult; 00149 } 00150 00151 // ************************************************************* 00152 00153 WindowsPipeSender::WindowsPipeSender() 00154 : m_resultPending(false), m_lastResult(0) 00155 { 00156 m_event.AttachHandle(CreateEvent(NULL, true, false, NULL), true); 00157 CheckAndHandleError("CreateEvent", m_event.HandleValid()); 00158 memset(&m_overlapped, 0, sizeof(m_overlapped)); 00159 m_overlapped.hEvent = m_event; 00160 } 00161 00162 void WindowsPipeSender::Send(const byte* buf, unsigned int bufLen) 00163 { 00164 DWORD written = 0; 00165 HANDLE h = GetHandle(); 00166 if (WriteFile(h, buf, bufLen, &written, &m_overlapped)) 00167 { 00168 m_resultPending = false; 00169 m_lastResult = written; 00170 } 00171 else 00172 { 00173 if (GetLastError() != ERROR_IO_PENDING) 00174 CheckAndHandleError("WriteFile", false); 00175 00176 m_resultPending = true; 00177 } 00178 } 00179 00180 void WindowsPipeSender::GetWaitObjects(WaitObjectContainer &container) 00181 { 00182 if (m_resultPending) 00183 container.AddHandle(m_event); 00184 else 00185 container.SetNoWait(); 00186 } 00187 00188 unsigned int WindowsPipeSender::GetSendResult() 00189 { 00190 if (m_resultPending) 00191 { 00192 HANDLE h = GetHandle(); 00193 BOOL result = GetOverlappedResult(h, &m_overlapped, &m_lastResult, false); 00194 CheckAndHandleError("GetOverlappedResult", result); 00195 m_resultPending = false; 00196 } 00197 return m_lastResult; 00198 } 00199 00200 NAMESPACE_END 00201 00202 #endif

Generated on Fri Aug 13 09:56:55 2004 for Crypto++ by doxygen 1.3.7