ReactOS 0.4.15-dev-7953-g1f49173
fsctrl.c File Reference
#include "fatprocs.h"
Include dependency graph for fsctrl.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (FAT_BUG_CHECK_FSCTRL)
 
#define Dbg   (DEBUG_TRACE_FSCTRL)
 
#define MCB_SCALE_LOG2   (Vcb->AllocationSupport.LogOfBytesPerSector)
 
#define MCB_SCALE   (1 << MCB_SCALE_LOG2)
 
#define MCB_SCALE_MODULO   (MCB_SCALE - 1)
 

Functions

 _Requires_lock_held_ (_Global_critical_region_)
 
BOOLEAN FatAddMcbEntry (IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, IN LBO Lbo, IN ULONG SectorCount)
 
BOOLEAN FatLookupMcbEntry (IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, OUT PLBO Lbo, OUT PULONG ByteCount OPTIONAL, OUT PULONG Index OPTIONAL)
 
BOOLEAN FatLookupLastMcbEntry (IN PVCB Vcb, IN PLARGE_MCB Mcb, OUT PVBO Vbo, OUT PLBO Lbo, OUT PULONG Index)
 
BOOLEAN FatGetNextMcbEntry (IN PVCB Vcb, IN PLARGE_MCB Mcb, IN ULONG RunIndex, OUT PVBO Vbo, OUT PLBO Lbo, OUT PULONG ByteCount)
 
VOID FatRemoveMcbEntry (IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, IN ULONG SectorCount)
 
 _Function_class_ (IRP_MJ_FILE_SYSTEM_CONTROL)
 
BOOLEAN FatIsBootSectorFat (IN PPACKED_BOOT_SECTOR BootSector)
 
BOOLEAN FatIsMediaWriteProtected (IN PIRP_CONTEXT IrpContext, IN PDEVICE_OBJECT TargetDeviceObject)
 
NTSTATUS FatUnlockVolume (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
 
NTSTATUS FatUnlockVolumeInternal (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_OBJECT FileObject OPTIONAL)
 
NTSTATUS FatIsVolumeDirty (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
 
NTSTATUS FatIsVolumeMounted (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
 
NTSTATUS FatIsPathnameValid (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
 
NTSTATUS FatQueryBpb (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
 
BOOLEAN FatPerformVerifyDiskRead (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PVOID Buffer, IN LBO Lbo, IN ULONG NumberOfBytesToRead, IN BOOLEAN ReturnOnError)
 
NTSTATUS FatGetStatistics (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
 
VOID FatComputeMoveFileSplicePoints (IN PIRP_CONTEXT IrpContext, IN PFCB FcbOrDcb, IN ULONG FileOffset, IN ULONG TargetCluster, IN ULONG BytesToReallocate, OUT PULONG FirstSpliceSourceCluster, OUT PULONG FirstSpliceTargetCluster, OUT PULONG SecondSpliceSourceCluster, OUT PULONG SecondSpliceTargetCluster, IN OUT PLARGE_MCB SourceMcb)
 
NTSTATUS FatAllowExtendedDasdIo (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
 
NTSTATUS FatSearchBufferForLabel (IN PIRP_CONTEXT IrpContext, IN PVPB Vpb, IN PVOID Buffer, IN ULONG Size, OUT PBOOLEAN LabelFound)
 
VOID FatVerifyLookupFatEntry (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN ULONG FatIndex, IN OUT PULONG FatEntry)
 
NTSTATUS FatSetZeroOnDeallocate (__in PIRP_CONTEXT IrpContext, __in PIRP Irp)
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (FAT_BUG_CHECK_FSCTRL)

Definition at line 24 of file fsctrl.c.

◆ Dbg

#define Dbg   (DEBUG_TRACE_FSCTRL)

Definition at line 30 of file fsctrl.c.

◆ MCB_SCALE

#define MCB_SCALE   (1 << MCB_SCALE_LOG2)

◆ MCB_SCALE_LOG2

#define MCB_SCALE_LOG2   (Vcb->AllocationSupport.LogOfBytesPerSector)

◆ MCB_SCALE_MODULO

#define MCB_SCALE_MODULO   (MCB_SCALE - 1)

Function Documentation

◆ _Function_class_()

_Function_class_ ( IRP_MJ_FILE_SYSTEM_CONTROL  )

Definition at line 635 of file fsctrl.c.

663{
666 PIRP_CONTEXT IrpContext = NULL;
667
669
670 PAGED_CODE();
671 UNREFERENCED_PARAMETER( VolumeDeviceObject );
672
673 DebugTrace(+1, Dbg,"FatFsdFileSystemControl\n", 0);
674
675 //
676 // Call the common FileSystem Control routine, with blocking allowed if
677 // synchronous. This opeation needs to special case the mount
678 // and verify suboperations because we know they are allowed to block.
679 // We identify these suboperations by looking at the file object field
680 // and seeing if its null.
681 //
682
684
685 Wait = TRUE;
686
687 } else {
688
689 Wait = CanFsdWait( Irp );
690 }
691
693
695
696 _SEH2_TRY {
697
699
701
702 //
703 // We need to made a special check here for the InvalidateVolumes
704 // FSCTL as that comes in with a FileSystem device object instead
705 // of a volume device object.
706 //
707
711 (IrpSp->Parameters.FileSystemControl.FsControlCode ==
713
714 Status = FatInvalidateVolumes( Irp );
715
716 } else {
717
718 IrpContext = FatCreateIrpContext( Irp, Wait );
719
720 Status = FatCommonFileSystemControl( IrpContext, Irp );
721 }
722
724
725 //
726 // We had some trouble trying to perform the requested
727 // operation, so we'll abort the I/O request with
728 // the error status that we get back from the
729 // execption code
730 //
731
732 Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
733 } _SEH2_END;
734
735 if (TopLevel) { IoSetTopLevelIrp( NULL ); }
736
738
739 //
740 // And return to our caller
741 //
742
743 DebugTrace(-1, Dbg, "FatFsdFileSystemControl -> %08lx\n", Status);
744
745 return Status;
746}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define CanFsdWait(I)
Definition: cdprocs.h:2001
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define Dbg
Definition: fsctrl.c:30
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2417
#define FatDeviceIsFatFsdo(D)
Definition: fatprocs.h:3095
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2301
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
Status
Definition: gdiplustypes.h:25
#define FSCTL_INVALIDATE_VOLUMES
Definition: nt_native.h:847
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
union _IO_STACK_LOCATION::@1564 Parameters
struct _IO_STACK_LOCATION::@3978::@3993 FileSystemControl
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4403

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 36 of file fsctrl.c.

341{
342 LBO Lbo;
343 ULONG Index = 0;
344 LONGLONG llVbo = 0;
345
347
348 while (FsRtlGetNextLargeMcbEntry(Mcb, Index, &llVbo, &Lbo, ByteCount)) {
349 *Vbo = (VBO)llVbo;
350 if (((ULONG)Lbo) == -1) {
351 return FALSE;
352 }
353
354 Index++;
355 }
356
357 *Vbo = (VBO)llVbo;
358
359 return TRUE;
360}
#define FALSE
Definition: types.h:117
LONGLONG LBO
Definition: fat.h:34
ULONG32 VBO
Definition: fat.h:38
IN PFCB IN VBO OUT PLBO Lbo
Definition: fatprocs.h:308
IN PFCB IN VBO Vbo
Definition: fatprocs.h:307
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:348
BOOLEAN NTAPI FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, IN ULONG RunIndex, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn, OUT PLONGLONG SectorCount)
Definition: largemcb.c:392
#define Vcb
Definition: cdprocs.h:1415
int64_t LONGLONG
Definition: typedefs.h:68
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1099

◆ FatAddMcbEntry()

BOOLEAN FatAddMcbEntry ( IN PVCB  Vcb,
IN PLARGE_MCB  Mcb,
IN VBO  Vbo,
IN LBO  Lbo,
IN ULONG  SectorCount 
)

Definition at line 364 of file fsctrl.c.

372{
374#if DBG
375 VBO SparseVbo;
376 LONGLONG SparseByteCount;
377#endif
378
379 PAGED_CODE();
380
381 if (SectorCount) {
382
383 //
384 // Round up sectors, but be careful as SectorCount approaches 4Gb.
385 // Note that for x>0, (x+m-1)/m = ((x-1)/m)+(m/m) = ((x-1)/m)+1
386 //
387
388 SectorCount--;
390 SectorCount++;
391 }
392
395
396 NT_ASSERT( SectorCount != 0 );
397
398 if (Mcb != &Vcb->DirtyFatMcb) {
399 NT_ASSERT( FatNonSparseMcb( Vcb, Mcb, &SparseVbo, &SparseByteCount ) ||
400 ((SparseVbo == Vbo) && (SparseByteCount == SectorCount )) );
401 }
402
404 ((LONGLONG) Vbo),
405 ((LONGLONG) Lbo),
406 ((LONGLONG) SectorCount) );
407
408 if (Mcb != &Vcb->DirtyFatMcb) {
409 NT_ASSERT( FatNonSparseMcb( Vcb, Mcb, &SparseVbo, &SparseByteCount ) ||
410 ((SparseVbo == Vbo) && (SparseByteCount == SectorCount )) );
411 }
412
413 return Result;
414}
#define MCB_SCALE_LOG2
BOOLEAN NTAPI FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG Lbn, IN LONGLONG SectorCount)
Definition: largemcb.c:288
ULONG SectorCount
Definition: part_xbox.c:31
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by _Requires_lock_held_(), FatComputeMoveFileSplicePoints(), FatExamineFatEntries(), and FatSetFatRun().

◆ FatAllowExtendedDasdIo()

NTSTATUS FatAllowExtendedDasdIo ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp 
)

Definition at line 7022 of file fsctrl.c.

7043{
7045 PVCB Vcb;
7046 PFCB Fcb;
7047 PCCB Ccb;
7048
7049 PAGED_CODE();
7050
7051 //
7052 // Get the current Irp stack location and save some references.
7053 //
7054
7056
7057 //
7058 // Extract and decode the file object and check for type of open.
7059 //
7060
7062
7065 }
7066
7068
7070
7071 DebugTrace(-1, Dbg, "FatAllowExtendedDasdIo -> %08lx\n", STATUS_INVALID_PARAMETER);
7073 }
7074
7076
7077 FatCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
7078 return STATUS_SUCCESS;
7079}
@ UserVolumeOpen
Definition: cdprocs.h:575
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define CCB_FLAG_ALLOW_EXTENDED_DASD_IO
Definition: cdstruc.h:1108
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2633
#define CCB_FLAG_MANAGE_VOLUME_ACCESS
Definition: fatstruc.h:1338
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: cdstruc.h:1067
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:536
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
Definition: cdstruc.h:498
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

