branch update for HEAD-2003050101
[reactos.git] / drivers / fs / vfat / flush.c
1 /* $Id$
2  *
3  * COPYRIGHT:        See COPYING in the top level directory
4  * PROJECT:          ReactOS kernel
5  * FILE:             drivers/fs/vfat/flush.c
6  * PURPOSE:          VFAT Filesystem
7  * PROGRAMMER:       Hartmut Birr
8  */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <ddk/ntddk.h>
13 #include "vfat.h"
14
15 #define NDEBUG
16 #include <debug.h>
17
18 /* FUNCTIONS ****************************************************************/
19
20 NTSTATUS VfatFlushFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb)
21 {
22    IO_STATUS_BLOCK IoStatus;
23
24    DPRINT("VfatFlushFile(DeviceExt %x, Fcb %x) for '%S'\n", DeviceExt, Fcb, Fcb->PathName);
25
26    CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, &IoStatus);
27    if (IoStatus.Status == STATUS_INVALID_PARAMETER)
28    {
29       /* FIXME: Caching was possible not initialized */
30       IoStatus.Status = STATUS_SUCCESS;
31    }
32    return IoStatus.Status;
33 }
34
35 NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb)
36 {
37    PLIST_ENTRY ListEntry;
38    PVFATFCB Fcb;
39    NTSTATUS Status, ReturnStatus = STATUS_SUCCESS;
40
41    DPRINT("VfatFlushVolume(DeviceExt %x, FatFcb %x)\n", DeviceExt, VolumeFcb);
42
43    ListEntry = DeviceExt->FcbListHead.Flink;
44    while (ListEntry != &DeviceExt->FcbListHead)
45    {
46       Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
47       ListEntry = ListEntry->Flink;
48       ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
49       Status = VfatFlushFile(DeviceExt, Fcb);
50       ExReleaseResourceLite (&Fcb->MainResource);
51       if (!NT_SUCCESS(Status))
52       {
53          DPRINT1("VfatFlushFile failed, status = %x\n", Status);
54          ReturnStatus = Status;
55       }
56       /* FIXME: Stop flushing if this is a removable media and the media was removed */
57    }
58
59    Fcb = (PVFATFCB) DeviceExt->FATFileObject->FsContext;
60   
61    ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
62    Status = VfatFlushFile(DeviceExt, Fcb);
63    ExReleaseResourceLite(&DeviceExt->FatResource);
64
65    /* FIXME: Flush the buffers from storage device */
66
67    if (!NT_SUCCESS(Status))
68    {
69       DPRINT1("VfatFlushFile failed, status = %x\n", Status);
70       ReturnStatus = Status;
71    }
72
73    return ReturnStatus;
74 }
75
76 NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext)
77 {
78   NTSTATUS Status;
79   PVFATFCB Fcb;
80   /*
81    * This request is not allowed on the main device object.
82    */
83   if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
84   {
85      Status = STATUS_INVALID_DEVICE_REQUEST;
86      goto ByeBye;
87   }
88
89   Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
90   assert(Fcb);
91
92   if (Fcb->Flags & FCB_IS_VOLUME)
93   {
94      ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
95      Status = VfatFlushVolume(IrpContext->DeviceExt, Fcb);
96      ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
97   }
98   else
99   {
100      ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
101      Status = VfatFlushFile(IrpContext->DeviceExt, Fcb);
102      ExReleaseResourceLite (&Fcb->MainResource);
103   }
104
105 ByeBye:
106   IrpContext->Irp->IoStatus.Status = Status;
107   IrpContext->Irp->IoStatus.Information = 0;
108   IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
109   VfatFreeIrpContext(IrpContext);
110
111   return (Status);
112 }
113
114 /* EOF */