ReactOS 0.4.17-dev-1344-g1103f43
fatdata.c File Reference
#include "fatprocs.h"
Include dependency graph for fatdata.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (FAT_BUG_CHECK_FATDATA)
 
#define Dbg   (DEBUG_TRACE_CATCH_EXCEPTIONS)
 

Functions

ULONG FatExceptionFilter (IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
 
 _Requires_lock_held_ (_Global_critical_region_)
 
VOID FatCompleteRequest_Real (IN PIRP_CONTEXT IrpContext OPTIONAL, IN PIRP Irp OPTIONAL, IN NTSTATUS Status)
 
BOOLEAN FatIsIrpTopLevel (IN PIRP Irp)
 
 _Function_class_ (FAST_IO_CHECK_IF_POSSIBLE)
 
 _Function_class_ (FAST_IO_QUERY_BASIC_INFO)
 
 _Function_class_ (FAST_IO_QUERY_STANDARD_INFO)
 
 _Function_class_ (FAST_IO_QUERY_NETWORK_OPEN_INFO)
 

Variables

FAT_DATA FatData
 
PDEVICE_OBJECT FatDiskFileSystemDeviceObject
 
PDEVICE_OBJECT FatCdromFileSystemDeviceObject
 
LARGE_INTEGER FatLargeZero = {0,0}
 
LARGE_INTEGER FatMaxLarge = {MAXULONG,MAXLONG}
 
LARGE_INTEGER Fat30Milliseconds = {(ULONG)(-30 * 1000 * 10), -1}
 
LARGE_INTEGER Fat100Milliseconds = {(ULONG)(-30 * 1000 * 10), -1}
 
LARGE_INTEGER FatOneDay = {0x2a69c000, 0xc9}
 
LARGE_INTEGER FatJanOne1980 = {0xe1d58000,0x01a8e79f}
 
LARGE_INTEGER FatDecThirtyOne1979 = {0xb76bc000,0x01a8e6d6}
 
FAT_TIME_STAMP FatTimeJanOne1980 = {{0,0,0},{1,1,0}}
 
LARGE_INTEGER FatMagic10000 = {0xe219652c, 0xd1b71758}
 
LARGE_INTEGER FatMagic86400000 = {0xfa67b90e, 0xc6d750eb}
 
FAST_IO_DISPATCH FatFastIoDispatch
 
NPAGED_LOOKASIDE_LIST FatIrpContextLookasideList
 
NPAGED_LOOKASIDE_LIST FatNonPagedFcbLookasideList
 
NPAGED_LOOKASIDE_LIST FatEResourceLookasideList
 
SLIST_HEADER FatCloseContextSList
 
FAST_MUTEX FatCloseQueueMutex
 
PMDL FatReserveMdl = NULL
 
KEVENT FatReserveEvent
 
LOGICAL FatDiskAccountingEnabled = FALSE
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (FAT_BUG_CHECK_FATDATA)

Definition at line 22 of file fatdata.c.

◆ Dbg

#define Dbg   (DEBUG_TRACE_CATCH_EXCEPTIONS)

Definition at line 28 of file fatdata.c.

Function Documentation

◆ _Function_class_() [1/4]

_Function_class_ ( FAST_IO_CHECK_IF_POSSIBLE  )

Definition at line 857 of file fatdata.c.

902{
903 PVCB Vcb;
904 PFCB Fcb;
905 PCCB Ccb;
906
907 LARGE_INTEGER LargeLength;
908
909 PAGED_CODE();
910
914 //
915 // Decode the file object to get our fcb, the only one we want
916 // to deal with is a UserFileOpen
917 //
918
920
921 return FALSE;
922 }
923
924 LargeLength.QuadPart = Length;
925
926 //
927 // Based on whether this is a read or write operation we call
928 // fsrtl check for read/write
929 //
930
932
935 &LargeLength,
936 LockKey,
939
940 return TRUE;
941 }
942
943 } else {
944
945
946 //
947 // Also check for a write-protected volume here.
948 //
949
950 if (!FlagOn(Vcb->VcbState, VCB_STATE_FLAG_WRITE_PROTECTED) &&
953 &LargeLength,
954 LockKey,
957
958 return TRUE;
959 }
960 }
961
962 return FALSE;
963}
#define PAGED_CODE()
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
@ UserFileOpen
Definition: cdprocs.h:577
_In_ PFCB Fcb
Definition: cdprocs.h:159
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2666
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN CheckForReadOperation
Definition: fatprocs.h:2667
#define VCB_STATE_FLAG_WRITE_PROTECTED
Definition: fatstruc.h:570
BOOLEAN NTAPI FsRtlFastCheckLockForWrite(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process)
Definition: filelock.c:784
BOOLEAN NTAPI FsRtlFastCheckLockForRead(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process)
Definition: filelock.c:750
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define Vcb
Definition: cdprocs.h:1415
Definition: cdstruc.h:1067
Definition: cdstruc.h:902
union _FCB::@927 Specific
struct _FCB::@927::@930 Fcb
Definition: cdstruc.h:498
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
#define PsGetCurrentProcess
Definition: psfuncs.h:17

◆ _Function_class_() [2/4]