◆ FatComputeMoveFileSplicePoints()

VOID FatComputeMoveFileSplicePoints ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  FcbOrDcb,
IN ULONG  FileOffset,
IN ULONG  TargetCluster,
IN ULONG  BytesToReallocate,
OUT PULONG  FirstSpliceSourceCluster,
OUT PULONG  FirstSpliceTargetCluster,
OUT PULONG  SecondSpliceSourceCluster,
OUT PULONG  SecondSpliceTargetCluster,
IN OUT PLARGE_MCB  SourceMcb 
)

Definition at line 6822 of file fsctrl.c.

6874{
6875 VBO SourceVbo;
6876 LBO SourceLbo;
6877 ULONG SourceIndex;
6878 ULONG SourceBytesInRun;
6879 ULONG SourceBytesRemaining;
6880
6881 ULONG SourceMcbVbo = 0;
6882 ULONG SourceMcbBytesInRun = 0;
6883
6884 PVCB Vcb;
6886
6887 PAGED_CODE();
6888
6889 Vcb = FcbOrDcb->Vcb;
6890
6891 //
6892 // Get information on the final cluster in the previous allocation and
6893 // prepare to enumerate it in the follow loop.
6894 //
6895
6896 if (FileOffset == 0) {
6897
6898 SourceIndex = 0;
6899 *FirstSpliceSourceCluster = 0;
6901 0,
6902 &SourceVbo,
6903 &SourceLbo,
6904 &SourceBytesInRun );
6905
6906 } else {
6907
6909 FileOffset-1,
6910 &SourceLbo,
6911 &SourceBytesInRun,
6912 &SourceIndex);
6913
6914 *FirstSpliceSourceCluster = FatGetIndexFromLbo( Vcb, SourceLbo );
6915
6916 if ((Result) && (SourceBytesInRun == 1)) {
6917
6918 SourceIndex += 1;
6920 SourceIndex,
6921 &SourceVbo,
6922 &SourceLbo,
6923 &SourceBytesInRun);
6924
6925 } else {
6926
6927 SourceVbo = FileOffset;
6928 SourceLbo += 1;
6929 SourceBytesInRun -= 1;
6930 }
6931 }
6932
6933 //
6934 // Run should always be present, but don't bugcheck in the case where it's not.
6935 //
6936
6937 if (!Result) {
6938
6939 NT_ASSERT( FALSE);
6941 }
6942
6943 //
6944 // At this point the variables:
6945 //
6946 // - SourceIndex - SourceLbo - SourceBytesInRun -
6947 //
6948 // all correctly decribe the allocation to be removed. In the loop
6949 // below we will start here and continue enumerating the Mcb runs
6950 // until we are finished with the allocation to be relocated.
6951 //
6952
6953 *FirstSpliceTargetCluster = TargetCluster;
6954
6955 *SecondSpliceSourceCluster =
6956 *FirstSpliceTargetCluster +
6957 (BytesToReallocate >> Vcb->AllocationSupport.LogOfBytesPerCluster) - 1;
6958
6959 for (SourceBytesRemaining = BytesToReallocate, SourceMcbVbo = 0;
6960
6961 SourceBytesRemaining > 0;
6962
6963 SourceIndex += 1,
6964 SourceBytesRemaining -= SourceMcbBytesInRun,
6965 SourceMcbVbo += SourceMcbBytesInRun) {
6966
6967 if (SourceMcbVbo != 0) {
6968#ifdef _MSC_VER
6969#pragma prefast( suppress:28931, "needed for debug build" )
6970#endif
6972 SourceIndex,
6973 &SourceVbo,
6974 &SourceLbo,
6975 &SourceBytesInRun );
6976 NT_ASSERT( Result);
6977 }
6978
6979 NT_ASSERT( SourceVbo == SourceMcbVbo + FileOffset );
6980
6981 SourceMcbBytesInRun =
6982 SourceBytesInRun < SourceBytesRemaining ?
6983 SourceBytesInRun : SourceBytesRemaining;
6984
6985 FatAddMcbEntry( Vcb, SourceMcb,
6986 SourceMcbVbo,
6987 SourceLbo,
6988 SourceMcbBytesInRun );
6989 }
6990
6991 //
6992 // Now compute the cluster of the target of the second
6993 // splice. If the final run in the above loop was
6994 // more than we needed, then we can just do arithmetic,
6995 // otherwise we have to look up the next run.
6996 //
6997
6998 if (SourceMcbBytesInRun < SourceBytesInRun) {
6999
7000 *SecondSpliceTargetCluster =
7001 FatGetIndexFromLbo( Vcb, SourceLbo + SourceMcbBytesInRun );
7002
7003 } else {
7004
7006 SourceIndex,
7007 &SourceVbo,
7008 &SourceLbo,
7009 &SourceBytesInRun )) {
7010
7011 *SecondSpliceTargetCluster = FatGetIndexFromLbo( Vcb, SourceLbo );
7012
7013 } else {
7014
7015 *SecondSpliceTargetCluster = FAT_CLUSTER_LAST;
7016 }
7017 }
7018}
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define FatGetIndexFromLbo(VCB, LBO)
Definition: fat.h:566
#define FAT_CLUSTER_LAST
Definition: fat.h:258
BOOLEAN FatLookupMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, OUT PLBO Lbo, OUT PULONG ByteCount OPTIONAL, OUT PULONG Index OPTIONAL)
Definition: fsctrl.c:418
BOOLEAN FatGetNextMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN ULONG RunIndex, OUT PVBO Vbo, OUT PLBO Lbo, OUT PULONG ByteCount)
Definition: fsctrl.c:541
BOOLEAN FatAddMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, IN LBO Lbo, IN ULONG SectorCount)
Definition: fsctrl.c:364
IN PFCB FcbOrDcb
Definition: fatprocs.h:306
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2977
PVCB Vcb
Definition: cdstruc.h:933
CD_MCB Mcb
Definition: cdstruc.h:1016
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168

