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 );
924 ULONG ChangeCount = 0;
931 #if (NTDDI_VERSION > NTDDI_WIN8) 932 GUID VolumeGuid = {0};
1020 &PartitionInformation,
1036 FatScanForDismountedVcb( IrpContext );
1048 MountNewVolume =
FALSE;
1057 #pragma prefast( push ) 1058 #pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" ) 1059 #pragma prefast( disable: 28193, "this will always wait" ) 1065 #pragma prefast( pop ) 1099 VolDo->OverflowQueueCount = 0;
1102 VolDo->PostedRequestCount = 0;
1137 #pragma prefast( suppress: 28175, "this is a filesystem driver, touching SectorSize is fine" ) 1161 RealDevice =
Vpb->RealDevice;
1167 WeClearedVerifyRequiredBit =
TRUE;
1174 FatInitializeVcb( IrpContext,
1225 #if (NTDDI_VERSION > NTDDI_WIN8) 1230 if (
NT_SUCCESS( IoVolumeDeviceToGuid(
Vcb->TargetDeviceObject, &VolumeGuid ))) {
1246 if (
Vcb->VolumeGuidPath.Buffer) {
1248 Vcb->VolumeGuidPath.Buffer =
NULL;
1249 Vcb->VolumeGuidPath.Length =
Vcb->VolumeGuidPath.MaximumLength = 0;
1252 IoVolumeDeviceToGuidPath(
Vcb->TargetDeviceObject, &
Vcb->VolumeGuidPath );
1288 (
Vcb->Bpb.Sectors != 0 &&
1289 Vcb->Bpb.Sectors < 0x80)) {
1291 DebugTrace( 0,
Dbg,
"OS/2 Boot Manager volume detected, volume not mounted. \n", 0 );
1319 if (
Vcb->Bpb.Sectors != 0) {
Vcb->Bpb.LargeSectors = 0; }
1336 Vcb->First0x24BytesOfBootSector =
1370 if (
Vcb->Bpb.FsInfoSector >=
Vcb->Bpb.ReservedSectors) {
1372 Vcb->Bpb.FsInfoSector = 0;
1390 FatCreateRootDcb( IrpContext,
Vcb );
1421 FatLocateVolumeLabel( IrpContext,
1463 Vpb->VolumeLabelLength = 0;
1472 Vcb->ChangeCount = ChangeCount;
1482 Links = Links->
Flink) {
1485 OldVpb = OldVcb->
Vpb;
1491 if (OldVpb ==
Vpb) {
continue; }
1507 &
Vpb->VolumeLabel[0],
1508 Vpb->VolumeLabelLength)) &&
1514 LargeSectorsPerFat) ))) {
1554 #pragma prefast( suppress: 28175, "touching Vpb is ok for a filesystem" ) 1571 if (*IrpVpb ==
Vpb) {
1598 DebugTrace(0,
Dbg,
"Truncate and reinitialize the volume file\n", 0);
1716 MountNewVolume =
TRUE;
1728 RootDirectoryFile =
Vcb->RootDcb->Specific.Dcb.DirectoryFile;
1754 if ( !MountNewVolume ) {
1762 FatCheckForDismount( IrpContext,
1766 IrpContext->Vcb =
NULL;
1768 }
else if (VolDo !=
NULL) {
1788 FatCheckForDismount( IrpContext,
1794 if ( WeClearedVerifyRequiredBit ==
TRUE ) {
1810 if (RootDirectoryFile !=
NULL) {
1812 #if (NTDDI_VERSION >= NTDDI_WIN8) 1905 LBO RootDirectoryLbo;
1906 ULONG RootDirectorySize;
1909 ULONG ChangeCount = 0;
1936 IrpContext->Vcb =
Vcb = &VolDo->
Vcb;
1961 #pragma prefast( push ) 1962 #pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" ) 1963 #pragma prefast( disable: 28193, "this will always wait" ) 1969 #pragma prefast( pop ) 1995 DebugTrace(0,
Dbg,
"RealDevice has already been verified\n", 0);
1997 VerifyAlreadyDone =
TRUE;
2010 Vcb->TargetDeviceObject,
2013 &PartitionInformation,
2032 Vcb->TargetDeviceObject,
2048 if (AllowRawMount) {
2058 if (
Iosb.Information !=
sizeof(
ULONG)) {
2072 Vcb->ChangeCount = ChangeCount;
2093 Vcb->TargetDeviceObject,
2109 if (AllowRawMount) {
2200 LargeSectorsPerFat) )) {
2238 RootDirectoryLbo = FatRootDirectoryLbo(&Bpb);
2240 if (!FatPerformVerifyDiskRead( IrpContext,
2247 try_return( Status = STATUS_WRONG_VOLUME );
2259 if (!LabelFound &&
Vpb->VolumeLabelLength > 0) {
2266 ULONG RootDirectoryCluster;
2307 RootDirectoryCluster,
2308 &RootDirectoryCluster );
2331 Vpb->VolumeLabelLength > 0) {
2358 if (!VerifyAlreadyDone) {
2361 ReleaseEntireVolume =
TRUE;
2387 if (!ReleaseEntireVolume) {
2389 ReleaseEntireVolume =
TRUE;
2396 FatPurgeReferencedFileObjects( IrpContext,
Vcb->RootDcb,
NoFlush );
2415 }
else if (!VerifyAlreadyDone) {
2422 if (!ReleaseEntireVolume) {
2424 ReleaseEntireVolume =
TRUE;
2436 FatPurgeReferencedFileObjects( IrpContext,
Vcb->RootDcb,
Flush );
2497 if (ReleaseEntireVolume) {
2611 }
else if (Bpb.
Fats == 0) {
2634 }
else if ((Bpb.
Media != 0xf0) &&
2635 (Bpb.
Media != 0xf8) &&
2636 (Bpb.
Media != 0xf9) &&
2637 (Bpb.
Media != 0xfb) &&
2638 (Bpb.
Media != 0xfc) &&
2639 (Bpb.
Media != 0xfd) &&
2640 (Bpb.
Media != 0xfe) &&
2641 (Bpb.
Media != 0xff) &&
2643 (Bpb.
Media != 0x01) &&
2644 (Bpb.
Media != 0xfa)))) {
2833 #if (NTDDI_VERSION >= NTDDI_WIN7) 2834 case FSCTL_REQUEST_OPLOCK:
2836 Status = FatOplockRequest( IrpContext,
Irp );
2841 Status = FatLockVolume( IrpContext,
Irp );
2851 Status = FatDismountVolume( IrpContext,
Irp );
2856 Status = FatDirtyVolume( IrpContext,
Irp );
2874 Status = FatQueryRetrievalPointers( IrpContext,
Irp );
2885 #if (NTDDI_VERSION >= NTDDI_WIN7) 2887 Status = FatGetRetrievalPointerBase( IrpContext,
Irp );
2890 case FSCTL_GET_BOOT_AREA_INFO:
2891 Status = FatGetBootAreaInfo( IrpContext,
Irp );
2896 Status = FatGetVolumeBitmap( IrpContext,
Irp );
2900 Status = FatGetRetrievalPointers( IrpContext,
Irp );
2904 Status = FatMoveFile( IrpContext,
Irp );
2912 Status = FatMarkHandle( IrpContext,
Irp );
2915 #if (NTDDI_VERSION >= NTDDI_WIN8) 2917 case FSCTL_SET_PURGE_FAILURE_MODE:
2918 Status = FatSetPurgeFailureMode( IrpContext,
Irp );
2924 #if (NTDDI_VERSION >= NTDDI_WIN7) 2980 ULONG OplockCount = 0;
2987 #if (NTDDI_VERSION >= NTDDI_WIN7) 3020 DebugTrace(-1,
Dbg,
"FatOplockRequest -> STATUS_INVALID_PARAMETER\n", 0);
3024 #if (NTDDI_VERSION >= NTDDI_WIN7) 3033 InputBuffer = (PREQUEST_OPLOCK_INPUT_BUFFER)
Irp->AssociatedIrp.SystemBuffer;
3045 DebugTrace(-1,
Dbg,
"FatOplockRequest -> STATUS_BUFFER_TOO_SMALL\n", 0);
3057 !FsRtlOplockIsSharedRequest(
Irp ))) {
3060 DebugTrace(-1,
Dbg,
"FatOplockRequest -> STATUS_INVALID_PARAMETER\n", 0);
3094 FatAcquireSharedVcb( IrpContext,
Fcb->
Vcb );
3096 FatAcquireExclusiveFcb( IrpContext,
Fcb );
3099 #if (NTDDI_VERSION >= NTDDI_WIN7) 3100 if (FsRtlOplockIsSharedRequest(
Irp )) {
3116 #if (NTDDI_VERSION >= NTDDI_WIN8) 3118 #elif (NTDDI_VERSION >= NTDDI_WIN7) 3119 OplockCount = (
ULONG) FsRtlAreThereCurrentOrInProgressFileLocks( &
Fcb->
Specific.
Fcb.FileLock );
3141 FatAcquireSharedFcb( IrpContext,
Fcb );
3143 #if (NTDDI_VERSION >= NTDDI_WIN7) 3159 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" ) 3437 FatLockVolumeInternal (
3499 FatPurgeReferencedFileObjects( IrpContext,
Vcb->RootDcb,
Flush );
3534 FatPurgeReferencedFileObjects( IrpContext,
Vcb->RootDcb,
Flush );
3571 (
Vcb->Vpb->ReferenceCount <= 2 + RemainingUserReferences) &&
3650 Vcb->FileObjectWithVcbLocked =
NULL;
3778 #pragma prefast( push ) 3779 #pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" ) 3780 #pragma prefast( disable: 28193, "this will always wait" ) 3786 #pragma prefast( pop ) 3840 #if (NTDDI_VERSION >= NTDDI_WIN8) 3842 FsRtlDismountComplete(
Vcb->TargetDeviceObject,
Status );
3958 DebugTrace(-1,
Dbg,
"FatDirtyVolume -> STATUS_SUCCESS\n", 0);
4014 if (
Irp->AssociatedIrp.SystemBuffer !=
NULL) {
4018 }
else if (
Irp->MdlAddress !=
NULL) {
4092 Irp->IoStatus.Information =
sizeof(
ULONG );
4262 if (
Vcb->First0x24BytesOfBootSector ==
NULL) {
4291 Vcb->First0x24BytesOfBootSector,
4294 Irp->IoStatus.Information = 0x24;
4308 FatInvalidateVolumes (
4365 #if defined(_WIN64) && defined(BUILD_WOW64_ENABLED) 4366 if (IoIs32bitProcess(
Irp )) {
4388 #
if defined(_WIN64) && defined(BUILD_WOW64_ENABLED)
4400 (
PVOID *)&FileToMarkBad,
4423 DeviceToMarkBad = FileToMarkBad->DeviceObject;
4433 #pragma prefast( push ) 4434 #pragma prefast( disable: 28137, "prefast wants the wait to be a constant, but that isn't possible for the way fastfat is designed" ) 4435 #pragma prefast( disable: 28193, "this will always wait" ) 4441 #pragma prefast( pop ) 4460 Links = Links->
Flink;
4481 #pragma prefast( push ) 4482 #pragma prefast( disable: 28175, "touching Vpb is ok for a filesystem" ) 4485 if (ExistingVcb->
Vpb == DeviceToMarkBad->Vpb) {
4495 NewVpb = ExistingVcb->
SwapVpb;
4505 DeviceToMarkBad->Vpb = NewVpb;
4511 #pragma prefast( pop ) 4542 FatPurgeReferencedFileObjects( &IrpContext,
4548 VcbDeleted = FatCheckForDismount( &IrpContext, ExistingVcb,
FALSE );
4566 DebugTrace(-1,
Dbg,
"FatInvalidateVolumes -> STATUS_SUCCESS\n", 0);
4639 Vcb->TargetDeviceObject,
4641 NumberOfBytesToRead,
4684 if (ReturnOnError) {
4708 FatQueryRetrievalPointers (
4794 RequestedMapSize =
IrpSp->
Parameters.FileSystemControl.Type3InputBuffer;
4795 MappingPairs =
Irp->UserBuffer;
4801 FatAcquireExclusiveFcb( IrpContext,
Fcb );
4809 FatVerifyFcb( IrpContext,
Fcb );
4815 if ((*RequestedMapSize).QuadPart >
Fcb->
Header.FileSize.QuadPart) {
4829 RequestedMapSize->
LowPart - 1,
4854 MapSize = RequestedMapSize->
LowPart;
4865 (*MappingPairs)[
i*2 + 1 ].QuadPart =
Lbo;
4870 (*MappingPairs)[
i*2 + 0 ].QuadPart = 0;
4952 Buffer =
Irp->AssociatedIrp.SystemBuffer;
5048 ULONG TotalClusters;
5049 ULONG DesiredClusters;
5050 ULONG StartingCluster;
5051 ULONG EndingCluster;
5065 DebugTrace(+1,
Dbg,
"FatGetVolumeBitmap, FsControlCode = %08lx\n",
5113 TotalClusters =
Vcb->AllocationSupport.NumberOfClusters;
5148 StartingCluster = StartingLcn.
LowPart & ~7;
5158 DesiredClusters = TotalClusters - StartingCluster;
5192 if (
Vcb->NumberOfWindows == 1) {
5201 (
PUCHAR)
Vcb->FreeClusterBitMap.Buffer + StartingCluster/8,
5217 EndingCluster = StartingCluster + (
BytesToCopy * 8);
5223 if (EndingCluster > TotalClusters) {
5225 EndingCluster = TotalClusters;
5230 StartingCluster + 2,
5231 EndingCluster + 2 - 1,
5268 FatGetRetrievalPointers (
5304 ULONG ClusterShift = 0;
5330 DebugTrace(+1,
Dbg,
"FatGetRetrievalPointers, FsControlCode = %08lx\n",
5409 FatVerifyFcb( IrpContext,
FcbOrDcb );
5417 FatLookupFileAllocationSize( IrpContext,
FcbOrDcb );
5433 ClusterShift =
Vcb->AllocationSupport.LogOfBytesPerCluster;
5436 #pragma prefast( suppress:28931, "calculate it anyway, in case someone adds code that uses this in the future" ) 5457 ClusterShift =
Vcb->AllocationSupport.LogOfBytesPerCluster;
5471 McbToUse = &
Vcb->BadBlockMcb;
5515 StartingVcn.
LowPart << ClusterShift,
5521 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" ) 5576 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" ) 5596 OutputBuffer->StartingVcn.QuadPart = Vcn >> ClusterShift;
5643 DebugTrace(-1,
Dbg,
"FatGetRetrievalPointers -> VOID\n", 0);
5656 FatMoveFileNeedsWriteThrough (