reactos/drivers/filesystems/vfatfs/shutdown.c
Stanislav Motylkov 542e9f2ba0
[FS_REC][VFATFS] Update headers per our current coding style
No code changes. Addendum to 14c39362 and 6d65da93.
2022-09-24 16:24:08 +03:00

132 lines
3.5 KiB
C

/*
* PROJECT: VFAT Filesystem
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Shutdown handlers
* COPYRIGHT: Copyright 2000-2013 Eric Kohl <eric.kohl@reactos.org>
*/
/* INCLUDES *****************************************************************/
#include "vfat.h"
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ****************************************************************/
static
NTSTATUS
VfatDiskShutDown(
PVCB Vcb)
{
PIRP Irp;
KEVENT Event;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatus;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN, Vcb->StorageDevice,
NULL, 0, NULL, &Event, &IoStatus);
if (Irp)
{
Status = IoCallDriver(Vcb->StorageDevice, Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = IoStatus.Status;
}
}
else
{
Status = STATUS_INSUFFICIENT_RESOURCES;
}
return Status;
}
NTSTATUS
NTAPI
VfatShutdown(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
NTSTATUS Status;
PLIST_ENTRY ListEntry;
PDEVICE_EXTENSION DeviceExt;
DPRINT("VfatShutdown(DeviceObject %p, Irp %p)\n",DeviceObject, Irp);
FsRtlEnterFileSystem();
/* FIXME: block new mount requests */
VfatGlobalData->ShutdownStarted = TRUE;
if (DeviceObject == VfatGlobalData->DeviceObject)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE);
ListEntry = VfatGlobalData->VolumeListHead.Flink;
while (ListEntry != &VfatGlobalData->VolumeListHead)
{
DeviceExt = CONTAINING_RECORD(ListEntry, VCB, VolumeListEntry);
ListEntry = ListEntry->Flink;
ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
/* Flush volume & files */
Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
/* We're performing a clean shutdown */
if (BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_CLEAR_DIRTY) &&
BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_IS_DIRTY))
{
/* Drop the dirty bit */
if (NT_SUCCESS(SetDirtyStatus(DeviceExt, FALSE)))
DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
}
if (NT_SUCCESS(Status))
{
Status = VfatDiskShutDown(DeviceExt);
if (!NT_SUCCESS(Status))
{
DPRINT1("VfatDiskShutDown failed, status = %x\n", Status);
}
}
else
{
DPRINT1("VfatFlushVolume failed, status = %x\n", Status);
}
ExReleaseResourceLite(&DeviceExt->DirResource);
/* Unmount the logical volume */
#ifdef ENABLE_SWAPOUT
VfatCheckForDismount(DeviceExt, FALSE);
#endif
if (!NT_SUCCESS(Status))
Irp->IoStatus.Status = Status;
}
ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
/* FIXME: Free all global acquired resources */
Status = Irp->IoStatus.Status;
}
else
{
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Status = STATUS_INVALID_DEVICE_REQUEST;
}
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
FsRtlExitFileSystem();
return Status;
}
/* EOF */