◆ FatGetNextMcbEntry()

BOOLEAN FatGetNextMcbEntry ( IN PVCB  Vcb,
IN PLARGE_MCB  Mcb,
IN ULONG  RunIndex,
OUT PVBO  Vbo,
OUT PLBO  Lbo,
OUT PULONG  ByteCount 
)

Definition at line 541 of file fsctrl.c.

550{
551 BOOLEAN Results;
552 LONGLONG LiVbo;
553 LONGLONG LiLbo;
554 LONGLONG LiSectorCount;
555
556 PAGED_CODE();
557
558 LiVbo = LiLbo = 0;
559
561 RunIndex,
562 &LiVbo,
563 &LiLbo,
564 &LiSectorCount );
565
566 if (Results) {
567
568 *Vbo = ((VBO) LiVbo) << MCB_SCALE_LOG2;
569
570 if (((ULONG) LiLbo) != -1) {
571
572 *Lbo = ((LBO) LiLbo) << MCB_SCALE_LOG2;
573
574 } else {
575
576 *Lbo = 0;
577 }
578
579 *ByteCount = ((ULONG) LiSectorCount) << MCB_SCALE_LOG2;
580
581 if ((*ByteCount == 0) && (LiSectorCount != 0)) {
582
583 //
584 // If 'ByteCount' overflows, then this is likely a file of
585 // max supported size (2^32 - 1) in one contiguous run.
586 //
587
588 NT_ASSERT( RunIndex == 0 );
589
590 *ByteCount = 0xFFFFFFFF;
591 }
592 }
593
594 return Results;
595}
_Must_inspect_result_ _In_ ULONG RunIndex
Definition: fsrtlfuncs.h:538

Referenced by _Requires_lock_held_(), FatComputeMoveFileSplicePoints(), and FatPagingFileIo().

◆ FatGetStatistics()

NTSTATUS FatGetStatistics ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp 
)

Definition at line 4892 of file fsctrl.c.

4914{
4917 PVCB Vcb;
4918
4921 ULONG StatsSize;
4923
4924 PAGED_CODE();
4925
4927
4928 DebugTrace(+1, Dbg, "FatGetStatistics...\n", 0);
4929
4930 //
4931 // Extract the buffer
4932 //
4933
4934 BufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
4935
4936 //
4937 // Get a pointer to the output buffer.
4938 //
4939
4940 Buffer = Irp->AssociatedIrp.SystemBuffer;
4941
4942 //
4943 // Make sure the buffer is big enough for at least the common part.
4944 //
4945
4946 if (BufferLength < sizeof(FILESYSTEM_STATISTICS)) {
4947
4949
4950 DebugTrace(-1, Dbg, "FatGetStatistics -> %08lx\n", STATUS_BUFFER_TOO_SMALL );
4951
4953 }
4954
4955 //
4956 // Now see how many bytes we can copy.
4957 //
4958
4959 StatsSize = sizeof(FILE_SYSTEM_STATISTICS) * FatData.NumberProcessors;
4960
4961 if (BufferLength < StatsSize) {
4962
4965
4966 } else {
4967
4968 BytesToCopy = StatsSize;
4970 }
4971
4972 //
4973 // Get the Vcb.
4974 //
4975
4977
4978 //
4979 // Fill in the output buffer
4980 //
4981
4982 RtlCopyMemory( Buffer, Vcb->Statistics, BytesToCopy );
4983
4984 Irp->IoStatus.Information = BytesToCopy;
4985
4986 FatCompleteRequest( IrpContext, Irp, Status );
4987
4988 DebugTrace(-1, Dbg, "FatGetStatistics -> %08lx\n", Status);
4989
4990 return Status;
4991}
VOLUME_DEVICE_OBJECT * PVOLUME_DEVICE_OBJECT
Definition: cdstruc.h:769
Definition: bufpool.h:45
FAT_DATA FatData
Definition: fatdata.c:56
struct _FILE_SYSTEM_STATISTICS FILE_SYSTEM_STATISTICS
if(dx< 0)
Definition: linetemp.h:194
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
ULONG NumberProcessors
Definition: fatstruc.h:81
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771

