ReactOS 0.4.15-dev-7907-g95bf896
verfysup.c File Reference
#include "fatprocs.h"
Include dependency graph for verfysup.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (FAT_BUG_CHECK_VERFYSUP)
 
#define Dbg   (DEBUG_TRACE_VERFYSUP)
 

Functions

VOID FatResetFcb (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
 
BOOLEAN FatMatchFileSize (__in PIRP_CONTEXT IrpContext, __in PDIRENT Dirent, __in PFCB Fcb)
 
 _Requires_lock_held_ (_Global_critical_region_)
 
BOOLEAN FatMarkDevForVerifyIfVcbMounted (IN PVCB Vcb)
 
VOID FatVerifyVcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
VOID NTAPI FatDeferredCleanVolume (_In_ PVOID Parameter)
 
VOID NTAPI FatCleanVolumeDpc (_In_ PKDPC Dpc, _In_opt_ PVOID DeferredContext, _In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument2)
 
VOID NTAPI FatFspMarkVolumeDirtyWithRecover (PVOID Parameter)
 
VOID FatCheckDirtyBit (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
VOID FatVerifyOperationIsLegal (IN PIRP_CONTEXT IrpContext)
 
VOID FatQuickVerifyVcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
 
NTSTATUS NTAPI FatMarkVolumeCompletionRoutine (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt)
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (FAT_BUG_CHECK_VERFYSUP)

Definition at line 23 of file verfysup.c.

◆ Dbg

#define Dbg   (DEBUG_TRACE_VERFYSUP)

Definition at line 29 of file verfysup.c.

Function Documentation

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 48 of file verfysup.c.

119{
120 PAGED_CODE();
121
122 DebugTrace(+1, Dbg, "FatMarkFcbCondition, Fcb = %p\n", Fcb );
123
124 //
125 // If we are marking this Fcb something other than Good, we will need
126 // to have the Vcb exclusive.
127 //
128
129 NT_ASSERT( FcbCondition != FcbNeedsToBeVerified ? TRUE :
130 FatVcbAcquiredExclusive(IrpContext, Fcb->Vcb) );
131
132 //
133 // If this is a PagingFile it has to be good unless media underneath is
134 // removable. The "removable" check was added specifically for ReadyBoost,
135 // which opens its cache file on a removable device as a paging file and
136 // relies on the file system to validate its mapping information after a
137 // power transition.
138 //
139
142
144 return;
145 }
146
147 //
148 // Update the condition of the Fcb.
149 //
150
151 Fcb->FcbCondition = FcbCondition;
152
153 DebugTrace(0, Dbg, "MarkFcb: %wZ\n", &Fcb->FullFileName);
154
155 //
156 // This FastIo flag is based on FcbCondition, so update it now. This only
157 // applies to regular FCBs, of course.
158 //
159
160 if (Fcb->Header.NodeTypeCode == FAT_NTC_FCB) {
161
162 Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb );
163 }
164
165 if (FcbCondition == FcbNeedsToBeVerified) {
166 FatResetFcb( IrpContext, Fcb );
167 }
168
169 //
170 // Now if we marked NeedsVerify or Bad a directory then we also need to
171 // go and mark all of our children with the same condition.
172 //
173
174 if ( ((FcbCondition == FcbNeedsToBeVerified) ||
175 (FcbCondition == FcbBad)) &&
176 Recursive &&
177 ((Fcb->Header.NodeTypeCode == FAT_NTC_DCB) ||
178 (Fcb->Header.NodeTypeCode == FAT_NTC_ROOT_DCB)) ) {
179
180 PFCB OriginalFcb = Fcb;
181
182 while ( (Fcb = FatGetNextFcbTopDown(IrpContext, Fcb, OriginalFcb)) != NULL ) {
183
184 DebugTrace(0, Dbg, "MarkFcb: %wZ\n", &Fcb->FullFileName);
185
186 Fcb->FcbCondition = FcbCondition;
187
188 //
189 // We already know that FastIo is not possible since we are propagating
190 // a parent's bad/verify flag down the tree - IO to the children must
191 // take the long route for now.
192 //
193
194 Fcb->Header.IsFastIoPossible = FastIoIsNotPossible;
195
196 //
197 // Leave all the Fcbs in a condition to be verified.
198 //
199
200 if (FcbCondition == FcbNeedsToBeVerified) {
201 FatResetFcb( IrpContext, Fcb );
202 }
203
204 }
205 }
206
207 DebugTrace(-1, Dbg, "FatMarkFcbCondition -> VOID\n", 0);
208
209 return;
210}
#define PAGED_CODE()
_In_ PFCB Fcb
Definition: cdprocs.h:159
@ FcbGood
Definition: cdstruc.h:779
@ FcbBad
Definition: cdstruc.h:780
@ FcbNeedsToBeVerified
Definition: cdstruc.h:781
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
#define FAT_NTC_FCB
Definition: nodetype.h:29
#define FAT_NTC_DCB
Definition: nodetype.h:30
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
VOID FatResetFcb(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
Definition: verfysup.c:1396
#define Dbg
Definition: verfysup.c:29
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define FatVcbAcquiredExclusive(IRPCONTEXT, VCB)
Definition: fatprocs.h:1495
PFCB FatGetNextFcbTopDown(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PFCB TerminationFcb)
Definition: strucsup.c:2627
#define FatIsFastIoPossible(FCB)
Definition: fatprocs.h:2813
#define VCB_STATE_FLAG_REMOVABLE_MEDIA
Definition: fatstruc.h:560
#define FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1195
@ FastIoIsNotPossible
Definition: fsrtltypes.h:240
Definition: cdstruc.h:902
PVCB Vcb
Definition: cdstruc.h:933
UNICODE_STRING FullFileName
Definition: fatstruc.h:1122
FCB_CONDITION FcbCondition
Definition: fatstruc.h:850
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925
ULONG FcbState
Definition: cdstruc.h:971
ULONG VcbState
Definition: cdstruc.h:540
#define NT_ASSERT
Definition: rtlfuncs.h:3310

◆ FatCheckDirtyBit()

VOID FatCheckDirtyBit ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 1185 of file verfysup.c.

1207{
1208 BOOLEAN Dirty;
1209
1211 PBCB BootSectorBcb;
1212
1213 UNICODE_STRING VolumeLabel;
1214
1215 PAGED_CODE();
1216
1217 //
1218 // Look in the boot sector
1219 //
1220
1221 FatReadVolumeFile( IrpContext,
1222 Vcb,
1223 0,
1224 sizeof(PACKED_BOOT_SECTOR),
1225 &BootSectorBcb,
1226 (PVOID *)&BootSector );
1227
1228 _SEH2_TRY {
1229
1230 //
1231 // Check if the magic bit is set
1232 //
1233
1234 if (IsBpbFat32(&BootSector->PackedBpb)) {
1235 Dirty = BooleanFlagOn( ((PPACKED_BOOT_SECTOR_EX)BootSector)->CurrentHead,
1237 } else {
1238 Dirty = BooleanFlagOn( BootSector->CurrentHead, FAT_BOOT_SECTOR_DIRTY );
1239 }
1240
1241 //
1242 // Setup the VolumeLabel string
1243 //
1244
1245 VolumeLabel.Length = Vcb->Vpb->VolumeLabelLength;
1247 VolumeLabel.Buffer = &Vcb->Vpb->VolumeLabel[0];
1248
1249 if ( Dirty ) {
1250
1251 //
1252 // Do not trigger the mounted dirty bit if this is a verify
1253 // and the volume is a boot or paging device. We know that
1254 // a boot or paging device cannot leave the system, and thus
1255 // that on its mount we will have figured this out correctly.
1256 //
1257 // This logic is a reasonable change. Why?
1258 // 'cause setup cracked a non-exclusive DASD handle near the
1259 // end of setup, wrote some data, closed the handle and we
1260 // set the verify bit ... came back around and saw that other
1261 // arbitrary activity had left the volume in a temporarily dirty
1262 // state.
1263 //
1264 // Of course, the real problem is that we don't have a journal.
1265 //
1266
1267 if (!(IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
1268 IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME &&
1270
1273 "FASTFAT: WARNING! Mounting Dirty Volume %Z\n",
1274 &VolumeLabel));
1275
1277 }
1278
1279 } else {
1280
1281 if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) {
1282
1285 "FASTFAT: Volume %Z has been cleaned.\n",
1286 &VolumeLabel));
1287
1289
1290 } else {
1291
1292 (VOID)FsRtlBalanceReads( Vcb->TargetDeviceObject );
1293 }
1294 }
1295
1296 } _SEH2_FINALLY {
1297
1298 FatUnpinBcb( IrpContext, BootSectorBcb );
1299 } _SEH2_END;
1300}
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
@ DPFLTR_FASTFAT_ID
Definition: dpfilter.h:61
#define IsBpbFat32(bpb)
Definition: fat.h:101
#define FAT_BOOT_SECTOR_DIRTY
Definition: fat.h:213
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
VOID FatReadVolumeFile(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN VBO StartingVbo, IN ULONG ByteCount, OUT PBCB *Bcb, OUT PVOID *Buffer)
Definition: cachesup.c:102
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:546
#define VCB_STATE_FLAG_BOOT_OR_PAGING_FILE
Definition: fatstruc.h:567
#define VCB_STATE_FLAG_MOUNTED_DIRTY
Definition: fatstruc.h:562
NTSTATUS NTAPI FsRtlBalanceReads(PDEVICE_OBJECT TargetDevice)
Definition: faulttol.c:35
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define DPFLTR_INFO_LEVEL
Definition: kdtypes.h:33
#define Vcb
Definition: cdprocs.h:1415
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4405
#define MAXIMUM_VOLUME_LABEL_LENGTH
Definition: iotypes.h:177
#define KdPrintEx(_x_)
Definition: kdfuncs.h:114

