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.

347 lines
8.6 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: pipe.c
  3. *
  4. * Copyright (c) 1991, Microsoft Corporation
  5. *
  6. * This module implements:
  7. * 1. a version of CreatePipe that allows control over the file
  8. * flags. e.g. FILE_FLAG_OVERLAPPED
  9. * 2. Timed-out pipe read and write
  10. *
  11. * History:
  12. * 06-29-92 Davidc Created.
  13. * 05-17-94 DaveTh Added ReadPipe, WritePipe.
  14. \***************************************************************************/
  15. #include <nt.h>
  16. #include <ntrtl.h>
  17. #include <windef.h>
  18. #include <nturtl.h>
  19. #include <winbase.h>
  20. #include "rcmdsrv.h"
  21. ULONG PipeSerialNumber = 0;
  22. #define PIPE_FORMAT_STRING "\\\\.\\pipe\\rshsrv\\%08x.%08x"
  23. /////////////////////////////////////////////////////////////////////////////
  24. //
  25. // RcCreatePipe
  26. //
  27. // Creates a uni-directional pipe with the specified security attributes,
  28. // size and timeout. The handles are opened with the specified file-flags
  29. // so FILE_FLAG_OVERLAPPED etc. can be specified.
  30. //
  31. // Returns handles to both end of pipe in passed parameters.
  32. //
  33. // Returns TRUE on success, FALSE on failure. (GetLastError() for details)
  34. //
  35. /////////////////////////////////////////////////////////////////////////////
  36. BOOL
  37. RcCreatePipe(
  38. LPHANDLE ReadHandle,
  39. LPHANDLE WriteHandle,
  40. LPSECURITY_ATTRIBUTES SecurityAttributes,
  41. DWORD Size,
  42. DWORD Timeout,
  43. DWORD ReadHandleFlags,
  44. DWORD WriteHandleFlags
  45. )
  46. {
  47. CHAR PipeName[MAX_PATH];
  48. //
  49. // Make up a random pipe name
  50. //
  51. sprintf(PipeName, PIPE_FORMAT_STRING, GetCurrentProcessId(), PipeSerialNumber++);
  52. //
  53. // Create the pipe
  54. //
  55. *ReadHandle = CreateNamedPipeA(
  56. PipeName,
  57. PIPE_ACCESS_INBOUND | ReadHandleFlags,
  58. PIPE_TYPE_BYTE | PIPE_WAIT,
  59. 1, // Number of pipes
  60. Size, // Out buffer size
  61. Size, // In buffer size
  62. Timeout, // Timeout in ms
  63. SecurityAttributes
  64. );
  65. if (*ReadHandle == NULL) {
  66. RcDbgPrint("RcCreatePipe: failed to created pipe <%s>, error = %d\n", PipeName, GetLastError());
  67. return(FALSE);
  68. }
  69. //
  70. // Open the client end of the pipe
  71. //
  72. *WriteHandle = CreateFileA(
  73. PipeName,
  74. GENERIC_WRITE,
  75. 0, // No sharing
  76. SecurityAttributes,
  77. OPEN_EXISTING,
  78. FILE_ATTRIBUTE_NORMAL | WriteHandleFlags,
  79. NULL // Template file
  80. );
  81. if (*WriteHandle == INVALID_HANDLE_VALUE ) {
  82. RcDbgPrint("Failed to open client end of pipe <%s>, error = %d\n", PipeName, GetLastError());
  83. RcCloseHandle(*ReadHandle, "async pipe (server(read) side)");
  84. return(FALSE);
  85. }
  86. //
  87. // Everything succeeded
  88. //
  89. return(TRUE);
  90. }
  91. /***************************************************************************\
  92. * FUNCTION: ReadPipe
  93. *
  94. * PURPOSE: Implements a timed-out (ms) read on a pipe.
  95. *
  96. * RETURNS: ERROR_SUCCESS on success
  97. * WAIT_TIMEOUT if timed out before completing read
  98. * or respective error code on other failures
  99. *
  100. * HISTORY:
  101. *
  102. * 05-17-94 DaveTh Created from DavidC read pipe.
  103. *
  104. \***************************************************************************/
  105. DWORD
  106. ReadPipe(
  107. HANDLE PipeHandle,
  108. LPVOID lpBuffer,
  109. DWORD nNumberOfBytesToRead,
  110. LPDWORD lpNumberOfBytesRead,
  111. DWORD Timeout
  112. )
  113. {
  114. DWORD Result;
  115. OVERLAPPED Overlapped;
  116. HANDLE EventHandle;
  117. DWORD Error;
  118. //
  119. // Create an event for the overlapped operation
  120. //
  121. EventHandle = CreateEvent(
  122. NULL, // no security
  123. TRUE, // Manual reset
  124. FALSE, // Initial state
  125. NULL // Name
  126. );
  127. if (EventHandle == NULL) {
  128. RcDbgPrint("Internal error = %d\n", GetLastError());
  129. return(GetLastError());
  130. }
  131. Overlapped.hEvent = EventHandle;
  132. Result = ReadFile(
  133. PipeHandle,
  134. lpBuffer,
  135. nNumberOfBytesToRead,
  136. lpNumberOfBytesRead,
  137. &Overlapped
  138. );
  139. if (Result) {
  140. //
  141. // Success without waiting - it's too easy !
  142. //
  143. CloseHandle(EventHandle);
  144. } else {
  145. //
  146. // Read failed, if it's overlapped io, go wait for it
  147. //
  148. Error = GetLastError();
  149. if (Error != ERROR_IO_PENDING) {
  150. RcDbgPrint("ReadPipe: ReadFile failed, error = %d\n", Error);
  151. CloseHandle(EventHandle);
  152. return(Error);
  153. }
  154. //
  155. // Wait for the I/O to complete
  156. //
  157. Result = WaitForSingleObject(EventHandle, Timeout);
  158. if (Result != WAIT_OBJECT_0) {
  159. if (Result == WAIT_TIMEOUT) {
  160. return(Result);
  161. } else {
  162. RcDbgPrint("ReadPipe: event wait failed, result = %d, last error = %d\n", Result, GetLastError());
  163. }
  164. CloseHandle(EventHandle);
  165. }
  166. //
  167. // Go get the I/O result
  168. //
  169. Result = GetOverlappedResult( PipeHandle,
  170. &Overlapped,
  171. lpNumberOfBytesRead,
  172. FALSE
  173. );
  174. //
  175. // We're finished with the event handle
  176. //
  177. CloseHandle(EventHandle);
  178. //
  179. // Check result of GetOverlappedResult
  180. //
  181. if (!Result) {
  182. RcDbgPrint("ReadPipe: GetOverlappedResult failed, error = %d\n", GetLastError());
  183. return(GetLastError());
  184. }
  185. }
  186. return(ERROR_SUCCESS);
  187. }
  188. /***************************************************************************\
  189. * FUNCTION: WritePipe
  190. *
  191. * PURPOSE: Implements a timed-out (ms) write on a pipe.
  192. *
  193. * RETURNS: ERROR_SUCCESS on success
  194. * WAIT_TIMEOUT if timed out before completing write
  195. * or respective error code on other failures
  196. *
  197. * HISTORY:
  198. *
  199. * 05-22-94 DaveTh Created.
  200. *
  201. \***************************************************************************/
  202. DWORD
  203. WritePipe(
  204. HANDLE PipeHandle,
  205. LPVOID lpBuffer,
  206. DWORD nNumberOfBytesToWrite,
  207. LPDWORD lpNumberOfBytesWritten,
  208. DWORD Timeout
  209. )
  210. {
  211. DWORD Result;
  212. OVERLAPPED Overlapped;
  213. HANDLE EventHandle;
  214. DWORD Error;
  215. //
  216. // Create an event for the overlapped operation
  217. //
  218. EventHandle = CreateEvent(
  219. NULL, // no security
  220. TRUE, // Manual reset
  221. FALSE, // Initial state
  222. NULL // Name
  223. );
  224. if (EventHandle == NULL) {
  225. RcDbgPrint("Internal error = %d\n", GetLastError());
  226. return(GetLastError());
  227. }
  228. Overlapped.hEvent = EventHandle;
  229. Result = WriteFile(
  230. PipeHandle,
  231. lpBuffer,
  232. nNumberOfBytesToWrite,
  233. lpNumberOfBytesWritten,
  234. &Overlapped
  235. );
  236. if (Result) {
  237. //
  238. // Success without waiting - it's too easy !
  239. //
  240. CloseHandle(EventHandle);
  241. } else {
  242. //
  243. // Write failed, if it's overlapped io, go wait for it
  244. //
  245. Error = GetLastError();
  246. if (Error != ERROR_IO_PENDING) {
  247. RcDbgPrint("WritePipe: WriteFile failed, error = %d\n", Error);
  248. CloseHandle(EventHandle);
  249. return(Error);
  250. }
  251. //
  252. // Wait for the I/O to complete
  253. //
  254. Result = WaitForSingleObject(EventHandle, Timeout);
  255. if (Result != WAIT_OBJECT_0) {
  256. if (Result == WAIT_TIMEOUT) {
  257. return(Result);
  258. } else {
  259. RcDbgPrint("Write: event wait failed, result = %d, last error = %d\n", Result, GetLastError());
  260. }
  261. CloseHandle(EventHandle);
  262. }
  263. //
  264. // Go get the I/O result
  265. //
  266. Result = GetOverlappedResult( PipeHandle,
  267. &Overlapped,
  268. lpNumberOfBytesWritten,
  269. FALSE
  270. );
  271. //
  272. // We're finished with the event handle
  273. //
  274. CloseHandle(EventHandle);
  275. //
  276. // Check result of GetOverlappedResult
  277. //
  278. if (!Result) {
  279. RcDbgPrint("WritePipe: GetOverlappedResult failed, error = %d\n", GetLastError());
  280. return(GetLastError());
  281. }
  282. }
  283. return(ERROR_SUCCESS);
  284. }