Leaked source code of windows server 2003
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.

351 lines
6.2 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. sacio.cpp
  5. Abstract:
  6. This module implements the SAC IoHandler functionality.
  7. The SAC IoHandler implements a write buffer so that the
  8. # of calls to teh SAC driver are reduced.
  9. Author:
  10. Brian Guarraci (briangu), 2001
  11. Revision History:
  12. --*/
  13. #include "sacio.h"
  14. //
  15. // Enable the write buffer
  16. //
  17. #define USE_SEND_BUFFER 1
  18. //
  19. // The size of the write buffer
  20. //
  21. #define SEND_BUFFER_SIZE 8192
  22. CSacIoHandler::CSacIoHandler(
  23. VOID
  24. )
  25. /*++
  26. Routine Description:
  27. Constructor
  28. Arguments:
  29. None
  30. Return Value:
  31. N/A
  32. --*/
  33. {
  34. //
  35. // We don't yet have a SAC channel object
  36. //
  37. mySacChannel = NULL;
  38. //
  39. // Create a send buffer
  40. //
  41. mySendBufferIndex = 0;
  42. mySendBuffer = new BYTE[SEND_BUFFER_SIZE];
  43. }
  44. CSacIoHandler::~CSacIoHandler(
  45. )
  46. /*++
  47. Routine Description:
  48. Destructor
  49. Arguments:
  50. N/A
  51. Return Value:
  52. N/A
  53. --*/
  54. {
  55. if (mySacChannel) {
  56. delete mySacChannel;
  57. }
  58. delete [] mySendBuffer;
  59. }
  60. CSacIoHandler*
  61. CSacIoHandler::Construct(
  62. IN SAC_CHANNEL_OPEN_ATTRIBUTES Attributes
  63. )
  64. /*++
  65. Routine Description:
  66. static constructor - this does the real construction
  67. Arguments:
  68. Attributes - attributes of the SAC channel to create
  69. Return Value:
  70. On success, a pointer to the new IoHandler
  71. On failure, NULL
  72. --*/
  73. {
  74. CSacIoHandler *IoHandler;
  75. //
  76. // Create a new SAC IoHandler
  77. //
  78. IoHandler = new CSacIoHandler();
  79. //
  80. // Attempt to open a SAC channel
  81. //
  82. IoHandler->mySacChannel = EMSCmdChannel::Construct(Attributes);
  83. //
  84. // If we failed to open the SAC channel,
  85. // then destroy the IoHandler and notify the caller
  86. // that we failed by returning null
  87. //
  88. if (IoHandler->mySacChannel == NULL) {
  89. delete IoHandler;
  90. return NULL;
  91. }
  92. return IoHandler;
  93. }
  94. BOOL
  95. CSacIoHandler::Write(
  96. IN PBYTE Buffer,
  97. IN ULONG BufferSize
  98. )
  99. /*++
  100. Routine Description:
  101. This routine impelements a buffered write IoHandler operation.
  102. Arguments:
  103. Buffer - the data to send
  104. BufferSize - the size of the buffer in bytes
  105. Return Value:
  106. TRUE - success
  107. FALSE - otherwise
  108. --*/
  109. {
  110. #if USE_SEND_BUFFER
  111. //
  112. // If the requested buffer to send is bigger than the
  113. // remaining local buffer, send the local buffer.
  114. //
  115. if (mySendBufferIndex + BufferSize > SEND_BUFFER_SIZE) {
  116. if (! Flush()) {
  117. return FALSE;
  118. }
  119. }
  120. // ASSERT(mySendBufferIndex + BufferSize <= SEND_BUFFER_SIZE);
  121. //
  122. // Copy the incoming buffer into our local buffer
  123. //
  124. RtlCopyMemory(
  125. &mySendBuffer[mySendBufferIndex],
  126. Buffer,
  127. BufferSize
  128. );
  129. //
  130. // Account for the added buffer contents
  131. //
  132. mySendBufferIndex += BufferSize;
  133. // ASSERT(mySendBufferIndex % sizeof(WCHAR) == 0);
  134. //
  135. // we succeeded
  136. //
  137. return TRUE;
  138. #else
  139. //
  140. // Send the local buffer to the SAC channel
  141. //
  142. bSuccess = mySacChannel->Write(
  143. (PCWCHAR)Buffer,
  144. BufferSize
  145. );
  146. //
  147. // Reset the local buffer index
  148. //
  149. mySendBufferIndex = 0;
  150. return bSuccess;
  151. #endif
  152. }
  153. BOOL
  154. CSacIoHandler::Flush(
  155. VOID
  156. )
  157. /*++
  158. Routine Description:
  159. This routine implements the Flush IoHandler method.
  160. If there is any data stored in the write buffer, it
  161. is flushed to the SAC channel.
  162. Arguments:
  163. None
  164. Return Value:
  165. TRUE - success
  166. FALSE - otherwise
  167. --*/
  168. {
  169. #if USE_SEND_BUFFER
  170. BOOL bSuccess;
  171. //
  172. // default: we succeeded
  173. //
  174. bSuccess = TRUE;
  175. #if 0
  176. TCHAR Buffer[1024];
  177. wsprintf(Buffer, TEXT("buffsize=%d\r\n"), mySendBufferIndex);
  178. OutputDebugString(Buffer);
  179. #endif
  180. //
  181. // Send the local buffer to the SAC channel
  182. //
  183. if (mySendBufferIndex > 0) {
  184. bSuccess = mySacChannel->Write(
  185. mySendBuffer,
  186. mySendBufferIndex
  187. );
  188. //
  189. // Reset the local buffer index
  190. //
  191. mySendBufferIndex = 0;
  192. }
  193. return bSuccess;
  194. #else
  195. return TRUE;
  196. #endif
  197. }
  198. BOOL
  199. CSacIoHandler::Read(
  200. OUT PBYTE Buffer,
  201. IN ULONG BufferSize,
  202. OUT PULONG ByteCount
  203. )
  204. /*++
  205. Routine Description:
  206. This routine implements the Read IoHandler method.
  207. Arguments:
  208. Buffer - on success, contains the read data
  209. BufferSize - the size of the read buffer in bytes
  210. ByteCount - on success, contains the # of bytes read
  211. Return Value:
  212. TRUE - success
  213. FALSE - otherwise
  214. --*/
  215. {
  216. if (!mySacChannel) {
  217. return FALSE;
  218. }
  219. //
  220. // Read data from the channel
  221. //
  222. return mySacChannel->Read(
  223. Buffer,
  224. BufferSize,
  225. ByteCount
  226. );
  227. }
  228. //
  229. // Determine if the ioHandler has new data to read
  230. //
  231. BOOL
  232. CSacIoHandler::HasNewData(
  233. OUT PBOOL InputWaiting
  234. )
  235. /*++
  236. Routine Description:
  237. This routine impelements the HasNewData IoHandler method.
  238. Arguments:
  239. InputWaiting - on success, contains the status of the channel's
  240. input buffer.
  241. Return Value:
  242. TRUE - success
  243. FALSE - otherwise
  244. --*/
  245. {
  246. //
  247. // Determine if the channel has new data
  248. //
  249. return mySacChannel->HasNewData(InputWaiting);
  250. }