diff --git a/drivers/filesystems/udfs/dircntrl.cpp b/drivers/filesystems/udfs/dircntrl.cpp index c9b2f7d62cf64..3bf15c9a86a66 100644 --- a/drivers/filesystems/udfs/dircntrl.cpp +++ b/drivers/filesystems/udfs/dircntrl.cpp @@ -279,7 +279,10 @@ UDFQueryDirectory( // check whether we need to store this search pattern in // the CCB. if (Ccb->DirectorySearchPattern) { - MyFreePool__(Ccb->DirectorySearchPattern->Buffer); + if (Ccb->DirectorySearchPattern->Buffer) { + MyFreePool__(Ccb->DirectorySearchPattern->Buffer); + Ccb->DirectorySearchPattern->Buffer = NULL; + } MyFreePool__(Ccb->DirectorySearchPattern); Ccb->DirectorySearchPattern = NULL; } @@ -297,6 +300,8 @@ UDFQueryDirectory( Ccb->DirectorySearchPattern->MaximumLength = PtrSearchPattern->MaximumLength; Ccb->DirectorySearchPattern->Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool,PtrSearchPattern->MaximumLength); if (!(Ccb->DirectorySearchPattern->Buffer)) { + MyFreePool__(Ccb->DirectorySearchPattern); + Ccb->DirectorySearchPattern = NULL; try_return(RC = STATUS_INSUFFICIENT_RESOURCES); } RtlCopyMemory(Ccb->DirectorySearchPattern->Buffer,PtrSearchPattern->Buffer, diff --git a/drivers/filesystems/udfs/strucsup.cpp b/drivers/filesystems/udfs/strucsup.cpp index 6e746f30fc8a4..4d1d32d119234 100644 --- a/drivers/filesystems/udfs/strucsup.cpp +++ b/drivers/filesystems/udfs/strucsup.cpp @@ -144,6 +144,7 @@ Return Value: ExInitializeResourceLite(&FcbNonpaged->FcbPagingIoResource); ExInitializeResourceLite(&FcbNonpaged->FcbResource); + ExInitializeResourceLite(&FcbNonpaged->CcbListResource); ExInitializeFastMutex(&FcbNonpaged->FcbMutex); ExInitializeFastMutex(&FcbNonpaged->AdvancedFcbHeaderMutex); ExInitializeFastMutex(&FcbNonpaged->FcbFastMutex); @@ -175,11 +176,21 @@ Return Value: { PAGED_CODE(); - + UNREFERENCED_PARAMETER(IrpContext); - + + // Acquire each resource exclusively to drain any active holders before + // calling ExDeleteResourceLite. Freeing a pool block that still contains + // an active ERESOURCE triggers Driver Verifier bugcheck 0xC4/0xD2. + ExAcquireResourceExclusiveLite(&FcbNonpaged->FcbPagingIoResource, TRUE); + ExReleaseResourceLite(&FcbNonpaged->FcbPagingIoResource); + + ExAcquireResourceExclusiveLite(&FcbNonpaged->FcbResource, TRUE); + ExReleaseResourceLite(&FcbNonpaged->FcbResource); + ExDeleteResourceLite(&FcbNonpaged->FcbResource); ExDeleteResourceLite(&FcbNonpaged->FcbPagingIoResource); + ExDeleteResourceLite(&FcbNonpaged->CcbListResource); UDFDeallocateFcbNonpaged(FcbNonpaged); diff --git a/drivers/filesystems/udfs/struct.h b/drivers/filesystems/udfs/struct.h index 74c032224266d..1764831d2facf 100644 --- a/drivers/filesystems/udfs/struct.h +++ b/drivers/filesystems/udfs/struct.h @@ -151,6 +151,10 @@ struct FCB_NONPAGED { ERESOURCE FcbPagingIoResource; + // Resource protecting the CCB list on this Fcb. + + ERESOURCE CcbListResource; + // This is the FastMutex for this Fcb. FAST_MUTEX FcbMutex; diff --git a/drivers/filesystems/udfs/udf_info/dirtree.cpp b/drivers/filesystems/udfs/udf_info/dirtree.cpp index e4ed3534956e4..ddc656892cb6b 100644 --- a/drivers/filesystems/udfs/udf_info/dirtree.cpp +++ b/drivers/filesystems/udfs/udf_info/dirtree.cpp @@ -102,8 +102,8 @@ UDFDirIndexFree( uint32 k; PDIR_INDEX_ITEM* FrameList; - FrameList = (PDIR_INDEX_ITEM*)(hDirNdx+1); if (!hDirNdx) return; + FrameList = (PDIR_INDEX_ITEM*)(hDirNdx+1); for(k=0; kFrameCount; k++, FrameList++) { if (*FrameList) MyFreePool__(*FrameList); } diff --git a/drivers/filesystems/udfs/udf_info/udf_info.cpp b/drivers/filesystems/udfs/udf_info/udf_info.cpp index e9556aa93de31..290d663e78221 100644 --- a/drivers/filesystems/udfs/udf_info/udf_info.cpp +++ b/drivers/filesystems/udfs/udf_info/udf_info.cpp @@ -2604,24 +2604,31 @@ UDFCleanUpFile__( } #endif //UDF_TRACK_ONDISK_ALLOCATION if (FileInfo->Dloc->DirIndex) { + PDIR_INDEX_HDR tmpDirIndex; uint_di i; - for(i=2; (DirNdx = UDFDirIndex(Dloc->DirIndex,i)); i++) { + tmpDirIndex = Dloc->DirIndex; + Dloc->DirIndex = NULL; + for(i=2; (DirNdx = UDFDirIndex(tmpDirIndex,i)); i++) { ASSERT(!DirNdx->FileInfo); - if (DirNdx->FName.Buffer) + if (DirNdx->FName.Buffer) { MyFreePool__(DirNdx->FName.Buffer); + DirNdx->FName.Buffer = NULL; + } } - UDFDirIndexFree(Dloc->DirIndex); - Dloc->DirIndex = NULL; + UDFDirIndexFree(tmpDirIndex); #ifdef UDF_TRACK_ONDISK_ALLOCATION UDFIndexDirectory(Vcb, FileInfo); if (FileInfo->Dloc->DirIndex) { - for(i=2; DirNdx = UDFDirIndex(Dloc->DirIndex,i); i++) { + tmpDirIndex = Dloc->DirIndex; + Dloc->DirIndex = NULL; + for(i=2; (DirNdx = UDFDirIndex(tmpDirIndex,i)); i++) { ASSERT(!DirNdx->FileInfo); - if (DirNdx->FName.Buffer) + if (DirNdx->FName.Buffer) { MyFreePool__(DirNdx->FName.Buffer); + DirNdx->FName.Buffer = NULL; + } } - UDFDirIndexFree(Dloc->DirIndex); - Dloc->DirIndex = NULL; + UDFDirIndexFree(tmpDirIndex); } #endif //UDF_TRACK_ONDISK_ALLOCATION }