_Function_class_ ( FAST_IO_QUERY_BASIC_INFO  )

Definition at line 966 of file fatdata.c.

1000{
1002 IRP_CONTEXT IrpContext;
1003
1005 PVCB Vcb;
1006 PFCB Fcb;
1007 PCCB Ccb;
1008
1009 BOOLEAN FcbAcquired = FALSE;
1010
1011 PAGED_CODE();
1013
1014 //
1015 // Prepare the dummy irp context
1016 //
1017
1018 RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT) );
1019 IrpContext.NodeTypeCode = FAT_NTC_IRP_CONTEXT;
1020 IrpContext.NodeByteSize = sizeof(IRP_CONTEXT);
1021
1022 if (Wait) {
1023
1024 SetFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
1025
1026 } else {
1027
1028 ClearFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
1029 }
1030
1031 //
1032 // Determine the type of open for the input file object and only accept
1033 // the user file or directory open
1034 //
1035
1037
1039
1040 return Results;
1041 }
1042
1044
1045 //
1046 // Get access to the Fcb but only if it is not the paging file
1047 //
1048
1050
1051 if (!ExAcquireResourceSharedLite( Fcb->Header.Resource, Wait )) {
1052
1054 return Results;
1055 }
1056
1057 FcbAcquired = TRUE;
1058 }
1059
1060 _SEH2_TRY {
1061
1062 //
1063 // If the Fcb is not in a good state, return FALSE.
1064 //
1065
1066 if (Fcb->FcbCondition != FcbGood) {
1067
1069 }
1070
1071 Buffer->FileAttributes = 0;
1072
1073 //
1074 // If the fcb is not the root dcb then we will fill in the
1075 // buffer otherwise it is all setup for us.
1076 //
1077
1078 if (NodeType(Fcb) != FAT_NTC_ROOT_DCB) {
1079
1080 //
1081 // Extract the data and fill in the non zero fields of the output
1082 // buffer
1083 //
1084
1085 Buffer->LastWriteTime = Fcb->LastWriteTime;
1086 Buffer->CreationTime = Fcb->CreationTime;
1087 Buffer->LastAccessTime = Fcb->LastAccessTime;
1088
1089 //
1090 // Zero out the field we don't support.
1091 //
1092
1093 Buffer->ChangeTime.QuadPart = 0;
1094 Buffer->FileAttributes = Fcb->DirentFatFlags;
1095
1096 } else {
1097
1098 Buffer->LastWriteTime.QuadPart = 0;
1099 Buffer->CreationTime.QuadPart = 0;
1100 Buffer->LastAccessTime.QuadPart = 0;
1101 Buffer->ChangeTime.QuadPart = 0;
1102
1103 Buffer->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
1104 }
1105
1106
1107 //
1108 // If the temporary flag is set, then set it in the buffer.
1109 //
1110
1112
1113 SetFlag( Buffer->FileAttributes, FILE_ATTRIBUTE_TEMPORARY );
1114 }
1115
1116 //
1117 // If no attributes were set, set the normal bit.
1118 //
1119
1120 if (Buffer->FileAttributes == 0) {
1121
1122 Buffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
1123 }
1124
1125 IoStatus->Status = STATUS_SUCCESS;
1126 IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);
1127
1128 Results = TRUE;
1129
1130 try_exit: NOTHING;
1131 } _SEH2_FINALLY {
1132
1133 if (FcbAcquired) { ExReleaseResourceLite( Fcb->Header.Resource ); }
1134
1136 } _SEH2_END;
1137
1138 //
1139 // And return to our caller
1140 //
1141
1142 return Results;
1143}
unsigned char BOOLEAN
Definition: actypes.h:127
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN TypeOfOpen
Definition: cdprocs.h:589
@ UserDirectoryOpen
Definition: cdprocs.h:576
enum _TYPE_OF_OPEN TYPE_OF_OPEN
#define try_return(S)
Definition: cdprocs.h:2179
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
@ FcbGood
Definition: cdstruc.h:779
Definition: bufpool.h:45
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define NodeType(P)
Definition: nodetype.h:51
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
#define FAT_NTC_IRP_CONTEXT
Definition: nodetype.h:33
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FCB_STATE_TEMPORARY
Definition: fatstruc.h:1198
#define FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1195
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define NOTHING
Definition: input_list.c:10
macro TEXTAREA section xr p2align endm macro DATAAREA section dw endm macro RODATAAREA section dr endm macro XDATAAREA section dr p2align endm macro PDATAAREA section dr p2align endm macro DCRVA Symbol rva Symbol endm macro EXPORT Attribute global Name endm macro IMPORT Target ifc WEAK weak Name set Target endif endm set macro SET_COMDAT_ALIGNMENT Alignment set Alignment endm macro NESTED_ENTRY Name global Name p2align xr p2align __ComdatAlignment NESTED_ENTRY Name endm macro ALTERNATE_ENTRY Name global Name Results
Definition: kxarm64.h:185
#define FILE_BASIC_INFORMATION
Definition: disk.h:53
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define _SEH2_FINALLY
Definition: pseh2_64.h:153
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define STATUS_SUCCESS
Definition: shellext.h:65
LONGLONG CreationTime
Definition: cdstruc.h:1030
FCB_CONDITION FcbCondition
Definition: fatstruc.h:850
LARGE_INTEGER LastWriteTime
Definition: fatstruc.h:922
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:925
ULONG FcbState
Definition: cdstruc.h:971
LARGE_INTEGER LastAccessTime
Definition: fatstruc.h:921
UCHAR DirentFatFlags
Definition: fatstruc.h:1133
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