◆ FatIsBootSectorFat()

BOOLEAN FatIsBootSectorFat ( IN PPACKED_BOOT_SECTOR  BootSector)

Definition at line 2522 of file fsctrl.c.

2542{
2544 BIOS_PARAMETER_BLOCK Bpb = {0};
2545
2546 DebugTrace(+1, Dbg, "FatIsBootSectorFat, BootSector = %p\n", BootSector);
2547
2548 //
2549 // The result is true unless we decide that it should be false
2550 //
2551
2552 Result = TRUE;
2553
2554 //
2555 // Unpack the bios and then test everything
2556 //
2557
2558 FatUnpackBios( &Bpb, &BootSector->PackedBpb );
2559 if (Bpb.Sectors != 0) { Bpb.LargeSectors = 0; }
2560
2561 if ((BootSector->Jump[0] != 0xe9) &&
2562 (BootSector->Jump[0] != 0xeb) &&
2563 (BootSector->Jump[0] != 0x49)) {
2564
2565 Result = FALSE;
2566
2567 //
2568 // Enforce some sanity on the sector size (easy check)
2569 //
2570
2571 } else if ((Bpb.BytesPerSector != 128) &&
2572 (Bpb.BytesPerSector != 256) &&
2573 (Bpb.BytesPerSector != 512) &&
2574 (Bpb.BytesPerSector != 1024) &&
2575 (Bpb.BytesPerSector != 2048) &&
2576 (Bpb.BytesPerSector != 4096)) {
2577
2578 Result = FALSE;
2579
2580 //
2581 // Likewise on the clustering.
2582 //
2583
2584 } else if ((Bpb.SectorsPerCluster != 1) &&
2585 (Bpb.SectorsPerCluster != 2) &&
2586 (Bpb.SectorsPerCluster != 4) &&
2587 (Bpb.SectorsPerCluster != 8) &&
2588 (Bpb.SectorsPerCluster != 16) &&
2589 (Bpb.SectorsPerCluster != 32) &&
2590 (Bpb.SectorsPerCluster != 64) &&
2591 (Bpb.SectorsPerCluster != 128)) {
2592
2593 Result = FALSE;
2594
2595 //
2596 // Likewise on the reserved sectors (must reflect at least the boot sector!)
2597 //
2598
2599 } else if (Bpb.ReservedSectors == 0) {
2600
2601 Result = FALSE;
2602
2603 //
2604 // No FATs? Wrong ...
2605 //
2606
2607 } else if (Bpb.Fats == 0) {
2608
2609 Result = FALSE;
2610
2611 //
2612 // Prior to DOS 3.2 might contains value in both of Sectors and
2613 // Sectors Large.
2614 //
2615
2616 } else if ((Bpb.Sectors == 0) && (Bpb.LargeSectors == 0)) {
2617
2618 Result = FALSE;
2619
2620 //
2621 // Check that FAT32 (SectorsPerFat == 0) claims some FAT space and
2622 // is of a version we recognize, currently Version 0.0.
2623 //
2624
2625 } else if (Bpb.SectorsPerFat == 0 && ( Bpb.LargeSectorsPerFat == 0 ||
2626 Bpb.FsVersion != 0 )) {
2627
2628 Result = FALSE;
2629
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) &&
2638 (!FatData.FujitsuFMR || ((Bpb.Media != 0x00) &&
2639 (Bpb.Media != 0x01) &&
2640 (Bpb.Media != 0xfa)))) {
2641
2642 Result = FALSE;
2643
2644 //
2645 // If this isn't FAT32, then there better be a claimed root directory
2646 // size here ...
2647 //
2648
2649 } else if (Bpb.SectorsPerFat != 0 && Bpb.RootEntries == 0) {
2650
2651 Result = FALSE;
2652
2653 //
2654 // If this is FAT32 (i.e., extended BPB), look for and refuse to mount
2655 // mirror-disabled volumes. If we did, we would need to only write to
2656 // the FAT# indicated in the ActiveFat field. The only user of this is
2657 // the FAT->FAT32 converter after the first pass of protected mode work
2658 // (booting into realmode) and NT should absolutely not be attempting
2659 // to mount such an in-transition volume.
2660 //
2661
2662 } else if (Bpb.SectorsPerFat == 0 && Bpb.MirrorDisabled) {
2663
2664 Result = FALSE;
2665 }
2666
2667 DebugTrace(-1, Dbg, "FatIsBootSectorFat -> %08lx\n", Result);
2668
2669 return Result;
2670}
#define FatUnpackBios(Bios, Pbios)
Definition: fat.h:136
USHORT ReservedSectors
Definition: fat.h:106
USHORT BytesPerSector
Definition: fat.h:104
USHORT FsVersion
Definition: fat.h:126
USHORT Sectors
Definition: fat.h:109
ULONG MirrorDisabled
Definition: fat.h:122
ULONG32 LargeSectors
Definition: fat.h:115
ULONG32 LargeSectorsPerFat
Definition: fat.h:116
USHORT RootEntries
Definition: fat.h:108
UCHAR SectorsPerCluster
Definition: fat.h:105
USHORT SectorsPerFat
Definition: fat.h:111
BOOLEAN FujitsuFMR
Definition: fatstruc.h:95

◆ FatIsMediaWriteProtected()

BOOLEAN FatIsMediaWriteProtected ( IN PIRP_CONTEXT  IrpContext,
IN PDEVICE_OBJECT  TargetDeviceObject 
)

Definition at line 2678 of file fsctrl.c.

