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.

313 lines
6.8 KiB

  1. /*++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. DevCtrl.c
  5. Abstract:
  6. This module implements the File System Device Control routines for Fat
  7. called by the dispatch driver.
  8. // @@BEGIN_DDKSPLIT
  9. Author:
  10. Gary Kimura [GaryKi] 28-Dec-1989
  11. Revision History:
  12. // @@END_DDKSPLIT
  13. --*/
  14. #include "FatProcs.h"
  15. //
  16. // The local debug trace level
  17. //
  18. #define Dbg (DEBUG_TRACE_DEVCTRL)
  19. //
  20. // Local procedure prototypes
  21. //
  22. NTSTATUS
  23. FatDeviceControlCompletionRoutine(
  24. IN PDEVICE_OBJECT DeviceObject,
  25. IN PIRP Irp,
  26. IN PVOID Contxt
  27. );
  28. #ifdef ALLOC_PRAGMA
  29. #pragma alloc_text(PAGE, FatCommonDeviceControl)
  30. #pragma alloc_text(PAGE, FatFsdDeviceControl)
  31. #endif
  32. NTSTATUS
  33. FatFsdDeviceControl (
  34. IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
  35. IN PIRP Irp
  36. )
  37. /*++
  38. Routine Description:
  39. This routine implements the FSD part of Device control operations
  40. Arguments:
  41. VolumeDeviceObject - Supplies the volume device object where the
  42. file exists
  43. Irp - Supplies the Irp being processed
  44. Return Value:
  45. NTSTATUS - The FSD status for the IRP
  46. --*/
  47. {
  48. NTSTATUS Status;
  49. PIRP_CONTEXT IrpContext = NULL;
  50. BOOLEAN TopLevel;
  51. DebugTrace(+1, Dbg, "FatFsdDeviceControl\n", 0);
  52. FsRtlEnterFileSystem();
  53. TopLevel = FatIsIrpTopLevel( Irp );
  54. try {
  55. IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ));
  56. Status = FatCommonDeviceControl( IrpContext, Irp );
  57. } except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {
  58. //
  59. // We had some trouble trying to perform the requested
  60. // operation, so we'll abort the I/O request with
  61. // the error status that we get back from the
  62. // execption code
  63. //
  64. Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
  65. }
  66. if (TopLevel) { IoSetTopLevelIrp( NULL ); }
  67. FsRtlExitFileSystem();
  68. //
  69. // And return to our caller
  70. //
  71. DebugTrace(-1, Dbg, "FatFsdDeviceControl -> %08lx\n", Status);
  72. UNREFERENCED_PARAMETER( VolumeDeviceObject );
  73. return Status;
  74. }
  75. NTSTATUS
  76. FatCommonDeviceControl (
  77. IN PIRP_CONTEXT IrpContext,
  78. IN PIRP Irp
  79. )
  80. /*++
  81. Routine Description:
  82. This is the common routine for doing Device control operations called
  83. by both the fsd and fsp threads
  84. Arguments:
  85. Irp - Supplies the Irp to process
  86. InFsp - Indicates if this is the fsp thread or someother thread
  87. Return Value:
  88. NTSTATUS - The return status for the operation
  89. --*/
  90. {
  91. NTSTATUS Status;
  92. PIO_STACK_LOCATION IrpSp;
  93. KEVENT WaitEvent;
  94. PVOID CompletionContext = NULL;
  95. PVCB Vcb;
  96. PFCB Fcb;
  97. PCCB Ccb;
  98. //
  99. // Get a pointer to the current Irp stack location
  100. //
  101. IrpSp = IoGetCurrentIrpStackLocation( Irp );
  102. DebugTrace(+1, Dbg, "FatCommonDeviceControl\n", 0);
  103. DebugTrace( 0, Dbg, "Irp = %08lx\n", Irp);
  104. DebugTrace( 0, Dbg, "MinorFunction = %08lx\n", IrpSp->MinorFunction);
  105. //
  106. // Decode the file object, the only type of opens we accept are
  107. // user volume opens.
  108. //
  109. if (FatDecodeFileObject( IrpSp->FileObject, &Vcb, &Fcb, &Ccb ) != UserVolumeOpen) {
  110. FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
  111. DebugTrace(-1, Dbg, "FatCommonDeviceControl -> %08lx\n", STATUS_INVALID_PARAMETER);
  112. return STATUS_INVALID_PARAMETER;
  113. }
  114. //
  115. // A few IOCTLs actually require some intervention on our part
  116. //
  117. switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
  118. case IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES:
  119. //
  120. // This is sent by the Volume Snapshot driver (Lovelace).
  121. // We flush the volume, and hold all file resources
  122. // to make sure that nothing more gets dirty. Then we wait
  123. // for the IRP to complete or cancel.
  124. //
  125. SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
  126. FatAcquireExclusiveVolume( IrpContext, Vcb );
  127. FatFlushAndCleanVolume( IrpContext,
  128. Irp,
  129. Vcb,
  130. FlushWithoutPurge );
  131. KeInitializeEvent( &WaitEvent, NotificationEvent, FALSE );
  132. CompletionContext = &WaitEvent;
  133. //
  134. // Get the next stack location, and copy over the stack location
  135. //
  136. IoCopyCurrentIrpStackLocationToNext( Irp );
  137. //
  138. // Set up the completion routine
  139. //
  140. IoSetCompletionRoutine( Irp,
  141. FatDeviceControlCompletionRoutine,
  142. CompletionContext,
  143. TRUE,
  144. TRUE,
  145. TRUE );
  146. break;
  147. default:
  148. //
  149. // FAT doesn't need to see this on the way back, so skip ourselves.
  150. //
  151. IoSkipCurrentIrpStackLocation( Irp );
  152. break;
  153. }
  154. //
  155. // Send the request.
  156. //
  157. Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
  158. if (Status == STATUS_PENDING && CompletionContext) {
  159. KeWaitForSingleObject( &WaitEvent,
  160. Executive,
  161. KernelMode,
  162. FALSE,
  163. NULL );
  164. Status = Irp->IoStatus.Status;
  165. }
  166. //
  167. // If we had a context, the IRP remains for us and we will complete it.
  168. // Handle it appropriately.
  169. //
  170. if (CompletionContext) {
  171. //
  172. // Release all the resources that we held because of a
  173. // VOLSNAP_FLUSH_AND_HOLD.
  174. //
  175. ASSERT( IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES );
  176. FatReleaseVolume( IrpContext, Vcb );
  177. //
  178. // If we had no context, the IRP will complete asynchronously.
  179. //
  180. } else {
  181. Irp = NULL;
  182. }
  183. FatCompleteRequest( IrpContext, Irp, Status );
  184. DebugTrace(-1, Dbg, "FatCommonDeviceControl -> %08lx\n", Status);
  185. return Status;
  186. }
  187. //
  188. // Local support routine
  189. //
  190. NTSTATUS
  191. FatDeviceControlCompletionRoutine(
  192. IN PDEVICE_OBJECT DeviceObject,
  193. IN PIRP Irp,
  194. IN PVOID Contxt
  195. )
  196. {
  197. PKEVENT Event = (PKEVENT) Contxt;
  198. //
  199. // If there is an event, this is a synch request. Signal and
  200. // let I/O know this isn't done yet.
  201. //
  202. if (Event) {
  203. KeSetEvent( Event, 0, FALSE );
  204. return STATUS_MORE_PROCESSING_REQUIRED;
  205. }
  206. UNREFERENCED_PARAMETER( DeviceObject );
  207. UNREFERENCED_PARAMETER( Irp );
  208. return STATUS_SUCCESS;
  209. }