ReactOS  0.4.14-dev-556-g4c5b21f
close.cpp
Go to the documentation of this file.
1 // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine
3 // All rights reserved
4 // This file was released under the GPLv2 on June 2015.
6 /*************************************************************************
7 *
8 * File: Close.cpp
9 *
10 * Module: UDF File System Driver (Kernel mode execution only)
11 *
12 * Description:
13 * Contains code to handle the "Close" dispatch entry point.
14 *
15 *************************************************************************/
16 
17 #include "udffs.h"
18 
19 // define the file specific bug-check id
20 #define UDF_BUG_CHECK_ID UDF_FILE_CLOSE
21 
23 #define TREE_ITEM_LIST_GRAN 32
24 
27  IN PVCB Vcb,
29  IN PCHECK_TREE_ITEM CheckItemProc,
30  IN PUDF_DATALOC_INFO** PassedList,
31  IN PULONG PassedListSize,
32  IN PUDF_DATALOC_INFO** FoundList,
33  IN PULONG FoundListSize);
34 
35 // callbacks, can't be __fastcall
36 BOOLEAN
39 
40 BOOLEAN
43 
44 /*************************************************************************
45 *
46 * Function: UDFClose()
47 *
48 * Description:
49 * The I/O Manager will invoke this routine to handle a close
50 * request
51 *
52 * Expected Interrupt Level (for execution) :
53 *
54 * IRQL_PASSIVE_LEVEL (invocation at higher IRQL will cause execution
55 * to be deferred to a worker thread context)
56 *
57 * Return Value: STATUS_SUCCESS
58 *
59 *************************************************************************/
61 NTAPI
63  PDEVICE_OBJECT DeviceObject, // the logical volume device object
64  PIRP Irp // I/O Request Packet
65  )
66 {
68  PtrUDFIrpContext PtrIrpContext = NULL;
69  BOOLEAN AreWeTopLevel = FALSE;
70 
71  AdPrint(("UDFClose: \n"));
72 
75  ASSERT(Irp);
76 
77  // If we were called with our file system device object instead of a
78  // volume device object, just complete this request with STATUS_SUCCESS
79  if (UDFIsFSDevObj(DeviceObject)) {
80  // this is a close of the FSD itself
81  Irp->IoStatus.Status = RC;
82  Irp->IoStatus.Information = 0;
83 
86  return(RC);
87  }
88 
89  // set the top level context
90  AreWeTopLevel = UDFIsIrpTopLevel(Irp);
91 
92  _SEH2_TRY {
93 
94  // get an IRP context structure and issue the request
95  PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
96  ASSERT(PtrIrpContext);
97 
98  RC = UDFCommonClose(PtrIrpContext, Irp);
99 
101 
102  RC = UDFExceptionHandler(PtrIrpContext, Irp);
103 
105  } _SEH2_END;
106 
107  if (AreWeTopLevel) {
109  }
110 
112 
113  return(RC);
114 }
115 
116 
117 
118 
119 /*************************************************************************
120 *
121 * Function: UDFCommonClose()
122 *
123 * Description:
124 * The actual work is performed here. This routine may be invoked in one'
125 * of the two possible contexts:
126 * (a) in the context of a system worker thread
127 * (b) in the context of the original caller
128 *
129 * Expected Interrupt Level (for execution) :
130 *
131 * IRQL_PASSIVE_LEVEL
132 *
133 * Return Value: must be STATUS_SUCCESS
134 *
135 *************************************************************************/
136 NTSTATUS
138  PtrUDFIrpContext PtrIrpContext,
139  PIRP Irp
140  )
141 {
145  PtrUDFFCB Fcb = NULL;
146  PtrUDFCCB Ccb = NULL;
147  PVCB Vcb = NULL;
148 // PERESOURCE PtrResourceAcquired = NULL;
149  BOOLEAN AcquiredVcb = FALSE;
150  BOOLEAN AcquiredGD = FALSE;
151  PUDF_FILE_INFO fi;
152  ULONG i = 0;
153 // ULONG clean_stat = 0;
154 
155 // BOOLEAN CompleteIrp = TRUE;
156  BOOLEAN PostRequest = FALSE;
157 
158 #ifdef UDF_DBG
159  UNICODE_STRING CurName;
160  PDIR_INDEX_HDR DirNdx;
161 #endif
162 
163  AdPrint(("UDFCommonClose: \n"));
164 
165  _SEH2_TRY {
166  if (Irp) {
167 
168  // If this is the first (IOManager) request
169  // First, get a pointer to the current I/O stack location
171  ASSERT(IrpSp);
172 
175 
176  // Get the FCB and CCB pointers
177  Ccb = (PtrUDFCCB)(FileObject->FsContext2);
178  ASSERT(Ccb);
179  if(Ccb->CCBFlags & UDF_CCB_READ_ONLY) {
180  PtrIrpContext->IrpContextFlags |= UDF_IRP_CONTEXT_READ_ONLY;
181  }
182  Fcb = Ccb->Fcb;
183  } else {
184  // If this is a queued call (for our dispatch)
185  // Get saved Fcb address
186  Fcb = PtrIrpContext->Fcb;
187  i = PtrIrpContext->TreeLength;
188  }
189 
190  ASSERT(Fcb);
191  Vcb = (PVCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension);
192  ASSERT(Vcb);
193  ASSERT(Vcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB);
194 // Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
195 
196  // Steps we shall take at this point are:
197  // (a) Acquire the VCB shared
198  // (b) Acquire the FCB's CCB list exclusively
199  // (c) Delete the CCB structure (free memory)
200  // (d) If this is the last close, release the FCB structure
201  // (unless we keep these around for "delayed close" functionality.
202  // Note that it is often the case that the close dispatch entry point is invoked
203  // in the most inconvenient of situations (when it is not possible, for example,
204  // to safely acquire certain required resources without deadlocking or waiting).
205  // Therefore, be extremely careful in implementing this close dispatch entry point.
206  // Also note that we do not have the option of returning a failure code from the
207  // close dispatch entry point; the system expects that the close will always succeed.
208 
209  UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
210  AcquiredVcb = TRUE;
211 
212  // Is this is the first (IOManager) request ?
213  if (Irp) {
214  PtrIrpContext->TreeLength =
215  i = Ccb->TreeLength;
216  // remember the number of incomplete Close requests
217  InterlockedIncrement((PLONG)&(Fcb->CcbCount));
218  // we can release CCB in any case
220  FileObject->FsContext2 = NULL;
221 #ifdef DBG
222 /* } else {
223  ASSERT(Fcb->NTRequiredFCB);
224  if(Fcb->NTRequiredFCB) {
225  ASSERT(Fcb->NTRequiredFCB->FileObject);
226  if(Fcb->NTRequiredFCB->FileObject) {
227  ASSERT(!Fcb->NTRequiredFCB->FileObject->FsContext2);
228  }
229  }*/
230 #endif //DBG
231  }
232 
233 #ifdef UDF_DELAYED_CLOSE
234  // check if this is the last Close (no more Handles)
235  // and try to Delay it....
236  if((Fcb->FCBFlags & UDF_FCB_DELAY_CLOSE) &&
237  (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) &&
238  !(Vcb->VCBFlags & UDF_VCB_FLAGS_NO_DELAYED_CLOSE) &&
239  !(Fcb->OpenHandleCount)) {
240  UDFReleaseResource(&(Vcb->VCBResource));
241  AcquiredVcb = FALSE;
242  if((RC = UDFQueueDelayedClose(PtrIrpContext,Fcb)) == STATUS_SUCCESS)
244  // do standard Close if we can't Delay this opeartion
245  AdPrint((" Cant queue Close Irp, status=%x\n", RC));
246  }
247 #endif //UDF_DELAYED_CLOSE
248 
249  if(Irp) {
250  // We should post actual procesing if this is a recursive call
251  if((PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_NOT_TOP_LEVEL) ||
252  (Fcb->NTRequiredFCB->AcqFlushCount)) {
253  AdPrint((" post NOT_TOP_LEVEL Irp\n"));
254  PostRequest = TRUE;
256  }
257  }
258 
259  // Close request is near completion, Vcb is acquired.
260  // Now we can safely decrease CcbCount, because no Rename
261  // operation can run until Vcb release.
262  InterlockedDecrement((PLONG)&(Fcb->CcbCount));
263 
264  UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
265  if(PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_READ_ONLY)
266  UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCountRO));
267 
268  if(!i || (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB)) {
269 
270  AdPrint(("UDF: Closing volume\n"));
271  AdPrint(("UDF: ReferenceCount: %x\n",Fcb->ReferenceCount));
272 
273  if (Vcb->VCBOpenCount > UDF_RESIDUAL_REFERENCE) {
274  ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB);
275  UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
276  ASSERT(Fcb->NTRequiredFCB);
277  UDFInterlockedDecrement((PLONG)&(Fcb->NTRequiredFCB->CommonRefCount));
278 
280  }
281 
282  UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
283 
284  if(AcquiredVcb) {
285  UDFReleaseResource(&(Vcb->VCBResource));
286  AcquiredVcb = FALSE;
287  } else {
288  BrutePoint();
289  }
290  // Acquire GlobalDataResource
291  UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
292  AcquiredGD = TRUE;
293 // // Acquire Vcb
294  UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
295  AcquiredVcb = TRUE;
296 
297  UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
298 
299 
300  ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB);
301  UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
302  ASSERT(Fcb->NTRequiredFCB);
303  UDFInterlockedDecrement((PLONG)&(Fcb->NTRequiredFCB->CommonRefCount));
304 
305  //AdPrint(("UDF: Closing volume, reset driver (e.g. stop BGF)\n"));
306  //UDFResetDeviceDriver(Vcb, Vcb->TargetDeviceObject, FALSE);
307 
308  AdPrint(("UDF: Closing volume, reset write status\n"));
309  RC = UDFPhSendIOCTL(IOCTL_CDRW_RESET_WRITE_STATUS, Vcb->TargetDeviceObject,
310  NULL, 0, NULL, 0, TRUE, NULL);
311 
312  if((Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED) ||
313  ((!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) && (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE))) {
314  // Try to KILL dismounted volume....
315  // w2k requires this, NT4 - recomends
316  AcquiredVcb = UDFCheckForDismount(PtrIrpContext, Vcb, TRUE);
317  }
318 
320  }
321 
322  fi = Fcb->FileInfo;
323 #ifdef UDF_DBG
324  if(!fi) {
325  BrutePoint();
326  }
327 
328  DirNdx = UDFGetDirIndexByFileInfo(fi);
329  if(DirNdx) {
330  CurName.Buffer = UDFDirIndex(DirNdx,fi->Index)->FName.Buffer;
331  if(CurName.Buffer) {
332  AdPrint(("Closing file: %ws %8.8x\n", CurName.Buffer, FileObject));
333  } else {
334  AdPrint(("Closing file: ??? \n"));
335  }
336  }
337  AdPrint(("UDF: ReferenceCount: %x\n",Fcb->ReferenceCount));
338 #endif // UDF_DBG
339  // try to clean up as long chain as it is possible
340  UDFCleanUpFcbChain(Vcb, fi, i, TRUE);
341 
342 try_exit: NOTHING;
343 
344  } _SEH2_FINALLY {
345 
346  if(AcquiredVcb) {
347  UDFReleaseResource(&(Vcb->VCBResource));
348  }
349  if(AcquiredGD) {
350  UDFReleaseResource(&(UDFGlobalData.GlobalDataResource));
351  }
352 
353  // Post IRP if required
354  if (PostRequest) {
355 
356  // Perform the post operation & complete the IRP
357  // if this is first call of UDFCommonClose
358  // and will return STATUS_SUCCESS back to us
359  PtrIrpContext->Irp = NULL;
360  PtrIrpContext->Fcb = Fcb;
361  UDFPostRequest(PtrIrpContext, NULL);
362  }
363 
364  if (!_SEH2_AbnormalTermination()) {
365  // If this is not async close complete the IRP
366  if (Irp) {
367 /* if( FileObject ) {
368  if(clean_stat & UDF_CLOSE_NTREQFCB_DELETED) {
369 // ASSERT(!FileObject->FsContext2);
370  FileObject->FsContext = NULL;
371 #ifdef DBG
372  } else {
373  UDFNTRequiredFCB* NtReqFcb = ((UDFNTRequiredFCB*)(FileObject->FsContext));
374  if(NtReqFcb->FileObject == FileObject) {
375  NtReqFcb->FileObject = NULL;
376  }
377 #endif //DBG
378  }
379  }*/
380  Irp->IoStatus.Status = STATUS_SUCCESS;
381  Irp->IoStatus.Information = 0;
383  }
384  // Free up the Irp Context
385  if(!PostRequest)
386  UDFReleaseIrpContext(PtrIrpContext);
387  }
388 
389  } _SEH2_END; // end of "__finally" processing
390 
391  return STATUS_SUCCESS ;
392 } // end UDFCommonClose()
393 
394 /*
395  This routine walks through the tree to RootDir & kills all unreferenced
396  structures....
397  imho, Useful feature
398  */
399 ULONG
401  IN PVCB Vcb,
402  IN PUDF_FILE_INFO fi,
403  IN ULONG TreeLength,
404  IN BOOLEAN VcbAcquired
405  )
406 {
407  PtrUDFFCB Fcb = NULL;
409  PUDF_FILE_INFO ParentFI;
411  ULONG CleanCode;
412  LONG RefCount, ComRefCount;
413  BOOLEAN Delete = FALSE;
414  ULONG ret_val = 0;
415 
416  ValidateFileInfo(fi);
417  AdPrint(("UDFCleanUpFcbChain\n"));
418 
419  ASSERT(TreeLength);
420 
421  // we can't process Tree until we can acquire Vcb
422  if(!VcbAcquired)
423  UDFAcquireResourceShared(&(Vcb->VCBResource),TRUE);
424 
425  // cleanup parent chain (if any & unused)
426  while(fi) {
427 
428  // acquire parent
429  if((ParentFI = fi->ParentFile)) {
430  ASSERT(fi->Fcb);
431  ParentFcb = fi->Fcb->ParentFcb;
432  ASSERT(ParentFcb);
433  ASSERT(ParentFcb->NTRequiredFCB);
434  UDF_CHECK_PAGING_IO_RESOURCE(ParentFcb->NTRequiredFCB);
436  } else {
437  // we get to RootDir, it has no parent
438  if(!VcbAcquired)
439  UDFAcquireResourceShared(&(Vcb->VCBResource),TRUE);
440  }
441  Fcb = fi->Fcb;
442  ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_FCB);
443 
444  NtReqFcb = Fcb->NTRequiredFCB;
445  ASSERT(NtReqFcb->CommonFCBHeader.NodeTypeCode == UDF_NODE_TYPE_NT_REQ_FCB);
446 
447  // acquire current file/dir
448  // we must assure that no more threads try to re-use this object
449 #ifdef UDF_DBG
450  _SEH2_TRY {
451 #endif // UDF_DBG
453  UDFAcquireResourceExclusive(&(NtReqFcb->MainResource),TRUE);
454 #ifdef UDF_DBG
456  BrutePoint();
457  if(ParentFI) {
458  UDF_CHECK_PAGING_IO_RESOURCE(ParentFcb->NTRequiredFCB);
459  UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
460  } else {
461  if(!VcbAcquired)
462  UDFReleaseResource(&(Vcb->VCBResource));
463  }
464  break;
465  } _SEH2_END;
466 #endif // UDF_DBG
467  ASSERT_REF((Fcb->ReferenceCount > fi->RefCount) || !TreeLength);
468  // If we haven't pass through all files opened
469  // in UDFCommonCreate before target file (TreeLength specfies
470  // the number of such files) dereference them.
471  // Otherwise we'll just check if the file has no references.
472 #ifdef UDF_DBG
473  if(Fcb) {
474  if(TreeLength) {
475  ASSERT(Fcb->ReferenceCount);
476  ASSERT(NtReqFcb->CommonRefCount);
477  RefCount = UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
478  ComRefCount = UDFInterlockedDecrement((PLONG)&(NtReqFcb->CommonRefCount));
479  }
480  } else {
481  BrutePoint();
482  }
483  if(TreeLength)
484  TreeLength--;
485  ASSERT(Fcb->OpenHandleCount <= Fcb->ReferenceCount);
486 #else
487  if(TreeLength) {
488  RefCount = UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
489  ComRefCount = UDFInterlockedDecrement((PLONG)&(NtReqFcb->CommonRefCount));
490  TreeLength--;
491  }
492 #endif
493 
494 /* if(Fcb && Fcb->FCBName && Fcb->FCBName->ObjectName.Buffer) {
495  AdPrint((" %ws (%x)\n",
496  Fcb->FCBName->ObjectName.Buffer,Fcb->ReferenceCount));
497  } else if (Fcb) {
498  AdPrint((" ??? (%x)\n",Fcb->ReferenceCount));
499  } else {
500  AdPrint((" ??? (??)\n"));
501  }*/
502  // ...and delete if it has gone
503 
504  if(!RefCount && !Fcb->OpenHandleCount) {
505  // no more references... current file/dir MUST DIE!!!
506  BOOLEAN AutoInherited = UDFIsAStreamDir(fi) || UDFIsAStream(fi);
507 
508  if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) {
509  // do nothing
510  } else
511 #ifndef UDF_READ_ONLY_BUILD
512  if(Delete) {
513 /* if(!(Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
514  // set file size to zero (for UdfInfo package)
515  // we should not do this for directories
516  UDFResizeFile__(Vcb, fi, 0);
517  }*/
518  UDFReferenceFile__(fi);
519  ASSERT(Fcb->ReferenceCount < fi->RefCount);
520  UDFFlushFile__(Vcb, fi);
521  UDFUnlinkFile__(Vcb, fi, TRUE);
522  UDFCloseFile__(Vcb, fi);
523  ASSERT(Fcb->ReferenceCount == fi->RefCount);
524  Fcb->FCBFlags |= UDF_FCB_DELETED;
525  Delete = FALSE;
526  } else
527 #endif //UDF_READ_ONLY_BUILD
528  if(!(Fcb->FCBFlags & UDF_FCB_DELETED)) {
529  UDFFlushFile__(Vcb, fi);
530  } else {
531 // BrutePoint();
532  }
533 #ifndef UDF_READ_ONLY_BUILD
534  // check if we should try to delete Parent for the next time
535  if(Fcb->FCBFlags & UDF_FCB_DELETE_PARENT)
536  Delete = TRUE;
537 #endif //UDF_READ_ONLY_BUILD
538 
539  // remove references to OS-specific structures
540  // to let UDF_INFO release FI & Co
541  fi->Fcb = NULL;
542  if(!ComRefCount) {
543  // CommonFcb is also completly dereferenced
544  // Kill it!
545  fi->Dloc->CommonFcb = NULL;
546  }
547 
548  if((CleanCode = UDFCleanUpFile__(Vcb, fi))) {
549  // Check, if we can uninitialize & deallocate CommonFcb part
550  // kill some cross links
551  Fcb->FileInfo = NULL;
552  // release allocated resources
553  if(CleanCode & UDF_FREE_DLOC) {
554  // Obviously, it is a good time & place to release
555  // CommonFcb structure
556 
557 // NtReqFcb->NtReqFCBFlags &= ~UDF_NTREQ_FCB_VALID;
558  // Unitialize byte-range locks support structure
559  FsRtlUninitializeFileLock(&(NtReqFcb->FileLock));
560  // Remove resources
562  UDFReleaseResource(&(NtReqFcb->MainResource));
563  if(NtReqFcb->CommonFCBHeader.Resource) {
564  UDFDeleteResource(&(NtReqFcb->MainResource));
565  UDFDeleteResource(&(NtReqFcb->PagingIoResource));
566  }
567  NtReqFcb->CommonFCBHeader.Resource =
568  NtReqFcb->CommonFCBHeader.PagingIoResource = NULL;
569  UDFDeassignAcl(NtReqFcb, AutoInherited);
570  UDFPrint(("UDFReleaseNtReqFCB: %x\n", NtReqFcb));
571 #ifdef DBG
572 // NtReqFcb->FileObject->FsContext2 = NULL;
573 // ASSERT(NtReqFcb->FileObject);
574 /* if(NtReqFcb->FileObject) {
575  ASSERT(!NtReqFcb->FileObject->FsContext2);
576  NtReqFcb->FileObject->FsContext = NULL;
577  NtReqFcb->FileObject->SectionObjectPointer = NULL;
578  }*/
579 #endif //DBG
581  ret_val |= UDF_CLOSE_NTREQFCB_DELETED;
582  } else {
583  // we usually get here when the file has some opened links
585  UDFReleaseResource(&(NtReqFcb->MainResource));
586  }
587  // remove some references & free Fcb structure
588  Fcb->NTRequiredFCB = NULL;
589  Fcb->ParentFcb = NULL;
591  MyFreePool__(fi);
592  ret_val |= UDF_CLOSE_FCB_DELETED;
593  // get pointer to parent FCB
594  fi = ParentFI;
595  // free old parent's resource...
596  if(fi) {
597  UDF_CHECK_PAGING_IO_RESOURCE(ParentFcb->NTRequiredFCB);
598  UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
599  } else {
600  if(!VcbAcquired)
601  UDFReleaseResource(&(Vcb->VCBResource));
602  }
603  } else {
604  // Stop cleaning up
605 
606  // Restore pointers
607  fi->Fcb = Fcb;
608  fi->Dloc->CommonFcb = NtReqFcb;
609  // free all acquired resources
611  UDFReleaseResource(&(NtReqFcb->MainResource));
612  fi = ParentFI;
613  if(fi) {
614  UDF_CHECK_PAGING_IO_RESOURCE(ParentFcb->NTRequiredFCB);
615  UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
616  } else {
617  if(!VcbAcquired)
618  UDFReleaseResource(&(Vcb->VCBResource));
619  }
620  // If we have dereferenced all parents 'associated'
621  // with input file & current file is still in use
622  // then it isn't worth walking down the tree
623  // 'cause in this case all the rest files are also used
624  if(!TreeLength)
625  break;
626 // AdPrint(("Stop on referenced File/Dir\n"));
627  }
628  } else {
629  // we get to referenced file/dir. Stop search & release resource
631  UDFReleaseResource(&(NtReqFcb->MainResource));
632  if(ParentFI) {
633  UDF_CHECK_PAGING_IO_RESOURCE(ParentFcb->NTRequiredFCB);
634  UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
635  } else {
636  if(!VcbAcquired)
637  UDFReleaseResource(&(Vcb->VCBResource));
638  }
639  Delete = FALSE;
640  if(!TreeLength)
641  break;
642  fi = ParentFI;
643  }
644  }
645  if(fi) {
646  Fcb = fi->Fcb;
647  for(;TreeLength && fi;TreeLength--) {
648  if(Fcb) {
650  ASSERT(Fcb->ReferenceCount);
651  ASSERT(Fcb->NTRequiredFCB->CommonRefCount);
652  ASSERT_REF(Fcb->ReferenceCount > fi->RefCount);
653  UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
654  UDFInterlockedDecrement((PLONG)&(Fcb->NTRequiredFCB->CommonRefCount));
655 #ifdef UDF_DBG
656  } else {
657  BrutePoint();
658 #endif
659  }
660  Fcb = ParentFcb;
661  }
662  }
663  if(!VcbAcquired)
664  UDFReleaseResource(&(Vcb->VCBResource));
665  return ret_val;
666 
667 } // end UDFCleanUpFcbChain()
668 
669 VOID
671  IN PtrUDFIrpContextLite NextIrpContextLite
672  )
673 {
674  PtrUDFIrpContext IrpContext;
675 
676  AdPrint((" UDFDoDelayedClose\n"));
677  UDFInitializeIrpContextFromLite(&IrpContext,NextIrpContextLite);
678  IrpContext->Fcb->IrpContextLite = NULL;
679  MyFreePool__(NextIrpContextLite);
680  IrpContext->Fcb->FCBFlags &= ~UDF_FCB_DELAY_CLOSE;
681  UDFCommonClose(IrpContext,NULL);
682 } // end UDFDoDelayedClose()
683 
684 /*
685  This routine removes request from Delayed Close queue.
686  It operates until reach lower threshold
687  */
688 VOID
689 NTAPI
691  PVOID unused
692  )
693 {
695  PtrUDFIrpContextLite NextIrpContextLite;
696 
697  AdPrint((" UDFDelayedClose\n"));
698  // Acquire DelayedCloseResource
699  UDFAcquireResourceExclusive(&(UDFGlobalData.DelayedCloseResource), TRUE);
700 
701  while (UDFGlobalData.ReduceDelayedClose &&
702  (UDFGlobalData.DelayedCloseCount > UDFGlobalData.MinDelayedCloseCount)) {
703 
704  Entry = UDFGlobalData.DelayedCloseQueue.Flink;
705 
706  if (!IsListEmpty(Entry)) {
707  // Extract the IrpContext.
708  NextIrpContextLite = CONTAINING_RECORD( Entry,
710  DelayedCloseLinks );
711 
713  UDFGlobalData.DelayedCloseCount--;
714  UDFDoDelayedClose(NextIrpContextLite);
715  } else {
716  BrutePoint();
717  }
718  }
719 
720  while (UDFGlobalData.ReduceDirDelayedClose &&
721  (UDFGlobalData.DirDelayedCloseCount > UDFGlobalData.MinDirDelayedCloseCount)) {
722 
723  Entry = UDFGlobalData.DirDelayedCloseQueue.Flink;
724 
725  if (!IsListEmpty(Entry)) {
726  // Extract the IrpContext.
727  NextIrpContextLite = CONTAINING_RECORD( Entry,
729  DelayedCloseLinks );
730 
732  UDFGlobalData.DirDelayedCloseCount--;
733  UDFDoDelayedClose(NextIrpContextLite);
734  } else {
735  BrutePoint();
736  }
737  }
738 
739  UDFGlobalData.FspCloseActive = FALSE;
740  UDFGlobalData.ReduceDelayedClose = FALSE;
741  UDFGlobalData.ReduceDirDelayedClose = FALSE;
742 
743  // Release DelayedCloseResource
744  UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
745 
746  return;
747 } // end UDFDelayedClose()
748 
749 /*
750  This routine performs Close operation for all files from
751  Delayed Close queue.
752  */
753 VOID
755  IN PVCB Vcb
756  )
757 {
759  PtrUDFIrpContextLite NextIrpContextLite;
760  BOOLEAN GlobalDataAcquired = FALSE;
761 
762  AdPrint((" UDFCloseAllDelayed\n"));
763  // Acquire DelayedCloseResource
764  if (!ExIsResourceAcquiredExclusive(&UDFGlobalData.GlobalDataResource)) {
765  UDFAcquireResourceExclusive(&(UDFGlobalData.DelayedCloseResource), TRUE);
766  GlobalDataAcquired = TRUE;
767  }
768 
769  Entry = UDFGlobalData.DelayedCloseQueue.Flink;
770 
771  while (Entry != &UDFGlobalData.DelayedCloseQueue) {
772  // Extract the IrpContext.
773  NextIrpContextLite = CONTAINING_RECORD( Entry,
775  DelayedCloseLinks );
776  Entry = Entry->Flink;
777  if (NextIrpContextLite->Fcb->Vcb == Vcb) {
778  RemoveEntryList( &(NextIrpContextLite->DelayedCloseLinks) );
779  UDFGlobalData.DelayedCloseCount--;
780  UDFDoDelayedClose(NextIrpContextLite);
781  }
782  }
783 
784  Entry = UDFGlobalData.DirDelayedCloseQueue.Flink;
785 
786  while (Entry != &UDFGlobalData.DirDelayedCloseQueue) {
787  // Extract the IrpContext.
788  NextIrpContextLite = CONTAINING_RECORD( Entry,
790  DelayedCloseLinks );
791  Entry = Entry->Flink;
792  if (NextIrpContextLite->Fcb->Vcb == Vcb) {
793  RemoveEntryList( &(NextIrpContextLite->DelayedCloseLinks) );
794  UDFGlobalData.DirDelayedCloseCount--;
795  UDFDoDelayedClose(NextIrpContextLite);
796  }
797  }
798 
799  // Release DelayedCloseResource
800  if(GlobalDataAcquired)
801  UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
802 
803 } // end UDFCloseAllDelayed()
804 
805 NTSTATUS
807  IN PVCB Vcb,
809  IN PCHECK_TREE_ITEM CheckItemProc,
810  IN PUDF_FILE_INFO** PassedList,
811  IN PULONG PassedListSize,
812  IN PUDF_FILE_INFO** FoundList,
813  IN PULONG FoundListSize
814  )
815 {
816  PDIR_INDEX_HDR hDirNdx;
817  PUDF_FILE_INFO SDirInfo;
818  ULONG i;
819 
820  UDFPrint((" UDFBuildTreeItemsList():\n"));
821  if(!(*PassedList) || !(*FoundList)) {
822 
823  (*PassedList) = (PUDF_FILE_INFO*)
825  if(!(*PassedList))
827  (*PassedListSize) = 0;
828 
829  (*FoundList) = (PUDF_FILE_INFO*)
831  if(!(*FoundList)) {
832  MyFreePool__(*PassedList);
833  *PassedList = NULL;
835  }
836  (*FoundListSize) = 0;
837  }
838 
839  // check if already passed
840  for(i=0;i<(*PassedListSize);i++) {
841  if( ((*PassedList)[i]) == FileInfo )
842  return STATUS_SUCCESS;
843  }
844  // remember passed object
845  // we should not proceed linked objects twice
846  (*PassedListSize)++;
847  if( !((*PassedListSize) & (TREE_ITEM_LIST_GRAN - 1)) ) {
848  if(!MyReallocPool__((PCHAR)(*PassedList), (*PassedListSize)*sizeof(PUDF_FILE_INFO),
849  (PCHAR*)PassedList, ((*PassedListSize)+TREE_ITEM_LIST_GRAN)*sizeof(PUDF_FILE_INFO))) {
851  }
852  }
853  (*PassedList)[(*PassedListSize)-1] = FileInfo;
854 
855  // check if this object matches our conditions
856  if(CheckItemProc(FileInfo)) {
857  // remember matched object
858  (*FoundListSize)++;
859  if( !((*FoundListSize) & (TREE_ITEM_LIST_GRAN - 1)) ) {
860  if(!MyReallocPool__((PCHAR)(*FoundList), (*FoundListSize)*sizeof(PUDF_DATALOC_INFO),
861  (PCHAR*)FoundList, ((*FoundListSize)+TREE_ITEM_LIST_GRAN)*sizeof(PUDF_DATALOC_INFO))) {
863  }
864  }
865  (*FoundList)[(*FoundListSize)-1] = FileInfo;
866  }
867 
868  // walk through SDir (if any)
869  if((SDirInfo = FileInfo->Dloc->SDirInfo))
870  UDFBuildTreeItemsList(Vcb, SDirInfo, CheckItemProc,
871  PassedList, PassedListSize, FoundList, FoundListSize);
872 
873  // walk through subsequent objects (if any)
874  if((hDirNdx = FileInfo->Dloc->DirIndex)) {
875 
876  // scan DirIndex
877  UDF_DIR_SCAN_CONTEXT ScanContext;
878  PDIR_INDEX_ITEM DirNdx;
879  PUDF_FILE_INFO CurFileInfo;
880 
881  if(UDFDirIndexInitScan(FileInfo, &ScanContext, 2)) {
882  while((DirNdx = UDFDirIndexScan(&ScanContext, &CurFileInfo))) {
883  if(!CurFileInfo)
884  continue;
885  UDFBuildTreeItemsList(Vcb, CurFileInfo, CheckItemProc,
886  PassedList, PassedListSize, FoundList, FoundListSize);
887  }
888  }
889 
890  }
891  return STATUS_SUCCESS;
892 } // end UDFBuildTreeItemsList()
893 
894 BOOLEAN
897 {
898  ASSERT(FileInfo);
899  return (FileInfo->Fcb && FileInfo->Fcb->IrpContextLite);
900 } // end UDFIsInDelayedCloseQueue()
901 
902 BOOLEAN
905 {
906  ASSERT(FileInfo);
907  PtrUDFFCB Fcb = FileInfo->Fcb;
908  if( Fcb &&
909  !Fcb->OpenHandleCount &&
910  Fcb->ReferenceCount &&
911  Fcb->NTRequiredFCB->SectionObject.DataSectionObject) {
912  return TRUE;
913  }
914  return FALSE;
915 } // UDFIsLastClose()
916 
917 NTSTATUS
919  IN PVCB Vcb,
922  )
923 {
924  PUDF_FILE_INFO* PassedList = NULL;
925  ULONG PassedListSize = 0;
926  PUDF_FILE_INFO* FoundList = NULL;
927  ULONG FoundListSize = 0;
928  NTSTATUS RC;
929  ULONG i;
930  BOOLEAN ResAcq = FALSE;
931  BOOLEAN AcquiredVcb = FALSE;
933  PUDF_FILE_INFO CurFileInfo;
934  PFE_LIST_ENTRY CurListPtr;
935  PFE_LIST_ENTRY* ListPtrArray = NULL;
936 
937  _SEH2_TRY {
938 
939  UDFPrint((" UDFCloseAllXXXDelayedInDir(): Acquire DelayedCloseResource\n"));
940  // Acquire DelayedCloseResource
941  UDFAcquireResourceExclusive(&(UDFGlobalData.DelayedCloseResource), TRUE);
942  ResAcq = TRUE;
943 
944  UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
945  AcquiredVcb = TRUE;
946 
949  &PassedList, &PassedListSize, &FoundList, &FoundListSize);
950 
951  if(!NT_SUCCESS(RC)) {
952  UDFPrint((" UDFBuildTreeItemsList(): error %x\n", RC));
953  try_return(RC);
954  }
955 
956  if(!FoundList || !FoundListSize) {
958  }
959 
960  // build array of referenced pointers
961  ListPtrArray = (PFE_LIST_ENTRY*)(MyAllocatePool__(NonPagedPool, FoundListSize*sizeof(PFE_LIST_ENTRY)));
962  if(!ListPtrArray) {
963  UDFPrint((" Can't alloc ListPtrArray for %x items\n", FoundListSize));
965  }
966 
967  for(i=0;i<FoundListSize;i++) {
968 
969  _SEH2_TRY {
970 
971  CurFileInfo = FoundList[i];
972  if(!CurFileInfo->ListPtr) {
974  if(!CurFileInfo->ListPtr) {
975  UDFPrint((" Can't alloc ListPtrEntry for items %x\n", i));
977  }
978  CurFileInfo->ListPtr->FileInfo = CurFileInfo;
979  CurFileInfo->ListPtr->EntryRefCount = 0;
980  }
981  CurFileInfo->ListPtr->EntryRefCount++;
982  ListPtrArray[i] = CurFileInfo->ListPtr;
983 
985  BrutePoint();
986  } _SEH2_END;
987  }
988 
989  UDFReleaseResource(&(Vcb->VCBResource));
990  AcquiredVcb = FALSE;
991 
992  if(System) {
993  // Remove from system queue
994  PtrUDFFCB Fcb;
996  BOOLEAN NoDelayed = (Vcb->VCBFlags & UDF_VCB_FLAGS_NO_DELAYED_CLOSE) ?
997  TRUE : FALSE;
998 
999  Vcb->VCBFlags |= UDF_VCB_FLAGS_NO_DELAYED_CLOSE;
1000  for(i=FoundListSize;i>0;i--) {
1001  UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
1002  AcquiredVcb = TRUE;
1003  _SEH2_TRY {
1004 
1005  CurListPtr = ListPtrArray[i-1];
1006  CurFileInfo = CurListPtr->FileInfo;
1007  if(CurFileInfo &&
1008  (Fcb = CurFileInfo->Fcb)) {
1009  NtReqFcb = Fcb->NTRequiredFCB;
1010  ASSERT((ULONG_PTR)NtReqFcb > 0x1000);
1011 // ASSERT((ULONG)(NtReqFcb->SectionObject) > 0x1000);
1012  if(!(NtReqFcb->NtReqFCBFlags & UDF_NTREQ_FCB_DELETED) &&
1013  (NtReqFcb->NtReqFCBFlags & UDF_NTREQ_FCB_MODIFIED)) {
1014  MmPrint((" CcFlushCache()\n"));
1015  CcFlushCache(&(NtReqFcb->SectionObject), NULL, 0, &IoStatus);
1016  }
1017  if(NtReqFcb->SectionObject.ImageSectionObject) {
1018  MmPrint((" MmFlushImageSection()\n"));
1019  MmFlushImageSection(&(NtReqFcb->SectionObject), MmFlushForWrite);
1020  }
1021  if(NtReqFcb->SectionObject.DataSectionObject) {
1022  MmPrint((" CcPurgeCacheSection()\n"));
1023  CcPurgeCacheSection( &(NtReqFcb->SectionObject), NULL, 0, FALSE );
1024  }
1025  } else {
1026  MmPrint((" Skip item: deleted\n"));
1027  }
1028  CurListPtr->EntryRefCount--;
1029  if(!CurListPtr->EntryRefCount) {
1030  if(CurListPtr->FileInfo)
1031  CurListPtr->FileInfo->ListPtr = NULL;
1032  MyFreePool__(CurListPtr);
1033  }
1035  BrutePoint();
1036  } _SEH2_END;
1037  UDFReleaseResource(&(Vcb->VCBResource));
1038  AcquiredVcb = FALSE;
1039  }
1040  if(!NoDelayed)
1041  Vcb->VCBFlags &= ~UDF_VCB_FLAGS_NO_DELAYED_CLOSE;
1042  } else {
1043  // Remove from internal queue
1044  PtrUDFIrpContextLite NextIrpContextLite;
1045 
1046  for(i=FoundListSize;i>0;i--) {
1047 
1048  UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
1049  AcquiredVcb = TRUE;
1050 
1051  CurListPtr = ListPtrArray[i-1];
1052  CurFileInfo = CurListPtr->FileInfo;
1053 
1054  if(CurFileInfo &&
1055  CurFileInfo->Fcb &&
1056  (NextIrpContextLite = CurFileInfo->Fcb->IrpContextLite)) {
1057  RemoveEntryList( &(NextIrpContextLite->DelayedCloseLinks) );
1058  if (NextIrpContextLite->Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
1059 // BrutePoint();
1060  UDFGlobalData.DirDelayedCloseCount--;
1061  } else {
1062  UDFGlobalData.DelayedCloseCount--;
1063  }
1064  UDFDoDelayedClose(NextIrpContextLite);
1065  }
1066  CurListPtr->EntryRefCount--;
1067  if(!CurListPtr->EntryRefCount) {
1068  if(CurListPtr->FileInfo)
1069  CurListPtr->FileInfo->ListPtr = NULL;
1070  MyFreePool__(CurListPtr);
1071  }
1072  UDFReleaseResource(&(Vcb->VCBResource));
1073  AcquiredVcb = FALSE;
1074  }
1075  }
1076  RC = STATUS_SUCCESS;
1077 
1078 try_exit: NOTHING;
1079 
1080  } _SEH2_FINALLY {
1081  // release Vcb
1082  if(AcquiredVcb)
1083  UDFReleaseResource(&(Vcb->VCBResource));
1084  // Release DelayedCloseResource
1085  if(ResAcq)
1086  UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
1087 
1088  if(ListPtrArray)
1089  MyFreePool__(ListPtrArray);
1090  if(PassedList)
1091  MyFreePool__(PassedList);
1092  if(FoundList)
1093  MyFreePool__(FoundList);
1094  } _SEH2_END;
1095 
1096  return RC;
1097 } // end UDFCloseAllXXXDelayedInDir(
1098 
1099 
1100 /*
1101  This routine adds request to Delayed Close queue.
1102  If number of queued requests exceeds higher threshold it fires
1103  UDFDelayedClose()
1104  */
1105 NTSTATUS
1107  PtrUDFIrpContext IrpContext,
1108  PtrUDFFCB Fcb
1109  )
1110 {
1111  PtrUDFIrpContextLite IrpContextLite;
1112  BOOLEAN StartWorker = FALSE;
1113  _SEH2_VOLATILE BOOLEAN AcquiredVcb = FALSE;
1114  NTSTATUS RC;
1115 
1116  AdPrint((" UDFQueueDelayedClose\n"));
1117 
1118  _SEH2_TRY {
1119  // Acquire DelayedCloseResource
1120  UDFAcquireResourceExclusive(&(UDFGlobalData.DelayedCloseResource), TRUE);
1121 
1122  UDFAcquireResourceShared(&(Fcb->Vcb->VCBResource), TRUE);
1123  AcquiredVcb = TRUE;
1124 
1125  if(Fcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE) {
1127  }
1128 
1129  if(Fcb->IrpContextLite ||
1130  Fcb->FCBFlags & UDF_FCB_POSTED_RENAME) {
1131 // BrutePoint();
1133  }
1134 
1135  if(!NT_SUCCESS(RC = UDFInitializeIrpContextLite(&IrpContextLite,IrpContext,Fcb))) {
1136  try_return(RC);
1137  }
1138 
1139  if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
1140  InsertTailList( &UDFGlobalData.DirDelayedCloseQueue,
1141  &IrpContextLite->DelayedCloseLinks );
1142  UDFGlobalData.DirDelayedCloseCount++;
1143  } else {
1144  InsertTailList( &UDFGlobalData.DelayedCloseQueue,
1145  &IrpContextLite->DelayedCloseLinks );
1146  UDFGlobalData.DelayedCloseCount++;
1147  }
1148  Fcb->IrpContextLite = IrpContextLite;
1149 
1150  // If we are above our threshold then start the delayed
1151  // close operation.
1152  if(UDFGlobalData.DelayedCloseCount > UDFGlobalData.MaxDelayedCloseCount) {
1153 
1154  UDFGlobalData.ReduceDelayedClose = TRUE;
1155 
1156  if(!UDFGlobalData.FspCloseActive) {
1157 
1158  UDFGlobalData.FspCloseActive = TRUE;
1159  StartWorker = TRUE;
1160  }
1161  }
1162  // If we are above our threshold then start the delayed
1163  // close operation.
1164  if(UDFGlobalData.DirDelayedCloseCount > UDFGlobalData.MaxDirDelayedCloseCount) {
1165 
1166  UDFGlobalData.ReduceDirDelayedClose = TRUE;
1167 
1168  if(!UDFGlobalData.FspCloseActive) {
1169 
1170  UDFGlobalData.FspCloseActive = TRUE;
1171  StartWorker = TRUE;
1172  }
1173  }
1174  // Start the FspClose thread if we need to.
1175  if(StartWorker) {
1177  }
1178  RC = STATUS_SUCCESS;
1179 
1180 try_exit: NOTHING;
1181 
1182  } _SEH2_FINALLY {
1183 
1184  if(!NT_SUCCESS(RC)) {
1185  Fcb->FCBFlags &= ~UDF_FCB_DELAY_CLOSE;
1186  }
1187  if(AcquiredVcb) {
1188  UDFReleaseResource(&(Fcb->Vcb->VCBResource));
1189  }
1190  // Release DelayedCloseResource
1191  UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
1192  } _SEH2_END;
1193  return RC;
1194 } // end UDFQueueDelayedClose()
1195 
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
signed char * PCHAR
Definition: retypes.h:7
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
UNICODE_STRING FName
Definition: udf_rel.h:173
#define UDF_CLOSE_NTREQFCB_DELETED
Definition: protos.h:80
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:384
#define UDFReferenceFile__(fi)
Definition: udf_info.h:1043
#define UDF_CLOSE_FCB_DELETED
Definition: protos.h:81
#define IN
Definition: typedefs.h:38
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:308
#define ASSERT_REF(_a_)
Definition: udf_dbg.h:267
#define UDFPrint(Args)
Definition: udffs.h:225
#define TRUE
Definition: types.h:120
struct _UDFContextControlBlock * PtrUDFCCB
#define UDF_CCB_READ_ONLY
Definition: struct.h:170
NTSTATUS NTAPI UDFPhSendIOCTL(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN OverrideVerify, OUT PIO_STATUS_BLOCK Iosb OPTIONAL)
Definition: env_spec.cpp:511
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define FsRtlEnterFileSystem
BOOLEAN UDFCheckForDismount(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:629
ULONG EntryRefCount
Definition: udf_rel.h:416
NTSTATUS UDFBuildTreeItemsList(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN PCHECK_TREE_ITEM CheckItemProc, IN PUDF_DATALOC_INFO **PassedList, IN PULONG PassedListSize, IN PUDF_DATALOC_INFO **FoundList, IN PULONG FoundListSize)
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
ULONG UDFCleanUpFcbChain(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
Definition: close.cpp:400
struct _Entry Entry
Definition: kefuncs.h:640
#define UDF_IRP_CONTEXT_NOT_TOP_LEVEL
Definition: struct.h:390
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
#define FsRtlExitFileSystem
Definition: udf_rel.h:414
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
_In_ PIRP Irp
Definition: csq.h:116
#define UDF_FCB_DELETE_PARENT
Definition: struct.h:319
#define UDF_FCB_POSTED_RENAME
Definition: struct.h:317
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1278
#define UDF_NODE_TYPE_FCB
Definition: struct.h:60
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
LONG NTSTATUS
Definition: precomp.h:26
ULONG MyReallocPool__(PCHAR addr, ULONG len, PCHAR *pnewaddr, ULONG newlen)
Definition: mem_tools.h:224
#define UDF_FCB_DELETE_ON_CLOSE
Definition: struct.h:309
__inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx, IN uint_di i)
Definition: udf_info.h:1105
BOOLEAN UDFIsInDelayedCloseQueue(PUDF_FILE_INFO FileInfo)
Definition: close.cpp:895
struct _FE_LIST_ENTRY * PFE_LIST_ENTRY
Definition: cdstruc.h:504
_UDFFileControlBlock * Fcb
Definition: struct.h:378
PDEVICE_OBJECT TargetDeviceObject
Definition: struct.h:374
#define InsertTailList(ListHead, Entry)
VOID NTAPI UDFDelayedClose(PVOID unused)
Definition: close.cpp:690
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define UDF_NODE_TYPE_NT_REQ_FCB
Definition: struct.h:57
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define TREE_ITEM_LIST_GRAN
Definition: close.cpp:23
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
WORD unused[29]
Definition: crypt.c:1155
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PDIR_INDEX_HDR UDFGetDirIndexByFileInfo(IN PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:1092
long LONG
Definition: pedump.c:60
struct _UDFIrpContextLite * IrpContextLite
Definition: struct.h:291
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define UDFInterlockedDecrement(addr)
Definition: env_spec_w32.h:677
LONG RefCount
Definition: ntfs.h:531
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS UDFInitializeIrpContextLite(OUT PtrUDFIrpContextLite *IrpContextLite, IN PtrUDFIrpContext IrpContext, IN PtrUDFFCB Fcb)
Definition: misc.cpp:2457
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define IoCompleteRequest
Definition: irp.c:1240
OSSTATUS UDFFlushFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN ULONG FlushFlags)
Definition: udf_info.cpp:4119
uint32 IrpContextFlags
Definition: struct.h:364
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS UDFCloseAllXXXDelayedInDir(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN BOOLEAN System)
Definition: close.cpp:918
struct _UDFVolumeControlBlock * Vcb
Definition: struct.h:259
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
#define UDFIsAStreamDir(FI)
Definition: udf_info.h:998
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
ULONG TreeLength
Definition: struct.h:379
uint32 UDFCleanUpFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2276
VOID UDFDoDelayedClose(IN PtrUDFIrpContextLite NextIrpContextLite)
Definition: close.cpp:670
ULONG OpenHandleCount
Definition: ntfs.h:533
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint_di Index
Definition: udf_rel.h:392
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4798
#define try_return(S)
Definition: cdprocs.h:2189
struct _FE_LIST_ENTRY * ListPtr
Definition: udf_rel.h:411
#define Vcb
Definition: cdprocs.h:1425
#define UDFDeleteResource(Resource)
Definition: env_spec_w32.h:663
#define MyFreePool__(addr)
Definition: mem_tools.h:152
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
#define BrutePoint()
Definition: env_spec_w32.h:504
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
NTSTATUS UDFCommonClose(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: close.cpp:137
* PFILE_OBJECT
Definition: iotypes.h:1955
struct _UDF_FILE_INFO * ParentFile
Definition: udf_rel.h:381
NTSTATUS UDFQueueDelayedClose(PtrUDFIrpContext IrpContext, PtrUDFFCB Fcb)
Definition: close.cpp:1106
_In_ PFCB ParentFcb
Definition: cdprocs.h:741
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define NtReqFcb
#define ValidateFileInfo(fi)
Definition: env_spec_w32.h:516
PDIR_INDEX_ITEM UDFDirIndexScan(PUDF_DIR_SCAN_CONTEXT Context, PUDF_FILE_INFO *_FileInfo)
Definition: dirtree.cpp:378
#define UDF_NTREQ_FCB_DELETED
Definition: struct.h:235
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
#define UDF_VCB_FLAGS_NO_DELAYED_CLOSE
Definition: udf_common.h:480
#define UDF_FCB_DELETED
Definition: struct.h:314
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
NTSTATUS NTAPI UDFClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: close.cpp:62
#define InterlockedDecrement
Definition: armddk.h:52
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define UDF_FCB_DELAY_CLOSE
Definition: struct.h:313
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
struct _FCB::@708::@711 Fcb
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define NOTHING
Definition: env_spec_w32.h:461
struct _VCB * PVCB
Definition: fatstruc.h:556
Definition: typedefs.h:117
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
ERESOURCE MainResource
Definition: ntfs.h:524
OSSTATUS UDFCloseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2994
BOOLEAN(* PCHECK_TREE_ITEM)(IN PUDF_FILE_INFO FileInfo)
Definition: close.cpp:22
#define UDF_FREE_DLOC
Definition: udf_info.h:650
#define UDFInterlockedIncrement(addr)
Definition: env_spec_w32.h:675
LIST_ENTRY DelayedCloseLinks
Definition: struct.h:410
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
#define UDF_IRP_CONTEXT_READ_ONLY
Definition: struct.h:394
#define UDF_VCB_FLAGS_BEING_DISMOUNTED
Definition: udf_common.h:461
_SEH2_END
Definition: create.c:4424
#define InterlockedIncrement
Definition: armddk.h:53
VOID __fastcall UDFCleanUpCCB(PtrUDFCCB Ccb)
Definition: misc.cpp:805
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:262
_SEH2_FINALLY
Definition: create.c:4395
OSSTATUS UDFUnlinkFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN BOOLEAN FreeSpace)
Definition: udf_info.cpp:1766
#define IOCTL_CDRW_RESET_WRITE_STATUS
Definition: cdrw_usr.h:102
VOID UDFInitializeIrpContextFromLite(OUT PtrUDFIrpContext *IrpContext, IN PtrUDFIrpContextLite IrpContextLite)
Definition: misc.cpp:2419
unsigned int * PULONG
Definition: retypes.h:1
BOOLEAN UDFIsLastClose(PUDF_FILE_INFO FileInfo)
Definition: close.cpp:903
VOID __fastcall UDFCleanUpFCB(PtrUDFFCB Fcb)
Definition: misc.cpp:908
VOID UDFCloseAllDelayed(IN PVCB Vcb)
Definition: close.cpp:754
#define BOOLEAN
Definition: pedump.c:73
struct FileInfo FileInfo
BOOLEAN UDFDirIndexInitScan(IN PUDF_FILE_INFO DirInfo, OUT PUDF_DIR_SCAN_CONTEXT Context, IN uint_di Index)
Definition: dirtree.cpp:347
_UDFFileControlBlock * Fcb
Definition: struct.h:408
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
PVCB Vcb
Definition: cdstruc.h:939
struct _FCB * ParentFcb
Definition: cdstruc.h:946
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
struct _UDFFileControlBlock * Fcb
Definition: udf_rel.h:362
_In_ PFCB Fcb
Definition: cdprocs.h:151
#define ExIsResourceAcquiredExclusive
Definition: exfuncs.h:347
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define UDFIsAStream(FI)
Definition: udf_info.h:1002
signed int * PLONG
Definition: retypes.h:5
PUDF_FILE_INFO FileInfo
Definition: udf_rel.h:415
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
VOID UDFDeassignAcl(IN PtrUDFNTRequiredFCB NtReqFcb, IN BOOLEAN AutoInherited)
Definition: secursup.cpp:772
base of all file and directory entries
Definition: entries.h:82
#define UDF_RESIDUAL_REFERENCE
Definition: struct.h:336
#define UDF_NTREQ_FCB_MODIFIED
Definition: struct.h:236