◆ _Function_class_() [3/4]

_Function_class_ ( FAST_IO_QUERY_NETWORK_OPEN_INFO  )

Definition at line 1307 of file fatdata.c.

1341{
1343 IRP_CONTEXT IrpContext;
1344
1346 PVCB Vcb;
1347 PFCB Fcb;
1348 PCCB Ccb;
1349
1350 BOOLEAN FcbAcquired = FALSE;
1351
1352 PAGED_CODE();
1353
1355
1356 //
1357 // Prepare the dummy irp context
1358 //
1359
1360 RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT) );
1361 IrpContext.NodeTypeCode = FAT_NTC_IRP_CONTEXT;
1362 IrpContext.NodeByteSize = sizeof(IRP_CONTEXT);
1363
1364 if (Wait) {
1365
1366 SetFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
1367
1368 } else {
1369
1370 ClearFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
1371 }
1372
1373 //
1374 // Determine the type of open for the input file object and only accept
1375 // the user file or directory open
1376 //
1377
1379
1381
1382 return Results;
1383 }
1384
1386
1387 //
1388 // Get access to the Fcb but only if it is not the paging file
1389 //
1390
1392
1393 if (!ExAcquireResourceSharedLite( Fcb->Header.Resource, Wait )) {
1394
1396 return Results;
1397 }
1398
1399 FcbAcquired = TRUE;
1400 }
1401
1402 _SEH2_TRY {
1403
1404 //
1405 // If the Fcb is not in a good state, return FALSE.
1406 //
1407
1408 if (Fcb->FcbCondition != FcbGood) {
1409
1411 }
1412
1413 //
1414 // Extract the data and fill in the non zero fields of the output
1415 // buffer
1416 //
1417
1418 //
1419 // Default the field we don't support to a reasonable value.
1420 //
1421
1423 &Buffer->ChangeTime );
1424
1425 Buffer->FileAttributes = Fcb->DirentFatFlags;
1426
1427 if (Fcb->Header.NodeTypeCode == FAT_NTC_ROOT_DCB) {
1428
1429 //
1430 // Reuse the default for the root dir.
1431 //
1432
1433 Buffer->CreationTime =
1434 Buffer->LastAccessTime =
1435 Buffer->LastWriteTime = Buffer->ChangeTime;
1436
1437 } else {
1438
1439 Buffer->LastWriteTime = Fcb->LastWriteTime;
1440 Buffer->CreationTime = Fcb->CreationTime;
1441 Buffer->LastAccessTime = Fcb->LastAccessTime;
1442
1443 }
1444
1445 //
1446 // If the temporary flag is set, then set it in the buffer.
1447 //
1448
1450
1451 SetFlag( Buffer->FileAttributes, FILE_ATTRIBUTE_TEMPORARY );
1452 }
1453
1454
1455
1456 //
1457 // If no attributes were set, set the normal bit.
1458 //
1459
1460 if (Buffer->FileAttributes == 0) {
1461
1462 Buffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
1463 }
1464
1465 if (NodeType(Fcb) == FAT_NTC_FCB) {
1466
1467 //
1468 // If we don't already know the allocation size, we cannot
1469 // lock it up in the fast path.
1470 //
1471
1472 if (Fcb->Header.AllocationSize.QuadPart == FCB_LOOKUP_ALLOCATIONSIZE_HINT) {
1473
1475 }
1476
1477 Buffer->AllocationSize = Fcb->Header.AllocationSize;
1478 Buffer->EndOfFile = Fcb->Header.FileSize;
1479
1480 } else {
1481
1482 Buffer->AllocationSize = FatLargeZero;
1483 Buffer->EndOfFile = FatLargeZero;
1484 }
1485
1486 IoStatus->Status = STATUS_SUCCESS;
1487 IoStatus->Information = sizeof(FILE_NETWORK_OPEN_INFORMATION);
1488
1489 Results = TRUE;
1490
1491 try_exit: NOTHING;
1492 } _SEH2_FINALLY {
1493
1494 if (FcbAcquired) { ExReleaseResourceLite( Fcb->Header.Resource ); }
1495
1497 } _SEH2_END;
1498
1499 //
1500 // And return to our caller
1501 //
1502
1503 return Results;
1504}
#define FAT_NTC_FCB
Definition: nodetype.h:29
#define ExLocalTimeToSystemTime(LocTime, SysTime)
Definition: env_spec_w32.h:738
LARGE_INTEGER FatJanOne1980
Definition: fatdata.c:73
LARGE_INTEGER FatLargeZero
Definition: fatdata.c:62
#define FCB_LOOKUP_ALLOCATIONSIZE_HINT
Definition: fatstruc.h:1241
struct _FILE_NETWORK_OPEN_INFORMATION FILE_NETWORK_OPEN_INFORMATION

