Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
8.6 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1997
  5. //
  6. // File: pipes.hxx
  7. //
  8. //---------------------------------------------------------------------------
  9. #include <objidl.h>
  10. //+**************************************************************************
  11. // CPipePSFactory : public IPSFactoryBuffer
  12. //
  13. // Description: Class factory for creating pipe proxy and stub.
  14. //
  15. // History:
  16. // Date: Time: Developer: Action:
  17. // 11/11/97 11:16:05 AM RichN Created.
  18. //
  19. // Notes:
  20. //
  21. //-**************************************************************************
  22. class CPipePSFactory : public IPSFactoryBuffer
  23. {
  24. public:
  25. STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj);
  26. STDMETHOD_(ULONG,AddRef) ();
  27. STDMETHOD_(ULONG,Release) ();
  28. STDMETHOD(CreateProxy) ( IUnknown *pUnkOuter,
  29. REFIID riid,
  30. IRpcProxyBuffer **ppProxy,
  31. void **ppv );
  32. STDMETHOD(CreateStub) ( REFIID riid,
  33. IUnknown *pUnkServer,
  34. IRpcStubBuffer **ppStub );
  35. CPipePSFactory();
  36. virtual ~CPipePSFactory();
  37. private:
  38. LONG m_cRef;
  39. };
  40. //+**************************************************************************
  41. // CPipeProxyImp : public IRpcProxyBuffer
  42. //
  43. // Description: Actual implementation of the proxy since it is agragated
  44. // by the proxy manager. It holds a pointer to the real
  45. // pipe proxy which has a pointer to the real proxy.
  46. //
  47. // History:
  48. // Date: Time: Developer: Action:
  49. // 11/11/97 11:16:48 AM RichN Created.
  50. //
  51. // Notes: When the ref count goes to zero, delete the pipe proxy object which
  52. // will addref the outer unknown and then release the real
  53. // proxy. Next, release the IRpcProxyBuffer pointer and delete this.
  54. //
  55. //-**************************************************************************
  56. class CPipeProxyImp : public IRpcProxyBuffer
  57. {
  58. public:
  59. STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj);
  60. STDMETHOD_(ULONG,AddRef) ();
  61. STDMETHOD_(ULONG,Release) ();
  62. // Interface IRpcProxyBuffer
  63. STDMETHOD(Connect)(IRpcChannelBuffer *pRpcChannelBuffer);
  64. STDMETHOD_(void, Disconnect)( void);
  65. CPipeProxyImp(IUnknown *pUnkOuter,
  66. IRpcProxyBuffer *pInternalPB,
  67. IUnknown *pRealPipeProxy,
  68. IUnknown *pInternalPipeProxy,
  69. IID iid);
  70. virtual ~CPipeProxyImp();
  71. private:
  72. LONG m_cRef; // Reference count.
  73. IUnknown *m_pUnkOuter; // Outer unknown.
  74. IUnknown *m_pRealPipeProxy; // Pointer to real proxy.
  75. IUnknown *m_pInternalPipeProxy; // Pointer to internal proxy.
  76. IRpcProxyBuffer *m_pInternalPB; // pointer to real RPC Proxy Buffer.
  77. IID m_IidOfPipe; // iid of the pipe.
  78. };
  79. //+**************************************************************************
  80. // CPipeProxy : public I
  81. //
  82. // Description: The proxy that intercepts the pipe calls and does all
  83. // the read ahead and write behind.
  84. //
  85. // History:
  86. // Date: Time: Developer: Action:
  87. // 11/11/97 11:19:37 AM RichN Created.
  88. //
  89. // Notes:
  90. //
  91. //-**************************************************************************
  92. typedef enum PULLSTATE
  93. {
  94. PULLSTATE0_ENTRY = 0x00, // Default start.
  95. PULLSTATE1_FIRST_CALL, // Start, no saved data, no outstanding async call
  96. PULLSTATE2_NS_RQlsRA, // No saved, request < read ahead
  97. PULLSTATE3_NS_RQgeRA, // No saved, request >= read ahead
  98. PULLSTATE4_S_RQlsBS, // Have saved data, request < buffer size(saved data)
  99. PULLSTATE5_S_RQgeBS, // Have saved data, request >= buffer size
  100. PULLSTATE6_DONE // No saved, last data read was zero
  101. } PULLSTATE;
  102. const LONG MAX_PULL_STATES = PULLSTATE6_DONE + 1;
  103. typedef enum PUSHSTATE
  104. {
  105. PUSHSTATE0_ENTRY = 0x00, // Default start.
  106. PUSHSTATE1_FIRSTCALL, // First call to push. Create buffer in this state.
  107. PUSHSTATE2_FS_PSgeFS, // Free space > 0 and the push size is >= Free space.
  108. PUSHSTATE3_FS_PSltFS, // Free space > 0 and the push size is < Free space.
  109. PUSHSTATE4_FS_PSZERO, // Free space > 0 and push size is zero.
  110. PUSHSTATE5_DONE_ERROR // Done, really should never get here.
  111. } PUSHSTATE;
  112. const LONG MAX_PUSH_STATES = PUSHSTATE5_DONE_ERROR + 1;
  113. template<class T, const IID *ID, const IID *AsyncID, class I, class AsyncI>
  114. class CPipeProxy : public I,
  115. public CPrivAlloc
  116. {
  117. friend CPipeProxyImp;
  118. public:
  119. // IUnknown
  120. STDMETHOD(QueryInterface) (REFIID riid, LPVOID FAR* ppvObj);
  121. STDMETHOD_(ULONG,AddRef) ();
  122. STDMETHOD_(ULONG,Release) ();
  123. // IPipexxxx methods.
  124. STDMETHOD(Pull)( T *Buf, ULONG Request, ULONG *Received);
  125. STDMETHOD(Push)( T *Buf, ULONG count);
  126. CPipeProxy( IUnknown *pUnkOuter, void * pProxy );
  127. virtual ~CPipeProxy( void );
  128. private:
  129. HRESULT InitAsync(IUnknown** ppCallObj,
  130. AsyncI** ppAsyncPipe,
  131. ISynchronize** ppISync); // Create async interfaces.
  132. void CleanupProxy(T ** ppBuffer,
  133. IUnknown** ppCallObj,
  134. AsyncI** ppAsyncPipe,
  135. ISynchronize** ppISync); // Release async interfaces.
  136. void CancelTheCall(IUnknown *pCallObj, DWORD delay);
  137. // Implements the state machine for read ahead.
  138. // See constructor for brief explaination of the names.
  139. // Number at the end corresponds to the state number.
  140. HRESULT PullStateTransition(ULONG Request);
  141. HRESULT NbNaRgtRA1 (T *Buf, ULONG Request, ULONG *Received);
  142. HRESULT NbaRltRA2 (T *Buf, ULONG Request, ULONG *Received);
  143. HRESULT NbaRgtRA3 (T *Buf, ULONG Request, ULONG *Received);
  144. HRESULT baRltB4 (T *Buf, ULONG Request, ULONG *Received);
  145. HRESULT baRgtB5 (T *Buf, ULONG Request, ULONG *Received);
  146. HRESULT PullDone6 (T *Buf, ULONG Request, ULONG *Received);
  147. private:
  148. // Implements the state machine for write behind.
  149. // See constructor for brief explaination of the names.
  150. // Number at the end corresponds to the state number.
  151. HRESULT PushStateTransition(ULONG PushSize);
  152. HRESULT NbNf1 (T *Buf, ULONG PushSize);
  153. HRESULT bfPgtF2 (T *Buf, ULONG PushSize);
  154. HRESULT bfPltF3 (T *Buf, ULONG PushSize);
  155. HRESULT bPSz4 (T *Buf, ULONG PushSize);
  156. HRESULT PushDone5 (T *Buf, ULONG PushSize);
  157. private:
  158. // State for the entire object.
  159. IUnknown *m_pUnkOuter; // Outer unknown
  160. LONG m_cRef; // internal reference count.
  161. I *m_pRealProxy; // Pointer to real proxy.
  162. private:
  163. // Helper methods and state for Pull.
  164. void SetReadAhead (ULONG Request);
  165. HRESULT CheckAndSetKeepBuffer(void);
  166. IUnknown *m_pPullCallObj; // Call object.
  167. AsyncI *m_pAsyncPullPipe; // Ptr to async interface.
  168. ISynchronize *m_pISyncPull; // Ptr to the synchronize obj.
  169. PULLSTATE m_PullState; // Current pull state.
  170. ULONG m_cReadAhead; // Read ahead size in the async call.
  171. ULONG m_cLastRead; // Last amount read.
  172. ULONG m_cKeepBufferSize; // Size of the keep buffer.
  173. T *m_pKeepBuffer; // Where we store any data we keep around.
  174. ULONG m_cKeepDataSize; // Amount of data kept.
  175. T *m_pKeepData; // Pointer to the data in the buffer.
  176. private:
  177. // Helper methods and state for Push.
  178. HRESULT SetPushBuffer(ULONG PushSize);
  179. IUnknown *m_pPushCallObj; // Call object.
  180. AsyncI *m_pAsyncPushPipe; // Ptr to async interface.
  181. ISynchronize *m_pISyncPush; // Ptr to the synchronize obj.
  182. PUSHSTATE m_PushState; // Current push state.
  183. ULONG m_cPushBufferSize; // Size of the push buffer in elements.
  184. T *m_pPushBuffer; // Ptr to the buffer.
  185. ULONG m_cFreeSpace; // Unused space in push buffer.
  186. T *m_pFreeSpace; // Ptr to start of free space.
  187. // Arrays for holding the state methods.
  188. typedef HRESULT
  189. (CPipeProxy<T, ID, AsyncID, I, AsyncI>::*PPULLSTATEFUNC)
  190. (T *Buf, ULONG Request, ULONG *Received);
  191. PPULLSTATEFUNC PullStateFunc[MAX_PULL_STATES];
  192. typedef HRESULT
  193. (CPipeProxy<T, ID, AsyncID, I, AsyncI>::*PPUSHSTATEFUNC)
  194. (T *Buf, ULONG Count);
  195. PPUSHSTATEFUNC PushStateFunc[MAX_PUSH_STATES];
  196. };
  197. // Prototypes
  198. EXTERN_C HRESULT ProxyDllGetClassObject(REFCLSID clsid, REFIID iid, void **ppv);