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
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, 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
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
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
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