◆ FatCleanVolumeDpc()

VOID NTAPI FatCleanVolumeDpc ( _In_ PKDPC  Dpc,
_In_opt_ PVOID  DeferredContext,
_In_opt_ PVOID  SystemArgument1,
_In_opt_ PVOID  SystemArgument2 
)

Definition at line 654 of file verfysup.c.

679{
680 PVCB Vcb;
682
686
688
689
690 //
691 // If there is still dirty data (highly unlikely), set the timer for a
692 // second in the future.
693 //
694
695 if (CcIsThereDirtyData(Vcb->Vpb)) {
696
697 LARGE_INTEGER TwoSecondsFromNow;
698
699 TwoSecondsFromNow.QuadPart = (LONG)-2*1000*1000*10;
700
701 KeSetTimer( &Vcb->CleanVolumeTimer,
702 TwoSecondsFromNow,
703 &Vcb->CleanVolumeDpc );
704
705 return;
706 }
707
708 //
709 // If we couldn't get pool, oh well....
710 //
711
712 Packet = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(CLEAN_AND_DIRTY_VOLUME_PACKET), ' taF');
713
714 if ( Packet ) {
715
716 Packet->Vcb = Vcb;
717 Packet->Irp = NULL;
718
719 //
720 // Clear the dirty flag now since we cannot synchronize after this point.
721 //
722
724
726
727#ifdef _MSC_VER
728#pragma prefast( suppress:28159, "prefast indicates this is an obsolete API, but it is ok for fastfat to keep using it" )
729#endif
731 }
732
733 return;
734}
struct _VCB * PVCB
Definition: fatstruc.h:557
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID NTAPI FatDeferredCleanVolume(_In_ PVOID Parameter)
Definition: verfysup.c:499
#define VCB_STATE_FLAG_VOLUME_DIRTY
Definition: fatstruc.h:561
BOOLEAN NTAPI CcIsThereDirtyData(IN PVPB Vpb)
Definition: logsup.c:55
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1549
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
long LONG
Definition: pedump.c:60
Definition: cdstruc.h:498
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ CriticalWorkQueue
Definition: extypes.h:189
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:688
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:687
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:689