◆ _Function_class_() [4/4]

_Function_class_ ( FAST_IO_QUERY_STANDARD_INFO  )

Definition at line 1146 of file fatdata.c.

1180{
1182 IRP_CONTEXT IrpContext;
1183
1185 PVCB Vcb;
1186 PFCB Fcb;
1187 PCCB Ccb;
1188
1189 BOOLEAN FcbAcquired = FALSE;
1190
1191 PAGED_CODE();
1192
1194
1195 //
1196 // Prepare the dummy irp context
1197 //
1198
1199 RtlZeroMemory( &IrpContext, sizeof(IRP_CONTEXT) );
1200 IrpContext.NodeTypeCode = FAT_NTC_IRP_CONTEXT;
1201 IrpContext.NodeByteSize = sizeof(IRP_CONTEXT);
1202
1203 if (Wait) {
1204
1205 SetFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
1206
1207 } else {
1208
1209 ClearFlag(IrpContext.Flags, IRP_CONTEXT_FLAG_WAIT);
1210 }
1211
1212 //
1213 // Determine the type of open for the input file object and only accept
1214 // the user file or directory open
1215 //
1216
1218
1220
1221 return Results;
1222 }
1223
1224 //
1225 // Get access to the Fcb but only if it is not the paging file
1226 //
1227
1229
1231
1232 if (!ExAcquireResourceSharedLite( Fcb->Header.Resource, Wait )) {
1233
1235 return Results;
1236 }
1237
1238 FcbAcquired = TRUE;
1239 }
1240
1241 _SEH2_TRY {
1242
1243 //
1244 // If the Fcb is not in a good state, return FALSE.
1245 //
1246
1247 if (Fcb->FcbCondition != FcbGood) {
1248
1250 }
1251
1252 Buffer->NumberOfLinks = 1;
1254
1255 //
1256 // Case on whether this is a file or a directory, and extract
1257 // the information and fill in the fcb/dcb specific parts
1258 // of the output buffer.
1259 //
1260
1261 if (NodeType(Fcb) == FAT_NTC_FCB) {
1262
1263 //
1264 // If we don't alread know the allocation size, we cannot look
1265 // it up in the fast path.
1266 //
1267
1268 if (Fcb->Header.AllocationSize.QuadPart == FCB_LOOKUP_ALLOCATIONSIZE_HINT) {
1269
1271 }
1272
1273 Buffer->AllocationSize = Fcb->Header.AllocationSize;
1274 Buffer->EndOfFile = Fcb->Header.FileSize;
1275
1276 Buffer->Directory = FALSE;
1277
1278 } else {
1279
1280 Buffer->AllocationSize = FatLargeZero;
1281 Buffer->EndOfFile = FatLargeZero;
1282
1283 Buffer->Directory = TRUE;
1284 }
1285
1286 IoStatus->Status = STATUS_SUCCESS;
1287 IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION);
1288
1289 Results = TRUE;
1290
1291 try_exit: NOTHING;
1292 } _SEH2_FINALLY {
1293
1294 if (FcbAcquired) { ExReleaseResourceLite( Fcb->Header.Resource ); }
1295
1297 } _SEH2_END;
1298
1299 //
1300 // And return to our caller
1301 //
1302
1303 return Results;
1304}
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define FCB_STATE_DELETE_ON_CLOSE
Definition: fatstruc.h:1193
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 320 of file fatdata.c.

