[FASTFAT] Implement delayed close
[reactos.git] / 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 = 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 */