2699{
2700 PIRP Irp;
2701 KEVENT Event;
2704
2705 PAGED_CODE();
2706 UNREFERENCED_PARAMETER( IrpContext );
2707
2708 //
2709 // Query the partition table
2710 //
2711
2713
2714 //
2715 // See if the media is write protected. On success or any kind
2716 // of error (possibly illegal device function), assume it is
2717 // writeable, and only complain if he tells us he is write protected.
2718 //
2719
2722 NULL,
2723 0,
2724 NULL,
2725 0,
2726 FALSE,
2727 &Event,
2728 &Iosb );
2729
2730 //
2731 // Just return FALSE in the unlikely event we couldn't allocate an Irp.
2732 //
2733
2734 if ( Irp == NULL ) {
2735
2736 return FALSE;
2737 }
2738
2740
2742
2743 if ( Status == STATUS_PENDING ) {
2744
2746 Executive,
2747 KernelMode,
2748 FALSE,
2750
2751 Status = Iosb.Status;
2752 }
2753
2755}
#define VOID
Definition: acefi.h:82
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
return Iosb
Definition: create.c:4402
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1674
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823
@ Executive
Definition: ketypes.h:415

◆ FatIsPathnameValid()

NTSTATUS FatIsPathnameValid ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp 
)

Definition at line 4168 of file fsctrl.c.

4195{
4196 PAGED_CODE();
4197
4198 DebugTrace(+1, Dbg, "FatIsPathnameValid...\n", 0);
4199
4200 FatCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
4201
4202 DebugTrace(-1, Dbg, "FatIsPathnameValid -> %08lx\n", STATUS_SUCCESS);
4203
4204 return STATUS_SUCCESS;
4205}

◆ FatIsVolumeDirty()

NTSTATUS FatIsVolumeDirty ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp 
)

Definition at line 3965 of file fsctrl.c.

3986{
3988
3990 PVCB Vcb;
3991 PFCB Fcb;
3992 PCCB Ccb;
3993
3995
3996 PAGED_CODE();
3997
3998 //
3999 // Get the current stack location and extract the output
4000 // buffer information.
4001 //
4002
4004
4005 //
4006 // Get a pointer to the output buffer. Look at the system buffer field in the
4007 // irp first. Then the Irp Mdl.
4008 //
4009
4010 if (Irp->AssociatedIrp.SystemBuffer != NULL) {
4011
4012 VolumeState = Irp->AssociatedIrp.SystemBuffer;
4013
4014 } else if (Irp->MdlAddress != NULL) {
4015
4016 VolumeState = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, LowPagePriority | MdlMappingNoExecute );
4017
4018 if (VolumeState == NULL) {
4019
4022 }
4023
4024 } else {
4025
4028 }
4029
4030 //
4031 // Make sure the output buffer is large enough and then initialize
4032 // the answer to be that the volume isn't dirty.
4033 //
4034
4035 if (IrpSp->Parameters.FileSystemControl.OutputBufferLength < sizeof(ULONG)) {
4036
4039 }
4040
4041 *VolumeState = 0;
4042
4043 //
4044 // Decode the file object
4045 //
4046
4048
4049 if (TypeOfOpen != UserVolumeOpen) {
4050
4053 }
4054
4055 if (Vcb->VcbCondition != VcbGood) {
4056
4059 }
4060
4061 //
4062 // Disable PopUps, we want to return any error.
4063 //
4064
4065 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS);
4066
4067 //
4068 // Verify the Vcb. We want to make double sure that this volume
4069 // is around so that we know our information is good.
4070 //
4071
4072 FatVerifyVcb( IrpContext, Vcb );
4073
4074 //
4075 // Now set the returned information. We can avoid probing the disk since
4076 // we know our internal state is in sync.
4077 //
4078
4079 if ( FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY) ) {
4080
4082 }
4083
4084 Irp->IoStatus.Information = sizeof( ULONG );
4085
4086 FatCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
4087 return STATUS_SUCCESS;
4088}
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:589
enum _TYPE_OF_OPEN TYPE_OF_OPEN
#define IRP_CONTEXT_FLAG_DISABLE_POPUPS
Definition: cdstruc.h:1222
VOID FatVerifyVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:270
IN PVCB IN FAT_VOLUME_STATE VolumeState
Definition: fatprocs.h:1998
#define VCB_STATE_FLAG_MOUNTED_DIRTY
Definition: fatstruc.h:562
@ VcbGood
Definition: fatstruc.h:223
@ LowPagePriority
Definition: imports.h:55
#define VOLUME_IS_DIRTY
Definition: ntifs_ex.h:330
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:747
uint32_t * PULONG
Definition: typedefs.h:59
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)

◆ FatIsVolumeMounted()

NTSTATUS FatIsVolumeMounted ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp 
)

Definition at line 4096 of file fsctrl.c.

4117{
4119
4121
4122 PVCB Vcb = NULL;
4123 PFCB Fcb;
4124 PCCB Ccb;
4125
4126 PAGED_CODE();
4127
4129
4131
4132 DebugTrace(+1, Dbg, "FatIsVolumeMounted...\n", 0);
4133
4134 //
4135 // Decode the file object.
4136 //
4137
4139
4140 NT_ASSERT( Vcb != NULL );
4142
4143 //
4144 // Disable PopUps, we want to return any error.
4145 //
4146
4147 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS);
4148
4149 //
4150 // Verify the Vcb.
4151 //
4152
4153 FatVerifyVcb( IrpContext, Vcb );
4154
4155 FatCompleteRequest( IrpContext, Irp, Status );
4156
4157 DebugTrace(-1, Dbg, "FatIsVolumeMounted -> %08lx\n", Status);
4158
4159 return Status;
4160}
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901

◆ FatLookupLastMcbEntry()

BOOLEAN FatLookupLastMcbEntry ( IN PVCB  Vcb,
IN PLARGE_MCB  Mcb,
OUT PVBO  Vbo,
OUT PLBO  Lbo,
OUT PULONG Index  OPTIONAL 
)

Definition at line 494 of file fsctrl.c.

502{
503 BOOLEAN Results;
504 LONGLONG LiVbo;
505 LONGLONG LiLbo;
506 ULONG LocalIndex;
507
508 PAGED_CODE();
509
510 LiVbo = LiLbo = 0;
511 LocalIndex = 0;
512
514 &LiVbo,
515 &LiLbo,
516 &LocalIndex );
517
518 *Vbo = ((VBO) LiVbo) << MCB_SCALE_LOG2;
519
520 if (((ULONG) LiLbo) != -1) {
521
522 *Lbo = ((LBO) LiLbo) << MCB_SCALE_LOG2;
523
524 *Lbo += (MCB_SCALE - 1);
525 *Vbo += (MCB_SCALE - 1);
526
527 } else {
528
529 *Lbo = 0;
530 }
531
532 if (Index) {
533 *Index = LocalIndex;
534 }
535
536 return Results;
537}
#define MCB_SCALE
BOOLEAN NTAPI FsRtlLookupLastLargeMcbEntryAndIndex(IN PLARGE_MCB OpaqueMcb, OUT PLONGLONG LargeVbn, OUT PLONGLONG LargeLbn, OUT PULONG Index)
Definition: largemcb.c:671

