update for HEAD-2003021201
[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    PVFATCCB Ccb;
40    NTSTATUS Status, ReturnStatus = STATUS_SUCCESS;
41
42    DPRINT("VfatFlushVolume(DeviceExt %x, FatFcb %x)\n", DeviceExt, VolumeFcb);
43
44    ListEntry = DeviceExt->FcbListHead.Flink;
45    while (ListEntry != &DeviceExt->FcbListHead)
46    {
47       Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
48       ListEntry = ListEntry->Flink;
49       ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
50       Status = VfatFlushFile(DeviceExt, Fcb);
51       ExReleaseResourceLite (&Fcb->MainResource);
52       if (!NT_SUCCESS(Status))
53       {
54          DPRINT1("VfatFlushFile failed, status = %x\n", Status);
55          ReturnStatus = Status;
56       }
57       /* FIXME: Stop flushing if this a removable media and the media was removed */
58    }
59
60    Ccb = (PVFATCCB) DeviceExt->FATFileObject->FsContext2;
61    Fcb =  Ccb->pFcb;
62   
63    ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
64    Status = VfatFlushFile(DeviceExt, Fcb);
65    ExReleaseResourceLite(&DeviceExt->FatResource);
66
67    /* FIXME: Flush the buffers from storage device */
68
69    if (!NT_SUCCESS(Status))
70    {
71       DPRINT1("VfatFlushFile failed, status = %x\n", Status);
72       ReturnStatus = Status;
73    }
74
75    return ReturnStatus;
76 }
77
78 NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext)
79 {
80   NTSTATUS Status;
81   PVFATFCB Fcb;
82   PVFATCCB Ccb;
83   /*
84    * This request is not allowed on the main device object.
85    */
86   if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
87   {
88      Status = STATUS_INVALID_DEVICE_REQUEST;
89      goto ByeBye;
90   }
91
92   Ccb = (PVFATCCB) IrpContext->FileObject->FsContext2;
93   assert(Ccb);
94   Fcb =  Ccb->pFcb;
95   assert(Fcb);
96
97   if (Fcb->Flags & FCB_IS_VOLUME)
98   {
99      ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
100      Status = VfatFlushVolume(IrpContext->DeviceExt, Fcb);
101      ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
102   }
103   else
104   {
105      ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
106      Status = VfatFlushFile(IrpContext->DeviceExt, Fcb);
107      ExReleaseResourceLite (&Fcb->MainResource);
108   }
109
110 ByeBye:
111   IrpContext->Irp->IoStatus.Status = Status;
112   IrpContext->Irp->IoStatus.Information = 0;
113   IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
114   VfatFreeIrpContext(IrpContext);
115
116   return (Status);
117 }
118
119 /* EOF */