348{
349 PVCB Vcb;
351 FAT_VOLUME_STATE TransitionState = VolumeDirty;
352 ULONG SavedFlags = 0;
353
354 PAGED_CODE();
355
356 DebugTrace(0, Dbg, "FatProcessException\n", 0);
357
358 //
359 // If there is not an irp context, we must have had insufficient resources.
360 //
361
362 if ( !ARGUMENT_PRESENT( IrpContext ) ) {
363
365
366 return ExceptionCode;
367 }
368
369 //
370 // Get the real exception status from IrpContext->ExceptionStatus, and
371 // reset it.
372 //
373
374 ExceptionCode = IrpContext->ExceptionStatus;
375 FatResetExceptionState( IrpContext );
376
377 //
378 // If this is an Mdl write request, then take care of the Mdl
379 // here so that things get cleaned up properly. Cc now leaves
380 // the MDL in place so a filesystem can retry after clearing an
381 // internal condition (FAT does not).
382 //
383
384 if ((IrpContext->MajorFunction == IRP_MJ_WRITE) &&
385 (FlagOn( IrpContext->MinorFunction, IRP_MN_COMPLETE_MDL ) == IRP_MN_COMPLETE_MDL) &&
386 (Irp->MdlAddress != NULL)) {
387
389
390 CcMdlWriteAbort( LocalIrpSp->FileObject, Irp->MdlAddress );
391 Irp->MdlAddress = NULL;
392 }
393
394 //
395 // If we are going to post the request, we may have to lock down the
396 // user's buffer, so do it here in a try except so that we failed the
397 // request if the LockPages fails.
398 //
399 // Also unpin any repinned Bcbs, protected by the try {} except {} filter.
400 //
401
402 _SEH2_TRY {
403
404 SavedFlags = IrpContext->Flags;
405
406 //
407 // Make sure we don't try to write through Bcbs
408 //
409
411
412 FatUnpinRepinnedBcbs( IrpContext );
413
414 IrpContext->Flags = SavedFlags;
415
416 //
417 // If we will have to post the request, do it here. Note
418 // that the last thing FatPrePostIrp() does is mark the Irp pending,
419 // so it is critical that we actually return PENDING. Nothing
420 // from this point to return can fail, so we are OK.
421 //
422 // We cannot do a verify operations at APC level because we
423 // have to wait for Io operations to complete.
424 //
425
426 if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) &&
429#else
431#endif
433
434 ExceptionCode = FatFsdPostRequest( IrpContext, Irp );
435 }
436
438
439 ExceptionCode = IrpContext->ExceptionStatus;
440 IrpContext->ExceptionStatus = 0;
441
442 IrpContext->Flags = SavedFlags;
443 } _SEH2_END;
444
445 //
446 // If we posted the request, just return here.
447 //
448
450
451 return ExceptionCode;
452 }
453
455
456
457 //
458 // If this request is not a "top-level" irp, just complete it.
459 //
460
461 if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL)) {
462
463 //
464 // If there is a cache operation above us, commute verify
465 // to a lock conflict. This will cause retries so that
466 // we have a chance of getting through without needing
467 // to return an unaesthetic error for the operation.
468 //
469
472
474 }
475
476 FatCompleteRequest( IrpContext, Irp, ExceptionCode );
477
478 return ExceptionCode;
479 }
480
482
483 //
484 // Check for the various error conditions that can be caused by,
485 // and possibly resolved by the user.
486 //
487
489
491
492 DebugTrace(0, Dbg, "Perform Verify Operation\n", 0);
493
494 //
495 // Now we are at the top level file system entry point.
496 //
497 // Grab the device to verify from the thread local storage
498 // and stick it in the information field for transportation
499 // to the fsp. We also clear the field at this time.
500 //
501
502 Device = IoGetDeviceToVerify( Irp->Tail.Overlay.Thread );
503 IoSetDeviceToVerify( Irp->Tail.Overlay.Thread, NULL );
504
505 if ( Device == NULL ) {
506
509
510 NT_ASSERT( Device != NULL );
511 }
512
513 //
514 // It turns out some storage drivers really do set invalid non-NULL device
515 // objects to verify.
516 //
517 // To work around this, completely ignore the device to verify in the thread,
518 // and just use our real device object instead.
519 //
520
521 if (IrpContext->Vcb) {
522
523 Device = IrpContext->Vcb->Vpb->RealDevice;
524
525 } else {
526
527 //
528 // For FSCTLs, IrpContext->Vcb may not be populated, so get the IrpContext->RealDevice instead
529 //
530
531 Device = IrpContext->RealDevice;
532 }
533
534 //
535 // Let's not BugCheck just because the device to verify is somehow still NULL.
536 //
537
538 if (Device == NULL) {
539
541
542 FatCompleteRequest( IrpContext, Irp, ExceptionCode );
543
544 return ExceptionCode;
545 }
546
547 //
548 // FatPerformVerify() will do the right thing with the Irp.
549
550 return FatPerformVerify( IrpContext, Irp, Device );
551 }
552
553 //
554 // The other user induced conditions generate an error unless
555 // they have been disabled for this request.
556 //
557
558 if (FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS)) {
559
560 FatCompleteRequest( IrpContext, Irp, ExceptionCode );
561
562 return ExceptionCode;
563
564 } else {
565
566 //
567 // Generate a pop-up
568 //
569
570 PDEVICE_OBJECT RealDevice = NULL;
571 PVPB Vpb;
573
575
577
578 } else {
579
580 Vpb = NULL;
581 }
582
583 //
584 // The device to verify is either in my thread local storage
585 // or that of the thread that owns the Irp.
586 //
587
588 Thread = Irp->Tail.Overlay.Thread;
589 RealDevice = IoGetDeviceToVerify( Thread );
590
591 if ( RealDevice == NULL ) {
592
594 RealDevice = IoGetDeviceToVerify( Thread );
595
596 NT_ASSERT( RealDevice != NULL );
597 }
598
599 //
600 // It turns out some storage drivers really do set invalid non-NULL device
601 // objects to verify.
602 //
603 // To work around this, completely ignore the device to verify in the thread,
604 // and just use our real device object instead.
605 //
606
607 if (IrpContext->Vcb) {
608
609 RealDevice = IrpContext->Vcb->Vpb->RealDevice;
610
611 } else {
612
613 //
614 // For FSCTLs, IrpContext->Vcb may not be populated, so get the IrpContext->RealDevice instead
615 //
616
617 RealDevice = IrpContext->RealDevice;
618 }
619
620 //
621 // Let's not BugCheck just because the device to verify is somehow still NULL.
622 //
623
624 if (RealDevice == NULL) {
625
626 FatCompleteRequest( IrpContext, Irp, ExceptionCode );
627
628 return ExceptionCode;
629 }
630
631 //
632 // This routine actually causes the pop-up. It usually
633 // does this by queuing an APC to the callers thread,
634 // but in some cases it will complete the request immediately,
635 // so it is very important to IoMarkIrpPending() first.
636 //
637
639 IoRaiseHardError( Irp, Vpb, RealDevice );
640
641 //
642 // We will be handing control back to the caller here, so
643 // reset the saved device object.
644 //
645
647
648 //
649 // The Irp will be completed by Io or resubmitted. In either
650 // case we must clean up the IrpContext here.
651 //
652
653 FatDeleteIrpContext( IrpContext );
654 return STATUS_PENDING;
655 }
656 }
657
658 //
659 // This is just a run of the mill error. If is a STATUS that we
660 // raised ourselves, and the information would be use for the
661 // user, raise an informational pop-up.
662 //
663
665 Vcb = IrpContext->Vcb;
666
667 //
668 // Now, if the Vcb is unknown to us this means that the error was raised
669 // in the process of a mount and before we even had a chance to build
670 // a full Vcb - and was really handled there.
671 //
672
673 if (Vcb != NULL) {
674
678
679 TransitionState = VolumeDirtyWithSurfaceTest;
680 }
681
682 //
683 // If this was a STATUS_FILE_CORRUPT or similar error indicating some
684 // nastiness out on the media, then mark the volume permanently dirty.
685 //
686
687 if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS) &&
688 ( TransitionState == VolumeDirtyWithSurfaceTest ||
695
697 NT_ASSERT( !FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL));
698
700 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
701
702 //
703 // Do the "dirty" work, ignoring any error. We need to take the Vcb here
704 // to synchronize against the verify path tearing things down, since
705 // we dropped all synchronization when backing up due to the exception.
706 //
707
709
710 _SEH2_TRY {
711
712 if (VcbGood == Vcb->VcbCondition) {
713
714 FatMarkVolume( IrpContext, Vcb, TransitionState );
715 }
716 }
718
719 NOTHING;
720 } _SEH2_END;
721
722 FatReleaseVcb( IrpContext, Vcb);
723 }
724 }
725
726 FatCompleteRequest( IrpContext, Irp, ExceptionCode );
727
728 return ExceptionCode;
729}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define STATUS_EA_LIST_INCONSISTENT
Definition: IoEaTest.cpp:21
VOID NTAPI CcMdlWriteAbort(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:120
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1774
#define IRP_CONTEXT_FLAG_DISABLE_POPUPS
Definition: cdstruc.h:1222
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4138
#define FAT_NTC_VCB
Definition: nodetype.h:28
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID FatUnpinRepinnedBcbs(IN PIRP_CONTEXT IrpContext)
Definition: cachesup.c:1407
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
#define Dbg
Definition: fatdata.c:28
#define FatNull
Definition: fatdata.h:321
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
@ VolumeDirty
Definition: fatprocs.h:1956
@ VolumeDirtyWithSurfaceTest
Definition: fatprocs.h:1957
#define FatDeleteIrpContext(IRPCONTEXT)
Definition: fatprocs.h:1763
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2634
#define FatDeviceIsFatFsdo(D)
Definition: fatprocs.h:3096
#define FatResetExceptionState(IRPCONTEXT)
Definition: fatprocs.h:2984
#define FatAcquireExclusiveVcbNoOpCheck(IC, V)
Definition: fatprocs.h:1462
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1676
enum _FAT_VOLUME_STATE FAT_VOLUME_STATE
#define FatReleaseVcb(IRPCONTEXT, Vcb)
Definition: fatprocs.h:1641
#define IRP_CONTEXT_FLAG_RECURSIVE_CALL
Definition: fatstruc.h:1566
#define VCB_STATE_FLAG_MOUNTED_DIRTY
Definition: fatstruc.h:562
@ VcbGood
Definition: fatstruc.h:223
#define IRP_CONTEXT_FLAG_DISABLE_WRITE_THROUGH
Definition: fatstruc.h:1565
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60
_Must_inspect_result_ _In_ PUCXHUB_DEVICE_CREATE_INFO _Out_ UCXUSBDEVICE * Device
Definition: hubucx.h:258
IoMarkIrpPending(Irp)
#define NTDDI_VERSION
Definition: k32.h:35
_In_ PIRP Irp
Definition: kse.h:79
if(dx< 0)
Definition: linetemp.h:194
#define ARGUMENT_PRESENT(ArgumentPointer)
BOOLEAN NTAPI FsRtlIsTotalDeviceFailure(IN NTSTATUS NtStatus)
Definition: filter.c:37
VOID NTAPI IoRaiseHardError(IN PIRP Irp, IN PVPB Vpb, IN PDEVICE_OBJECT RealDeviceObject)
Definition: error.c:664
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1875
VOID NTAPI IoSetDeviceToVerify(IN PETHREAD Thread, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:304
PDEVICE_OBJECT NTAPI IoGetDeviceToVerify(IN PETHREAD Thread)
Definition: util.c:336
BOOLEAN NTAPI KeAreAllApcsDisabled(VOID)
Definition: apc.c:985
#define STATUS_CANT_WAIT
Definition: ntstatus.h:546
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:414
#define STATUS_INVALID_EA_NAME
Definition: ntstatus.h:279
#define STATUS_EA_CORRUPT_ERROR
Definition: ntstatus.h:413
#define STATUS_NO_EAS_ON_FILE
Definition: ntstatus.h:412
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:203
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define NTDDI_VISTA
Definition: sdkddkver.h:103
PFILE_OBJECT FileObject
Definition: iotypes.h:3184
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3238
IO_STATUS_BLOCK IoStatus
Definition: iotypes.h:189
#define STATUS_PENDING
Definition: telnetd.h:14
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
#define STATUS_DISK_CORRUPT_ERROR
Definition: udferr_usr.h:147
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:3142
#define IRP_MN_COMPLETE_MDL
Definition: iotypes.h:4440
#define NT_ASSERT
Definition: rtlfuncs.h:3334

◆ FatCompleteRequest_Real()

VOID FatCompleteRequest_Real ( IN PIRP_CONTEXT IrpContext  OPTIONAL,
IN PIRP Irp  OPTIONAL,
IN NTSTATUS  Status 
)

Definition at line 733 of file fatdata.c.

757{
758 PAGED_CODE();
759
760#if DBG
761 if ( (FatBreakOnInterestingIrpCompletion != 0) && (Status == FatBreakOnInterestingIrpCompletion) ) {
763 }
764
765#endif
766
767 //
768 // If we have an Irp Context then unpin all of the repinned bcbs
769 // we might have collected.
770 //
771
772 if (IrpContext != NULL) {
773
774 NT_ASSERT( IrpContext->Repinned.Bcb[0] == NULL );
775
776 FatUnpinRepinnedBcbs( IrpContext );
777 }
778
779 //
780 // Delete the Irp context before completing the IRP so if
781 // we run into some of the asserts, we can still backtrack
782 // through the IRP.
783 //
784
785 if (IrpContext != NULL) {
786
787 FatDeleteIrpContext( IrpContext );
788 }
789
790 //
791 // If we have an Irp then complete the irp.
792 //
793
794 if (Irp != NULL) {
795
796 //
797 // We got an error, so zero out the information field before
798 // completing the request if this was an input operation.
799 // Otherwise IopCompleteRequest will try to copy to the user's buffer.
800 //
801
802 if ( NT_ERROR(Status) &&
803 FlagOn(Irp->Flags, IRP_INPUT_OPERATION) ) {
804
805 Irp->IoStatus.Information = 0;
806 }
807
808 Irp->IoStatus.Status = Status;
809
811 }
812
813 return;
814}
Status
Definition: gdiplustypes.h:24
#define IoCompleteRequest
Definition: irp.c:1272
#define NT_ERROR(Status)
Definition: umtypes.h:106
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define IRP_INPUT_OPERATION
#define IO_DISK_INCREMENT
Definition: iotypes.h:600

◆ FatExceptionFilter()

ULONG FatExceptionFilter ( IN PIRP_CONTEXT  IrpContext,
IN PEXCEPTION_POINTERS  ExceptionPointer 
)

Definition at line 204 of file fatdata.c.

229{
231
232 ExceptionCode = ExceptionPointer->ExceptionRecord->ExceptionCode;
233 DebugTrace(0, DEBUG_TRACE_UNWIND, "FatExceptionFilter %X\n", ExceptionCode);
234 DebugDump("FatExceptionFilter\n", Dbg, NULL );
235
236#if DBG
237
238 if( FatBreakOnInterestingExceptionStatus != 0 && ExceptionCode == FatBreakOnInterestingExceptionStatus ) {
240 }
241
242#endif
243
244 //
245 // If the exception is STATUS_IN_PAGE_ERROR, get the I/O error code
246 // from the exception record.
247 //
248
250 if (ExceptionPointer->ExceptionRecord->NumberParameters >= 3) {
251 ExceptionCode = (NTSTATUS)ExceptionPointer->ExceptionRecord->ExceptionInformation[2];
252 }
253 }
254
255 //
256 // If there is not an irp context, we must have had insufficient resources.
257 //
258
259 if ( !ARGUMENT_PRESENT( IrpContext ) ) {
260
262
263#ifdef _MSC_VER
264#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
265#endif
266 FatBugCheck( (ULONG_PTR)ExceptionPointer->ExceptionRecord,
267 (ULONG_PTR)ExceptionPointer->ContextRecord,
268 (ULONG_PTR)ExceptionPointer->ExceptionRecord->ExceptionAddress );
269 }
270
272 }
273
274 //
275 // For the purposes of processing this exception, let's mark this
276 // request as being able to wait and disable write through if we
277 // aren't posting it.
278 //
279
280 SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
281
284
286 }
287
288 if ( IrpContext->ExceptionStatus == 0 ) {
289
291
292 IrpContext->ExceptionStatus = ExceptionCode;
293
295
296 } else {
297
298#ifdef _MSC_VER
299#pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
300#endif
301 FatBugCheck( (ULONG_PTR)ExceptionPointer->ExceptionRecord,
302 (ULONG_PTR)ExceptionPointer->ContextRecord,
303 (ULONG_PTR)ExceptionPointer->ExceptionRecord->ExceptionAddress );
304 }
305
306 } else {
307
308 //
309 // We raised this code explicitly ourselves, so it had better be
310 // expected.
311 //
312
313 NT_ASSERT( IrpContext->ExceptionStatus == ExceptionCode );
315 }
316
318}
LONG NTSTATUS
Definition: precomp.h:26
#define NTSTATUS
Definition: precomp.h:19
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
#define DebugDump(STR, LEVEL, PTR)
Definition: fatdata.h:314
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:336
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by _Function_class_(), _Requires_lock_held_(), FatFlushFat(), FatFspDispatch(), FatFspMarkVolumeDirtyWithRecover(), FatMultiAsyncCompletionRoutine(), and FatSingleAsyncCompletionRoutine().