◆ FatDeferredCleanVolume()

VOID NTAPI FatDeferredCleanVolume ( _In_ PVOID  Parameter)

Definition at line 499 of file verfysup.c.

521{
523 PLIST_ENTRY Links;
524 PVCB Vcb;
525 IRP_CONTEXT IrpContext;
526 BOOLEAN VcbExists = FALSE;
527
528 PAGED_CODE();
529
530 DebugTrace(+1, Dbg, "FatDeferredCleanVolume\n", 0);
531
533
534 Vcb = Packet->Vcb;
535
536 //
537 // Make us appear as a top level FSP request so that we will
538 // receive any errors from the operation.
539 //
540
542
543 //
544 // Dummy up and Irp Context so we can call our worker routines
545 //
546
547 RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT));
548
549 SetFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
550
551 //
552 // Acquire shared access to the global lock and make sure this volume
553 // still exists.
554 //
555
556#ifdef _MSC_VER
557#pragma prefast( push )
558#pragma prefast( disable: 28193, "this will always wait" )
559#endif
560 FatAcquireSharedGlobal( &IrpContext );
561#ifdef _MSC_VER
562#pragma prefast( pop )
563#endif
564
565 for (Links = FatData.VcbQueue.Flink;
566 Links != &FatData.VcbQueue;
567 Links = Links->Flink) {
568
569 PVCB ExistingVcb;
570
571 ExistingVcb = CONTAINING_RECORD(Links, VCB, VcbLinks);
572
573 if ( Vcb == ExistingVcb ) {
574
575 VcbExists = TRUE;
576 break;
577 }
578 }
579
580 //
581 // If the vcb is good then mark it clean. Ignore any problems.
582 //
583
584 if ( VcbExists &&
585 (Vcb->VcbCondition == VcbGood) &&
586 !FlagOn(Vcb->VcbState, VCB_STATE_FLAG_SHUTDOWN) ) {
587
588 _SEH2_TRY {
589
590 if (!FlagOn(Vcb->VcbState, VCB_STATE_FLAG_MOUNTED_DIRTY)) {
591
592 FatMarkVolume( &IrpContext, Vcb, VolumeClean );
593 }
594
595 //
596 // Check for a pathological race condition, and fix it.
597 //
598
599 if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_VOLUME_DIRTY)) {
600
601 FatMarkVolume( &IrpContext, Vcb, VolumeDirty );
602
603 } else {
604
605 //
606 // Unlock the volume if it is removable.
607 //
608
609 if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_REMOVABLE_MEDIA) &&
611
612 FatToggleMediaEjectDisable( &IrpContext, Vcb, FALSE );
613 }
614 }
615
618
619 NOTHING;
620 } _SEH2_END;
621 }
622
623 //
624 // Release the global resource, unpin and repinned Bcbs and return.
625 //
626
627 FatReleaseGlobal( &IrpContext );
628
629 _SEH2_TRY {
630
631 FatUnpinRepinnedBcbs( &IrpContext );
632
635
636 NOTHING;
637 } _SEH2_END;
638
640
641 //
642 // and finally free the packet.
643 //
644
646
647 return;
648}
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
#define FALSE
Definition: types.h:117
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID FatUnpinRepinnedBcbs(IN PIRP_CONTEXT IrpContext)
Definition: cachesup.c:1407
NTSTATUS FatToggleMediaEjectDisable(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN PreventRemoval)
Definition: deviosup.c:3495
FAT_DATA FatData
Definition: fatdata.c:56
@ VolumeClean
Definition: fatprocs.h:1954
@ VolumeDirty
Definition: fatprocs.h:1955
#define FatReleaseGlobal(IRPCONTEXT)
Definition: fatprocs.h:1636
#define FatAcquireSharedGlobal(IRPCONTEXT)
Definition: fatprocs.h:1391
#define VCB_STATE_FLAG_SHUTDOWN
Definition: fatstruc.h:563
@ VcbGood
Definition: fatstruc.h:223
struct _CLEAN_AND_DIRTY_VOLUME_PACKET * PCLEAN_AND_DIRTY_VOLUME_PACKET
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define NOTHING
Definition: input_list.c:10
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
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
LIST_ENTRY VcbQueue
Definition: fatstruc.h:49
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_Inout_opt_ PVOID Parameter
Definition: rtltypes.h:323

