ReactOS  0.4.14-dev-114-gc8cbd56
close.c
Go to the documentation of this file.
1 /*
2  * FFS File System Driver for Windows
3  *
4  * close.c
5  *
6  * 2004.5.6 ~
7  *
8  * Lee Jae-Hong, http://www.pyrasis.com
9  *
10  * See License.txt
11  *
12  */
13 
14 #include "ntifs.h"
15 #include "ffsdrv.h"
16 
17 /* Globals */
18 
19 extern PFFS_GLOBAL FFSGlobal;
20 
21 /* Definitions */
22 
23 #ifdef ALLOC_PRAGMA
24 #pragma alloc_text(PAGE, FFSClose)
25 #pragma alloc_text(PAGE, FFSQueueCloseRequest)
26 #pragma alloc_text(PAGE, FFSDeQueueCloseRequest)
27 #endif
28 
29 
33  IN PFFS_IRP_CONTEXT IrpContext)
34 {
37  PFFS_VCB Vcb = 0;
38  BOOLEAN VcbResourceAcquired = FALSE;
40  PFFS_FCB Fcb = 0;
41  BOOLEAN FcbResourceAcquired = FALSE;
42  PFFS_CCB Ccb;
43  BOOLEAN FreeVcb = FALSE;
44 
45  PAGED_CODE();
46 
47  _SEH2_TRY
48  {
49  ASSERT(IrpContext != NULL);
50 
51  ASSERT((IrpContext->Identifier.Type == FFSICX) &&
52  (IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
53 
54  DeviceObject = IrpContext->DeviceObject;
55 
57  {
60  }
61 
63 
64  ASSERT(Vcb != NULL);
65 
66  ASSERT((Vcb->Identifier.Type == FFSVCB) &&
67  (Vcb->Identifier.Size == sizeof(FFS_VCB)));
68 
70 
72  &Vcb->MainResource,
73  IrpContext->IsSynchronous))
74  {
75  FFSPrint((DBG_INFO, "FFSClose: PENDING ... Vcb: %xh/%xh\n",
76  Vcb->OpenFileHandleCount, Vcb->ReferenceCount));
77 
80  }
81 
82  VcbResourceAcquired = TRUE;
83 
84  FileObject = IrpContext->FileObject;
85 
86  if (IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE))
87  {
88  Fcb = IrpContext->Fcb;
89  Ccb = IrpContext->Ccb;
90  }
91  else
92  {
93  Fcb = (PFFS_FCB)FileObject->FsContext;
94 
95  if (!Fcb)
96  {
99  }
100 
101  ASSERT(Fcb != NULL);
102 
103  Ccb = (PFFS_CCB)FileObject->FsContext2;
104  }
105 
106  if (Fcb->Identifier.Type == FFSVCB)
107  {
108  Vcb->ReferenceCount--;
109 
110  if (!Vcb->ReferenceCount && FlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING))
111  {
112  FreeVcb = TRUE;
113  }
114 
115  if (Ccb)
116  {
117  FFSFreeCcb(Ccb);
118  if (FileObject)
119  {
120  FileObject->FsContext2 = Ccb = NULL;
121  }
122  }
123 
125 
126  _SEH2_LEAVE;
127  }
128 
129  if (Fcb->Identifier.Type != FFSFCB || Fcb->Identifier.Size != sizeof(FFS_FCB))
130  {
131 #if DBG
132  FFSPrint((DBG_ERROR, "FFSClose: Strange IRP_MJ_CLOSE by system!\n"));
135  TRUE);
136 
137  FFSGlobal->IRPCloseCount++;
138 
142 #endif
143  _SEH2_LEAVE;
144  }
145 
146  ASSERT((Fcb->Identifier.Type == FFSFCB) &&
147  (Fcb->Identifier.Size == sizeof(FFS_FCB)));
148 
149  /*
150  if ((!IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) &&
151  (!IsFlagOn(Fcb->Flags, FCB_PAGE_FILE)))
152  */
153  {
155  &Fcb->MainResource,
156  IrpContext->IsSynchronous))
157  {
159  _SEH2_LEAVE;
160  }
161 
162  FcbResourceAcquired = TRUE;
163  }
164 
165  if (!Ccb)
166  {
168  _SEH2_LEAVE;
169  }
170 
171  ASSERT((Ccb->Identifier.Type == FFSCCB) &&
172  (Ccb->Identifier.Size == sizeof(FFS_CCB)));
173 
174  Fcb->ReferenceCount--;
175  Vcb->ReferenceCount--;
176 
177  if (!Vcb->ReferenceCount && IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING))
178  {
179  FreeVcb = TRUE;
180  }
181 
182  FFSPrint((DBG_INFO, "FFSClose: OpenHandleCount: %u ReferenceCount: %u %s\n",
183  Fcb->OpenHandleCount, Fcb->ReferenceCount, Fcb->AnsiFileName.Buffer));
184 
185  if (Ccb)
186  {
187  FFSFreeCcb(Ccb);
188 
189  if (FileObject)
190  {
191  FileObject->FsContext2 = Ccb = NULL;
192  }
193  }
194 
195  if (!Fcb->ReferenceCount)
196  {
197  //
198  // Remove Fcb from Vcb->FcbList ...
199  //
200 
201  RemoveEntryList(&Fcb->Next);
202 
203  FFSFreeFcb(Fcb);
204 
205  FcbResourceAcquired = FALSE;
206  }
207 
209  }
210 
212  {
213  if (FcbResourceAcquired)
214  {
216  &Fcb->MainResource,
218  }
219 
220  if (VcbResourceAcquired)
221  {
223  &Vcb->MainResource,
225  }
226 
227  if (!IrpContext->ExceptionInProgress)
228  {
229  if (Status == STATUS_PENDING)
230  {
231  FFSQueueCloseRequest(IrpContext);
232 #if 0
233 /*
234  Status = STATUS_SUCCESS;
235 
236  if (IrpContext->Irp != NULL)
237  {
238  IrpContext->Irp->IoStatus.Status = Status;
239 
240  FFSCompleteRequest(
241  IrpContext->Irp,
242  (BOOLEAN)!IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED),
243  (CCHAR)
244  (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
245 
246  IrpContext->Irp = NULL;
247  }
248 */
249 #endif
250  }
251  else
252  {
253  FFSCompleteIrpContext(IrpContext, Status);
254 
255  if (FreeVcb)
256  {
258  &FFSGlobal->Resource, TRUE);
259 
261 
262  FFSRemoveVcb(Vcb);
263 
267 
268  FFSFreeVcb(Vcb);
269  }
270  }
271  }
272  } _SEH2_END;
273 
274  return Status;
275 }
276 
277 
278 VOID
280  IN PFFS_IRP_CONTEXT IrpContext)
281 {
282  PAGED_CODE();
283 
284  ASSERT(IrpContext);
285 
286  ASSERT((IrpContext->Identifier.Type == FFSICX) &&
287  (IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
288 
289  if (!IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE))
290  {
291  SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DELAY_CLOSE);
292 
293  IrpContext->Fcb = (PFFS_FCB)IrpContext->FileObject->FsContext;
294  IrpContext->Ccb = (PFFS_CCB)IrpContext->FileObject->FsContext2;
295 
296  IrpContext->FileObject = NULL;
297  }
298 
299  // IsSynchronous means we can block (so we don't requeue it)
300  IrpContext->IsSynchronous = TRUE;
301 
303  &IrpContext->WorkQueueItem,
305  IrpContext);
306 
307  ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
308 }
309 
310 
311 VOID NTAPI
313  IN PVOID Context)
314 {
315  PFFS_IRP_CONTEXT IrpContext;
316 
317  PAGED_CODE();
318 
319  IrpContext = (PFFS_IRP_CONTEXT) Context;
320 
321  ASSERT(IrpContext);
322 
323  ASSERT((IrpContext->Identifier.Type == FFSICX) &&
324  (IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));
325 
326  _SEH2_TRY
327  {
328  _SEH2_TRY
329  {
331  FFSClose(IrpContext);
332  }
334  {
335  FFSExceptionHandler(IrpContext);
336  } _SEH2_END;
337  }
339  {
341  } _SEH2_END;
342 }
#define ExGetCurrentResourceThread()
Definition: env_spec_w32.h:633
Definition: ffsdrv.h:281
#define IN
Definition: typedefs.h:38
#define IsMounted(Vcb)
Definition: ext2fs.h:803
struct _FCB::@697::@700 Fcb
#define TRUE
Definition: types.h:120
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
NTSTATUS FFSExceptionHandler(IN PFFS_IRP_CONTEXT IrpContext)
Definition: except.c:117
#define FsRtlEnterFileSystem
#define __drv_mustHoldCriticalRegion
Definition: ffsdrv.h:34
#define FsRtlExitFileSystem
LONG NTSTATUS
Definition: precomp.h:26
VOID FFSClearVpbFlag(IN PVPB Vpb, IN USHORT Flag)
Definition: fsctl.c:69
Definition: ffsdrv.h:283
struct _FFS_FCB * PFFS_FCB
PFFS_GLOBAL FFSGlobal
Definition: init.c:22
PDEVICE_OBJECT DeviceObject
Definition: ffsdrv.h:371
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
#define IRP_CONTEXT_FLAG_DELAY_CLOSE
Definition: ext2fs.h:1087
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
NTFSIDENTIFIER Identifier
Definition: ntfs.h:511
ERESOURCE CountResource
Definition: ffsdrv.h:355
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
struct _FFS_IRP_CONTEXT * PFFS_IRP_CONTEXT
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
Definition: ffsdrv.h:282
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _FFS_VCB * PFFS_VCB
FFS_IDENTIFIER_TYPE Type
Definition: ffsdrv.h:294
ULONG Size
Definition: ffsdrv.h:295
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
ULONG OpenHandleCount
Definition: ntfs.h:533
NTSTATUS FFSExceptionFilter(IN PFFS_IRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: except.c:31
__drv_mustHoldCriticalRegion NTSTATUS FFSClose(IN PFFS_IRP_CONTEXT IrpContext)
Definition: close.c:32
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
VOID FFSRemoveVcb(PFFS_VCB Vcb)
Definition: memory.c:1542
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define STATUS_PENDING
Definition: ntstatus.h:82
__drv_mustHoldCriticalRegion VOID FFSFreeFcb(IN PFFS_FCB Fcb)
Definition: memory.c:715
#define Vcb
Definition: cdprocs.h:1425
* PFILE_OBJECT
Definition: iotypes.h:1955
__drv_mustHoldCriticalRegion VOID FFSFreeVcb(IN PFFS_VCB Vcb)
Definition: memory.c:1886
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
__drv_mustHoldCriticalRegion NTSTATUS FFSCompleteIrpContext(IN PFFS_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:53
#define VCB_DISMOUNT_PENDING
Definition: ext2fs.h:782
ULONG Type
Definition: ntfs.h:95
Definition: ffsdrv.h:280
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define DBG_ERROR
Definition: ffsdrv.h:1031
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
ERESOURCE MainResource
Definition: ntfs.h:524
Status
Definition: gdiplustypes.h:24
#define FFSPrint(arg)
Definition: ffsdrv.h:1047
struct _FFS_CCB * PFFS_CCB
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
ERESOURCE Resource
Definition: ffsdrv.h:352
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4424
FFS_IDENTIFIER Identifier
Definition: ffsdrv.h:722
_SEH2_FINALLY
Definition: create.c:4395
VOID NTAPI FFSDeQueueCloseRequest(IN PVOID Context)
Definition: close.c:312
VOID NTAPI ExReleaseResourceForThreadLite(IN PERESOURCE Resource, IN ERESOURCE_THREAD Thread)
Definition: resource.c:1844
#define DBG_INFO
Definition: ffsdrv.h:1034
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
VOID FFSQueueCloseRequest(IN PFFS_IRP_CONTEXT IrpContext)
Definition: close.c:279
#define _SEH2_LEAVE
Definition: filesup.c:20
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define VPB_MOUNTED
Definition: iotypes.h:1764
__drv_mustHoldCriticalRegion VOID FFSFreeCcb(IN PFFS_CCB Ccb)
Definition: memory.c:853
ULONG Size
Definition: ntfs.h:96