Referenced by _Requires_lock_held_().

◆ FatLookupMcbEntry()

BOOLEAN FatLookupMcbEntry ( IN PVCB  Vcb,
IN PLARGE_MCB  Mcb,
IN VBO  Vbo,
OUT PLBO  Lbo,
OUT PULONG ByteCount  OPTIONAL,
OUT PULONG Index  OPTIONAL 
)

Definition at line 418 of file fsctrl.c.

426{
427 BOOLEAN Results;
428 LONGLONG LiLbo;
429 LONGLONG LiSectorCount;
431
432 LiLbo = 0;
433 LiSectorCount = 0;
434
436
437 Results = FsRtlLookupLargeMcbEntry( Mcb,
438 (Vbo >> MCB_SCALE_LOG2),
439 &LiLbo,
440 ARGUMENT_PRESENT(ByteCount) ? &LiSectorCount : NULL,
441 NULL,
442 NULL,
443 Index );
444
445 if ((ULONG) LiLbo != -1) {
446
447 *Lbo = (((LBO) LiLbo) << MCB_SCALE_LOG2);
448
449 if (Results) {
450
451 *Lbo += Remainder;
452 }
453
454 } else {
455
456 *Lbo = 0;
457 }
458
460
461 *ByteCount = (ULONG) LiSectorCount;
462
463 if (*ByteCount) {
464
466
467 //
468 // If ByteCount overflows, then this is likely the case of
469 // a file of max-supported size (4GiB - 1), allocated in a
470 // single continuous run.
471 //
472
473 if (*ByteCount == 0) {
474
475 *ByteCount = 0xFFFFFFFF;
476 }
477
478 if (Results) {
479
481 }
482 }
483
484 }
485
486 return Results;
487}
#define MCB_SCALE_MODULO
BOOLEAN NTAPI FsRtlLookupLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, OUT PLONGLONG Lbn OPTIONAL, OUT PLONGLONG SectorCountFromLbn OPTIONAL, OUT PLONGLONG StartingLbn OPTIONAL, OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL, OUT PULONG Index OPTIONAL)
Definition: largemcb.c:560
#define ARGUMENT_PRESENT(ArgumentPointer)
_In_ LARGE_INTEGER _Out_opt_ PLARGE_INTEGER Remainder
Definition: rtlfuncs.h:3045

Referenced by _Requires_lock_held_(), FatComputeMoveFileSplicePoints(), and FatPagingFileIo().

◆ FatPerformVerifyDiskRead()

BOOLEAN FatPerformVerifyDiskRead ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PVOID  Buffer,
IN LBO  Lbo,
IN ULONG  NumberOfBytesToRead,
IN BOOLEAN  ReturnOnError 
)

Definition at line 4569 of file fsctrl.c.

4607{
4608 KEVENT Event;
4609 PIRP Irp;
4613
4614 PAGED_CODE();
4615
4616 DebugTrace(0, Dbg, "FatPerformVerifyDiskRead, Lbo = %08lx\n", Lbo );
4617
4618 //
4619 // Initialize the event we're going to use
4620 //
4621
4623
4624 //
4625 // Build the irp for the operation and also set the overrride flag
4626 //
4627
4628 ByteOffset.QuadPart = Lbo;
4629
4631 Vcb->TargetDeviceObject,
4632 Buffer,
4633 NumberOfBytesToRead,
4634 &ByteOffset,
4635 &Event,
4636 &Iosb );
4637
4638 if ( Irp == NULL ) {
4639
4641 }
4642
4644
4645 //
4646 // Call the device to do the read and wait for it to finish.
4647 //
4648
4649 Status = IoCallDriver( Vcb->TargetDeviceObject, Irp );
4650
4651 if (Status == STATUS_PENDING) {
4652
4654
4655 Status = Iosb.Status;
4656 }
4657
4659
4660 //
4661 // Special case this error code because this probably means we used
4662 // the wrong sector size and we want to reject STATUS_WRONG_VOLUME.
4663 //
4664
4666
4667 return FALSE;
4668 }
4669
4670 //
4671 // If it doesn't succeed then either return or raise the error.
4672 //
4673
4674 if (!NT_SUCCESS(Status)) {
4675
4676 if (ReturnOnError) {
4677
4678 return FALSE;
4679
4680 } else {
4681
4682 FatNormalizeAndRaiseStatus( IrpContext, Status );
4683 }
4684 }
4685
4686 //
4687 // And return to our caller
4688 //
4689
4690 return TRUE;
4691}
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2995
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130

Referenced by FatVerifyLookupFatEntry().

◆ FatQueryBpb()

NTSTATUS FatQueryBpb ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp 
)

Definition at line 4213 of file fsctrl.c.

4234{
4236
4237 PVCB Vcb;
4238
4240
4241 PAGED_CODE();
4242
4244
4245 DebugTrace(+1, Dbg, "FatQueryBpb...\n", 0);
4246
4247 //
4248 // Get the Vcb. If we didn't keep the information needed for this call,
4249 // we had a reason ...
4250 //
4251
4253
4254 if (Vcb->First0x24BytesOfBootSector == NULL) {
4255
4257 DebugTrace(-1, Dbg, "FatQueryBpb -> %08lx\n", STATUS_INVALID_DEVICE_REQUEST );
4259 }
4260
4261 //
4262 // Extract the buffer
4263 //
4264
4265 BpbBuffer = (PFSCTL_QUERY_FAT_BPB_BUFFER)Irp->AssociatedIrp.SystemBuffer;
4266
4267 //
4268 // Make sure the buffer is big enough.
4269 //
4270
4271 if (IrpSp->Parameters.FileSystemControl.OutputBufferLength < 0x24) {
4272
4274 DebugTrace(-1, Dbg, "FatQueryBpb -> %08lx\n", STATUS_BUFFER_TOO_SMALL );
4276 }
4277
4278 //
4279 // Fill in the output buffer
4280 //
4281
4283 Vcb->First0x24BytesOfBootSector,
4284 0x24 );
4285
4286 Irp->IoStatus.Information = 0x24;
4287
4288 FatCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
4289 DebugTrace(-1, Dbg, "FatQueryBpb -> %08lx\n", STATUS_SUCCESS);
4290 return STATUS_SUCCESS;
4291}
UCHAR First0x24BytesOfBootSector[0x24]
Definition: iotypes.h:6234
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
struct _FSCTL_QUERY_FAT_BPB_BUFFER * PFSCTL_QUERY_FAT_BPB_BUFFER

