2 * FFS File System Driver for Windows
8 * Lee Jae-Hong, http://www.pyrasis.com
19 extern PFFS_GLOBAL FFSGlobal
;
25 #pragma alloc_text(PAGE, FFSAllocateIrpContext)
26 #pragma alloc_text(PAGE, FFSFreeIrpContext)
27 #pragma alloc_text(PAGE, FFSv1AllocateFcb)
28 #pragma alloc_text(PAGE, FFSv2AllocateFcb)
29 #pragma alloc_text(PAGE, FFSFreeFcb)
30 #pragma alloc_text(PAGE, FFSAllocateMcb)
31 #pragma alloc_text(PAGE, FFSFreeMcb)
32 #pragma alloc_text(PAGE, FFSSearchMcbTree)
33 #pragma alloc_text(PAGE, FFSSearchMcb)
34 #pragma alloc_text(PAGE, FFSGetFullFileName)
35 #pragma alloc_text(PAGE, FFSRefreshMcb)
36 #pragma alloc_text(PAGE, FFSAddMcbNode)
37 #pragma alloc_text(PAGE, FFSDeleteMcbNode)
38 #pragma alloc_text(PAGE, FFSFreeMcbTree)
39 #pragma alloc_text(PAGE, FFSCheckBitmapConsistency)
40 #pragma alloc_text(PAGE, FFSCheckSetBlock)
41 #pragma alloc_text(PAGE, FFSInitializeVcb)
42 #pragma alloc_text(PAGE, FFSFreeCcb)
43 #pragma alloc_text(PAGE, FFSAllocateCcb)
44 #pragma alloc_text(PAGE, FFSFreeVcb)
45 #pragma alloc_text(PAGE, FFSCreateFcbFromMcb)
46 #pragma alloc_text(PAGE, FFSSyncUninitializeCacheMap)
50 __drv_mustHoldCriticalRegion
52 FFSAllocateIrpContext(
53 IN PDEVICE_OBJECT DeviceObject
,
56 PIO_STACK_LOCATION IoStackLocation
;
57 PFFS_IRP_CONTEXT IrpContext
;
61 ASSERT(DeviceObject
!= NULL
);
64 IoStackLocation
= IoGetCurrentIrpStackLocation(Irp
);
66 ExAcquireResourceExclusiveLite(
67 &FFSGlobal
->LAResource
,
70 IrpContext
= (PFFS_IRP_CONTEXT
)(ExAllocateFromNPagedLookasideList(&(FFSGlobal
->FFSIrpContextLookasideList
)));
72 ExReleaseResourceForThreadLite(
73 &FFSGlobal
->LAResource
,
74 ExGetCurrentResourceThread());
76 if (IrpContext
== NULL
)
78 IrpContext
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(FFS_IRP_CONTEXT
), FFS_POOL_TAG
);
81 // Zero out the irp context and indicate that it is from pool and
82 // not region allocated
85 RtlZeroMemory(IrpContext
, sizeof(FFS_IRP_CONTEXT
));
87 SetFlag(IrpContext
->Flags
, IRP_CONTEXT_FLAG_FROM_POOL
);
92 // Zero out the irp context and indicate that it is from zone and
96 RtlZeroMemory(IrpContext
, sizeof(FFS_IRP_CONTEXT
));
104 IrpContext
->Identifier
.Type
= FFSICX
;
105 IrpContext
->Identifier
.Size
= sizeof(FFS_IRP_CONTEXT
);
107 IrpContext
->Irp
= Irp
;
109 IrpContext
->MajorFunction
= IoStackLocation
->MajorFunction
;
110 IrpContext
->MinorFunction
= IoStackLocation
->MinorFunction
;
112 IrpContext
->DeviceObject
= DeviceObject
;
114 IrpContext
->FileObject
= IoStackLocation
->FileObject
;
116 if (IrpContext
->FileObject
!= NULL
)
118 IrpContext
->RealDevice
= IrpContext
->FileObject
->DeviceObject
;
120 else if (IrpContext
->MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
)
122 if (IoStackLocation
->Parameters
.MountVolume
.Vpb
)
124 IrpContext
->RealDevice
=
125 IoStackLocation
->Parameters
.MountVolume
.Vpb
->RealDevice
;
129 if (IrpContext
->MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
||
130 IrpContext
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
||
131 IrpContext
->MajorFunction
== IRP_MJ_SHUTDOWN
)
133 IrpContext
->IsSynchronous
= TRUE
;
135 else if (IrpContext
->MajorFunction
== IRP_MJ_CLEANUP
||
136 IrpContext
->MajorFunction
== IRP_MJ_CLOSE
)
138 IrpContext
->IsSynchronous
= FALSE
;
140 #if (_WIN32_WINNT >= 0x0500)
141 else if (IrpContext
->MajorFunction
== IRP_MJ_PNP
)
143 if (IoGetCurrentIrpStackLocation(Irp
)->FileObject
== NULL
)
145 IrpContext
->IsSynchronous
= TRUE
;
149 IrpContext
->IsSynchronous
= IoIsOperationSynchronous(Irp
);
152 #endif //(_WIN32_WINNT >= 0x0500)
155 IrpContext
->IsSynchronous
= IoIsOperationSynchronous(Irp
);
160 // Temporary workaround for a bug in close that makes it reference a
161 // fileobject when it is no longer valid.
163 if (IrpContext
->MajorFunction
== IRP_MJ_CLOSE
)
165 IrpContext
->IsSynchronous
= TRUE
;
169 IrpContext
->IsTopLevel
= (IoGetTopLevelIrp() == Irp
);
171 IrpContext
->ExceptionInProgress
= FALSE
;
177 __drv_mustHoldCriticalRegion
180 IN PFFS_IRP_CONTEXT IrpContext
)
184 ASSERT(IrpContext
!= NULL
);
186 ASSERT((IrpContext
->Identifier
.Type
== FFSICX
) &&
187 (IrpContext
->Identifier
.Size
== sizeof(FFS_IRP_CONTEXT
)));
189 FFSUnpinRepinnedBcbs(IrpContext
);
191 // Return the Irp context record to the region or to pool depending on
194 if (FlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_FROM_POOL
))
196 IrpContext
->Identifier
.Type
= 0;
197 IrpContext
->Identifier
.Size
= 0;
199 ExFreePool(IrpContext
);
203 IrpContext
->Identifier
.Type
= 0;
204 IrpContext
->Identifier
.Size
= 0;
206 ExAcquireResourceExclusiveLite(
207 &FFSGlobal
->LAResource
,
210 ExFreeToNPagedLookasideList(&(FFSGlobal
->FFSIrpContextLookasideList
), IrpContext
);
212 ExReleaseResourceForThreadLite(
213 &FFSGlobal
->LAResource
,
214 ExGetCurrentResourceThread());
222 IN PFFS_IRP_CONTEXT IrpContext
,
225 PFFS_REPINNED_BCBS Repinned
;
228 Repinned
= &IrpContext
->Repinned
;
235 for (i
= 0; i
< FFS_REPINNED_BCBS_ARRAY_SIZE
; i
+= 1)
237 if (Repinned
->Bcb
[i
] == Bcb
)
243 Repinned
= Repinned
->Next
;
248 for (i
= 0; i
< FFS_REPINNED_BCBS_ARRAY_SIZE
; i
+= 1)
250 if (Repinned
->Bcb
[i
] == Bcb
)
255 if (Repinned
->Bcb
[i
] == NULL
)
257 Repinned
->Bcb
[i
] = Bcb
;
264 if (Repinned
->Next
== NULL
)
266 Repinned
->Next
= ExAllocatePoolWithTag(PagedPool
, sizeof(FFS_REPINNED_BCBS
), FFS_POOL_TAG
);
267 RtlZeroMemory(Repinned
->Next
, sizeof(FFS_REPINNED_BCBS
));
270 Repinned
= Repinned
->Next
;
276 FFSUnpinRepinnedBcbs(
277 IN PFFS_IRP_CONTEXT IrpContext
)
279 IO_STATUS_BLOCK RaiseIosb
;
280 PFFS_REPINNED_BCBS Repinned
;
281 BOOLEAN WriteThroughToDisk
;
282 PFILE_OBJECT FileObject
= NULL
;
283 BOOLEAN ForceVerify
= FALSE
;
286 Repinned
= &IrpContext
->Repinned
;
287 RaiseIosb
.Status
= STATUS_SUCCESS
;
289 WriteThroughToDisk
= (BOOLEAN
)(IsFlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_WRITE_THROUGH
) ||
290 IsFlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_FLOPPY
));
292 while (Repinned
!= NULL
)
294 for (i
= 0; i
< FFS_REPINNED_BCBS_ARRAY_SIZE
; i
+= 1)
296 if (Repinned
->Bcb
[i
] != NULL
)
298 IO_STATUS_BLOCK Iosb
;
300 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
302 if (FlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_FLOPPY
))
304 FileObject
= CcGetFileObjectFromBcb(Repinned
->Bcb
[i
]);
307 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
309 CcUnpinRepinnedBcb(Repinned
->Bcb
[i
],
313 ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL
);
315 if (!NT_SUCCESS(Iosb
.Status
))
317 if (RaiseIosb
.Status
== STATUS_SUCCESS
)
322 if (FlagOn(IrpContext
->Flags
, IRP_CONTEXT_FLAG_FLOPPY
) &&
323 (IrpContext
->MajorFunction
!= IRP_MJ_CLEANUP
) &&
324 (IrpContext
->MajorFunction
!= IRP_MJ_FLUSH_BUFFERS
) &&
325 (IrpContext
->MajorFunction
!= IRP_MJ_SET_INFORMATION
))
328 CcPurgeCacheSection(FileObject
->SectionObjectPointer
,
337 Repinned
->Bcb
[i
] = NULL
;
346 if (Repinned
!= &IrpContext
->Repinned
)
348 PFFS_REPINNED_BCBS Saved
;
350 Saved
= Repinned
->Next
;
351 ExFreePool(Repinned
);
357 Repinned
= Repinned
->Next
;
358 IrpContext
->Repinned
.Next
= NULL
;
362 if (!NT_SUCCESS(RaiseIosb
.Status
))
366 if (ForceVerify
&& FileObject
)
368 SetFlag(FileObject
->DeviceObject
->Flags
, DO_VERIFY_VOLUME
);
369 IoSetHardErrorOrVerifyDevice(IrpContext
->Irp
,
370 FileObject
->DeviceObject
);
373 IrpContext
->Irp
->IoStatus
= RaiseIosb
;
374 FFSNormalizeAndRaiseStatus(IrpContext
, RaiseIosb
.Status
);
381 __drv_mustHoldCriticalRegion
386 IN PFFSv1_INODE dinode1
)
392 ExAcquireResourceExclusiveLite(
393 &FFSGlobal
->LAResource
,
396 Fcb
= (PFFS_FCB
)(ExAllocateFromNPagedLookasideList(&(FFSGlobal
->FFSFcbLookasideList
)));
398 ExReleaseResourceForThreadLite(
399 &FFSGlobal
->LAResource
,
400 ExGetCurrentResourceThread());
404 Fcb
= (PFFS_FCB
)ExAllocatePoolWithTag(NonPagedPool
, sizeof(FFS_FCB
), FFS_POOL_TAG
);
406 RtlZeroMemory(Fcb
, sizeof(FFS_FCB
));
408 SetFlag(Fcb
->Flags
, FCB_FROM_POOL
);
412 RtlZeroMemory(Fcb
, sizeof(FFS_FCB
));
420 Fcb
->Identifier
.Type
= FFSFCB
;
421 Fcb
->Identifier
.Size
= sizeof(FFS_FCB
);
423 FsRtlInitializeFileLock(
424 &Fcb
->FileLockAnchor
,
428 Fcb
->OpenHandleCount
= 0;
429 Fcb
->ReferenceCount
= 0;
435 Fcb
->AnsiFileName
.MaximumLength
= (USHORT
)
436 RtlxUnicodeStringToOemSize(&(FFSMcb
->ShortName
)) + 1;
438 Fcb
->AnsiFileName
.Buffer
= (PUCHAR
)
439 ExAllocatePoolWithTag(PagedPool
, Fcb
->AnsiFileName
.MaximumLength
, FFS_POOL_TAG
);
441 if (!Fcb
->AnsiFileName
.Buffer
)
446 RtlZeroMemory(Fcb
->AnsiFileName
.Buffer
, Fcb
->AnsiFileName
.MaximumLength
);
448 FFSUnicodeToOEM(&(Fcb
->AnsiFileName
),
449 &(FFSMcb
->ShortName
));
453 FFSMcb
->FileAttr
= FILE_ATTRIBUTE_NORMAL
;
455 if ((dinode1
->di_mode
& IFMT
) == IFDIR
)
457 SetFlag(FFSMcb
->FileAttr
, FILE_ATTRIBUTE_DIRECTORY
);
460 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
) ||
461 FFSIsReadOnly(dinode1
->di_mode
))
463 SetFlag(FFSMcb
->FileAttr
, FILE_ATTRIBUTE_READONLY
);
466 Fcb
->dinode1
= dinode1
;
468 Fcb
->FFSMcb
= FFSMcb
;
469 FFSMcb
->FFSFcb
= Fcb
;
471 RtlZeroMemory(&Fcb
->Header
, sizeof(FSRTL_COMMON_FCB_HEADER
));
473 Fcb
->Header
.NodeTypeCode
= (USHORT
)FFSFCB
;
474 Fcb
->Header
.NodeByteSize
= sizeof(FFS_FCB
);
475 Fcb
->Header
.IsFastIoPossible
= FastIoIsNotPossible
;
476 Fcb
->Header
.Resource
= &(Fcb
->MainResource
);
477 Fcb
->Header
.PagingIoResource
= &(Fcb
->PagingIoResource
);
480 ULONG Totalblocks
= (Fcb
->dinode1
->di_blocks
);
481 Fcb
->Header
.AllocationSize
.QuadPart
=
482 (((LONGLONG
)FFSDataBlocks(Vcb
, Totalblocks
)) << BLOCK_BITS
);
485 Fcb
->Header
.FileSize
.QuadPart
= (LONGLONG
)(Fcb
->dinode1
->di_size
);
486 Fcb
->Header
.ValidDataLength
.QuadPart
= (LONGLONG
)(0x7fffffffffffffff);
488 Fcb
->SectionObject
.DataSectionObject
= NULL
;
489 Fcb
->SectionObject
.SharedCacheMap
= NULL
;
490 Fcb
->SectionObject
.ImageSectionObject
= NULL
;
492 ExInitializeResourceLite(&(Fcb
->MainResource
));
493 ExInitializeResourceLite(&(Fcb
->PagingIoResource
));
495 InsertTailList(&Vcb
->FcbList
, &Fcb
->Next
);
499 ExAcquireResourceExclusiveLite(
500 &FFSGlobal
->CountResource
,
503 FFSGlobal
->FcbAllocated
++;
505 ExReleaseResourceForThreadLite(
506 &FFSGlobal
->CountResource
,
507 ExGetCurrentResourceThread());
520 if (Fcb
->AnsiFileName
.Buffer
)
521 ExFreePool(Fcb
->AnsiFileName
.Buffer
);
524 if (FlagOn(Fcb
->Flags
, FCB_FROM_POOL
))
530 ExAcquireResourceExclusiveLite(
531 &FFSGlobal
->LAResource
,
534 ExFreeToNPagedLookasideList(&(FFSGlobal
->FFSFcbLookasideList
), Fcb
);
536 ExReleaseResourceForThreadLite(
537 &FFSGlobal
->LAResource
,
538 ExGetCurrentResourceThread());
547 __drv_mustHoldCriticalRegion
552 IN PFFSv2_INODE dinode2
)
558 ExAcquireResourceExclusiveLite(
559 &FFSGlobal
->LAResource
,
562 Fcb
= (PFFS_FCB
)(ExAllocateFromNPagedLookasideList(&(FFSGlobal
->FFSFcbLookasideList
)));
564 ExReleaseResourceForThreadLite(
565 &FFSGlobal
->LAResource
,
566 ExGetCurrentResourceThread());
570 Fcb
= (PFFS_FCB
)ExAllocatePoolWithTag(NonPagedPool
, sizeof(FFS_FCB
), FFS_POOL_TAG
);
572 RtlZeroMemory(Fcb
, sizeof(FFS_FCB
));
574 SetFlag(Fcb
->Flags
, FCB_FROM_POOL
);
578 RtlZeroMemory(Fcb
, sizeof(FFS_FCB
));
586 Fcb
->Identifier
.Type
= FFSFCB
;
587 Fcb
->Identifier
.Size
= sizeof(FFS_FCB
);
589 FsRtlInitializeFileLock(
590 &Fcb
->FileLockAnchor
,
594 Fcb
->OpenHandleCount
= 0;
595 Fcb
->ReferenceCount
= 0;
601 Fcb
->AnsiFileName
.MaximumLength
= (USHORT
)
602 RtlxUnicodeStringToOemSize(&(FFSMcb
->ShortName
)) + 1;
604 Fcb
->AnsiFileName
.Buffer
= (PUCHAR
)
605 ExAllocatePoolWithTag(PagedPool
, Fcb
->AnsiFileName
.MaximumLength
, FFS_POOL_TAG
);
607 if (!Fcb
->AnsiFileName
.Buffer
)
612 RtlZeroMemory(Fcb
->AnsiFileName
.Buffer
, Fcb
->AnsiFileName
.MaximumLength
);
614 FFSUnicodeToOEM(&(Fcb
->AnsiFileName
),
615 &(FFSMcb
->ShortName
));
619 FFSMcb
->FileAttr
= FILE_ATTRIBUTE_NORMAL
;
621 if ((dinode2
->di_mode
& IFMT
) == IFDIR
)
623 SetFlag(FFSMcb
->FileAttr
, FILE_ATTRIBUTE_DIRECTORY
);
626 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
) ||
627 FFSIsReadOnly(dinode2
->di_mode
))
629 SetFlag(FFSMcb
->FileAttr
, FILE_ATTRIBUTE_READONLY
);
632 Fcb
->dinode2
= dinode2
;
634 Fcb
->FFSMcb
= FFSMcb
;
635 FFSMcb
->FFSFcb
= Fcb
;
637 RtlZeroMemory(&Fcb
->Header
, sizeof(FSRTL_COMMON_FCB_HEADER
));
639 Fcb
->Header
.NodeTypeCode
= (USHORT
)FFSFCB
;
640 Fcb
->Header
.NodeByteSize
= sizeof(FFS_FCB
);
641 Fcb
->Header
.IsFastIoPossible
= FastIoIsNotPossible
;
642 Fcb
->Header
.Resource
= &(Fcb
->MainResource
);
643 Fcb
->Header
.PagingIoResource
= &(Fcb
->PagingIoResource
);
646 ULONG Totalblocks
= (ULONG
)(Fcb
->dinode2
->di_blocks
);
647 Fcb
->Header
.AllocationSize
.QuadPart
=
648 (((LONGLONG
)FFSDataBlocks(Vcb
, Totalblocks
)) << BLOCK_BITS
);
651 Fcb
->Header
.FileSize
.QuadPart
= (LONGLONG
)(Fcb
->dinode2
->di_size
);
652 Fcb
->Header
.ValidDataLength
.QuadPart
= (LONGLONG
)(0x7fffffffffffffff);
654 Fcb
->SectionObject
.DataSectionObject
= NULL
;
655 Fcb
->SectionObject
.SharedCacheMap
= NULL
;
656 Fcb
->SectionObject
.ImageSectionObject
= NULL
;
658 ExInitializeResourceLite(&(Fcb
->MainResource
));
659 ExInitializeResourceLite(&(Fcb
->PagingIoResource
));
661 InsertTailList(&Vcb
->FcbList
, &Fcb
->Next
);
665 ExAcquireResourceExclusiveLite(
666 &FFSGlobal
->CountResource
,
669 FFSGlobal
->FcbAllocated
++;
671 ExReleaseResourceForThreadLite(
672 &FFSGlobal
->CountResource
,
673 ExGetCurrentResourceThread());
686 if (Fcb
->AnsiFileName
.Buffer
)
687 ExFreePool(Fcb
->AnsiFileName
.Buffer
);
690 if (FlagOn(Fcb
->Flags
, FCB_FROM_POOL
))
696 ExAcquireResourceExclusiveLite(
697 &FFSGlobal
->LAResource
,
700 ExFreeToNPagedLookasideList(&(FFSGlobal
->FFSFcbLookasideList
), Fcb
);
702 ExReleaseResourceForThreadLite(
703 &FFSGlobal
->LAResource
,
704 ExGetCurrentResourceThread());
713 __drv_mustHoldCriticalRegion
724 ASSERT((Fcb
->Identifier
.Type
== FFSFCB
) &&
725 (Fcb
->Identifier
.Size
== sizeof(FFS_FCB
)));
729 FsRtlUninitializeFileLock(&Fcb
->FileLockAnchor
);
731 ExDeleteResourceLite(&Fcb
->MainResource
);
733 ExDeleteResourceLite(&Fcb
->PagingIoResource
);
735 Fcb
->FFSMcb
->FFSFcb
= NULL
;
737 if(IsFlagOn(Fcb
->Flags
, FCB_FILE_DELETED
))
741 FFSDeleteMcbNode(Vcb
, Fcb
->FFSMcb
->Parent
, Fcb
->FFSMcb
);
742 FFSFreeMcb(Fcb
->FFSMcb
);
746 if (Fcb
->LongName
.Buffer
)
748 ExFreePool(Fcb
->LongName
.Buffer
);
749 Fcb
->LongName
.Buffer
= NULL
;
753 ExFreePool(Fcb
->AnsiFileName
.Buffer
);
758 ExFreePool(Fcb
->dinode1
);
762 ExFreePool(Fcb
->dinode2
);
765 Fcb
->Header
.NodeTypeCode
= (SHORT
)0xCCCC;
766 Fcb
->Header
.NodeByteSize
= (SHORT
)0xC0C0;
768 if (FlagOn(Fcb
->Flags
, FCB_FROM_POOL
))
774 ExAcquireResourceExclusiveLite(
775 &FFSGlobal
->LAResource
,
778 ExFreeToNPagedLookasideList(&(FFSGlobal
->FFSFcbLookasideList
), Fcb
);
780 ExReleaseResourceForThreadLite(
781 &FFSGlobal
->LAResource
,
782 ExGetCurrentResourceThread());
787 ExAcquireResourceExclusiveLite(
788 &FFSGlobal
->CountResource
,
791 FFSGlobal
->FcbAllocated
--;
793 ExReleaseResourceForThreadLite(
794 &FFSGlobal
->CountResource
,
795 ExGetCurrentResourceThread());
801 __drv_mustHoldCriticalRegion
810 ExAcquireResourceExclusiveLite(
811 &FFSGlobal
->LAResource
,
814 Ccb
= (PFFS_CCB
)(ExAllocateFromNPagedLookasideList(&(FFSGlobal
->FFSCcbLookasideList
)));
816 ExReleaseResourceForThreadLite(
817 &FFSGlobal
->LAResource
,
818 ExGetCurrentResourceThread());
822 Ccb
= (PFFS_CCB
)ExAllocatePoolWithTag(NonPagedPool
, sizeof(FFS_CCB
), FFS_POOL_TAG
);
824 RtlZeroMemory(Ccb
, sizeof(FFS_CCB
));
826 SetFlag(Ccb
->Flags
, CCB_FROM_POOL
);
830 RtlZeroMemory(Ccb
, sizeof(FFS_CCB
));
838 Ccb
->Identifier
.Type
= FFSCCB
;
839 Ccb
->Identifier
.Size
= sizeof(FFS_CCB
);
841 Ccb
->CurrentByteOffset
= 0;
843 Ccb
->DirectorySearchPattern
.Length
= 0;
844 Ccb
->DirectorySearchPattern
.MaximumLength
= 0;
845 Ccb
->DirectorySearchPattern
.Buffer
= 0;
851 __drv_mustHoldCriticalRegion
860 ASSERT((Ccb
->Identifier
.Type
== FFSCCB
) &&
861 (Ccb
->Identifier
.Size
== sizeof(FFS_CCB
)));
863 if (Ccb
->DirectorySearchPattern
.Buffer
!= NULL
)
865 ExFreePool(Ccb
->DirectorySearchPattern
.Buffer
);
868 if (FlagOn(Ccb
->Flags
, CCB_FROM_POOL
))
874 ExAcquireResourceExclusiveLite(
875 &FFSGlobal
->LAResource
,
878 ExFreeToNPagedLookasideList(&(FFSGlobal
->FFSCcbLookasideList
), Ccb
);
880 ExReleaseResourceForThreadLite(
881 &FFSGlobal
->LAResource
,
882 ExGetCurrentResourceThread());
887 __drv_mustHoldCriticalRegion
891 PUNICODE_STRING FileName
,
895 PLIST_ENTRY List
= NULL
;
901 #define MCB_NUM_SHIFT 0x04
903 if (FFSGlobal
->McbAllocated
> (FFSGlobal
->MaxDepth
<< MCB_NUM_SHIFT
))
904 Extra
= FFSGlobal
->McbAllocated
-
905 (FFSGlobal
->MaxDepth
<< MCB_NUM_SHIFT
) +
909 "FFSAllocateMcb: CurrDepth=%xh/%xh/%xh FileName=%S\n",
910 FFSGlobal
->McbAllocated
,
911 FFSGlobal
->MaxDepth
<< MCB_NUM_SHIFT
,
912 FFSGlobal
->FcbAllocated
,
915 List
= Vcb
->McbList
.Flink
;
917 while ((List
!= &(Vcb
->McbList
)) && (Extra
> 0))
919 Mcb
= CONTAINING_RECORD(List
, FFS_MCB
, Link
);
922 if ((Mcb
->Inode
!= 2) && (Mcb
->Child
== NULL
) &&
923 (Mcb
->FFSFcb
== NULL
) && (!IsMcbUsed(Mcb
)))
925 FFSPrint((DBG_INFO
, "FFSAllocateMcb: Mcb %S will be freed.\n",
926 Mcb
->ShortName
.Buffer
));
928 if (FFSDeleteMcbNode(Vcb
, Vcb
->McbTree
, Mcb
))
937 ExAcquireResourceExclusiveLite(
938 &FFSGlobal
->LAResource
,
941 Mcb
= (PFFS_MCB
)(ExAllocateFromPagedLookasideList(
942 &(FFSGlobal
->FFSMcbLookasideList
)));
944 ExReleaseResourceForThreadLite(
945 &FFSGlobal
->LAResource
,
946 ExGetCurrentResourceThread());
950 Mcb
= (PFFS_MCB
)ExAllocatePoolWithTag(PagedPool
, sizeof(FFS_MCB
), FFS_POOL_TAG
);
952 RtlZeroMemory(Mcb
, sizeof(FFS_MCB
));
954 SetFlag(Mcb
->Flags
, MCB_FROM_POOL
);
958 RtlZeroMemory(Mcb
, sizeof(FFS_MCB
));
966 Mcb
->Identifier
.Type
= FFSMCB
;
967 Mcb
->Identifier
.Size
= sizeof(FFS_MCB
);
969 if (FileName
&& FileName
->Length
)
971 Mcb
->ShortName
.Length
= FileName
->Length
;
972 Mcb
->ShortName
.MaximumLength
= Mcb
->ShortName
.Length
+ 2;
974 Mcb
->ShortName
.Buffer
= ExAllocatePoolWithTag(PagedPool
, Mcb
->ShortName
.MaximumLength
, FFS_POOL_TAG
);
976 if (!Mcb
->ShortName
.Buffer
)
979 RtlZeroMemory(Mcb
->ShortName
.Buffer
, Mcb
->ShortName
.MaximumLength
);
980 RtlCopyMemory(Mcb
->ShortName
.Buffer
, FileName
->Buffer
, Mcb
->ShortName
.Length
);
983 Mcb
->FileAttr
= FileAttr
;
985 ExAcquireResourceExclusiveLite(
986 &FFSGlobal
->CountResource
,
989 FFSGlobal
->McbAllocated
++;
991 ExReleaseResourceForThreadLite(
992 &FFSGlobal
->CountResource
,
993 ExGetCurrentResourceThread());
1001 if (Mcb
->ShortName
.Buffer
)
1002 ExFreePool(Mcb
->ShortName
.Buffer
);
1004 if (FlagOn(Mcb
->Flags
, MCB_FROM_POOL
))
1010 ExAcquireResourceExclusiveLite(
1011 &FFSGlobal
->LAResource
,
1014 ExFreeToPagedLookasideList(&(FFSGlobal
->FFSMcbLookasideList
), Mcb
);
1016 ExReleaseResourceForThreadLite(
1017 &FFSGlobal
->LAResource
,
1018 ExGetCurrentResourceThread());
1026 __drv_mustHoldCriticalRegion
1032 PFFS_MCB Parent
= Mcb
->Parent
;
1036 ASSERT(Mcb
!= NULL
);
1038 ASSERT((Mcb
->Identifier
.Type
== FFSMCB
) &&
1039 (Mcb
->Identifier
.Size
== sizeof(FFS_MCB
)));
1041 FFSPrint((DBG_INFO
, "FFSFreeMcb: Mcb %S will be freed.\n", Mcb
->ShortName
.Buffer
));
1043 if (Mcb
->ShortName
.Buffer
)
1044 ExFreePool(Mcb
->ShortName
.Buffer
);
1046 if (FlagOn(Mcb
->Flags
, MCB_FROM_POOL
))
1052 ExAcquireResourceExclusiveLite(
1053 &FFSGlobal
->LAResource
,
1056 ExFreeToPagedLookasideList(&(FFSGlobal
->FFSMcbLookasideList
), Mcb
);
1058 ExReleaseResourceForThreadLite(
1059 &FFSGlobal
->LAResource
,
1060 ExGetCurrentResourceThread());
1063 ExAcquireResourceExclusiveLite(
1064 &FFSGlobal
->CountResource
,
1067 FFSGlobal
->McbAllocated
--;
1069 ExReleaseResourceForThreadLite(
1070 &FFSGlobal
->CountResource
,
1071 ExGetCurrentResourceThread());
1075 __drv_mustHoldCriticalRegion
1077 FFSCreateFcbFromMcb(
1081 PFFS_FCB Fcb
= NULL
;
1082 FFSv1_INODE dinode1
;
1083 FFSv2_INODE dinode2
;
1090 if (FS_VERSION
== 1)
1092 if (FFSv1LoadInode(Vcb
, Mcb
->Inode
, &dinode1
))
1094 PFFSv1_INODE pTmpInode
= ExAllocatePoolWithTag(PagedPool
, DINODE1_SIZE
, FFS_POOL_TAG
);
1100 RtlCopyMemory(pTmpInode
, &dinode1
, DINODE1_SIZE
);
1101 Fcb
= FFSv1AllocateFcb(Vcb
, Mcb
, pTmpInode
);
1104 ExFreePool(pTmpInode
);
1110 if (FFSv2LoadInode(Vcb
, Mcb
->Inode
, &dinode2
))
1112 PFFSv2_INODE pTmpInode
= ExAllocatePoolWithTag(PagedPool
, DINODE2_SIZE
, FFS_POOL_TAG
);
1118 RtlCopyMemory(pTmpInode
, &dinode2
, DINODE2_SIZE
);
1119 Fcb
= FFSv2AllocateFcb(Vcb
, Mcb
, pTmpInode
);
1122 ExFreePool(pTmpInode
);
1136 PUNICODE_STRING FileName
)
1139 PFFS_MCB TmpMcb
= Mcb
;
1140 PUNICODE_STRING FileNames
[256];
1141 SHORT Count
= 0 , i
= 0, j
= 0;
1145 while(TmpMcb
&& Count
< 256)
1147 if (TmpMcb
->Inode
== FFS_ROOT_INO
)
1150 FileNames
[Count
++] = &TmpMcb
->ShortName
;
1151 Length
+= (2 + TmpMcb
->ShortName
.Length
);
1153 TmpMcb
= TmpMcb
->Parent
;
1162 FileName
->Length
= Length
;
1163 FileName
->MaximumLength
= Length
+ 2;
1164 FileName
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Length
+ 2, FFS_POOL_TAG
);
1166 if (!FileName
->Buffer
)
1171 RtlZeroMemory(FileName
->Buffer
, FileName
->MaximumLength
);
1175 FileName
->Buffer
[0] = L
'\\';
1179 for (i
= Count
- 1; i
>= 0 && j
< (SHORT
)(FileName
->MaximumLength
); i
--)
1181 FileName
->Buffer
[j
++] = L
'\\';
1183 RtlCopyMemory(&(FileName
->Buffer
[j
]),
1184 FileNames
[i
]->Buffer
,
1185 FileNames
[i
]->Length
);
1187 j
+= FileNames
[i
]->Length
/ 2;
1200 PFFS_MCB Mcb
= NULL
;
1201 PLIST_ENTRY List
= NULL
;
1202 BOOLEAN bFind
= FALSE
;
1206 List
= Vcb
->McbList
.Flink
;
1208 while ((!bFind
) && (List
!= &(Vcb
->McbList
)))
1210 Mcb
= CONTAINING_RECORD(List
, FFS_MCB
, Link
);
1213 if (Mcb
->Inode
== Inode
)
1222 ASSERT(Mcb
!= NULL
);
1223 FFSRefreshMcb(Vcb
, Mcb
);
1238 PUNICODE_STRING FileName
)
1240 PFFS_MCB TmpMcb
= Parent
->Child
;
1246 if (!RtlCompareUnicodeString(
1247 &(TmpMcb
->ShortName
),
1251 TmpMcb
= TmpMcb
->Next
;
1256 FFSRefreshMcb(Vcb
, TmpMcb
);
1270 ASSERT (IsFlagOn(Mcb
->Flags
, MCB_IN_TREE
));
1272 RemoveEntryList(&(Mcb
->Link
));
1273 InsertTailList(&(Vcb
->McbList
), &(Mcb
->Link
));
1283 PFFS_MCB TmpMcb
= Parent
->Child
;
1287 if(IsFlagOn(Child
->Flags
, MCB_IN_TREE
))
1290 FFSPrint((DBG_ERROR
, "FFSAddMcbNode: Child Mcb is alreay in the tree.\n"));
1296 ASSERT(TmpMcb
->Parent
== Parent
);
1298 while (TmpMcb
->Next
)
1300 TmpMcb
= TmpMcb
->Next
;
1301 ASSERT(TmpMcb
->Parent
== Parent
);
1304 TmpMcb
->Next
= Child
;
1305 Child
->Parent
= Parent
;
1310 Parent
->Child
= Child
;
1311 Child
->Parent
= Parent
;
1315 InsertTailList(&(Vcb
->McbList
), &(Child
->Link
));
1316 SetFlag(Child
->Flags
, MCB_IN_TREE
);
1330 if(!IsFlagOn(FFSMcb
->Flags
, MCB_IN_TREE
))
1337 if (FFSMcb
->Parent
->Child
== FFSMcb
)
1339 FFSMcb
->Parent
->Child
= FFSMcb
->Next
;
1343 TmpMcb
= FFSMcb
->Parent
->Child
;
1345 while (TmpMcb
&& TmpMcb
->Next
!= FFSMcb
)
1346 TmpMcb
= TmpMcb
->Next
;
1350 TmpMcb
->Next
= FFSMcb
->Next
;
1359 else if (FFSMcb
->Child
)
1364 RemoveEntryList(&(FFSMcb
->Link
));
1365 ClearFlag(FFSMcb
->Flags
, MCB_IN_TREE
);
1371 __drv_mustHoldCriticalRegion
1383 FFSFreeMcbTree(McbTree
->Child
);
1391 Current
= McbTree
->Next
;
1395 Next
= Current
->Next
;
1399 FFSFreeMcbTree(Current
->Child
);
1402 FFSFreeMcb(Current
);
1407 FFSFreeMcb(McbTree
);
1413 PFFS_IRP_CONTEXT IrpContext
,
1419 ULONG Group
, dwBlk
, Length
;
1421 RTL_BITMAP BlockBitmap
;
1425 LARGE_INTEGER Offset
;
1427 BOOLEAN bModified
= FALSE
;
1430 //Group = (Block - FFS_FIRST_DATA_BLOCK) / BLOCKS_PER_GROUP;
1432 dwBlk
= (Block
- FFS_FIRST_DATA_BLOCK
) % BLOCKS_PER_GROUP
;
1435 Offset
.QuadPart
= (LONGLONG
) Vcb
->BlockSize
;
1436 Offset
.QuadPart
= Offset
.QuadPart
* Vcb
->ffs_group_desc
[Group
].bg_block_bitmap
;
1438 if (Group
== Vcb
->ffs_groups
- 1)
1440 Length
= TOTAL_BLOCKS
% BLOCKS_PER_GROUP
;
1442 /* s_blocks_count is integer multiple of s_blocks_per_group */
1444 Length
= BLOCKS_PER_GROUP
;
1448 Length
= BLOCKS_PER_GROUP
;
1451 if (dwBlk
>= Length
)
1454 if (!CcPinRead(Vcb
->StreamObj
,
1461 FFSPrint((DBG_ERROR
, "FFSDeleteBlock: PinReading error ...\n"));
1465 RtlInitializeBitMap(&BlockBitmap
,
1469 if (RtlCheckBit(&BlockBitmap
, dwBlk
) == 0)
1472 RtlSetBits(&BlockBitmap
, dwBlk
, 1);
1478 CcSetDirtyPinnedData(BitmapBcb
, NULL
);
1480 FFSRepinBcb(IrpContext
, BitmapBcb
);
1482 FFSAddMcbEntry(Vcb
, Offset
.QuadPart
, (LONGLONG
)Vcb
->BlockSize
);
1486 CcUnpinData(BitmapBcb
);
1490 RtlZeroMemory(&BlockBitmap
, sizeof(RTL_BITMAP
));
1493 return (!bModified
);
1500 FFSCheckBitmapConsistency(
1501 PFFS_IRP_CONTEXT IrpContext
,
1506 ULONG i
, j
, InodeBlocks
;
1508 for (i
= 0; i
< Vcb
->ffs_groups
; i
++)
1510 FFSCheckSetBlock(IrpContext
, Vcb
, Vcb
->ffs_group_desc
[i
].bg_block_bitmap
);
1511 FFSCheckSetBlock(IrpContext
, Vcb
, Vcb
->ffs_group_desc
[i
].bg_inode_bitmap
);
1514 if (i
== Vcb
->ffs_groups
- 1)
1516 InodeBlocks
= ((INODES_COUNT
% INODES_PER_GROUP
) * sizeof(FFS_INODE
) + Vcb
->BlockSize
- 1) / (Vcb
->BlockSize
);
1520 InodeBlocks
= (INODES_PER_GROUP
* sizeof(FFS_INODE
) + Vcb
->BlockSize
- 1) / (Vcb
->BlockSize
);
1523 for (j
= 0; j
< InodeBlocks
; j
++)
1524 FFSCheckSetBlock(IrpContext
, Vcb
, Vcb
->ffs_group_desc
[i
].bg_inode_table
+ j
);
1537 InsertTailList(&(FFSGlobal
->VcbList
), &Vcb
->Next
);
1545 RemoveEntryList(&Vcb
->Next
);
1549 __drv_mustHoldCriticalRegion
1552 IN PFFS_IRP_CONTEXT IrpContext
,
1554 IN PFFS_SUPER_BLOCK FFSSb
,
1555 IN PDEVICE_OBJECT TargetDevice
,
1556 IN PDEVICE_OBJECT VolumeDevice
,
1559 BOOLEAN VcbResourceInitialized
= FALSE
;
1560 USHORT VolumeLabelLength
;
1562 BOOLEAN NotifySyncInitialized
= FALSE
;
1565 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
1566 UNICODE_STRING RootNode
;
1576 Status
= STATUS_DEVICE_NOT_READY
;
1583 RootNode
.Buffer
= Buffer
;
1584 RootNode
.MaximumLength
= RootNode
.Length
= 2;
1586 Vcb
->McbTree
= FFSAllocateMcb(Vcb
, &RootNode
,
1587 FILE_ATTRIBUTE_DIRECTORY
| FILE_ATTRIBUTE_NORMAL
);
1595 SetFlag(Vcb
->Flags
, VCB_READ_ONLY
);
1596 #endif // FFS_READ_ONLY
1598 if (IsFlagOn(Vpb
->RealDevice
->Characteristics
, FILE_REMOVABLE_MEDIA
))
1600 SetFlag(Vcb
->Flags
, VCB_REMOVABLE_MEDIA
);
1603 if (IsFlagOn(Vpb
->RealDevice
->Characteristics
, FILE_FLOPPY_DISKETTE
))
1605 SetFlag(Vcb
->Flags
, VCB_FLOPPY_DISK
);
1608 if (IsFlagOn(FFSGlobal
->Flags
, FFS_SUPPORT_WRITING
))
1610 if (IsFlagOn(FFSGlobal
->Flags
, FFS_SUPPORT_WRITING
))
1612 ClearFlag(Vcb
->Flags
, VCB_READ_ONLY
);
1616 SetFlag(Vcb
->Flags
, VCB_READ_ONLY
);
1622 SetFlag(Vcb
->Flags
, VCB_READ_ONLY
);
1625 ExInitializeResourceLite(&Vcb
->MainResource
);
1626 ExInitializeResourceLite(&Vcb
->PagingIoResource
);
1628 ExInitializeResourceLite(&Vcb
->McbResource
);
1630 VcbResourceInitialized
= TRUE
;
1632 Vcb
->McbTree
->Inode
= FFS_ROOT_INO
;
1636 Vcb
->RealDevice
= Vpb
->RealDevice
;
1637 Vpb
->DeviceObject
= VolumeDevice
;
1640 UNICODE_STRING LabelName
;
1643 LabelName
.MaximumLength
= 16 * 2;
1644 LabelName
.Length
= 0;
1645 LabelName
.Buffer
= Vcb
->Vpb
->VolumeLabel
;
1647 RtlZeroMemory(LabelName
.Buffer
, LabelName
.MaximumLength
);
1649 VolumeLabelLength
= 16;
1651 while((VolumeLabelLength
> 0) &&
1652 ((FFSSb
->fs_volname
[VolumeLabelLength
-1] == 0x00) ||
1653 (FFSSb
->fs_volname
[VolumeLabelLength
-1] == 0x20)))
1655 VolumeLabelLength
--;
1658 OemName
.Buffer
= FFSSb
->fs_volname
;
1659 OemName
.MaximumLength
= 16;
1660 OemName
.Length
= VolumeLabelLength
;
1662 Status
= FFSOEMToUnicode(&LabelName
,
1665 if (!NT_SUCCESS(Status
))
1670 Vpb
->VolumeLabelLength
= LabelName
.Length
;
1673 Vpb
->SerialNumber
= ((ULONG
*)FFSSb
->fs_id
)[0] + ((ULONG
*)FFSSb
->fs_id
)[1];
1675 Vcb
->StreamObj
= IoCreateStreamFileObject(NULL
, Vcb
->Vpb
->RealDevice
);
1679 Vcb
->StreamObj
->SectionObjectPointer
= &(Vcb
->SectionObject
);
1680 Vcb
->StreamObj
->Vpb
= Vcb
->Vpb
;
1681 Vcb
->StreamObj
->ReadAccess
= TRUE
;
1682 if (IsFlagOn(Vcb
->Flags
, VCB_READ_ONLY
))
1684 Vcb
->StreamObj
->WriteAccess
= TRUE
;
1685 Vcb
->StreamObj
->DeleteAccess
= TRUE
;
1689 Vcb
->StreamObj
->WriteAccess
= TRUE
;
1690 Vcb
->StreamObj
->DeleteAccess
= TRUE
;
1692 Vcb
->StreamObj
->FsContext
= (PVOID
) Vcb
;
1693 Vcb
->StreamObj
->FsContext2
= NULL
;
1694 Vcb
->StreamObj
->Vpb
= Vcb
->Vpb
;
1696 SetFlag(Vcb
->StreamObj
->Flags
, FO_NO_INTERMEDIATE_BUFFERING
);
1703 InitializeListHead(&Vcb
->FcbList
);
1705 InitializeListHead(&Vcb
->NotifyList
);
1707 FsRtlNotifyInitializeSync(&Vcb
->NotifySync
);
1709 NotifySyncInitialized
= TRUE
;
1711 Vcb
->DeviceObject
= VolumeDevice
;
1713 Vcb
->TargetDeviceObject
= TargetDevice
;
1715 Vcb
->OpenFileHandleCount
= 0;
1717 Vcb
->ReferenceCount
= 0;
1719 Vcb
->ffs_super_block
= FFSSb
;
1721 Vcb
->Header
.NodeTypeCode
= (USHORT
) FFSVCB
;
1722 Vcb
->Header
.NodeByteSize
= sizeof(FFS_VCB
);
1723 Vcb
->Header
.IsFastIoPossible
= FastIoIsNotPossible
;
1724 Vcb
->Header
.Resource
= &(Vcb
->MainResource
);
1725 Vcb
->Header
.PagingIoResource
= &(Vcb
->PagingIoResource
);
1727 Vcb
->Vpb
->SerialNumber
= 'PS';
1730 Vcb
->DiskGeometry
.Cylinders
.QuadPart
*
1731 Vcb
->DiskGeometry
.TracksPerCylinder
*
1732 Vcb
->DiskGeometry
.SectorsPerTrack
*
1733 Vcb
->DiskGeometry
.BytesPerSector
;
1735 IoctlSize
= sizeof(PARTITION_INFORMATION
);
1737 Status
= FFSDiskIoControl(
1739 IOCTL_DISK_GET_PARTITION_INFO
,
1742 &Vcb
->PartitionInformation
,
1745 PartSize
= Vcb
->PartitionInformation
.PartitionLength
.QuadPart
;
1747 if (!NT_SUCCESS(Status
))
1749 Vcb
->PartitionInformation
.StartingOffset
.QuadPart
= 0;
1751 Vcb
->PartitionInformation
.PartitionLength
.QuadPart
=
1754 PartSize
= DiskSize
;
1756 Status
= STATUS_SUCCESS
;
1759 IoctlSize
= sizeof(ULONG
);
1760 Status
= FFSDiskIoControl(
1762 IOCTL_DISK_CHECK_VERIFY
,
1768 if (!NT_SUCCESS(Status
))
1773 Vcb
->ChangeCount
= ChangeCount
;
1775 Vcb
->Header
.AllocationSize
.QuadPart
=
1776 Vcb
->Header
.FileSize
.QuadPart
= PartSize
;
1778 Vcb
->Header
.ValidDataLength
.QuadPart
=
1779 (LONGLONG
)(0x7fffffffffffffff);
1781 Vcb->Header.AllocationSize.QuadPart = (LONGLONG)(ffs_super_block->s_blocks_count - ffs_super_block->s_free_blocks_count)
1782 * (FFS_MIN_BLOCK << ffs_super_block->s_log_block_size);
1783 Vcb->Header.FileSize.QuadPart = Vcb->Header.AllocationSize.QuadPart;
1784 Vcb->Header.ValidDataLength.QuadPart = Vcb->Header.AllocationSize.QuadPart;
1788 CC_FILE_SIZES FileSizes
;
1790 FileSizes
.AllocationSize
.QuadPart
=
1791 FileSizes
.FileSize
.QuadPart
=
1792 Vcb
->Header
.AllocationSize
.QuadPart
;
1794 FileSizes
.ValidDataLength
.QuadPart
= (LONGLONG
)(0x7fffffffffffffff);
1796 CcInitializeCacheMap(Vcb
->StreamObj
,
1799 &(FFSGlobal
->CacheManagerNoOpCallbacks
),
1802 #if 0 // LoadGroup XXX
1803 if (!FFSLoadGroup(Vcb
))
1805 Status
= STATUS_UNSUCCESSFUL
;
1809 FsRtlInitializeLargeMcb(&(Vcb
->DirtyMcbs
), PagedPool
);
1810 InitializeListHead(&(Vcb
->McbList
));
1812 if (IsFlagOn(FFSGlobal
->Flags
, FFS_CHECKING_BITMAP
))
1814 FFSCheckBitmapConsistency(IrpContext
, Vcb
);
1818 ULONG dwData
[FFS_BLOCK_TYPES
] = {NDADDR
, 1, 1, 1};
1819 ULONG dwMeta
[FFS_BLOCK_TYPES
] = {0, 0, 0, 0};
1822 if (FS_VERSION
== 1)
1824 for (i
= 0; i
< FFS_BLOCK_TYPES
; i
++)
1826 dwData
[i
] = dwData
[i
] << ((BLOCK_BITS
- 2) * i
);
1830 dwMeta
[i
] = 1 + (dwMeta
[i
- 1] << (BLOCK_BITS
- 2));
1833 Vcb
->dwData
[i
] = dwData
[i
];
1834 Vcb
->dwMeta
[i
] = dwMeta
[i
];
1839 for (i
= 0; i
< FFS_BLOCK_TYPES
; i
++)
1841 dwData
[i
] = dwData
[i
] << ((BLOCK_BITS
- 3) * i
);
1845 dwMeta
[i
] = 1 + (dwMeta
[i
- 1] << (BLOCK_BITS
- 3));
1848 Vcb
->dwData
[i
] = dwData
[i
];
1849 Vcb
->dwMeta
[i
] = dwMeta
[i
];
1854 SetFlag(Vcb
->Flags
, VCB_INITIALIZED
);
1859 if (!NT_SUCCESS(Status
))
1861 if (NotifySyncInitialized
)
1863 FsRtlNotifyUninitializeSync(&Vcb
->NotifySync
);
1866 if (Vcb
->ffs_super_block
)
1868 ExFreePool(Vcb
->ffs_super_block
);
1869 Vcb
->ffs_super_block
= NULL
;
1872 if (VcbResourceInitialized
)
1874 ExDeleteResourceLite(&Vcb
->MainResource
);
1875 ExDeleteResourceLite(&Vcb
->PagingIoResource
);
1884 __drv_mustHoldCriticalRegion
1891 ASSERT(Vcb
!= NULL
);
1893 ASSERT((Vcb
->Identifier
.Type
== FFSVCB
) &&
1894 (Vcb
->Identifier
.Size
== sizeof(FFS_VCB
)));
1896 FsRtlNotifyUninitializeSync(&Vcb
->NotifySync
);
1900 if (IsFlagOn(Vcb
->StreamObj
->Flags
, FO_FILE_MODIFIED
))
1902 IO_STATUS_BLOCK IoStatus
;
1904 CcFlushCache(&(Vcb
->SectionObject
), NULL
, 0, &IoStatus
);
1905 ClearFlag(Vcb
->StreamObj
->Flags
, FO_FILE_MODIFIED
);
1908 if (Vcb
->StreamObj
->PrivateCacheMap
)
1909 FFSSyncUninitializeCacheMap(Vcb
->StreamObj
);
1911 ObDereferenceObject(Vcb
->StreamObj
);
1912 Vcb
->StreamObj
= NULL
;
1916 if (FsRtlNumberOfRunsInLargeMcb(&(Vcb
->DirtyMcbs
)) != 0)
1920 LONGLONG DirtyLength
;
1923 for (i
= 0; FsRtlGetNextLargeMcbEntry (&(Vcb
->DirtyMcbs
), i
, &DirtyVba
, &DirtyLba
, &DirtyLength
); i
++)
1925 FFSPrint((DBG_INFO
, "DirtyVba = %I64xh\n", DirtyVba
));
1926 FFSPrint((DBG_INFO
, "DirtyLba = %I64xh\n", DirtyLba
));
1927 FFSPrint((DBG_INFO
, "DirtyLen = %I64xh\n\n", DirtyLength
));
1934 FsRtlUninitializeLargeMcb(&(Vcb
->DirtyMcbs
));
1936 FFSFreeMcbTree(Vcb
->McbTree
);
1938 if (Vcb
->ffs_super_block
)
1940 ExFreePool(Vcb
->ffs_super_block
);
1941 Vcb
->ffs_super_block
= NULL
;
1944 ExDeleteResourceLite(&Vcb
->McbResource
);
1946 ExDeleteResourceLite(&Vcb
->PagingIoResource
);
1948 ExDeleteResourceLite(&Vcb
->MainResource
);
1950 IoDeleteDevice(Vcb
->DeviceObject
);
1955 FFSSyncUninitializeCacheMap(
1956 IN PFILE_OBJECT FileObject
)
1958 CACHE_UNINITIALIZE_EVENT UninitializeCompleteEvent
;
1959 NTSTATUS WaitStatus
;
1960 LARGE_INTEGER FFSLargeZero
= {0, 0};
1964 KeInitializeEvent(&UninitializeCompleteEvent
.Event
,
1965 SynchronizationEvent
,
1968 CcUninitializeCacheMap(FileObject
,
1970 &UninitializeCompleteEvent
);
1972 WaitStatus
= KeWaitForSingleObject(&UninitializeCompleteEvent
.Event
,
1978 ASSERT (NT_SUCCESS(WaitStatus
));