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 65 if (DeviceObject == VfatGlobalData->DeviceObject) 66 { 67 Irp->IoStatus.Status = STATUS_SUCCESS; 68 ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE); 69 ListEntry = VfatGlobalData->VolumeListHead.Flink; 70 while (ListEntry != &VfatGlobalData->VolumeListHead) 71 { 72 DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry); 73 ListEntry = ListEntry->Flink; 74 75 ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE); 76 /* It was a clean volume mounted */ 77 if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY) 78 { 79 /* So, drop the dirty bit we set */ 80 if (NT_SUCCESS(SetDirtyStatus(DeviceExt, FALSE))) 81 DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY; 82 } 83 84 Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb); 85 if (NT_SUCCESS(Status)) 86 { 87 Status = VfatDiskShutDown(DeviceExt); 88 if (!NT_SUCCESS(Status)) 89 { 90 DPRINT1("VfatDiskShutDown failed, status = %x\n", Status); 91 } 92 } 93 else 94 { 95 DPRINT1("VfatFlushVolume failed, status = %x\n", Status); 96 } 97 ExReleaseResourceLite(&DeviceExt->DirResource); 98 99 /* FIXME: Unmount the logical volume */ 100 101 if (!NT_SUCCESS(Status)) 102 Irp->IoStatus.Status = Status; 103 } 104 ExReleaseResourceLite(&VfatGlobalData->VolumeListLock); 105 106 /* FIXME: Free all global acquired resources */ 107 108 Status = Irp->IoStatus.Status; 109 } 110 else 111 { 112 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; 113 Status = STATUS_INVALID_DEVICE_REQUEST; 114 } 115 116 Irp->IoStatus.Information = 0; 117 IoCompleteRequest(Irp, IO_NO_INCREMENT); 118 119 FsRtlExitFileSystem(); 120 121 return Status; 122 } 123 124 /* EOF */ 125