Referenced by FatCleanVolumeDpc().

◆ FatFspMarkVolumeDirtyWithRecover()

VOID NTAPI FatFspMarkVolumeDirtyWithRecover ( PVOID  Parameter)

Definition at line 1098 of file verfysup.c.

1123{
1125 PVCB Vcb;
1126 IRP_CONTEXT IrpContext;
1127 PIRP Irp;
1128
1129 DebugTrace(+1, Dbg, "FatFspMarkVolumeDirtyWithRecover\n", 0);
1130
1132
1133 Vcb = Packet->Vcb;
1134 Irp = Packet->Irp;
1135
1136 //
1137 // Dummy up the IrpContext so we can call our worker routines
1138 //
1139
1140 RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT));
1141
1142 SetFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
1143 IrpContext.OriginatingIrp = Irp;
1144
1145 //
1146 // Make us appear as a top level FSP request so that we will
1147 // receive any errors from the operation.
1148 //
1149
1151
1152 //
1153 // Try to write out the dirty bit. If something goes wrong, we
1154 // tried.
1155 //
1156
1157 _SEH2_TRY {
1158
1160
1161 FatMarkVolume( &IrpContext, Vcb, VolumeDirtyWithSurfaceTest );
1162
1164
1165 NOTHING;
1166 } _SEH2_END;
1167
1169
1170 //
1171 // Now complete the originating Irp or set the synchronous event.
1172 //
1173
1174 if (Packet->Event) {
1175 KeSetEvent( Packet->Event, 0, FALSE );
1176 } else {
1178 }
1179
1180 DebugTrace(-1, Dbg, "FatFspMarkVolumeDirtyWithRecover -> VOID\n", 0);
1181}
_In_ PIRP Irp
Definition: csq.h:116
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
@ VolumeDirtyWithSurfaceTest
Definition: fatprocs.h:1956
#define IoCompleteRequest
Definition: irp.c:1240
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define IO_DISK_INCREMENT
Definition: iotypes.h:600

