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.

353 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. mailslot.c
  5. Abstract:
  6. This module contains the Win32 Mailslot API
  7. Author:
  8. Manny Weiser (mannyw) 4-Mar-1991
  9. Revision History:
  10. --*/
  11. #include "basedll.h"
  12. HANDLE
  13. APIENTRY
  14. CreateMailslotW(
  15. IN LPCWSTR lpName,
  16. IN DWORD nMaxMessageSize,
  17. IN DWORD lReadTimeout,
  18. IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL
  19. )
  20. /*++
  21. Routine Description:
  22. The create mailslot API creates a local mailslot and return a
  23. server-side handle to the mailslot.
  24. Arguments:
  25. lpName - The name of the mailslot. This must be a local mailslot
  26. name.
  27. nMaxMessageSize - The size (in bytes) of the largest message that
  28. can be written to the mailslot.
  29. lReadTimeout - The initial read timeout, in milliseconds. This
  30. is the amount of time a read operation will block waiting for
  31. a message to be written to the mailslot. This value can be
  32. changed with the SetMailslotInfo API.
  33. lpSecurityAttributes - An optional pointer to security information
  34. for this mailslot.
  35. Return Value:
  36. Returns one of the following:
  37. 0xFFFFFFFF --An error occurred. Call GetLastError for more
  38. information.
  39. Anything else --Returns a handle for use in the server side of
  40. subsequent mailslot operations.
  41. --*/
  42. {
  43. OBJECT_ATTRIBUTES objectAttributes;
  44. UNICODE_STRING fileName;
  45. LPWSTR filePart;
  46. IO_STATUS_BLOCK ioStatusBlock;
  47. LARGE_INTEGER readTimeout;
  48. HANDLE handle;
  49. NTSTATUS status;
  50. PVOID freeBuffer;
  51. BOOLEAN TranslationStatus;
  52. RtlInitUnicodeString( &fileName, lpName );
  53. TranslationStatus = RtlDosPathNameToNtPathName_U(
  54. lpName,
  55. &fileName,
  56. &filePart,
  57. NULL
  58. );
  59. if ( !TranslationStatus ) {
  60. SetLastError(ERROR_PATH_NOT_FOUND);
  61. return INVALID_HANDLE_VALUE;
  62. }
  63. freeBuffer = fileName.Buffer;
  64. InitializeObjectAttributes(
  65. &objectAttributes,
  66. &fileName,
  67. OBJ_CASE_INSENSITIVE,
  68. NULL,
  69. NULL
  70. );
  71. if ( ARGUMENT_PRESENT(lpSecurityAttributes) ) {
  72. objectAttributes.SecurityDescriptor =
  73. lpSecurityAttributes->lpSecurityDescriptor;
  74. if ( lpSecurityAttributes->bInheritHandle ) {
  75. objectAttributes.Attributes |= OBJ_INHERIT;
  76. }
  77. }
  78. if (lReadTimeout == MAILSLOT_WAIT_FOREVER) {
  79. readTimeout.HighPart = 0xFFFFFFFF;
  80. readTimeout.LowPart = 0xFFFFFFFF;
  81. } else {
  82. readTimeout.QuadPart = - (LONGLONG)UInt32x32To64( lReadTimeout, 10 * 1000 );
  83. }
  84. status = NtCreateMailslotFile (
  85. &handle,
  86. GENERIC_READ | SYNCHRONIZE | WRITE_DAC,
  87. &objectAttributes,
  88. &ioStatusBlock,
  89. FILE_CREATE,
  90. 0,
  91. nMaxMessageSize,
  92. (PLARGE_INTEGER)&readTimeout
  93. );
  94. if ( status == STATUS_NOT_SUPPORTED ||
  95. status == STATUS_INVALID_DEVICE_REQUEST ) {
  96. //
  97. // The request must have been processed by some other device driver
  98. // (other than MSFS). Map the error to something reasonable.
  99. //
  100. status = STATUS_OBJECT_NAME_INVALID;
  101. }
  102. RtlFreeHeap( RtlProcessHeap(), 0, freeBuffer );
  103. if (!NT_SUCCESS(status)) {
  104. BaseSetLastNTError( status );
  105. return INVALID_HANDLE_VALUE;
  106. }
  107. return handle;
  108. }
  109. HANDLE
  110. APIENTRY
  111. CreateMailslotA(
  112. IN LPCSTR lpName,
  113. IN DWORD nMaxMessageSize,
  114. IN DWORD lReadTimeout,
  115. IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL
  116. )
  117. {
  118. PUNICODE_STRING unicode;
  119. ANSI_STRING ansiString;
  120. NTSTATUS status;
  121. unicode = &NtCurrentTeb()->StaticUnicodeString;
  122. RtlInitAnsiString( &ansiString, lpName );
  123. status = RtlAnsiStringToUnicodeString( unicode, &ansiString, FALSE );
  124. if ( !NT_SUCCESS( status ) ) {
  125. if ( status == STATUS_BUFFER_OVERFLOW ) {
  126. SetLastError(ERROR_FILENAME_EXCED_RANGE);
  127. } else {
  128. BaseSetLastNTError(status);
  129. }
  130. return INVALID_HANDLE_VALUE;
  131. }
  132. return ( CreateMailslotW( unicode->Buffer,
  133. nMaxMessageSize,
  134. lReadTimeout,
  135. lpSecurityAttributes
  136. ) );
  137. }
  138. BOOL
  139. APIENTRY
  140. GetMailslotInfo(
  141. IN HANDLE hMailslot,
  142. OUT LPDWORD lpMaxMessageSize OPTIONAL,
  143. OUT LPDWORD lpNextSize OPTIONAL,
  144. OUT LPDWORD lpMessageCount OPTIONAL,
  145. OUT LPDWORD lpReadTimeout OPTIONAL
  146. )
  147. /*++
  148. Routine Description:
  149. This function will return the requested information about the
  150. specified mailslot.
  151. Arguments:
  152. hMailslot - A handle to the mailslot.
  153. lpMaxMessageSize - If specified returns the size of the largest
  154. message that can be written to the mailslot.
  155. lpNextSize - If specified returns the size of the next message in
  156. the mailslot buffer. It will return MAILSLOT_NO_MESSAGE if
  157. there are no messages in the mailslot.
  158. lpMessageCount - If specified returns the number of unread message
  159. currently in the mailslot.
  160. lpReadTimeout - If specified returns the read timeout, in
  161. milliseconds.
  162. Return Value:
  163. TRUE - The operation was successful.
  164. FALSE/NULL - The operation failed. Extended error status is available
  165. using GetLastError.
  166. --*/
  167. {
  168. NTSTATUS status;
  169. IO_STATUS_BLOCK ioStatusBlock;
  170. FILE_MAILSLOT_QUERY_INFORMATION mailslotInfo;
  171. LARGE_INTEGER millisecondTimeout, tmp;
  172. status = NtQueryInformationFile( hMailslot,
  173. &ioStatusBlock,
  174. &mailslotInfo,
  175. sizeof( mailslotInfo ),
  176. FileMailslotQueryInformation );
  177. if ( !NT_SUCCESS( status ) ) {
  178. BaseSetLastNTError( status );
  179. return ( FALSE );
  180. }
  181. if ( ARGUMENT_PRESENT( lpMaxMessageSize ) ) {
  182. *lpMaxMessageSize = mailslotInfo.MaximumMessageSize;
  183. }
  184. if ( ARGUMENT_PRESENT( lpNextSize ) ) {
  185. *lpNextSize = mailslotInfo.NextMessageSize;
  186. }
  187. if ( ARGUMENT_PRESENT( lpMessageCount ) ) {
  188. *lpMessageCount = mailslotInfo.MessagesAvailable;
  189. }
  190. if ( ARGUMENT_PRESENT( lpReadTimeout ) ) {
  191. //
  192. // Convert read timeout from 100 ns intervals to milliseconds.
  193. // The readtime is currently negative, since it is a relative time.
  194. //
  195. if ( mailslotInfo.ReadTimeout.HighPart != 0xFFFFFFFF
  196. || mailslotInfo.ReadTimeout.LowPart != 0xFFFFFFFF ) {
  197. tmp.QuadPart = - mailslotInfo.ReadTimeout.QuadPart;
  198. millisecondTimeout = RtlExtendedLargeIntegerDivide(
  199. tmp,
  200. 10 * 1000,
  201. NULL );
  202. if ( millisecondTimeout.HighPart == 0 ) {
  203. *lpReadTimeout = millisecondTimeout.LowPart;
  204. } else {
  205. //
  206. // The millisecond calculation would overflow the dword.
  207. // Approximate a large number as best we can.
  208. //
  209. *lpReadTimeout = 0xFFFFFFFE;
  210. }
  211. } else {
  212. //
  213. // The mailslot timeout is infinite.
  214. //
  215. *lpReadTimeout = MAILSLOT_WAIT_FOREVER;
  216. }
  217. }
  218. return( TRUE );
  219. }
  220. BOOL
  221. APIENTRY
  222. SetMailslotInfo(
  223. IN HANDLE hMailslot,
  224. IN DWORD lReadTimeout
  225. )
  226. /*++
  227. Routine Description:
  228. This function will set the read timeout for the specified mailslot.
  229. Arguments:
  230. hMailslot - A handle to the mailslot.
  231. lReadTimeout - The new read timeout, in milliseconds.
  232. Return Value:
  233. TRUE - The operation was successful.
  234. FALSE/NULL - The operation failed. Extended error status is available
  235. using GetLastError.
  236. --*/
  237. {
  238. NTSTATUS status;
  239. IO_STATUS_BLOCK ioStatusBlock;
  240. FILE_MAILSLOT_SET_INFORMATION mailslotInfo;
  241. LARGE_INTEGER timeout;
  242. if ( lReadTimeout == MAILSLOT_WAIT_FOREVER ) {
  243. timeout.HighPart = 0xFFFFFFFF;
  244. timeout.LowPart = 0xFFFFFFFF;
  245. } else {
  246. timeout.QuadPart = - (LONGLONG)UInt32x32To64( lReadTimeout, 10 * 1000 );
  247. }
  248. mailslotInfo.ReadTimeout = &timeout;
  249. status = NtSetInformationFile( hMailslot,
  250. &ioStatusBlock,
  251. &mailslotInfo,
  252. sizeof( mailslotInfo ),
  253. FileMailslotSetInformation );
  254. if ( !NT_SUCCESS( status ) ) {
  255. BaseSetLastNTError( status );
  256. return ( FALSE );
  257. }
  258. return TRUE;
  259. }