ReactOS 0.4.15-dev-7958-gcd0bb1a
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:2665
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:2666
#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:782
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:748
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_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::@720 Specific
struct _FCB::@720::@723 Fcb
Definition: cdstruc.h:498
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_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{
1001 BOOLEAN Results = FALSE;
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
1068 try_return( Results );
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
_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 _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define NOTHING
Definition: input_list.c:10
#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 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{
1342 BOOLEAN Results = FALSE;
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
1410 try_return( Results );
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
1474 try_return( Results );
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{
1181 BOOLEAN Results = FALSE;
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
1249 try_return( Results );
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
1270 try_return( Results );
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
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#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:1955
@ VolumeDirtyWithSurfaceTest
Definition: fatprocs.h:1956
#define FatDeleteIrpContext(IRPCONTEXT)
Definition: fatprocs.h:1762
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
#define FatCompleteRequest(IRPCONTEXT, IRP, STATUS)
Definition: fatprocs.h:2633
#define FatDeviceIsFatFsdo(D)
Definition: fatprocs.h:3095
#define FatResetExceptionState(IRPCONTEXT)
Definition: fatprocs.h:2983
#define FatAcquireExclusiveVcbNoOpCheck(IC, V)
Definition: fatprocs.h:1461
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1675
enum _FAT_VOLUME_STATE FAT_VOLUME_STATE
#define FatReleaseVcb(IRPCONTEXT, Vcb)
Definition: fatprocs.h:1640
#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
IoMarkIrpPending(Irp)
#define NTDDI_VERSION
Definition: k32.h:33
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:1843
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:452
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:320
#define STATUS_INVALID_EA_NAME
Definition: ntstatus.h:199
#define STATUS_EA_CORRUPT_ERROR
Definition: ntstatus.h:319
#define STATUS_NO_EAS_ON_FILE
Definition: ntstatus.h:318
#define STATUS_PENDING
Definition: ntstatus.h:82
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define NTDDI_VISTA
Definition: sdkddkver.h:103
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
IO_STATUS_BLOCK IoStatus
Definition: iotypes.h:189
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
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817
#define IRP_MN_COMPLETE_MDL
Definition: iotypes.h:4424
#define NT_ASSERT
Definition: rtlfuncs.h:3310

◆ 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:25
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define IoCompleteRequest
Definition: irp.c:1240
#define NT_ERROR(Status)
Definition: umtypes.h:106
#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:21
#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:85
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:243
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:2000

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

LOGICAL FatDiskAccountingEnabled = FALSE

◆ 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.