◆ FatMarkDevForVerifyIfVcbMounted()

BOOLEAN FatMarkDevForVerifyIfVcbMounted ( IN PVCB  Vcb)

Definition at line 213 of file verfysup.c.

234{
236 KIRQL SavedIrql;
237
238 IoAcquireVpbSpinLock( &SavedIrql );
239
240#ifdef _MSC_VER
241#pragma prefast( push )
242#pragma prefast( disable: 28175, "touching Vpb is ok for a filesystem" )
243#endif
244
245 if (Vcb->Vpb->RealDevice->Vpb == Vcb->Vpb) {
246
247 SetFlag( Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
248 Marked = TRUE;
249 }
250 else {
251
252 //
253 // Flag this to avoid the VPB spinlock in future passes.
254 //
255
257 }
258
259#ifdef _MSC_VER
260#pragma prefast( pop )
261#endif
262
263 IoReleaseVpbSpinLock( SavedIrql );
264
265 return Marked;
266}
#define VCB_STATE_VPB_NOT_ON_DEVICE
Definition: cdstruc.h:714
#define Marked(f)
Definition: render.c:146
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204

Referenced by FatQuickVerifyVcb().

◆ FatMarkVolumeCompletionRoutine()

NTSTATUS NTAPI FatMarkVolumeCompletionRoutine ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp,
_In_reads_opt_(_Inexpressible_("varies")) PVOID  Contxt 
)

Definition at line 2013 of file verfysup.c.

2019{
2020 //
2021 // Set the event so that our call will wake up.
2022 //
2023
2024 KeSetEvent( (PKEVENT)Contxt, 0, FALSE );
2025
2028
2030}
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055

◆ FatMatchFileSize()

BOOLEAN FatMatchFileSize ( __in PIRP_CONTEXT  IrpContext,
__in PDIRENT  Dirent,
__in PFCB  Fcb 
)

