[FASTFAT]
[reactos.git] / reactos / drivers / filesystems / fastfat / shutdown.c
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 = IoStatus.Status;
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 */