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 ULONG eocMark; 59 60 DPRINT("VfatShutdown(DeviceObject %p, Irp %p)\n",DeviceObject, Irp); 61 62 FsRtlEnterFileSystem(); 63 64 /* FIXME: block new mount requests */ 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 if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY) 78 { 79 /* set clean shutdown bit */ 80 Status = GetNextCluster(DeviceExt, 1, &eocMark); 81 if (NT_SUCCESS(Status)) 82 { 83 eocMark |= DeviceExt->CleanShutBitMask; 84 if (NT_SUCCESS(WriteCluster(DeviceExt, 1, eocMark))) 85 DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY; 86 } 87 } 88 89 Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb); 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 /* FIXME: Unmount the logical volume */ 105 106 if (!NT_SUCCESS(Status)) 107 Irp->IoStatus.Status = Status; 108 } 109 ExReleaseResourceLite(&VfatGlobalData->VolumeListLock); 110 111 /* FIXME: Free all global acquired resources */ 112 113 Status = Irp->IoStatus.Status; 114 } 115 else 116 { 117 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; 118 Status = STATUS_INVALID_DEVICE_REQUEST; 119 } 120 121 Irp->IoStatus.Information = 0; 122 IoCompleteRequest(Irp, IO_NO_INCREMENT); 123 124 FsRtlExitFileSystem(); 125 126 return Status; 127 } 128 129 /* EOF */ 130