◆ FatRemoveMcbEntry()

VOID FatRemoveMcbEntry ( IN PVCB  Vcb,
IN PLARGE_MCB  Mcb,
IN VBO  Vbo,
IN ULONG  SectorCount 
)

Definition at line 599 of file fsctrl.c.

605{
606 PAGED_CODE();
607
608 if ((SectorCount) && (SectorCount != 0xFFFFFFFF)) {
609
610 SectorCount--;
612 SectorCount++;
613 }
614
616
617#if DBG
618 _SEH2_TRY {
619#endif
620
622 (LONGLONG) Vbo,
624
625#if DBG
626 } _SEH2_EXCEPT(FatBugCheckExceptionFilter( _SEH2_GetExceptionInformation() )) {
627
628 NOTHING;
629 } _SEH2_END;
630#endif
631
632}
#define NOTHING
Definition: input_list.c:10
VOID NTAPI FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG SectorCount)
Definition: largemcb.c:905

Referenced by _Requires_lock_held_(), FatCloseEaFile(), and FatTearDownAllocationSupport().

◆ FatSearchBufferForLabel()

NTSTATUS FatSearchBufferForLabel ( IN PIRP_CONTEXT  IrpContext,
IN PVPB  Vpb,
IN PVOID  Buffer,
IN ULONG  Size,
OUT PBOOLEAN  LabelFound 
)

Definition at line 7819 of file fsctrl.c.

7857{
7859 WCHAR UnicodeBuffer[11];
7860
7862 PDIRENT TerminationDirent;
7863 ULONG VolumeLabelLength;
7864 UCHAR OemBuffer[11];
7867
7868 PAGED_CODE();
7869
7870 UNREFERENCED_PARAMETER( IrpContext );
7871
7872 Dirent = Buffer;
7873
7874 TerminationDirent = Dirent + Size / sizeof(DIRENT);
7875
7876 while ( Dirent < TerminationDirent ) {
7877
7878 if ( Dirent->FileName[0] == FAT_DIRENT_NEVER_USED ) {
7879
7880 Dirent = TerminationDirent;
7881 break;
7882 }
7883
7884 //
7885 // If the entry is the non-deleted volume label break from the loop.
7886 //
7887 // Note that all out parameters are already correctly set.
7888 //
7889
7890 if (((Dirent->Attributes & ~FAT_DIRENT_ATTR_ARCHIVE) ==
7892 (Dirent->FileName[0] != FAT_DIRENT_DELETED)) {
7893
7894 break;
7895 }
7896
7897 Dirent += 1;
7898 }
7899
7900 if (Dirent >= TerminationDirent) {
7901
7902 //
7903 // We've run out of buffer.
7904 //
7905
7906 *LabelFound = FALSE;
7907 return STATUS_SUCCESS;
7908 }
7909
7910
7911 OemString.Buffer = (PCHAR)&OemBuffer[0];
7912 OemString.MaximumLength = 11;
7913
7914 RtlCopyMemory( OemString.Buffer, Dirent->FileName, 11 );
7915
7916 //
7917 // Translate the first character from 0x5 to 0xe5.
7918 //
7919
7920 if (OemString.Buffer[0] == FAT_DIRENT_REALLY_0E5) {
7921
7922 OemString.Buffer[0] = 0xe5;
7923 }
7924
7925 //
7926 // Compute the length of the volume name
7927 //
7928
7929 for ( OemString.Length = 11;
7930 OemString.Length > 0;
7931 OemString.Length -= 1) {
7932
7933 if ( (OemString.Buffer[OemString.Length-1] != 0x00) &&
7934 (OemString.Buffer[OemString.Length-1] != 0x20) ) { break; }
7935 }
7936
7937 UnicodeString.MaximumLength = sizeof( UnicodeBuffer );
7938 UnicodeString.Buffer = &UnicodeBuffer[0];
7939
7941 &OemString,
7942 FALSE );
7943
7944 if ( !NT_SUCCESS( Status ) ) {
7945
7946 return Status;
7947 }
7948
7949 VolumeLabelLength = UnicodeString.Length;
7950
7951 if ( (VolumeLabelLength != (ULONG)Vpb->VolumeLabelLength) ||
7952 (!RtlEqualMemory(&UnicodeBuffer[0],
7953 &Vpb->VolumeLabel[0],
7954 VolumeLabelLength)) ) {
7955
7956 return STATUS_WRONG_VOLUME;
7957 }
7958
7959 //
7960 // We found a matching label.
7961 //
7962
7963 *LabelFound = TRUE;
7964 return STATUS_SUCCESS;
7965}
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:427
#define FAT_DIRENT_ATTR_ARCHIVE
Definition: fat.h:373
#define FAT_DIRENT_ATTR_VOLUME_ID
Definition: fat.h:371
#define FAT_DIRENT_REALLY_0E5
Definition: fat.h:335
#define FAT_DIRENT_DELETED
Definition: fat.h:337
#define FAT_DIRENT_NEVER_USED
Definition: fat.h:334
#define DIRENT
Definition: fatfs.h:187
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1675
#define RtlEqualMemory(a, b, c)
Definition: kdvm.h:18
#define PCHAR
Definition: match.c:90
NTSTATUS NTAPI RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING UniDest, IN PCOEM_STRING OemSource, IN BOOLEAN AllocateDestinationString)
Definition: unicode.c:1473
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
STRING OEM_STRING
Definition: umtypes.h:203
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
*BytesInOemString PCHAR OemString
Definition: rtlfuncs.h:1560
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ FatSetZeroOnDeallocate()

NTSTATUS FatSetZeroOnDeallocate ( __in PIRP_CONTEXT  IrpContext,
__in PIRP  Irp 
)

Definition at line 8123 of file fsctrl.c.

