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.

202 lines
6.3 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. pipe.c
  5. Abstract:
  6. This module contains the Win32 Anonymous Pipe API
  7. Author:
  8. Steve Wood (stevewo) 24-Sep-1990
  9. Revision History:
  10. --*/
  11. #include "basedll.h"
  12. ULONG PipeSerialNumber;
  13. BOOL
  14. APIENTRY
  15. CreatePipe(
  16. OUT LPHANDLE lpReadPipe,
  17. OUT LPHANDLE lpWritePipe,
  18. IN LPSECURITY_ATTRIBUTES lpPipeAttributes,
  19. IN DWORD nSize
  20. )
  21. /*++
  22. Routine Description:
  23. The CreatePipe API is used to create an anonymous pipe I/O device.
  24. Two handles to the device are created. One handle is opened for
  25. reading and the other is opened for writing. These handles may be
  26. used in subsequent calls to ReadFile and WriteFile to transmit data
  27. through the pipe.
  28. Arguments:
  29. lpReadPipe - Returns a handle to the read side of the pipe. Data
  30. may be read from the pipe by specifying this handle value in a
  31. subsequent call to ReadFile.
  32. lpWritePipe - Returns a handle to the write side of the pipe. Data
  33. may be written to the pipe by specifying this handle value in a
  34. subsequent call to WriteFile.
  35. lpPipeAttributes - An optional parameter that may be used to specify
  36. the attributes of the new pipe. If the parameter is not
  37. specified, then the pipe is created without a security
  38. descriptor, and the resulting handles are not inherited on
  39. process creation. Otherwise, the optional security attributes
  40. are used on the pipe, and the inherit handles flag effects both
  41. pipe handles.
  42. nSize - Supplies the requested buffer size for the pipe. This is
  43. only a suggestion and is used by the operating system to
  44. calculate an appropriate buffering mechanism. A value of zero
  45. indicates that the system is to choose the default buffering
  46. scheme.
  47. Return Value:
  48. TRUE - The operation was successful.
  49. FALSE/NULL - The operation failed. Extended error status is available
  50. using GetLastError.
  51. --*/
  52. {
  53. WCHAR PipeNameBuffer[ MAX_PATH ];
  54. ANSI_STRING PipeName;
  55. OBJECT_ATTRIBUTES ObjectAttributes;
  56. HANDLE ReadPipeHandle, WritePipeHandle;
  57. NTSTATUS Status;
  58. IO_STATUS_BLOCK Iosb;
  59. LARGE_INTEGER Timeout;
  60. ULONG Attributes;
  61. PVOID SecurityDescriptor;
  62. UNICODE_STRING Unicode;
  63. static HANDLE PipeDirectory = NULL;
  64. //
  65. // Set the default timeout to 120 seconds
  66. //
  67. Timeout.QuadPart = - 10 * 1000 * 1000 * 120;
  68. if (nSize == 0) {
  69. nSize = 4096;
  70. }
  71. //
  72. // Cache the directory to the pipe driver.
  73. //
  74. if (PipeDirectory == NULL) {
  75. HANDLE TempDir;
  76. Unicode.Buffer = L"\\Device\\NamedPipe\\";
  77. Unicode.Length = sizeof (L"\\Device\\NamedPipe\\") - sizeof (WCHAR);
  78. InitializeObjectAttributes (&ObjectAttributes,
  79. &Unicode,
  80. 0,
  81. NULL,
  82. NULL);
  83. Status = NtOpenFile (&TempDir,
  84. GENERIC_READ | SYNCHRONIZE,
  85. &ObjectAttributes,
  86. &Iosb,
  87. FILE_SHARE_READ | FILE_SHARE_WRITE,
  88. FILE_SYNCHRONOUS_IO_NONALERT);
  89. if (!NT_SUCCESS (Status)) {
  90. BaseSetLastNTError (Status);
  91. return (FALSE);
  92. }
  93. if (InterlockedCompareExchangePointer (&PipeDirectory, TempDir, NULL) != NULL) {
  94. NtClose (TempDir);
  95. }
  96. }
  97. swprintf (PipeNameBuffer,
  98. L"Win32Pipes.%08x.%08x",
  99. HandleToUlong(NtCurrentTeb()->ClientId.UniqueProcess),
  100. InterlockedIncrement(&PipeSerialNumber));
  101. Unicode.Buffer = PipeNameBuffer;
  102. Unicode.Length = 12 * 2 + 8 * 2 * 2;
  103. if (ARGUMENT_PRESENT (lpPipeAttributes)) {
  104. Attributes =
  105. lpPipeAttributes->bInheritHandle ? (OBJ_INHERIT | OBJ_CASE_INSENSITIVE) : (OBJ_CASE_INSENSITIVE);
  106. SecurityDescriptor = lpPipeAttributes->lpSecurityDescriptor;
  107. } else {
  108. Attributes = OBJ_CASE_INSENSITIVE;
  109. SecurityDescriptor = NULL;
  110. }
  111. InitializeObjectAttributes (&ObjectAttributes,
  112. &Unicode,
  113. Attributes,
  114. PipeDirectory,
  115. SecurityDescriptor);
  116. Status = NtCreateNamedPipeFile (&ReadPipeHandle,
  117. GENERIC_READ | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
  118. &ObjectAttributes,
  119. &Iosb,
  120. FILE_SHARE_READ | FILE_SHARE_WRITE,
  121. FILE_CREATE,
  122. FILE_SYNCHRONOUS_IO_NONALERT,
  123. FILE_PIPE_BYTE_STREAM_TYPE,
  124. FILE_PIPE_BYTE_STREAM_MODE,
  125. FILE_PIPE_QUEUE_OPERATION,
  126. 1,
  127. nSize,
  128. nSize,
  129. (PLARGE_INTEGER) &Timeout);
  130. if (!NT_SUCCESS (Status)) {
  131. BaseSetLastNTError (Status);
  132. return (FALSE);
  133. }
  134. //
  135. // Now do a relative open with no filename from the created pipe.
  136. // We do this to eliminate all the name parsing etc.
  137. //
  138. Unicode.Buffer = L"";
  139. Unicode.Length = 0;
  140. InitializeObjectAttributes (&ObjectAttributes,
  141. &Unicode,
  142. Attributes,
  143. ReadPipeHandle,
  144. SecurityDescriptor);
  145. Status = NtOpenFile (&WritePipeHandle,
  146. GENERIC_WRITE | SYNCHRONIZE,
  147. &ObjectAttributes,
  148. &Iosb,
  149. FILE_SHARE_READ | FILE_SHARE_WRITE,
  150. FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
  151. if (!NT_SUCCESS (Status)) {
  152. NtClose (ReadPipeHandle);
  153. BaseSetLastNTError (Status);
  154. return (FALSE);
  155. }
  156. *lpReadPipe = ReadPipeHandle;
  157. *lpWritePipe = WritePipeHandle;
  158. return (TRUE);
  159. }