Definition at line 1495 of file verfysup.c.

1500{
1501
1502 UNREFERENCED_PARAMETER(IrpContext);
1503
1504 if (NodeType(Fcb) != FAT_NTC_FCB) {
1505 return TRUE;
1506 }
1507
1508
1509 if (Fcb->Header.FileSize.LowPart != Dirent->FileSize) {
1510 return FALSE;
1511 }
1512
1513
1514 return TRUE;
1515}
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:427
#define NodeType(P)
Definition: nodetype.h:51

◆ FatQuickVerifyVcb()

VOID FatQuickVerifyVcb ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 1662 of file verfysup.c.

1685{
1686 PAGED_CODE();
1687
1688 //
1689 // If the real device needs to be verified we'll set the
1690 // DeviceToVerify to be our real device and raise VerifyRequired.
1691 //
1692
1693 if (FlagOn(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME)) {
1694
1695 DebugTrace(0, Dbg, "The Vcb needs to be verified\n", 0);
1696
1697 IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1698 Vcb->Vpb->RealDevice );
1699
1701 }
1702
1703 //
1704 // Based on the condition of the Vcb we'll either return to our
1705 // caller or raise an error condition
1706 //
1707
1708 switch (Vcb->VcbCondition) {
1709
1710 case VcbGood:
1711
1712 DebugTrace(0, Dbg, "The Vcb is good\n", 0);
1713
1714 //
1715 // Do a check here of an operation that would try to modify a
1716 // write protected media.
1717 //
1718
1719 if (FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED) &&
1720 ((IrpContext->MajorFunction == IRP_MJ_WRITE) ||
1721 (IrpContext->MajorFunction == IRP_MJ_SET_INFORMATION) ||
1722 (IrpContext->MajorFunction == IRP_MJ_SET_EA) ||
1723 (IrpContext->MajorFunction == IRP_MJ_FLUSH_BUFFERS) ||
1724 (IrpContext->MajorFunction == IRP_MJ_SET_VOLUME_INFORMATION) ||
1725 (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
1726 IrpContext->MinorFunction == IRP_MN_USER_FS_REQUEST &&
1727 IoGetCurrentIrpStackLocation(IrpContext->OriginatingIrp)->Parameters.FileSystemControl.FsControlCode ==
1729
1730 //
1731 // Set the real device for the pop-up info, and set the verify
1732 // bit in the device object, so that we will force a verify
1733 // in case the user put the correct media back in.
1734 //
1735
1736
1737 IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1738 Vcb->Vpb->RealDevice );
1739
1741
1743 }
1744
1745 break;
1746
1747 case VcbNotMounted:
1748
1749 DebugTrace(0, Dbg, "The Vcb is not mounted\n", 0);
1750
1751 //
1752 // Set the real device for the pop-up info, and set the verify
1753 // bit in the device object, so that we will force a verify
1754 // in case the user put the correct media back in.
1755 //
1756
1757 IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
1758 Vcb->Vpb->RealDevice );
1759
1760 FatRaiseStatus( IrpContext, STATUS_WRONG_VOLUME );
1761
1762 break;
1763
1764 case VcbBad:
1765
1766 DebugTrace(0, Dbg, "The Vcb is bad\n", 0);
1767
1768 if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_VOLUME_DISMOUNTED )) {
1769
1771
1772 } else {
1773
1774 FatRaiseStatus( IrpContext, STATUS_FILE_INVALID );
1775 }
1776 break;
1777
1778 default:
1779
1780 DebugDump("Invalid VcbCondition\n", 0, Vcb);
1781#ifdef _MSC_VER
1782#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1783#endif
1784 FatBugCheck( Vcb->VcbCondition, 0, 0 );
1785 }
1786}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
@ VcbNotMounted
Definition: cdstruc.h:490
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
BOOLEAN FatMarkDevForVerifyIfVcbMounted(IN PVCB Vcb)
Definition: verfysup.c:213
#define DebugDump(STR, LEVEL, PTR)
Definition: fatdata.h:314
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2977
#define VCB_STATE_FLAG_WRITE_PROTECTED
Definition: fatstruc.h:570
#define VCB_STATE_FLAG_VOLUME_DISMOUNTED
Definition: fatstruc.h:572
@ VcbBad
Definition: fatstruc.h:225
#define FSCTL_MARK_VOLUME_DIRTY
Definition: nt_native.h:838
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:747
#define STATUS_FILE_INVALID
Definition: ntstatus.h:388
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
union _IO_STACK_LOCATION::@1564 Parameters
struct _IO_STACK_LOCATION::@3978::@3993 FileSystemControl
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define IRP_MJ_SET_VOLUME_INFORMATION
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4403
#define IRP_MJ_SET_EA
#define IRP_MJ_FLUSH_BUFFERS