8127{
8129
8130 PVCB Vcb;
8131 PFCB FcbOrDcb;
8132 PCCB Ccb;
8133
8135
8137
8138 BOOLEAN ReleaseFcb = FALSE;
8139
8140 PAGED_CODE();
8141
8142 //
8143 // This call should always be synchronous.
8144 //
8145
8146 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
8147
8149
8150 if ((TypeOfOpen != UserFileOpen) ||
8151 (!IrpSp->FileObject->WriteAccess) ) {
8152
8154 return STATUS_ACCESS_DENIED;
8155 }
8156
8157 //
8158 // Readonly mount should be just that: read only.
8159 //
8160
8161 if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED)) {
8162
8165 }
8166
8167 //
8168 // Acquire main then paging to exclude everyone from this FCB.
8169 //
8170
8171 FatAcquireExclusiveFcb(IrpContext, FcbOrDcb);
8172 ReleaseFcb = TRUE;
8173
8174 _SEH2_TRY {
8175
8177
8178 } _SEH2_FINALLY {
8179
8180 if (ReleaseFcb) {
8181 FatReleaseFcb(IrpContext, FcbOrDcb);
8182 }
8183
8184 } _SEH2_END;
8185
8186 FatCompleteRequest( IrpContext, Irp, Status );
8187 return Status;
8188}
@ UserFileOpen
Definition: cdprocs.h:577
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
#define FatReleaseFcb(IRPCONTEXT, Fcb)
Definition: fatprocs.h:1644
#define FCB_STATE_ZERO_ON_DEALLOCATION
Definition: fatstruc.h:1224
#define VCB_STATE_FLAG_WRITE_PROTECTED
Definition: fatstruc.h:570
#define _SEH2_FINALLY
Definition: filesup.c:21
ULONG FcbState
Definition: cdstruc.h:971
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145

◆ FatUnlockVolume()

NTSTATUS FatUnlockVolume ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp 
)

Definition at line 3354 of file fsctrl.c.

3376{
3378
3380
3381 PVCB Vcb;
3382 PFCB Fcb;
3383 PCCB Ccb;
3384
3385 PAGED_CODE();
3386
3388
3389 DebugTrace(+1, Dbg, "FatUnlockVolume...\n", 0);
3390
3391 //
3392 // Decode the file object, the only type of opens we accept are
3393 // user volume opens.
3394 //
3395
3397
3399
3400 DebugTrace(-1, Dbg, "FatUnlockVolume -> %08lx\n", STATUS_INVALID_PARAMETER);
3402 }
3403
3405
3407
3408 DebugTrace(-1, Dbg, "FatUnlockVolume -> %08lx\n", STATUS_INVALID_PARAMETER);
3410 }
3411
3413
3414 //
3415 // Send notification that the volume is avaliable.
3416 //
3417
3418 if (NT_SUCCESS( Status )) {
3419
3421 }
3422
3423 FatCompleteRequest( IrpContext, Irp, Status );
3424
3425 DebugTrace(-1, Dbg, "FatUnlockVolume -> %08lx\n", Status);
3426
3427 return Status;
3428}
NTSTATUS FatUnlockVolumeInternal(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_OBJECT FileObject OPTIONAL)
Definition: fsctrl.c:3601
#define FSRTL_VOLUME_UNLOCK
Definition: ntifs_ex.h:443
NTSTATUS NTAPI FsRtlNotifyVolumeEvent(IN PFILE_OBJECT FileObject, IN ULONG EventCode)
Definition: pnp.c:38

◆ FatUnlockVolumeInternal()

NTSTATUS FatUnlockVolumeInternal ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFILE_OBJECT FileObject  OPTIONAL 
)

Definition at line 3601 of file fsctrl.c.

3630{
3631 KIRQL SavedIrql;
3633
3634 UNREFERENCED_PARAMETER( IrpContext );
3635
3636 IoAcquireVpbSpinLock( &SavedIrql );
3637
3638 if (FlagOn(Vcb->Vpb->Flags, VPB_LOCKED) && FileObject == Vcb->FileObjectWithVcbLocked) {
3639
3640 //
3641 // This one locked it, unlock the volume
3642 //
3643
3645 ClearFlag( Vcb->VcbState, VCB_STATE_FLAG_LOCKED );
3646 Vcb->FileObjectWithVcbLocked = NULL;
3647
3649 }
3650
3651 IoReleaseVpbSpinLock( SavedIrql );
3652
3653 return Status;
3654}
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define VCB_STATE_FLAG_LOCKED
Definition: fatstruc.h:559
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
#define STATUS_NOT_LOCKED
Definition: ntstatus.h:279
#define VPB_DIRECT_WRITES_ALLOWED
Definition: iotypes.h:1812
#define VPB_LOCKED
Definition: iotypes.h:1808

Referenced by FatUnlockVolume().

◆ FatVerifyLookupFatEntry()

VOID FatVerifyLookupFatEntry ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN ULONG  FatIndex,
IN OUT PULONG  FatEntry 
)

Definition at line 7969 of file fsctrl.c.

7975{
7976 ULONG PageEntryOffset;
7977 ULONG OffsetIntoVolumeFile;
7978 PVOID Buffer;
7979
7980 PAGED_CODE();
7981
7982 NT_ASSERT(Vcb->AllocationSupport.FatIndexBitSize == 32);
7983
7984 FatVerifyIndexIsValid( IrpContext, Vcb, FatIndex);
7985
7986 Buffer = FsRtlAllocatePoolWithTag( NonPagedPoolNxCacheAligned,
7987 PAGE_SIZE,
7989
7990 OffsetIntoVolumeFile = FatReservedBytes(&Vcb->Bpb) + FatIndex * sizeof(ULONG);
7991 PageEntryOffset = (OffsetIntoVolumeFile % PAGE_SIZE) / sizeof(ULONG);
7992
7993 _SEH2_TRY {
7994
7995 FatPerformVerifyDiskRead( IrpContext,
7996 Vcb,
7997 Buffer,
7998 OffsetIntoVolumeFile & ~(PAGE_SIZE - 1),
7999 PAGE_SIZE,
8000 TRUE );
8001
8002 *FatEntry = ((PULONG)(Buffer))[PageEntryOffset];
8003
8004 } _SEH2_FINALLY {
8005
8006 ExFreePool( Buffer );
8007 } _SEH2_END;
8008}
#define FatVerifyIndexIsValid(IC, V, I)
Definition: fat.h:532
#define FatReservedBytes(B)
Definition: fat.h:414
#define TAG_ENTRY_LOOKUP_BUFFER
Definition: nodetype.h:181
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
BOOLEAN FatPerformVerifyDiskRead(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PVOID Buffer, IN LBO Lbo, IN ULONG NumberOfBytesToRead, IN BOOLEAN ReturnOnError)
Definition: fsctrl.c:4569
IN PVCB IN ULONG FatIndex
Definition: fatprocs.h:383
IN PVCB IN ULONG IN FAT_ENTRY FatEntry
Definition: fatprocs.h:385
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229