mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
542e9f2ba0
No code changes. Addendum to14c39362
and6d65da93
.
131 lines
3.5 KiB
C
131 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 */
|