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.

270 lines
6.4 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. DevCtrl.c
  5. Abstract:
  6. This module implements the Device Control routines for Ntfs called by
  7. the dispatch driver.
  8. Author:
  9. Gary Kimura [GaryKi] 28-May-1991
  10. Revision History:
  11. --*/
  12. #include "NtfsProc.h"
  13. #include <ntddsnap.h>
  14. //
  15. // The local debug trace level
  16. //
  17. #define Dbg (DEBUG_TRACE_DEVCTRL)
  18. //
  19. // Local procedure prototypes
  20. //
  21. NTSTATUS
  22. DeviceControlCompletionRoutine (
  23. IN PDEVICE_OBJECT DeviceObject,
  24. IN PIRP Irp,
  25. IN PVOID Contxt
  26. );
  27. #ifdef ALLOC_PRAGMA
  28. #pragma alloc_text(PAGE, NtfsCommonDeviceControl)
  29. #endif
  30. NTSTATUS
  31. NtfsCommonDeviceControl (
  32. IN PIRP_CONTEXT IrpContext,
  33. IN PIRP Irp
  34. )
  35. /*++
  36. Routine Description:
  37. This is the common routine for Device Control called by both the fsd and fsp
  38. threads.
  39. Arguments:
  40. Irp - Supplies the Irp to process
  41. Return Value:
  42. NTSTATUS - The return status for the operation
  43. --*/
  44. {
  45. NTSTATUS Status = STATUS_SUCCESS;
  46. TYPE_OF_OPEN TypeOfOpen;
  47. PIO_STACK_LOCATION IrpSp;
  48. NTFS_COMPLETION_CONTEXT Context;
  49. PNTFS_COMPLETION_CONTEXT CompletionContext = NULL;
  50. LOGICAL ReleaseResources = FALSE;
  51. PVCB Vcb;
  52. PFCB Fcb;
  53. PSCB Scb;
  54. PCCB Ccb;
  55. ASSERT_IRP_CONTEXT( IrpContext );
  56. ASSERT_IRP( Irp );
  57. ASSERT( FlagOn( IrpContext->TopLevelIrpContext->State, IRP_CONTEXT_STATE_OWNS_TOP_LEVEL ));
  58. PAGED_CODE();
  59. DebugTrace( +1, Dbg, ("NtfsCommonDeviceControl\n") );
  60. DebugTrace( 0, Dbg, ("IrpContext = %08lx\n", IrpContext) );
  61. DebugTrace( 0, Dbg, ("Irp = %08lx\n", Irp) );
  62. //
  63. // Extract and decode the file object
  64. //
  65. IrpSp = IoGetCurrentIrpStackLocation( Irp );
  66. TypeOfOpen = NtfsDecodeFileObject( IrpContext,
  67. IrpSp->FileObject,
  68. &Vcb,
  69. &Fcb,
  70. &Scb,
  71. &Ccb,
  72. TRUE );
  73. //
  74. // The only type of opens we accept are user volume opens.
  75. //
  76. if (TypeOfOpen != UserVolumeOpen) {
  77. NtfsCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );
  78. DebugTrace( -1, Dbg, ("NtfsCommonDeviceControl -> %08lx\n", STATUS_INVALID_PARAMETER) );
  79. return STATUS_INVALID_PARAMETER;
  80. }
  81. try {
  82. //
  83. // A few IOCTLs actually require some intervention on our part
  84. //
  85. switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
  86. case IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES:
  87. //
  88. // This is sent by the Volume Snapshot driver (Lovelace).
  89. // We flush the volume, and hold all file resources
  90. // to make sure that nothing more gets dirty. Then we wait
  91. // for the IRP to complete or cancel.
  92. //
  93. Status = NtfsCheckpointForVolumeSnapshot( IrpContext );
  94. if (NT_SUCCESS( Status )) {
  95. ReleaseResources = TRUE;
  96. }
  97. KeInitializeEvent( &Context.Event, NotificationEvent, FALSE );
  98. Context.IrpContext = IrpContext;
  99. CompletionContext = &Context;
  100. SetFlag( IrpContext->State, IRP_CONTEXT_STATE_WAIT );
  101. break;
  102. case IOCTL_VOLSNAP_RELEASE_WRITES:
  103. //
  104. // No-op for filesystems.
  105. //
  106. break;
  107. default:
  108. break;
  109. }
  110. //
  111. // If error, complete the irp, free the IrpContext
  112. // and return to the caller.
  113. //
  114. if (!NT_SUCCESS( Status )) {
  115. NtfsCompleteRequest( NULL, Irp, Status );
  116. leave;
  117. }
  118. //
  119. // Get the next stack location, and copy over the stack parameter
  120. // information
  121. //
  122. IoCopyCurrentIrpStackLocationToNext( Irp );
  123. //
  124. // Set up the completion routine
  125. //
  126. IoSetCompletionRoutine( Irp,
  127. DeviceControlCompletionRoutine,
  128. CompletionContext,
  129. TRUE,
  130. TRUE,
  131. TRUE );
  132. //
  133. // Send the request. And wait.
  134. //
  135. Status = IoCallDriver( Vcb->TargetDeviceObject, Irp );
  136. if ((Status == STATUS_PENDING) &&
  137. (CompletionContext != NULL)) {
  138. KeWaitForSingleObject( &CompletionContext->Event,
  139. Executive,
  140. KernelMode,
  141. FALSE,
  142. NULL );
  143. }
  144. } finally {
  145. //
  146. // Release all the resources that we held because of a
  147. // VOLSNAP_FLUSH_AND_HOLD.
  148. //
  149. if (ReleaseResources && !NtfsIsVolumeReadOnly( IrpContext->Vcb )) {
  150. NtfsReleaseAllFiles( IrpContext, IrpContext->Vcb, FALSE );
  151. NtfsReleaseVcb( IrpContext, Vcb );
  152. }
  153. #ifdef SUPW_DBG
  154. if (AbnormalTermination()) {
  155. DbgPrint("CommonDevControl Raised: Status %8lx\n", Status);
  156. }
  157. #endif
  158. }
  159. NtfsCleanupIrpContext( IrpContext, TRUE );
  160. DebugTrace( -1, Dbg, ("NtfsCommonDeviceControl -> %08lx\n", Status) );
  161. return Status;
  162. }
  163. //
  164. // Local support routine
  165. //
  166. NTSTATUS
  167. DeviceControlCompletionRoutine (
  168. IN PDEVICE_OBJECT DeviceObject,
  169. IN PIRP Irp,
  170. IN PVOID Contxt
  171. )
  172. {
  173. //
  174. // Add the hack-o-ramma to fix formats.
  175. //
  176. if (Irp->PendingReturned) {
  177. IoMarkIrpPending( Irp );
  178. }
  179. if (Contxt) {
  180. PNTFS_COMPLETION_CONTEXT CompletionContext = (PNTFS_COMPLETION_CONTEXT)Contxt;
  181. KeSetEvent( &CompletionContext->Event, 0, FALSE );
  182. }
  183. //
  184. // Return success always, because we want this IRP to go away for good
  185. // irrespective of the IRP completion status.
  186. //
  187. return STATUS_SUCCESS;
  188. UNREFERENCED_PARAMETER( DeviceObject );
  189. }