24 #define BugCheckFileId (FAT_BUG_CHECK_FSCTRL) 30 #define Dbg (DEBUG_TRACE_FSCTRL) 119 FatInvalidateVolumes (
125 FatScanForDismountedVcb (
141 FatQueryRetrievalPointers (
173 FatGetRetrievalPointerBase (
193 FatSetPurgeFailureMode (
211 FatGetRetrievalPointers (
218 FatMoveFileNeedsWriteThrough (
237 ULONG BytesToReallocate,
238 PULONG FirstSpliceSourceCluster,
239 PULONG FirstSpliceTargetCluster,
240 PULONG SecondSpliceSourceCluster,
241 PULONG SecondSpliceTargetCluster,
247 FatComputeMoveFileParameter (
276 #pragma alloc_text(PAGE, FatAddMcbEntry) 277 #pragma alloc_text(PAGE, FatAllowExtendedDasdIo) 278 #pragma alloc_text(PAGE, FatCommonFileSystemControl) 279 #pragma alloc_text(PAGE, FatComputeMoveFileParameter) 280 #pragma alloc_text(PAGE, FatComputeMoveFileSplicePoints) 281 #pragma alloc_text(PAGE, FatDirtyVolume) 282 #pragma alloc_text(PAGE, FatFsdFileSystemControl) 283 #pragma alloc_text(PAGE, FatGetRetrievalPointerBase) 284 #pragma alloc_text(PAGE, FatGetBootAreaInfo) 285 #pragma alloc_text(PAGE, FatMarkHandle) 286 #pragma alloc_text(PAGE, FatGetRetrievalPointers) 287 #pragma alloc_text(PAGE, FatGetStatistics) 288 #pragma alloc_text(PAGE, FatGetVolumeBitmap) 289 #pragma alloc_text(PAGE, FatIsMediaWriteProtected) 290 #pragma alloc_text(PAGE, FatIsPathnameValid) 291 #pragma alloc_text(PAGE, FatIsVolumeDirty) 292 #pragma alloc_text(PAGE, FatIsVolumeMounted) 293 #pragma alloc_text(PAGE, FatLockVolume) 294 #pragma alloc_text(PAGE, FatLookupLastMcbEntry) 295 #pragma alloc_text(PAGE, FatGetNextMcbEntry) 296 #pragma alloc_text(PAGE, FatMountVolume) 297 #pragma alloc_text(PAGE, FatMoveFileNeedsWriteThrough) 298 #pragma alloc_text(PAGE, FatMoveFile) 299 #pragma alloc_text(PAGE, FatOplockRequest) 300 #pragma alloc_text(PAGE, FatPerformVerifyDiskRead) 301 #pragma alloc_text(PAGE, FatQueryBpb) 302 #pragma alloc_text(PAGE, FatQueryRetrievalPointers) 303 #pragma alloc_text(PAGE, FatRemoveMcbEntry) 304 #pragma alloc_text(PAGE, FatScanForDismountedVcb) 305 #pragma alloc_text(PAGE, FatFlushAndCleanVolume) 306 #pragma alloc_text(PAGE, FatSearchBufferForLabel) 307 #pragma alloc_text(PAGE, FatSetPurgeFailureMode) 308 #pragma alloc_text(PAGE, FatUnlockVolume) 309 #pragma alloc_text(PAGE, FatUserFsCtrl) 310 #pragma alloc_text(PAGE, FatVerifyLookupFatEntry) 311 #pragma alloc_text(PAGE, FatVerifyVolume) 330 #define MCB_SCALE_LOG2 (Vcb->AllocationSupport.LogOfBytesPerSector) 331 #define MCB_SCALE (1 << MCB_SCALE_LOG2) 332 #define MCB_SCALE_MODULO (MCB_SCALE - 1) 398 if (
Mcb != &
Vcb->DirtyFatMcb) {
399 NT_ASSERT( FatNonSparseMcb(
Vcb,
Mcb, &SparseVbo, &SparseByteCount ) ||
408 if (
Mcb != &
Vcb->DirtyFatMcb) {
409 NT_ASSERT( FatNonSparseMcb(
Vcb,
Mcb, &SparseVbo, &SparseByteCount ) ||
445 if ((
ULONG) LiLbo != -1) {
520 if (((
ULONG) LiLbo) != -1) {
570 if (((
ULONG) LiLbo) != -1) {
581 if ((*
ByteCount == 0) && (LiSectorCount != 0)) {
639 FatFsdFileSystemControl (
720 Status = FatCommonFileSystemControl( IrpContext,
Irp );
751 FatCommonFileSystemControl (
799 Status = FatUserFsCtrl( IrpContext,
Irp );
804 Status = FatMountVolume( IrpContext,
824 Status = FatVerifyVolume( IrpContext,
Irp );
920 ULONG ChangeCount = 0;
927 #if (NTDDI_VERSION > NTDDI_WIN8) 928 GUID VolumeGuid = {0};
1016 &PartitionInformation,
1032 FatScanForDismountedVcb( IrpContext );
1044 MountNewVolume =
FALSE;
1053 #pragma prefast( push ) 1054 #pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" ) 1055 #pragma prefast( disable: 28193, "this will always wait" ) 1061 #pragma prefast( pop ) 1095 VolDo->OverflowQueueCount = 0;
1098 VolDo->PostedRequestCount = 0;
1133 #pragma prefast( suppress: 28175, "this is a filesystem driver, touching SectorSize is fine" ) 1157 RealDevice =
Vpb->RealDevice;
1163 WeClearedVerifyRequiredBit =
TRUE;
1170 FatInitializeVcb( IrpContext,
1221 #if (NTDDI_VERSION > NTDDI_WIN8) 1226 if (
NT_SUCCESS( IoVolumeDeviceToGuid(
Vcb->TargetDeviceObject, &VolumeGuid ))) {
1242 if (
Vcb->VolumeGuidPath.Buffer) {
1244 Vcb->VolumeGuidPath.Buffer =
NULL;
1245 Vcb->VolumeGuidPath.Length =
Vcb->VolumeGuidPath.MaximumLength = 0;
1248 IoVolumeDeviceToGuidPath(
Vcb->TargetDeviceObject, &
Vcb->VolumeGuidPath );
1284 (
Vcb->Bpb.Sectors != 0 &&
1285 Vcb->Bpb.Sectors < 0x80)) {
1287 DebugTrace( 0,
Dbg,
"OS/2 Boot Manager volume detected, volume not mounted. \n", 0 );
1315 if (
Vcb->Bpb.Sectors != 0) {
Vcb->Bpb.LargeSectors = 0; }
1332 Vcb->First0x24BytesOfBootSector =
1366 if (
Vcb->Bpb.FsInfoSector >=
Vcb->Bpb.ReservedSectors) {
1368 Vcb->Bpb.FsInfoSector = 0;
1386 FatCreateRootDcb( IrpContext,
Vcb );
1417 FatLocateVolumeLabel( IrpContext,
1425 UCHAR OemBuffer[11];
1471 Vpb->VolumeLabelLength = 0;
1480 Vcb->ChangeCount = ChangeCount;
1490 Links = Links->
Flink) {
1493 OldVpb = OldVcb->
Vpb;
1499 if (OldVpb ==
Vpb) {
continue; }
1515 &
Vpb->VolumeLabel[0],
1516 Vpb->VolumeLabelLength)) &&
1522 LargeSectorsPerFat) ))) {
1562 #pragma prefast( suppress: 28175, "touching Vpb is ok for a filesystem" ) 1579 if (*IrpVpb ==
Vpb) {
1606 DebugTrace(0,
Dbg,
"Truncate and reinitialize the volume file\n", 0);
1724 MountNewVolume =
TRUE;
1736 RootDirectoryFile =
Vcb->RootDcb->Specific.Dcb.DirectoryFile;
1762 if ( !MountNewVolume ) {
1770 FatCheckForDismount( IrpContext,
1774 IrpContext->Vcb =
NULL;
1776 }
else if (VolDo !=
NULL) {
1796 FatCheckForDismount( IrpContext,
1802 if ( WeClearedVerifyRequiredBit ==
TRUE ) {
1818 if (RootDirectoryFile !=
NULL) {
1820 #if (NTDDI_VERSION >= NTDDI_WIN8) 1913 LBO RootDirectoryLbo;
1914 ULONG RootDirectorySize;
1917 ULONG ChangeCount = 0;
1940 IrpContext->Vcb =
Vcb = &VolDo->
Vcb;
1965 #pragma prefast( push ) 1966 #pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" ) 1967 #pragma prefast( disable: 28193, "this will always wait" ) 1973 #pragma prefast( pop ) 1999 DebugTrace(0,
Dbg,
"RealDevice has already been verified\n", 0);
2001 VerifyAlreadyDone =
TRUE;
2014 Vcb->TargetDeviceObject,
2017 &PartitionInformation,
2036 Vcb->TargetDeviceObject,
2052 if (AllowRawMount) {
2062 if (
Iosb.Information !=
sizeof(
ULONG)) {
2076 Vcb->ChangeCount = ChangeCount;
2097 Vcb->TargetDeviceObject,
2113 if (AllowRawMount) {
2200 LargeSectorsPerFat) )) {
2255 if (!LabelFound &&
Vpb->VolumeLabelLength > 0) {
2262 ULONG RootDirectoryCluster;
2303 RootDirectoryCluster,
2304 &RootDirectoryCluster );
2327 Vpb->VolumeLabelLength > 0) {
2354 if (!VerifyAlreadyDone) {
2357 ReleaseEntireVolume =
TRUE;
2383 if (!ReleaseEntireVolume) {
2385 ReleaseEntireVolume =
TRUE;
2392 FatPurgeReferencedFileObjects( IrpContext,
Vcb->RootDcb,
NoFlush );
2411 }
else if (!VerifyAlreadyDone) {
2418 if (!ReleaseEntireVolume) {
2420 ReleaseEntireVolume =
TRUE;
2432 FatPurgeReferencedFileObjects( IrpContext,
Vcb->RootDcb,
Flush );
2493 if (ReleaseEntireVolume) {
2607 }
else if (Bpb.
Fats == 0) {
2630 }
else if ((Bpb.
Media != 0xf0) &&
2631 (Bpb.
Media != 0xf8) &&
2632 (Bpb.
Media != 0xf9) &&
2633 (Bpb.
Media != 0xfb) &&
2634 (Bpb.
Media != 0xfc) &&
2635 (Bpb.
Media != 0xfd) &&
2636 (Bpb.
Media != 0xfe) &&
2637 (Bpb.
Media != 0xff) &&
2639 (Bpb.
Media != 0x01) &&
2640 (Bpb.
Media != 0xfa)))) {
2829 #if (NTDDI_VERSION >= NTDDI_WIN7) 2830 case FSCTL_REQUEST_OPLOCK:
2832 Status = FatOplockRequest( IrpContext,
Irp );
2837 Status = FatLockVolume( IrpContext,
Irp );
2847 Status = FatDismountVolume( IrpContext,
Irp );
2852 Status = FatDirtyVolume( IrpContext,
Irp );
2870 Status = FatQueryRetrievalPointers( IrpContext,
Irp );
2881 #if (NTDDI_VERSION >= NTDDI_WIN7) 2883 Status = FatGetRetrievalPointerBase( IrpContext,
Irp );
2886 case FSCTL_GET_BOOT_AREA_INFO:
2887 Status = FatGetBootAreaInfo( IrpContext,
Irp );
2892 Status = FatGetVolumeBitmap( IrpContext,
Irp );
2896 Status = FatGetRetrievalPointers( IrpContext,
Irp );
2900 Status = FatMoveFile( IrpContext,
Irp );
2908 Status = FatMarkHandle( IrpContext,
Irp );
2911 #if (NTDDI_VERSION >= NTDDI_WIN8) 2913 case FSCTL_SET_PURGE_FAILURE_MODE:
2914 Status = FatSetPurgeFailureMode( IrpContext,
Irp );
2920 #if (NTDDI_VERSION >= NTDDI_WIN7) 2976 ULONG OplockCount = 0;
2983 #if (NTDDI_VERSION >= NTDDI_WIN7) 3016 DebugTrace(-1,
Dbg,
"FatOplockRequest -> STATUS_INVALID_PARAMETER\n", 0);
3020 #if (NTDDI_VERSION >= NTDDI_WIN7) 3029 InputBuffer = (PREQUEST_OPLOCK_INPUT_BUFFER)
Irp->AssociatedIrp.SystemBuffer;
3041 DebugTrace(-1,
Dbg,
"FatOplockRequest -> STATUS_BUFFER_TOO_SMALL\n", 0);
3053 !FsRtlOplockIsSharedRequest(
Irp ))) {
3056 DebugTrace(-1,
Dbg,
"FatOplockRequest -> STATUS_INVALID_PARAMETER\n", 0);
3090 FatAcquireSharedVcb( IrpContext,
Fcb->
Vcb );
3092 FatAcquireExclusiveFcb( IrpContext,
Fcb );
3095 #if (NTDDI_VERSION >= NTDDI_WIN7) 3096 if (FsRtlOplockIsSharedRequest(
Irp )) {
3112 #if (NTDDI_VERSION >= NTDDI_WIN8) 3114 #elif (NTDDI_VERSION >= NTDDI_WIN7) 3115 OplockCount = (
ULONG) FsRtlAreThereCurrentOrInProgressFileLocks( &
Fcb->
Specific.
Fcb.FileLock );
3137 FatAcquireSharedFcb( IrpContext,
Fcb );
3139 #if (NTDDI_VERSION >= NTDDI_WIN7) 3155 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" ) 3433 FatLockVolumeInternal (
3495 FatPurgeReferencedFileObjects( IrpContext,
Vcb->RootDcb,
Flush );
3530 FatPurgeReferencedFileObjects( IrpContext,
Vcb->RootDcb,
Flush );
3567 (
Vcb->Vpb->ReferenceCount <= 2 + RemainingUserReferences) &&
3646 Vcb->FileObjectWithVcbLocked =
NULL;
3774 #pragma prefast( push ) 3775 #pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" ) 3776 #pragma prefast( disable: 28193, "this will always wait" ) 3782 #pragma prefast( pop ) 3836 #if (NTDDI_VERSION >= NTDDI_WIN8) 3838 FsRtlDismountComplete(
Vcb->TargetDeviceObject,
Status );
3954 DebugTrace(-1,
Dbg,
"FatDirtyVolume -> STATUS_SUCCESS\n", 0);
4010 if (
Irp->AssociatedIrp.SystemBuffer !=
NULL) {
4014 }
else if (
Irp->MdlAddress !=
NULL) {
4084 Irp->IoStatus.Information =
sizeof(
ULONG );
4254 if (
Vcb->First0x24BytesOfBootSector ==
NULL) {
4283 Vcb->First0x24BytesOfBootSector,
4286 Irp->IoStatus.Information = 0x24;
4300 FatInvalidateVolumes (
4357 #if defined(_WIN64) && defined(BUILD_WOW64_ENABLED) 4358 if (IoIs32bitProcess(
Irp )) {
4380 #
if defined(_WIN64) && defined(BUILD_WOW64_ENABLED)
4392 (
PVOID *)&FileToMarkBad,
4415 DeviceToMarkBad = FileToMarkBad->DeviceObject;
4425 #pragma prefast( push ) 4426 #pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" ) 4427 #pragma prefast( disable: 28193, "this will always wait" ) 4433 #pragma prefast( pop ) 4452 Links = Links->
Flink;
4473 #pragma prefast( push ) 4474 #pragma prefast( disable: 28175, "touching Vpb is ok for a filesystem" ) 4477 if (ExistingVcb->
Vpb == DeviceToMarkBad->Vpb) {
4487 NewVpb = ExistingVcb->
SwapVpb;
4497 DeviceToMarkBad->Vpb = NewVpb;
4503 #pragma prefast( pop ) 4534 FatPurgeReferencedFileObjects( &IrpContext,
4540 VcbDeleted = FatCheckForDismount( &IrpContext, ExistingVcb,
FALSE );
4558 DebugTrace(-1,
Dbg,
"FatInvalidateVolumes -> STATUS_SUCCESS\n", 0);
4631 Vcb->TargetDeviceObject,
4633 NumberOfBytesToRead,
4676 if (ReturnOnError) {
4700 FatQueryRetrievalPointers (
4786 RequestedMapSize =
IrpSp->
Parameters.FileSystemControl.Type3InputBuffer;
4787 MappingPairs =
Irp->UserBuffer;
4793 FatAcquireExclusiveFcb( IrpContext,
Fcb );
4801 FatVerifyFcb( IrpContext,
Fcb );
4807 if ((*RequestedMapSize).QuadPart >
Fcb->
Header.FileSize.QuadPart) {
4821 RequestedMapSize->
LowPart - 1,
4842 MapSize = RequestedMapSize->
LowPart;
4853 (*MappingPairs)[
i*2 + 1 ].QuadPart =
Lbo;
4858 (*MappingPairs)[
i*2 + 0 ].QuadPart = 0;
4940 Buffer =
Irp->AssociatedIrp.SystemBuffer;
5036 ULONG TotalClusters;
5037 ULONG DesiredClusters;
5038 ULONG StartingCluster;
5039 ULONG EndingCluster;
5053 DebugTrace(+1,
Dbg,
"FatGetVolumeBitmap, FsControlCode = %08lx\n",
5101 TotalClusters =
Vcb->AllocationSupport.NumberOfClusters;
5136 StartingCluster = StartingLcn.
LowPart & ~7;
5146 DesiredClusters = TotalClusters - StartingCluster;
5180 if (
Vcb->NumberOfWindows == 1) {
5189 (
PUCHAR)
Vcb->FreeClusterBitMap.Buffer + StartingCluster/8,
5205 EndingCluster = StartingCluster + (
BytesToCopy * 8);
5211 if (EndingCluster > TotalClusters) {
5213 EndingCluster = TotalClusters;
5218 StartingCluster + 2,
5219 EndingCluster + 2 - 1,
5256 FatGetRetrievalPointers (
5292 ULONG ClusterShift = 0;
5318 DebugTrace(+1,
Dbg,
"FatGetRetrievalPointers, FsControlCode = %08lx\n",
5397 FatVerifyFcb( IrpContext,
FcbOrDcb );
5405 FatLookupFileAllocationSize( IrpContext,
FcbOrDcb );
5421 ClusterShift =
Vcb->AllocationSupport.LogOfBytesPerCluster;
5424 #pragma prefast( suppress:28931, "calculate it anyway, in case someone adds code that uses this in the future" ) 5445 ClusterShift =
Vcb->AllocationSupport.LogOfBytesPerCluster;
5459 McbToUse = &
Vcb->BadBlockMcb;
5503 StartingVcn.
LowPart << ClusterShift,
5509 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" ) 5564 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" ) 5584 OutputBuffer->StartingVcn.QuadPart = Vcn >> ClusterShift;
5631 DebugTrace(-1,
Dbg,
"FatGetRetrievalPointers -> VOID\n", 0);
5644 FatMoveFileNeedsWriteThrough (