◆ FatIsIrpTopLevel()

BOOLEAN FatIsIrpTopLevel ( IN PIRP  Irp)

Definition at line 817 of file fatdata.c.

841{
842 PAGED_CODE();
843
844 if ( IoGetTopLevelIrp() == NULL ) {
845
847
848 return TRUE;
849
850 } else {
851
852 return FALSE;
853 }
854}
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2032

Referenced by _Function_class_(), and _Requires_lock_held_().

Variable Documentation

◆ Fat100Milliseconds

LARGE_INTEGER Fat100Milliseconds = {(ULONG)(-30 * 1000 * 10), -1}

Definition at line 71 of file fatdata.c.

◆ Fat30Milliseconds

LARGE_INTEGER Fat30Milliseconds = {(ULONG)(-30 * 1000 * 10), -1}

Definition at line 70 of file fatdata.c.

Referenced by FatPagingFileIo().

◆ FatCdromFileSystemDeviceObject

PDEVICE_OBJECT FatCdromFileSystemDeviceObject

Definition at line 59 of file fatdata.c.

Referenced by _Requires_lock_held_().

◆ FatCloseContextSList

SLIST_HEADER FatCloseContextSList

Definition at line 106 of file fatdata.c.

Referenced by FatAllocateCloseContext(), and FatPreallocateCloseContext().

