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.

273 lines
6.1 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. write.c
  5. Abstract:
  6. This module implements the file write routines for MSFS called by the
  7. dispatch driver.
  8. Author:
  9. Manny Weiser (mannyw) 16-Jan-1991
  10. Revision History:
  11. --*/
  12. #include "mailslot.h"
  13. //
  14. // The debug trace level
  15. //
  16. #define Dbg (DEBUG_TRACE_WRITE)
  17. //
  18. // local procedure prototypes.
  19. //
  20. NTSTATUS
  21. MsCommonWrite (
  22. IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
  23. IN PIRP Irp
  24. );
  25. #ifdef ALLOC_PRAGMA
  26. #pragma alloc_text( PAGE, MsCommonWrite )
  27. #pragma alloc_text( PAGE, MsFsdWrite )
  28. #endif
  29. NTSTATUS
  30. MsFsdWrite (
  31. IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
  32. IN PIRP Irp
  33. )
  34. /*++
  35. Routine Description:
  36. This routine implements the FSD part of the NtWriteFile API call.
  37. Arguments:
  38. MsfsDeviceObject - Supplies the device object to use.
  39. Irp - Supplies the Irp being processed
  40. Return Value:
  41. NTSTATUS - The Fsd status for the Irp
  42. --*/
  43. {
  44. NTSTATUS status;
  45. PAGED_CODE();
  46. DebugTrace(+1, Dbg, "MsFsdWrite\n", 0);
  47. FsRtlEnterFileSystem();
  48. status = MsCommonWrite( MsfsDeviceObject, Irp );
  49. FsRtlExitFileSystem();
  50. //
  51. // Return to the caller.
  52. //
  53. DebugTrace(-1, Dbg, "MsFsdWrite -> %08lx\n", status );
  54. return status;
  55. }
  56. NTSTATUS
  57. MsCommonWrite (
  58. IN PMSFS_DEVICE_OBJECT MsfsDeviceObject,
  59. IN PIRP Irp
  60. )
  61. /*++
  62. Routine Description:
  63. This is the common routine for writing to a mailslot file.
  64. Arguments:
  65. Irp - Supplies the Irp to process
  66. Return Value:
  67. NTSTATUS - the return status for the operation
  68. --*/
  69. {
  70. NTSTATUS status;
  71. PIO_STACK_LOCATION irpSp;
  72. NODE_TYPE_CODE nodeTypeCode;
  73. PCCB ccb;
  74. PFCB fcb;
  75. PVOID fsContext2;
  76. PIRP writeIrp;
  77. PUCHAR writeBuffer;
  78. ULONG writeLength;
  79. PDATA_QUEUE writeQueue;
  80. PAGED_CODE();
  81. irpSp = IoGetCurrentIrpStackLocation( Irp );
  82. DebugTrace(+1, Dbg, "MsCommonWrite\n", 0);
  83. DebugTrace( 0, Dbg, "MsfsDeviceObject = %08lx\n", (ULONG)MsfsDeviceObject);
  84. DebugTrace( 0, Dbg, "Irp = %08lx\n", (ULONG)Irp);
  85. DebugTrace( 0, Dbg, "FileObject = %08lx\n", (ULONG)irpSp->FileObject);
  86. //
  87. // Get the CCB and make sure it isn't closing.
  88. //
  89. if ((nodeTypeCode = MsDecodeFileObject( irpSp->FileObject,
  90. (PVOID *)&ccb,
  91. &fsContext2 )) == NTC_UNDEFINED) {
  92. DebugTrace(0, Dbg, "The mailslot is disconnected\n", 0);
  93. MsCompleteRequest( Irp, STATUS_FILE_FORCED_CLOSED );
  94. status = STATUS_FILE_FORCED_CLOSED;
  95. DebugTrace(-1, Dbg, "MsCommonWrite -> %08lx\n", status );
  96. return status;
  97. }
  98. //
  99. // Allow write operations only to the client side of the mailslot.
  100. //
  101. if (nodeTypeCode != MSFS_NTC_CCB) {
  102. DebugTrace(0, Dbg, "FileObject is not the correct type", 0);
  103. MsDereferenceNode( &ccb->Header );
  104. MsCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
  105. status = STATUS_INVALID_PARAMETER;
  106. DebugTrace(-1, Dbg, "MsCommonWrite -> %08lx\n", status );
  107. return status;
  108. }
  109. //
  110. // Get a pointer to the FCB for this CCB
  111. //
  112. fcb = ccb->Fcb;
  113. //
  114. // Make local copies of the input parameters to make things easier, and
  115. // initialize the main variables that describe the write command.
  116. //
  117. writeIrp = Irp;
  118. writeBuffer = Irp->UserBuffer;
  119. writeLength = irpSp->Parameters.Write.Length;
  120. writeIrp->IoStatus.Information = 0;
  121. writeQueue = &fcb->DataQueue;
  122. //
  123. // Make sure the write does not exceed the stated maximum. If max is
  124. // zero, this means don't enforce.
  125. //
  126. if ( (writeQueue->MaximumMessageSize != 0) &&
  127. (writeLength > writeQueue->MaximumMessageSize) ) {
  128. DebugTrace(0, Dbg, "Write exceeds maximum message size", 0);
  129. MsDereferenceCcb( ccb );
  130. MsCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
  131. status = STATUS_INVALID_PARAMETER;
  132. DebugTrace(-1, Dbg, "MsCommonWrite -> %08lx\n", status );
  133. return status;
  134. }
  135. //
  136. // Now acquire exclusive access to the FCB.
  137. //
  138. MsAcquireExclusiveFcb( fcb );
  139. //
  140. // Ensure that this CCB still belongs to an active open mailslot.
  141. //
  142. status = MsVerifyCcb( ccb );
  143. if (NT_SUCCESS (status)) {
  144. //
  145. // Now we'll call our common write data queue routine to
  146. // transfer data out of our write buffer into the data queue.
  147. // If the result of the call is FALSE then there were no queued
  148. // read operations and we must queue this write.
  149. //
  150. status = MsWriteDataQueue( writeQueue,
  151. writeBuffer,
  152. writeLength );
  153. if (status == STATUS_MORE_PROCESSING_REQUIRED) {
  154. ASSERT( !MsIsDataQueueReaders( writeQueue ));
  155. DebugTrace(0, Dbg, "Add write to data queue\n", 0);
  156. //
  157. // Add this write request to the write queue
  158. //
  159. status = MsAddDataQueueEntry( writeQueue,
  160. WriteEntries,
  161. writeLength,
  162. Irp,
  163. NULL );
  164. } else {
  165. DebugTrace(0, Dbg, "Complete the Write Irp\n", 0);
  166. //
  167. // Update the FCB last modification time.
  168. //
  169. if (NT_SUCCESS (status)) {
  170. writeIrp->IoStatus.Information = writeLength;
  171. KeQuerySystemTime( &fcb->Specific.Fcb.LastModificationTime );
  172. }
  173. }
  174. }
  175. MsReleaseFcb( fcb );
  176. MsDereferenceCcb( ccb );
  177. MsCompleteRequest( writeIrp, status );
  178. DebugTrace(-1, Dbg, "MsCommonWrite -> %08lx\n", status);
  179. return status;
  180. }
  181.