Referenced by _Requires_lock_held_(), and FatVerifyVcb().

◆ FatResetFcb()

VOID FatResetFcb ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb 
)

Definition at line 1396 of file verfysup.c.

1423{
1424 LOGICAL IsRealPagingFile;
1425
1426 PAGED_CODE();
1427 UNREFERENCED_PARAMETER( IrpContext );
1428
1429 //
1430 // Don't do the two following operations for the Root Dcb
1431 // of a non FAT32 volume or paging files. Paging files!?
1432 // Yes, if someone diddles a volume we try to reverify all
1433 // of the Fcbs just in case; however, there is no safe way
1434 // to chuck and retrieve the mapping pair information for
1435 // a real paging file. Lose it and die.
1436 //
1437 // An exception is made for ReadyBoost cache files, which
1438 // are created as paging files on removable devices and
1439 // require validation after a power transition.
1440 //
1441
1444
1445 IsRealPagingFile = TRUE;
1446
1447 } else {
1448
1449 IsRealPagingFile = FALSE;
1450 }
1451
1452 if ( (NodeType(Fcb) != FAT_NTC_ROOT_DCB ||
1453 FatIsFat32( Fcb->Vcb )) &&
1454 !IsRealPagingFile ) {
1455
1456 //
1457 // Reset the mcb mapping.
1458 //
1459
1460 FsRtlRemoveLargeMcbEntry( &Fcb->Mcb, 0, 0xFFFFFFFF );
1461
1462 //
1463 // Reset the allocation size to 0 or unknown
1464 //
1465
1466 if ( Fcb->FirstClusterOfFile == 0 ) {
1467
1468 Fcb->Header.AllocationSize.QuadPart = 0;
1469
1470 } else {
1471
1472 Fcb->Header.AllocationSize.QuadPart = FCB_LOOKUP_ALLOCATIONSIZE_HINT;
1473 }
1474 }
1475
1476 //
1477 // If this is a directory, reset the hints.
1478 //
1479
1480 if ( (NodeType(Fcb) == FAT_NTC_DCB) ||
1481 (NodeType(Fcb) == FAT_NTC_ROOT_DCB) ) {
1482
1483 //
1484 // Force a rescan of the directory
1485 //
1486
1487 Fcb->Specific.Dcb.UnusedDirentVbo = 0xffffffff;
1488 Fcb->Specific.Dcb.DeletedDirentHint = 0xffffffff;
1489 }
1490}
#define FatIsFat32(VCB)
Definition: fatprocs.h:1446
#define FCB_LOOKUP_ALLOCATIONSIZE_HINT
Definition: fatstruc.h:1241
VOID NTAPI FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG SectorCount)
Definition: largemcb.c:905
union _FCB::@720 Specific
CD_MCB Mcb
Definition: cdstruc.h:1016
ULONG FirstClusterOfFile
Definition: fatstruc.h:818
struct _FCB::@720::@722 Dcb

◆ FatVerifyOperationIsLegal()

VOID FatVerifyOperationIsLegal ( IN PIRP_CONTEXT  IrpContext)

Definition at line 1304 of file verfysup.c.

