1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: drivers/fs/vfat/shutdown.c 5 * PURPOSE: VFAT Filesystem 6 * PROGRAMMER: Eric Kohl 7 */ 8 9 /* INCLUDES *****************************************************************/ 10 11 #include "vfat.h" 12 13 #define NDEBUG 14 #include <debug.h> 15 16 /* FUNCTIONS ****************************************************************/ 17 18 static 19 NTSTATUS 20 VfatDiskShutDown( 21 PVCB Vcb) 22 { 23 PIRP Irp; 24 KEVENT Event; 25 NTSTATUS Status; 26 IO_STATUS_BLOCK IoStatus; 27 28 KeInitializeEvent(&Event, NotificationEvent, FALSE); 29 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN, Vcb->StorageDevice, 30 NULL, 0, NULL, &Event, &IoStatus); 31 if (Irp) 32 { 33 Status = IoCallDriver(Vcb->StorageDevice, Irp); 34 if (Status == STATUS_PENDING) 35 { 36 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 37 Status = IoStatus.Status; 38 } 39 } 40 else 41 { 42 Status = STATUS_INSUFFICIENT_RESOURCES; 43 } 44 45 return Status; 46 } 47 48 49 NTSTATUS 50 NTAPI 51 VfatShutdown( 52 PDEVICE_OBJECT DeviceObject, 53 PIRP Irp) 54 { 55 NTSTATUS Status; 56 PLIST_ENTRY ListEntry; 57 PDEVICE_EXTENSION DeviceExt; 58 59 DPRINT("VfatShutdown(DeviceObject %p, Irp %p)\n",DeviceObject, Irp); 60 61 FsRtlEnterFileSystem(); 62 63 /* FIXME: block new mount requests */ 64 VfatGlobalData->ShutdownStarted = TRUE; 65 66 if (DeviceObject == VfatGlobalData->DeviceObject) 67 { 68 Irp->IoStatus.Status = STATUS_SUCCESS; 69 ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE); 70 ListEntry = VfatGlobalData->VolumeListHead.Flink; 71 while (ListEntry != &VfatGlobalData->VolumeListHead) 72 { 73 DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry); 74 ListEntry = ListEntry->Flink; 75 76 ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE); 77 78 /* Flush volume & files */ 79 Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb); 80 81 /* We're performing a clean shutdown */ 82 if (BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_CLEAR_DIRTY) && 83 BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_IS_DIRTY)) 84 { 85 /* Drop the dirty bit */ 86 if (NT_SUCCESS(SetDirtyStatus(DeviceExt, FALSE))) 87 DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY; 88 } 89 90 if (NT_SUCCESS(Status)) 91 { 92 Status = VfatDiskShutDown(DeviceExt); 93 if (!NT_SUCCESS(Status)) 94 { 95 DPRINT1("VfatDiskShutDown failed, status = %x\n", Status); 96 } 97 } 98 else 99 { 100 DPRINT1("VfatFlushVolume failed, status = %x\n", Status); 101 } 102 ExReleaseResourceLite(&DeviceExt->DirResource); 103 104 /* Unmount the logical volume */ 105 #ifdef ENABLE_SWAPOUT 106 VfatCheckForDismount(DeviceExt, FALSE); 107 #endif 108 109 if (!NT_SUCCESS(Status)) 110 Irp->IoStatus.Status = Status; 111 } 112 ExReleaseResourceLite(&VfatGlobalData->VolumeListLock); 113 114 /* FIXME: Free all global acquired resources */ 115 116 Status = Irp->IoStatus.Status; 117 } 118 else 119 { 120 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; 121 Status = STATUS_INVALID_DEVICE_REQUEST; 122 } 123 124 Irp->IoStatus.Information = 0; 125 IoCompleteRequest(Irp, IO_NO_INCREMENT); 126 127 FsRtlExitFileSystem(); 128 129 return Status; 130 } 131 132 /* EOF */ 133