00001 #ifndef CRYPTOPP_WINPIPES_H
00002 #define CRYPTOPP_WINPIPES_H
00003
00004 #include "cryptopp_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
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
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
00061 class WindowsPipeReceiver : public WindowsPipe, public NetworkReceiver
00062 {
00063 public:
00064 WindowsPipeReceiver();
00065
00066 bool MustWaitForResult() {return true;}
00067 bool Receive(byte* buf, unsigned int 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);
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
00083 class WindowsPipeSender : public WindowsPipe, public NetworkSender
00084 {
00085 public:
00086 WindowsPipeSender();
00087
00088 bool MustWaitForResult() {return true;}
00089 void Send(const byte* buf, unsigned int bufLen);
00090 unsigned int GetSendResult();
00091 void SendEof() {}
00092
00093 unsigned int GetMaxWaitObjectCount() const {return 1;}
00094 void GetWaitObjects(WaitObjectContainer &container);
00095
00096 private:
00097 WindowsHandle m_event;
00098 OVERLAPPED m_overlapped;
00099 bool m_resultPending;
00100 DWORD m_lastResult;
00101 };
00102
00103
00104 class WindowsPipeSource : public WindowsHandle, public NetworkSource, public WindowsPipeReceiver
00105 {
00106 public:
00107 WindowsPipeSource(HANDLE h=INVALID_HANDLE_VALUE, bool pumpAll=false, BufferedTransformation *attachment=NULL)
00108 : WindowsHandle(h), NetworkSource(attachment)
00109 {
00110 if (pumpAll)
00111 PumpAll();
00112 }
00113
00114 NetworkSource::GetMaxWaitObjectCount;
00115 NetworkSource::GetWaitObjects;
00116
00117 private:
00118 HANDLE GetHandle() const {return WindowsHandle::GetHandle();}
00119 NetworkReceiver & AccessReceiver() {return *this;}
00120 };
00121
00122
00123 class WindowsPipeSink : public WindowsHandle, public NetworkSink, public WindowsPipeSender
00124 {
00125 public:
00126 WindowsPipeSink(HANDLE h=INVALID_HANDLE_VALUE, unsigned int maxBufferSize=0, unsigned int autoFlushBound=16*1024)
00127 : WindowsHandle(h), NetworkSink(maxBufferSize, autoFlushBound) {}
00128
00129 NetworkSink::GetMaxWaitObjectCount;
00130 NetworkSink::GetWaitObjects;
00131
00132 private:
00133 HANDLE GetHandle() const {return WindowsHandle::GetHandle();}
00134 NetworkSender & AccessSender() {return *this;}
00135 };
00136
00137 NAMESPACE_END
00138
00139 #endif
00140
00141 #endif