Crypto++
|
00001 #ifndef CRYPTOPP_WINPIPES_H 00002 #define CRYPTOPP_WINPIPES_H 00003 00004 #include "config.h" 00005 00006 #ifdef WINDOWS_PIPES_AVAILABLE 00007 00008 #include "network.h" 00009 #include "queue.h" 00010 #include <winsock2.h> 00011 00012 NAMESPACE_BEGIN(CryptoPP) 00013 00014 //! Windows Handle 00015 class WindowsHandle 00016 { 00017 public: 00018 WindowsHandle(HANDLE h = INVALID_HANDLE_VALUE, bool own=false); 00019 WindowsHandle(const WindowsHandle &h) : m_h(h.m_h), m_own(false) {} 00020 virtual ~WindowsHandle(); 00021 00022 bool GetOwnership() const {return m_own;} 00023 void SetOwnership(bool own) {m_own = own;} 00024 00025 operator HANDLE() {return m_h;} 00026 HANDLE GetHandle() const {return m_h;} 00027 bool HandleValid() const; 00028 void AttachHandle(HANDLE h, bool own=false); 00029 HANDLE DetachHandle(); 00030 void CloseHandle(); 00031 00032 protected: 00033 virtual void HandleChanged() {} 00034 00035 HANDLE m_h; 00036 bool m_own; 00037 }; 00038 00039 //! Windows Pipe 00040 class WindowsPipe 00041 { 00042 public: 00043 class Err : public OS_Error 00044 { 00045 public: 00046 Err(HANDLE h, const std::string& operation, int error); 00047 HANDLE GetHandle() const {return m_h;} 00048 00049 private: 00050 HANDLE m_h; 00051 }; 00052 00053 protected: 00054 virtual HANDLE GetHandle() const =0; 00055 virtual void HandleError(const char *operation) const; 00056 void CheckAndHandleError(const char *operation, BOOL result) const 00057 {assert(result==TRUE || result==FALSE); if (!result) HandleError(operation);} 00058 }; 00059 00060 //! pipe-based implementation of NetworkReceiver 00061 class WindowsPipeReceiver : public WindowsPipe, public NetworkReceiver 00062 { 00063 public: 00064 WindowsPipeReceiver(); 00065 00066 bool MustWaitForResult() {return true;} 00067 bool Receive(byte* buf, size_t bufLen); 00068 unsigned int GetReceiveResult(); 00069 bool EofReceived() const {return m_eofReceived;} 00070 00071 unsigned int GetMaxWaitObjectCount() const {return 1;} 00072 void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); 00073 00074 private: 00075 WindowsHandle m_event; 00076 OVERLAPPED m_overlapped; 00077 bool m_resultPending; 00078 DWORD m_lastResult; 00079 bool m_eofReceived; 00080 }; 00081 00082 //! pipe-based implementation of NetworkSender 00083 class WindowsPipeSender : public WindowsPipe, public NetworkSender 00084 { 00085 public: 00086 WindowsPipeSender(); 00087 00088 bool MustWaitForResult() {return true;} 00089 void Send(const byte* buf, size_t bufLen); 00090 unsigned int GetSendResult(); 00091 bool MustWaitForEof() { return false; } 00092 void SendEof() {} 00093 00094 unsigned int GetMaxWaitObjectCount() const {return 1;} 00095 void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); 00096 00097 private: 00098 WindowsHandle m_event; 00099 OVERLAPPED m_overlapped; 00100 bool m_resultPending; 00101 DWORD m_lastResult; 00102 }; 00103 00104 //! Windows Pipe Source 00105 class WindowsPipeSource : public WindowsHandle, public NetworkSource, public WindowsPipeReceiver 00106 { 00107 public: 00108 WindowsPipeSource(HANDLE h=INVALID_HANDLE_VALUE, bool pumpAll=false, BufferedTransformation *attachment=NULL) 00109 : WindowsHandle(h), NetworkSource(attachment) 00110 { 00111 if (pumpAll) 00112 PumpAll(); 00113 } 00114 00115 NetworkSource::GetMaxWaitObjectCount; 00116 NetworkSource::GetWaitObjects; 00117 00118 private: 00119 HANDLE GetHandle() const {return WindowsHandle::GetHandle();} 00120 NetworkReceiver & AccessReceiver() {return *this;} 00121 }; 00122 00123 //! Windows Pipe Sink 00124 class WindowsPipeSink : public WindowsHandle, public NetworkSink, public WindowsPipeSender 00125 { 00126 public: 00127 WindowsPipeSink(HANDLE h=INVALID_HANDLE_VALUE, unsigned int maxBufferSize=0, unsigned int autoFlushBound=16*1024) 00128 : WindowsHandle(h), NetworkSink(maxBufferSize, autoFlushBound) {} 00129 00130 NetworkSink::GetMaxWaitObjectCount; 00131 NetworkSink::GetWaitObjects; 00132 00133 private: 00134 HANDLE GetHandle() const {return WindowsHandle::GetHandle();} 00135 NetworkSender & AccessSender() {return *this;} 00136 }; 00137 00138 NAMESPACE_END 00139 00140 #endif 00141 00142 #endif