1326{
1327 PIRP Irp;
1329
1330 PAGED_CODE();
1331
1332 Irp = IrpContext->OriginatingIrp;
1333
1334 //
1335 // If the Irp is not present, then we got here via close.
1336 //
1337 //
1338
1339 if ( Irp == NULL ) {
1340
1341 return;
1342 }
1343
1345
1346 //
1347 // If there is not a file object, we cannot continue.
1348 //
1349
1350 if ( FileObject == NULL ) {
1351
1352 return;
1353 }
1354
1355 //
1356 // If the file object has already been cleaned up, and
1357 //
1358 // A) This request is a paging io read or write, or
1359 // B) This request is a close operation, or
1360 // C) This request is a set or query info call (for Lou)
1361 // D) This is an MDL complete
1362 //
1363 // let it pass, otherwise return STATUS_FILE_CLOSED.
1364 //
1365
1366 if ( FlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE) ) {
1367
1369
1370 if ( (FlagOn(Irp->Flags, IRP_PAGING_IO)) ||
1374 ( ( (IrpSp->MajorFunction == IRP_MJ_READ) ||
1377
1378 NOTHING;
1379
1380 } else {
1381
1382 FatRaiseStatus( IrpContext, STATUS_FILE_CLOSED );
1383 }
1384 }
1385
1386 return;
1387}
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define STATUS_FILE_CLOSED
Definition: ntstatus.h:532
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
#define IRP_PAGING_IO
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1790
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by _Requires_lock_held_().

◆ FatVerifyVcb()

VOID FatVerifyVcb ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb 
)

Definition at line 270 of file verfysup.c.

292{
293 BOOLEAN DevMarkedForVerify;
294
295 PAGED_CODE();
296
297 DebugTrace(+1, Dbg, "FatVerifyVcb, Vcb = %p\n", Vcb );
298
299 //
300 // If the verify volume flag in the device object is set
301 // this means the media has potentially changed.
302 //
303 // Note that we only force this ping for create operations.
304 // For others we take a sporting chance. If in the end we
305 // have to physically access the disk, the right thing will happen.
306 //
307
308 DevMarkedForVerify = BooleanFlagOn(Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME);
309
310 //
311 // We ALWAYS force CREATE requests on unmounted volumes through the
312 // verify path. These requests could have been in limbo between
313 // IoCheckMountedVpb and us, when a verify/mount took place and caused
314 // a completely different fs/volume to be mounted. In this case the
315 // checks above may not have caught the condition, since we may already
316 // have verified (wrong volume) and decided that we have nothing to do.
317 // We want the requests to be re routed to the currently mounted volume,
318 // since they were directed at the 'drive', not our volume. So we take
319 // the verify path for synchronisation, and the request will eventually
320 // be bounced back to IO with STATUS_REPARSE by our verify handler.
321 //
322
323 if (!DevMarkedForVerify &&
324 (IrpContext->MajorFunction == IRP_MJ_CREATE) &&
325 (IrpContext->OriginatingIrp != NULL)) {
326
327 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( IrpContext->OriginatingIrp);
328
329 if ((IrpSp->FileObject->RelatedFileObject == NULL) &&
330 (Vcb->VcbCondition == VcbNotMounted)) {
331
332 DevMarkedForVerify = TRUE;
333 }
334 }
335
336 //
337 // Raise any error condition otherwise.
338 //
339
340 if (DevMarkedForVerify) {
341
342 DebugTrace(0, Dbg, "The Vcb needs to be verified\n", 0);
343
344 IoSetHardErrorOrVerifyDevice( IrpContext->OriginatingIrp,
345 Vcb->Vpb->RealDevice );
346
348 }
349
350 //
351 // Check the operation is legal for current Vcb state.
352 //
353
354 FatQuickVerifyVcb( IrpContext, Vcb );
355
356 DebugTrace(-1, Dbg, "FatVerifyVcb -> VOID\n", 0);
357}
VOID FatQuickVerifyVcb(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
Definition: verfysup.c:1662
#define FatNormalizeAndRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2995
#define IRP_MJ_CREATE
Definition: rdpdr.c:44

Referenced by FatFlushFat(), FatIsVolumeDirty(), and FatIsVolumeMounted().