VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS Status;
+ PLIST_ENTRY ListEntry;
+ PDEVICE_EXTENSION DeviceExt;
DPRINT("VfatShutdown(DeviceObject %x, Irp %x)\n",DeviceObject, Irp);
-#if 0
/* FIXME: block new mount requests */
-
- /* FIXME: Traverse list of logical volumes. For each volume: */
- {
- /* FIXME: acquire vcb resource exclusively */
-
- /* FIXME: Flush logical volume */
-
- /* FIXME: send IRP_MJ_SHUTDOWN to each volume */
-
- /* FIXME: wait for completion of IRP_MJ_SHUTDOWN */
-
- /* FIXME: release vcb resource */
- }
-
-#endif
-
- Status = STATUS_SUCCESS;
+ 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);
+ Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
+ ExReleaseResourceLite(&DeviceExt->DirResource);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("VfatFlushVolume failed, status = %x\n", Status);
+ Irp->IoStatus.Status = Status;
+ }
+ /* FIXME: Unmount the logical volume */
+
+ ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
+ }
+ /* FIXME: Free all global acquired resources */
+
+ Status = Irp->IoStatus.Status;
+ }
+ else
+ {
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ }
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;