ReactOS 0.4.15-dev-7788-g1ad9096
close.cpp File Reference
#include "udffs.h"
Include dependency graph for close.cpp:

Go to the source code of this file.

Macros

#define UDF_BUG_CHECK_ID   UDF_FILE_CLOSE
 
#define TREE_ITEM_LIST_GRAN   32
 

Typedefs

typedef BOOLEAN(* PCHECK_TREE_ITEM) (IN PUDF_FILE_INFO FileInfo)
 

Functions

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)
 
BOOLEAN UDFIsInDelayedCloseQueue (PUDF_FILE_INFO FileInfo)
 
BOOLEAN UDFIsLastClose (PUDF_FILE_INFO FileInfo)
 
NTSTATUS NTAPI UDFClose (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFCommonClose (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
ULONG UDFCleanUpFcbChain (IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
 
VOID UDFDoDelayedClose (IN PtrUDFIrpContextLite NextIrpContextLite)
 
VOID NTAPI UDFDelayedClose (PVOID unused)
 
VOID UDFCloseAllDelayed (IN PVCB Vcb)
 
NTSTATUS UDFBuildTreeItemsList (IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN PCHECK_TREE_ITEM CheckItemProc, IN PUDF_FILE_INFO **PassedList, IN PULONG PassedListSize, IN PUDF_FILE_INFO **FoundList, IN PULONG FoundListSize)
 
NTSTATUS UDFCloseAllXXXDelayedInDir (IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN BOOLEAN System)
 
NTSTATUS UDFQueueDelayedClose (PtrUDFIrpContext IrpContext, PtrUDFFCB Fcb)
 

Macro Definition Documentation

◆ TREE_ITEM_LIST_GRAN

#define TREE_ITEM_LIST_GRAN   32

Definition at line 23 of file close.cpp.

◆ UDF_BUG_CHECK_ID

#define UDF_BUG_CHECK_ID   UDF_FILE_CLOSE

Definition at line 20 of file close.cpp.

Typedef Documentation

◆ PCHECK_TREE_ITEM

typedef BOOLEAN(* PCHECK_TREE_ITEM) (IN PUDF_FILE_INFO FileInfo)

Definition at line 22 of file close.cpp.

Function Documentation

◆ UDFBuildTreeItemsList() [1/2]

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 
)

◆ UDFBuildTreeItemsList() [2/2]

NTSTATUS UDFBuildTreeItemsList ( IN PVCB  Vcb,
IN PUDF_FILE_INFO  FileInfo,
IN PCHECK_TREE_ITEM  CheckItemProc,
IN PUDF_FILE_INFO **  PassedList,
IN PULONG  PassedListSize,
IN PUDF_FILE_INFO **  FoundList,
IN PULONG  FoundListSize 
)

Definition at line 806 of file close.cpp.

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()
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 TREE_ITEM_LIST_GRAN
Definition: close.cpp:23
PDIR_INDEX_ITEM UDFDirIndexScan(PUDF_DIR_SCAN_CONTEXT Context, PUDF_FILE_INFO *_FileInfo)
Definition: dirtree.cpp:378
BOOLEAN UDFDirIndexInitScan(IN PUDF_FILE_INFO DirInfo, OUT PUDF_DIR_SCAN_CONTEXT Context, IN uint_di Index)
Definition: dirtree.cpp:347
#define NULL
Definition: types.h:112
#define NonPagedPool
Definition: env_spec_w32.h:307
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 MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define MyFreePool__(addr)
Definition: mem_tools.h:152
ULONG MyReallocPool__(PCHAR addr, ULONG len, PCHAR *pnewaddr, ULONG newlen)
Definition: mem_tools.h:230
#define Vcb
Definition: cdprocs.h:1415
#define STATUS_SUCCESS
Definition: shellext.h:65
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define UDFPrint(Args)
Definition: udffs.h:225

◆ UDFCleanUpFcbChain()

ULONG UDFCleanUpFcbChain ( IN PVCB  Vcb,
IN PUDF_FILE_INFO  fi,
IN ULONG  TreeLength,
IN BOOLEAN  VcbAcquired 
)

Definition at line 400 of file close.cpp.

406{
409 PUDF_FILE_INFO ParentFI;
411 ULONG CleanCode;
412 LONG RefCount, ComRefCount;
414 ULONG ret_val = 0;
415
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;
433 ASSERT(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) {
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 }*/
519 ASSERT(Fcb->ReferenceCount < fi->RefCount);
520 UDFFlushFile__(Vcb, fi);
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
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
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) {
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) {
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) {
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()
unsigned char BOOLEAN
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
_In_ PFCB ParentFcb
Definition: cdprocs.h:736
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
VOID __fastcall UDFCleanUpFCB(PtrUDFFCB Fcb)
Definition: misc.cpp:908
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
#define ValidateFileInfo(fi)
Definition: env_spec_w32.h:516
#define UDFDeleteResource(Resource)
Definition: env_spec_w32.h:663
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define UDFInterlockedDecrement(addr)
Definition: env_spec_w32.h:677
#define BrutePoint()
Definition: env_spec_w32.h:504
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
#define NtReqFcb
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1279
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define ASSERT(a)
Definition: mode.c:44
long LONG
Definition: pedump.c:60
VOID UDFDeassignAcl(IN PtrUDFNTRequiredFCB NtReqFcb, IN BOOLEAN AutoInherited)
Definition: secursup.cpp:772
#define UDF_CLOSE_NTREQFCB_DELETED
Definition: protos.h:80
#define UDF_CLOSE_FCB_DELETED
Definition: protos.h:81
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define UDF_NODE_TYPE_NT_REQ_FCB
Definition: struct.h:57
#define UDF_FCB_DELETED
Definition: struct.h:314
#define UDF_NODE_TYPE_FCB
Definition: struct.h:60
#define UDF_FCB_DELETE_PARENT
Definition: struct.h:319
struct _FCB * ParentFcb
Definition: cdstruc.h:940
LONG RefCount
Definition: ntfs.h:535
struct _FCB::@719::@722 Fcb
ULONG OpenHandleCount
Definition: ntfs.h:537
ERESOURCE MainResource
Definition: ntfs.h:528
int32_t * PLONG
Definition: typedefs.h:58
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
#define ASSERT_REF(_a_)
Definition: udf_dbg.h:267
OSSTATUS UDFCloseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2994
OSSTATUS UDFFlushFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN ULONG FlushFlags)
Definition: udf_info.cpp:4119
uint32 UDFCleanUpFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2276
OSSTATUS UDFUnlinkFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN BOOLEAN FreeSpace)
Definition: udf_info.cpp:1766
#define UDFReferenceFile__(fi)
Definition: udf_info.h:1043
#define UDFIsAStreamDir(FI)
Definition: udf_info.h:998
#define UDF_FREE_DLOC
Definition: udf_info.h:650
#define UDFIsAStream(FI)
Definition: udf_info.h:1002
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:262

Referenced by UDFCloseResidual(), UDFCommonClose(), UDFCommonCreate(), and UDFRename().

◆ UDFClose()

NTSTATUS NTAPI UDFClose ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 62 of file close.cpp.

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}
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS UDFCommonClose(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: close.cpp:137
_In_ PIRP Irp
Definition: csq.h:116
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by UDFInitializeFunctionPointers().

◆ UDFCloseAllDelayed()

VOID UDFCloseAllDelayed ( IN PVCB  Vcb)

Definition at line 754 of file close.cpp.

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()
VOID UDFDoDelayedClose(IN PtrUDFIrpContextLite NextIrpContextLite)
Definition: close.cpp:670
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _UDFVolumeControlBlock * Vcb
Definition: struct.h:259
LIST_ENTRY DelayedCloseLinks
Definition: struct.h:410
_UDFFileControlBlock * Fcb
Definition: struct.h:408
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define ExIsResourceAcquiredExclusive
Definition: exfuncs.h:347

Referenced by UDFCommonCreate(), UDFCommonDeviceControl(), UDFCommonFlush(), UDFCommonRead(), UDFCommonShutdown(), UDFCommonWrite(), UDFDismountVolume(), UDFEjectReqWaiter(), UDFInvalidateVolumes(), UDFLockVolume(), UDFPnpQueryRemove(), UDFPnpRemove(), and UDFPnpSurpriseRemove().

◆ UDFCloseAllXXXDelayedInDir()

NTSTATUS UDFCloseAllXXXDelayedInDir ( IN PVCB  Vcb,
IN PUDF_FILE_INFO  FileInfo,
IN BOOLEAN  System 
)

Definition at line 918 of file close.cpp.

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;
931 _SEH2_VOLATILE 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
996 BOOLEAN NoDelayed = (Vcb->VCBFlags & UDF_VCB_FLAGS_NO_DELAYED_CLOSE) ?
997 TRUE : FALSE;
998
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
1078try_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(
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 try_return(S)
Definition: cdprocs.h:2179
BOOLEAN UDFIsLastClose(PUDF_FILE_INFO FileInfo)
Definition: close.cpp:903
BOOLEAN UDFIsInDelayedCloseQueue(PUDF_FILE_INFO FileInfo)
Definition: close.cpp:895
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
#define _SEH2_FINALLY
Definition: filesup.c:21
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
#define NOTHING
Definition: input_list.c:10
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define _SEH2_VOLATILE
Definition: pseh2_64.h:163
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4356
#define UDF_NTREQ_FCB_DELETED
Definition: struct.h:235
#define UDF_NTREQ_FCB_MODIFIED
Definition: struct.h:236
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
Definition: udf_rel.h:414
ULONG EntryRefCount
Definition: udf_rel.h:416
PUDF_FILE_INFO FileInfo
Definition: udf_rel.h:415
struct _FE_LIST_ENTRY * ListPtr
Definition: udf_rel.h:411
struct _UDFFileControlBlock * Fcb
Definition: udf_rel.h:362
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define UDF_VCB_FLAGS_NO_DELAYED_CLOSE
Definition: udf_common.h:480
struct _FE_LIST_ENTRY * PFE_LIST_ENTRY

◆ UDFCommonClose()

NTSTATUS UDFCommonClose ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 137 of file close.cpp.

141{
147 PVCB Vcb = NULL;
148// PERESOURCE PtrResourceAcquired = NULL;
149 BOOLEAN AcquiredVcb = FALSE;
150 BOOLEAN AcquiredGD = FALSE;
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) {
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
341
342try_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
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()
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define IOCTL_CDRW_RESET_WRITE_STATUS
Definition: cdrw_usr.h:102
struct _VCB * PVCB
Definition: fatstruc.h:557
NTSTATUS UDFQueueDelayedClose(PtrUDFIrpContext IrpContext, PtrUDFFCB Fcb)
Definition: close.cpp:1106
ULONG UDFCleanUpFcbChain(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
Definition: close.cpp:400
PDIR_INDEX_HDR UDFGetDirIndexByFileInfo(IN PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:1092
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
VOID __fastcall UDFCleanUpCCB(PtrUDFCCB Ccb)
Definition: misc.cpp:805
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
#define UDFInterlockedIncrement(addr)
Definition: env_spec_w32.h:675
BOOLEAN UDFCheckForDismount(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:629
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:160
#define UDF_IRP_CONTEXT_NOT_TOP_LEVEL
Definition: struct.h:390
#define UDF_CCB_READ_ONLY
Definition: struct.h:170
struct _UDFContextControlBlock * PtrUDFCCB
#define UDF_RESIDUAL_REFERENCE
Definition: struct.h:336
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
#define UDF_IRP_CONTEXT_READ_ONLY
Definition: struct.h:394
#define UDF_FCB_DELAY_CLOSE
Definition: struct.h:313
PVOID DeviceExtension
Definition: env_spec_w32.h:418
UNICODE_STRING FName
Definition: udf_rel.h:173
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
_UDFFileControlBlock * Fcb
Definition: struct.h:378
uint32 IrpContextFlags
Definition: struct.h:364
ULONG TreeLength
Definition: struct.h:379
PDEVICE_OBJECT TargetDeviceObject
Definition: struct.h:374
uint_di Index
Definition: udf_rel.h:392
Definition: cdstruc.h:498
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
#define UDF_VCB_FLAGS_BEING_DISMOUNTED
Definition: udf_common.h:461
__inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx, IN uint_di i)
Definition: udf_info.h:1105
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
* PFILE_OBJECT
Definition: iotypes.h:1998
#define IO_DISK_INCREMENT
Definition: iotypes.h:600

Referenced by UDFClose(), UDFCommonDispatch(), and UDFDoDelayedClose().

◆ UDFDelayedClose()

VOID NTAPI UDFDelayedClose ( PVOID  unused)

Definition at line 690 of file close.cpp.

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()
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954

Referenced by DriverEntry().

◆ UDFDoDelayedClose()

VOID UDFDoDelayedClose ( IN PtrUDFIrpContextLite  NextIrpContextLite)

Definition at line 670 of file close.cpp.

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()
VOID UDFInitializeIrpContextFromLite(OUT PtrUDFIrpContext *IrpContext, IN PtrUDFIrpContextLite IrpContextLite)
Definition: misc.cpp:2419
struct _UDFIrpContextLite * IrpContextLite
Definition: struct.h:291

Referenced by UDFCloseAllDelayed(), UDFCloseAllXXXDelayedInDir(), and UDFDelayedClose().

◆ UDFIsInDelayedCloseQueue()

BOOLEAN UDFIsInDelayedCloseQueue ( PUDF_FILE_INFO  FileInfo)

Definition at line 895 of file close.cpp.

897{
899 return (FileInfo->Fcb && FileInfo->Fcb->IrpContextLite);
900} // end UDFIsInDelayedCloseQueue()

Referenced by UDFCloseAllXXXDelayedInDir().

◆ UDFIsLastClose()

BOOLEAN UDFIsLastClose ( PUDF_FILE_INFO  FileInfo)

Definition at line 903 of file close.cpp.

905{
907 PtrUDFFCB Fcb = FileInfo->Fcb;
908 if( Fcb &&
910 Fcb->ReferenceCount &&
911 Fcb->NTRequiredFCB->SectionObject.DataSectionObject) {
912 return TRUE;
913 }
914 return FALSE;
915} // UDFIsLastClose()

Referenced by UDFCloseAllXXXDelayedInDir().

◆ UDFQueueDelayedClose()

NTSTATUS UDFQueueDelayedClose ( PtrUDFIrpContext  IrpContext,
PtrUDFFCB  Fcb 
)

Definition at line 1106 of file close.cpp.

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
1180try_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()
NTSTATUS UDFInitializeIrpContextLite(OUT PtrUDFIrpContextLite *IrpContextLite, IN PtrUDFIrpContext IrpContext, IN PtrUDFFCB Fcb)
Definition: misc.cpp:2457
#define InsertTailList(ListHead, Entry)
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define UDF_FCB_POSTED_RENAME
Definition: struct.h:317
#define UDF_FCB_DELETE_ON_CLOSE
Definition: struct.h:309
PVCB Vcb
Definition: cdstruc.h:933
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
@ CriticalWorkQueue
Definition: extypes.h:189

Referenced by UDFCommonClose().