◆ FatCloseQueueMutex

FAST_MUTEX FatCloseQueueMutex

Definition at line 112 of file fatdata.c.

◆ FatData

◆ FatDecThirtyOne1979

LARGE_INTEGER FatDecThirtyOne1979 = {0xb76bc000,0x01a8e6d6}

Definition at line 74 of file fatdata.c.

◆ FatDiskAccountingEnabled

◆ FatDiskFileSystemDeviceObject

PDEVICE_OBJECT FatDiskFileSystemDeviceObject

Definition at line 58 of file fatdata.c.

Referenced by _Requires_lock_held_().

◆ FatEResourceLookasideList

NPAGED_LOOKASIDE_LIST FatEResourceLookasideList

Definition at line 104 of file fatdata.c.

Referenced by FatAllocateResource(), and FatFreeResource().

◆ FatFastIoDispatch

FAST_IO_DISPATCH FatFastIoDispatch

Definition at line 96 of file fatdata.c.

◆ FatIrpContextLookasideList

NPAGED_LOOKASIDE_LIST FatIrpContextLookasideList

Definition at line 102 of file fatdata.c.

Referenced by FatAllocateIrpContext(), and FatFreeIrpContext().

◆ FatJanOne1980

LARGE_INTEGER FatJanOne1980 = {0xe1d58000,0x01a8e79f}

