Removed outdated email addresses.
[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 #define NDEBUG
12 #include "vfat.h"
13
14 /* FUNCTIONS ****************************************************************/
15
16 static NTSTATUS
17 VfatDiskShutDown(PVCB Vcb)
18 {
19 PIRP Irp;
20 KEVENT Event;
21 NTSTATUS Status;
22 IO_STATUS_BLOCK IoStatus;
23
24 KeInitializeEvent(&Event, NotificationEvent, FALSE);
25 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN, Vcb->StorageDevice,
26 NULL, 0, NULL, &Event, &IoStatus);
27 if (Irp)
28 {
29 Status = IoCallDriver(Vcb->StorageDevice, Irp);
30 if (Status == STATUS_PENDING)
31 {
32 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
33 Status = IoStatus.Status;
34 }
35 }
36 else
37 {
38 Status = IoStatus.Status;
39 }
40
41 return Status;
42 }
43
44 NTSTATUS NTAPI
45 VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
46 {
47 NTSTATUS Status;
48 PLIST_ENTRY ListEntry;
49 PDEVICE_EXTENSION DeviceExt;
50 ULONG eocMark;
51
52 DPRINT("VfatShutdown(DeviceObject %p, Irp %p)\n",DeviceObject, Irp);
53
54 FsRtlEnterFileSystem();
55
56 /* FIXME: block new mount requests */
57
58 if (DeviceObject == VfatGlobalData->DeviceObject)
59 {
60 Irp->IoStatus.Status = STATUS_SUCCESS;
61 ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE);
62 ListEntry = VfatGlobalData->VolumeListHead.Flink;
63 while (ListEntry != &VfatGlobalData->VolumeListHead)
64 {
65 DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry);
66 ListEntry = ListEntry->Flink;
67
68 ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
69 if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY)
70 {
71 /* set clean shutdown bit */
72 Status = GetNextCluster(DeviceExt, 1, &eocMark);
73 if (NT_SUCCESS(Status))
74 {
75 eocMark |= DeviceExt->CleanShutBitMask;
76 if (NT_SUCCESS(WriteCluster(DeviceExt, 1, eocMark)))
77 DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
78 }
79 }
80 Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
81 if (NT_SUCCESS(Status))
82 {
83 Status = VfatDiskShutDown(DeviceExt);
84 if (!NT_SUCCESS(Status))
85 DPRINT1("VfatDiskShutDown failed, status = %x\n", Status);
86 }
87 else
88 {
89 DPRINT1("VfatFlushVolume failed, status = %x\n", Status);
90 }
91 ExReleaseResourceLite(&DeviceExt->DirResource);
92
93 /* FIXME: Unmount the logical volume */
94
95 if (!NT_SUCCESS(Status))
96 Irp->IoStatus.Status = Status;
97 }
98 ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
99
100 /* FIXME: Free all global acquired resources */
101
102 Status = Irp->IoStatus.Status;
103 }
104 else
105 {
106 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
107 Status = STATUS_INVALID_DEVICE_REQUEST;
108 }
109
110 Irp->IoStatus.Information = 0;
111 IoCompleteRequest(Irp, IO_NO_INCREMENT);
112
113 FsRtlExitFileSystem();
114
115 return(Status);
116 }
117
118 /* EOF */