◆ FatLargeZero

LARGE_INTEGER FatLargeZero = {0,0}

◆ FatMagic10000

LARGE_INTEGER FatMagic10000 = {0xe219652c, 0xd1b71758}

Definition at line 86 of file fatdata.c.

◆ FatMagic86400000

LARGE_INTEGER FatMagic86400000 = {0xfa67b90e, 0xc6d750eb}

Definition at line 87 of file fatdata.c.

◆ FatMaxLarge

LARGE_INTEGER FatMaxLarge = {MAXULONG,MAXLONG}

Definition at line 63 of file fatdata.c.

Referenced by _Requires_lock_held_(), FatOpenEaFile(), and FatSetupAllocationSupport().

◆ FatNonPagedFcbLookasideList

NPAGED_LOOKASIDE_LIST FatNonPagedFcbLookasideList

Definition at line 103 of file fatdata.c.

Referenced by FatAllocateNonPagedFcb(), and FatFreeNonPagedFcb().

◆ FatOneDay

LARGE_INTEGER FatOneDay = {0x2a69c000, 0xc9}

Definition at line 72 of file fatdata.c.

◆ FatReserveEvent

KEVENT FatReserveEvent

Definition at line 123 of file fatdata.c.

Referenced by FatPagingFileCompletionRoutineCatch(), and FatPagingFileIo().

◆ FatReserveMdl

PMDL FatReserveMdl = NULL

Definition at line 119 of file fatdata.c.

Referenced by FatPagingFileCompletionRoutineCatch(), and FatPagingFileIo().

◆ FatTimeJanOne1980

FAT_TIME_STAMP FatTimeJanOne1980 = {{0,0,0},{1,1,0}}

Definition at line 83 of file fatdata.c.