ReactOS  0.4.15-dev-1148-g8a4273b
deviosup.c File Reference
#include "fatprocs.h"
Include dependency graph for deviosup.c:

Go to the source code of this file.

Classes

struct  _FAT_SYNC_CONTEXT
 
struct  FAT_PAGING_FILE_CONTEXT
 

Macros

#define BugCheckFileId   (FAT_BUG_CHECK_DEVIOSUP)
 
#define Dbg   (DEBUG_TRACE_DEVIOSUP)
 
#define CollectDiskIoStats(VCB, FUNCTION, IS_USER_IO, COUNT)
 
#define FatLowLevelReadWrite(IRPCONTEXT, DO, IRP, VCB)
 
#define FatDoCompletionZero(I, C)
 
#define FatUpdateIOCountersPCW(IsAWrite, Count)
 

Typedefs

typedef struct _FAT_SYNC_CONTEXT FAT_SYNC_CONTEXT
 
typedef struct _FAT_SYNC_CONTEXTPFAT_SYNC_CONTEXT
 
typedef struct FAT_PAGING_FILE_CONTEXT FAT_PAGING_FILE_CONTEXT
 
typedef struct FAT_PAGING_FILE_CONTEXTPFAT_PAGING_FILE_CONTEXT
 

Functions

NTSTATUS NTAPI FatMultiSyncCompletionRoutine (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt)
 
NTSTATUS NTAPI FatMultiAsyncCompletionRoutine (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt)
 
NTSTATUS NTAPI FatSpecialSyncCompletionRoutine (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt)
 
NTSTATUS NTAPI FatSingleSyncCompletionRoutine (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt)
 
NTSTATUS NTAPI FatSingleAsyncCompletionRoutine (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt)
 
NTSTATUS NTAPI FatPagingFileCompletionRoutine (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID MasterIrp)
 
NTSTATUS NTAPI FatPagingFileCompletionRoutineCatch (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_reads_opt_(_Inexpressible_("varies")) PVOID Contxt)
 
VOID FatSingleNonAlignedSync (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PUCHAR Buffer, IN LBO Lbo, IN ULONG ByteCount, IN PIRP Irp)
 
VOID FatPagingFileIo (IN PIRP Irp, IN PFCB Fcb)
 
VOID FatUpdateDiskStats (IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN ULONG ByteCount)
 
 _Requires_lock_held_ (_Global_critical_region_)
 
VOID FatMultipleAsync (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PIRP MasterIrp, IN ULONG MultipleIrpCount, IN PIO_RUN IoRuns)
 
VOID FatSingleAsync (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN LBO Lbo, IN ULONG ByteCount, IN PIRP Irp)
 
VOID FatWaitSync (IN PIRP_CONTEXT IrpContext)
 
NTSTATUS FatPagingFileErrorHandler (IN PIRP Irp, IN PKEVENT Event OPTIONAL)
 
VOID FatLockUserBuffer (IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp, IN LOCK_OPERATION Operation, IN ULONG BufferLength)
 
PVOID FatMapUserBuffer (IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp)
 
PVOID FatBufferUserBuffer (IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp, IN ULONG BufferLength)
 
NTSTATUS FatToggleMediaEjectDisable (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN PreventRemoval)
 
NTSTATUS FatPerformDevIoCtrl (IN PIRP_CONTEXT IrpContext, IN ULONG IoControlCode, IN PDEVICE_OBJECT Device, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN BOOLEAN OverrideVerify, OUT PIO_STATUS_BLOCK Iosb OPTIONAL)
 
PMDL FatBuildZeroMdl (__in PIRP_CONTEXT IrpContext, __in ULONG Length)
 

Variables

IO_COMPLETION_ROUTINE FatMultiSyncCompletionRoutine
 
IO_COMPLETION_ROUTINE FatMultiAsyncCompletionRoutine
 
IO_COMPLETION_ROUTINE FatSpecialSyncCompletionRoutine
 
IO_COMPLETION_ROUTINE FatSingleSyncCompletionRoutine
 
IO_COMPLETION_ROUTINE FatSingleAsyncCompletionRoutine
 
IO_COMPLETION_ROUTINE FatPagingFileCompletionRoutine
 
IO_COMPLETION_ROUTINE FatPagingFileCompletionRoutineCatch
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (FAT_BUG_CHECK_DEVIOSUP)

Definition at line 22 of file deviosup.c.

◆ CollectDiskIoStats

#define CollectDiskIoStats (   VCB,
  FUNCTION,
  IS_USER_IO,
  COUNT 
)
Value:
{ \
PFILESYSTEM_STATISTICS Stats = &(VCB)->Statistics[KeGetCurrentProcessorNumber() % FatData.NumberProcessors].Common; \
if (IS_USER_IO) { \
if ((FUNCTION) == IRP_MJ_WRITE) { \
Stats->UserDiskWrites += (COUNT); \
} else { \
Stats->UserDiskReads += (COUNT); \
} \
} else { \
if ((FUNCTION) == IRP_MJ_WRITE) { \
Stats->MetaDataDiskWrites += (COUNT); \
} else { \
Stats->MetaDataDiskReads += (COUNT); \
} \
} \
}
#define COUNT
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:337
ULONG NumberProcessors
Definition: fatstruc.h:80
struct _VCB VCB
FAT_DATA FatData
Definition: fatdata.c:56
#define IRP_MJ_WRITE
Definition: rdpdr.c:47

Definition at line 30 of file deviosup.c.

◆ Dbg

#define Dbg   (DEBUG_TRACE_DEVIOSUP)

Definition at line 28 of file deviosup.c.

◆ FatDoCompletionZero

#define FatDoCompletionZero (   I,
  C 
)
Value:
if ((C)->ZeroMdl) { \
NT_ASSERT( (C)->ZeroMdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | \
if (NT_SUCCESS((I)->IoStatus.Status)) { \
RtlZeroMemory( (C)->ZeroMdl->MappedSystemVa, \
(C)->ZeroMdl->ByteCount ); \
} \
IoFreeMdl((C)->ZeroMdl); \
(C)->ZeroMdl = NULL; \
}
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2659
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
smooth NULL
Definition: ftsmooth.c:416
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define I(s)
Definition: ttei6.cpp:27
#define C(c)
Definition: builtin.c:4556

Definition at line 171 of file deviosup.c.

◆ FatLowLevelReadWrite

#define FatLowLevelReadWrite (   IRPCONTEXT,
  DO,
  IRP,
  VCB 
)
Value:
( \
IoCallDriver((DO),(IRP)) \
)
#define DO
Definition: ftp_var.h:15

Definition at line 163 of file deviosup.c.

◆ FatUpdateIOCountersPCW

#define FatUpdateIOCountersPCW (   IsAWrite,
  Count 
)
Value:
FsRtlUpdateDiskCounters( ((IsAWrite) ? 0 : (Count) ), \
((IsAWrite) ? (Count) : 0) )
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223

Definition at line 184 of file deviosup.c.

Typedef Documentation

◆ FAT_PAGING_FILE_CONTEXT

◆ FAT_SYNC_CONTEXT

◆ PFAT_PAGING_FILE_CONTEXT

◆ PFAT_SYNC_CONTEXT

Function Documentation

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 880 of file deviosup.c.

921 {
922 
923  //
924  // Declare some local variables for enumeration through the
925  // runs of the file, and an array to store parameters for
926  // parallel I/Os
927  //
928 
929  BOOLEAN Wait;
930 
931  LBO NextLbo;
932  VBO NextVbo;
933  ULONG NextByteCount;
934  BOOLEAN NextIsAllocated;
935 
936  LBO LastLbo;
937  ULONG LastByteCount;
938  BOOLEAN LastIsAllocated;
939 
941 
942  ULONG FirstIndex;
943  ULONG CurrentIndex;
944  ULONG LastIndex;
945 
946  ULONG NextRun;
947  ULONG BufferOffset;
948  ULONG OriginalByteCount;
949 
950 
951 
952  IO_RUN StackIoRuns[FAT_MAX_IO_RUNS_ON_STACK];
953  PIO_RUN IoRuns;
954 
955 
956  PAGED_CODE();
957 
959 
960  DebugTrace(+1, Dbg, "FatNonCachedIo\n", 0);
961  DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
962  DebugTrace( 0, Dbg, "MajorFunction = %08lx\n", IrpContext->MajorFunction );
963  DebugTrace( 0, Dbg, "FcbOrDcb = %p\n", FcbOrDcb );
964  DebugTrace( 0, Dbg, "StartingVbo = %08lx\n", StartingVbo );
965  DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount );
966 
967  if (!FlagOn(Irp->Flags, IRP_PAGING_IO)) {
968 
971 
972  if (IrpContext->MajorFunction == IRP_MJ_READ) {
973  Stats->Fat.NonCachedReads += 1;
974  Stats->Fat.NonCachedReadBytes += ByteCount;
975  } else {
976  Stats->Fat.NonCachedWrites += 1;
978  }
979  }
980 
981  //
982  // Initialize some locals.
983  //
984 
985  NextRun = 0;
986  BufferOffset = 0;
987  OriginalByteCount = ByteCount;
988 
989  Wait = BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
990 
991 #if (NTDDI_VERSION >= NTDDI_WIN8)
992 
993  //
994  // Disk IO accounting
995  //
996 
998 
999  FatUpdateDiskStats( IrpContext,
1000  Irp,
1001  ByteCount );
1002  }
1003 #endif
1004 
1005  //
1006  // For nonbuffered I/O, we need the buffer locked in all
1007  // cases.
1008  //
1009  // This call may raise. If this call succeeds and a subsequent
1010  // condition is raised, the buffers are unlocked automatically
1011  // by the I/O system when the request is completed, via the
1012  // Irp->MdlAddress field.
1013  //
1014 
1015  FatLockUserBuffer( IrpContext,
1016  Irp,
1017  (IrpContext->MajorFunction == IRP_MJ_READ) ?
1019  ByteCount );
1020 
1021 
1022 
1023  //
1024  // No zeroing for trailing sectors if requested.
1025  // Otherwise setup the required zeroing for read requests.
1026  //
1027 
1028 
1029  if (UserByteCount != ByteCount) {
1030 
1031 
1032  PMDL Mdl;
1033 
1036 
1037  Mdl = IoAllocateMdl( (PUCHAR) Irp->UserBuffer + UserByteCount,
1039  FALSE,
1040  FALSE,
1041  NULL );
1042 
1043  if (Mdl == NULL) {
1044 
1046  }
1047 
1048  IoBuildPartialMdl( Irp->MdlAddress,
1049  Mdl,
1050  (PUCHAR) Irp->UserBuffer + UserByteCount,
1052 
1053  IrpContext->FatIoContext->ZeroMdl = Mdl;
1054 
1055  //
1056  // Map the MDL now so we can't fail at IO completion time. Note
1057  // that this will be only a single page.
1058  //
1059 
1060  if (MmGetSystemAddressForMdlSafe( Mdl, NormalPagePriority | MdlMappingNoExecute ) == NULL) {
1061 
1063  }
1064  }
1065 
1066 
1067  //
1068  // Try to lookup the first run. If there is just a single run,
1069  // we may just be able to pass it on.
1070  //
1071 
1072  FatLookupFileAllocation( IrpContext,
1073  FcbOrDcb,
1074  StartingVbo,
1075  &NextLbo,
1076  &NextByteCount,
1077  &NextIsAllocated,
1078  &EndOnMax,
1079  &FirstIndex );
1080 
1081  //
1082  // We just added the allocation, thus there must be at least
1083  // one entry in the mcb corresponding to our write, ie.
1084  // NextIsAllocated must be true. If not, the pre-existing file
1085  // must have an allocation error.
1086  //
1087 
1088  if ( !NextIsAllocated ) {
1089 
1090  FatPopUpFileCorrupt( IrpContext, FcbOrDcb );
1091 
1093  }
1094 
1095  NT_ASSERT( NextByteCount != 0 );
1096 
1097  //
1098  // If the request was not aligned correctly, read in the first
1099  // part first.
1100  //
1101 
1102 
1103  //
1104  // See if the write covers a single valid run, and if so pass
1105  // it on. We must bias this by the byte that is lost at the
1106  // end of the maximal file.
1107  //
1108 
1109  if ( NextByteCount >= ByteCount - (EndOnMax ? 1 : 0)) {
1110 
1111  if (FlagOn(Irp->Flags, IRP_PAGING_IO)) {
1112  CollectDiskIoStats(FcbOrDcb->Vcb, IrpContext->MajorFunction,
1113  FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_USER_IO), 1);
1114  } else {
1115 
1116  PFILE_SYSTEM_STATISTICS Stats =
1118 
1119  if (IrpContext->MajorFunction == IRP_MJ_READ) {
1120  Stats->Fat.NonCachedDiskReads += 1;
1121  } else {
1122  Stats->Fat.NonCachedDiskWrites += 1;
1123  }
1124  }
1125 
1126  DebugTrace( 0, Dbg, "Passing 1 Irp on to Disk Driver\n", 0 );
1127 
1128  FatSingleAsync( IrpContext,
1129  FcbOrDcb->Vcb,
1130  NextLbo,
1131  ByteCount,
1132  Irp );
1133 
1134  } else {
1135 
1136  //
1137  // If there we can't wait, and there are more runs than we can handle,
1138  // we will have to post this request.
1139  //
1140 
1141  FatLookupFileAllocation( IrpContext,
1142  FcbOrDcb,
1143  StartingVbo + ByteCount - 1,
1144  &LastLbo,
1145  &LastByteCount,
1146  &LastIsAllocated,
1147  &EndOnMax,
1148  &LastIndex );
1149 
1150  //
1151  // Since we already added the allocation for the whole
1152  // write, assert that we find runs until ByteCount == 0
1153  // Otherwise this file is corrupt.
1154  //
1155 
1156  if ( !LastIsAllocated ) {
1157 
1158  FatPopUpFileCorrupt( IrpContext, FcbOrDcb );
1159 
1161  }
1162 
1163  if (LastIndex - FirstIndex + 1 > FAT_MAX_IO_RUNS_ON_STACK) {
1164 
1166  (LastIndex - FirstIndex + 1) * sizeof(IO_RUN),
1167  TAG_IO_RUNS );
1168 
1169  } else {
1170 
1171  IoRuns = StackIoRuns;
1172  }
1173 
1174  NT_ASSERT( LastIndex != FirstIndex );
1175 
1176  CurrentIndex = FirstIndex;
1177 
1178  //
1179  // Loop while there are still byte writes to satisfy.
1180  //
1181 
1182  while (CurrentIndex <= LastIndex) {
1183 
1184 
1185  NT_ASSERT( NextByteCount != 0);
1186  NT_ASSERT( ByteCount != 0);
1187 
1188  //
1189  // If next run is larger than we need, "ya get what you need".
1190  //
1191 
1192  if (NextByteCount > ByteCount) {
1193  NextByteCount = ByteCount;
1194  }
1195 
1196  //
1197  // Now that we have properly bounded this piece of the
1198  // transfer, it is time to write it.
1199  //
1200  // We remember each piece of a parallel run by saving the
1201  // essential information in the IoRuns array. The tranfers
1202  // are started up in parallel below.
1203  //
1204 
1205  IoRuns[NextRun].Vbo = StartingVbo;
1206  IoRuns[NextRun].Lbo = NextLbo;
1207  IoRuns[NextRun].Offset = BufferOffset;
1208  IoRuns[NextRun].ByteCount = NextByteCount;
1209  NextRun += 1;
1210 
1211  //
1212  // Now adjust everything for the next pass through the loop.
1213  //
1214 
1215  StartingVbo += NextByteCount;
1216  BufferOffset += NextByteCount;
1217  ByteCount -= NextByteCount;
1218 
1219  //
1220  // Try to lookup the next run (if we are not done).
1221  //
1222 
1223  CurrentIndex += 1;
1224 
1225  if ( CurrentIndex <= LastIndex ) {
1226 
1227  NT_ASSERT( ByteCount != 0 );
1228 
1230  CurrentIndex,
1231  &NextVbo,
1232  &NextLbo,
1233  &NextByteCount );
1234 
1235 
1236  NT_ASSERT(NextVbo == StartingVbo);
1237 
1238 
1239  }
1240 
1241  } // while ( CurrentIndex <= LastIndex )
1242 
1243  //
1244  // Now set up the Irp->IoStatus. It will be modified by the
1245  // multi-completion routine in case of error or verify required.
1246  //
1247 
1248  Irp->IoStatus.Status = STATUS_SUCCESS;
1249  Irp->IoStatus.Information = OriginalByteCount;
1250 
1251  if (FlagOn(Irp->Flags, IRP_PAGING_IO)) {
1252  CollectDiskIoStats(FcbOrDcb->Vcb, IrpContext->MajorFunction,
1253  FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_USER_IO), NextRun);
1254  }
1255 
1256  //
1257  // OK, now do the I/O.
1258  //
1259 
1260  _SEH2_TRY {
1261 
1262  DebugTrace( 0, Dbg, "Passing Multiple Irps on to Disk Driver\n", 0 );
1263 
1264  FatMultipleAsync( IrpContext,
1265  FcbOrDcb->Vcb,
1266  Irp,
1267  NextRun,
1268  IoRuns );
1269 
1270  } _SEH2_FINALLY {
1271 
1272  if (IoRuns != StackIoRuns) {
1273 
1274  ExFreePool( IoRuns );
1275  }
1276  } _SEH2_END;
1277  }
1278 
1279  if (!Wait) {
1280 
1281  DebugTrace(-1, Dbg, "FatNonCachedIo -> STATUS_PENDING\n", 0);
1282  return STATUS_PENDING;
1283  }
1284 
1285  FatWaitSync( IrpContext );
1286 
1287 
1288  DebugTrace(-1, Dbg, "FatNonCachedIo -> 0x%08lx\n", Irp->IoStatus.Status);
1289  return Irp->IoStatus.Status;
1290 }
ULONG NonCachedReadBytes
Definition: winioctl.h:681
#define TAG_IO_RUNS
Definition: nodetype.h:168
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
ULONG NonCachedWrites
Definition: winioctl.h:682
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _FILE_SYSTEM_STATISTICS * Statistics
Definition: fatstruc.h:505
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
ULONG NonCachedReads
Definition: winioctl.h:680
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
LOGICAL FatDiskAccountingEnabled
Definition: fatdata.c:129
VOID FatLockUserBuffer(IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp, IN LOCK_OPERATION Operation, IN ULONG BufferLength)
Definition: deviosup.c:3276
ULONG32 VBO
Definition: fat.h:38
unsigned char * PUCHAR
Definition: retypes.h:3
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
VOID FatWaitSync(IN PIRP_CONTEXT IrpContext)
Definition: deviosup.c:2367
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2974
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
ULONG NonCachedDiskWrites
Definition: winioctl.h:685
IN PIRP IN PFCB IN ULONG IN ULONG IN ULONG UserByteCount
Definition: fatprocs.h:589
_SEH2_TRY
Definition: create.c:4226
ULONG NonCachedWriteBytes
Definition: winioctl.h:683
FAT_STATISTICS Fat
Definition: fatstruc.h:601
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:337
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
IN PFCB FcbOrDcb
Definition: fatprocs.h:306
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN OUT PBOOLEAN EndOnMax
Definition: fatprocs.h:306
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
ULONG NumberProcessors
Definition: fatstruc.h:80
#define FALSE
Definition: types.h:117
LONGLONG LBO
Definition: fat.h:34
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define CollectDiskIoStats(VCB, FUNCTION, IS_USER_IO, COUNT)
Definition: deviosup.c:30
#define IRP_CONTEXT_FLAG_USER_IO
Definition: ext2fs.h:1086
FAT_DATA FatData
Definition: fatdata.c:56
ULONG NonCachedDiskReads
Definition: winioctl.h:684
#define STATUS_PENDING
Definition: ntstatus.h:82
BOOLEAN FatGetNextMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN ULONG RunIndex, OUT PVBO Vbo, OUT PLBO Lbo, OUT PULONG ByteCount)
Definition: fsctrl.c:541
#define FAT_MAX_IO_RUNS_ON_STACK
Definition: fatdata.h:102
CD_MCB Mcb
Definition: cdstruc.h:1022
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define Dbg
Definition: deviosup.c:28
IN PVCB IN VBO StartingVbo
Definition: fatprocs.h:411
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1081
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
_SEH2_END
Definition: create.c:4400
_SEH2_FINALLY
Definition: create.c:4371
#define IRP_PAGING_IO
#define IRP_MJ_READ
Definition: rdpdr.c:46
unsigned int ULONG
Definition: retypes.h:1
PVCB Vcb
Definition: cdstruc.h:939
VOID FatMultipleAsync(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PIRP MasterIrp, IN ULONG MultipleIrpCount, IN PIO_RUN IoRuns)
Definition: deviosup.c:1622
IN PIRP IN PFCB IN ULONG IN ULONG IN ULONG IN ULONG StreamFlags
Definition: fatprocs.h:589
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
VOID FatSingleAsync(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN LBO Lbo, IN ULONG ByteCount, IN PIRP Irp)
Definition: deviosup.c:1990
VOID FatUpdateDiskStats(IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN ULONG ByteCount)
Definition: deviosup.c:760
#define _Analysis_assume_(expr)
Definition: no_sal2.h:10
#define PAGED_CODE()
IN BOOLEAN Wait
Definition: fatprocs.h:1538
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ FatBufferUserBuffer()

PVOID FatBufferUserBuffer ( IN PIRP_CONTEXT  IrpContext,
IN OUT PIRP  Irp,
IN ULONG  BufferLength 
)

Definition at line 3411 of file deviosup.c.

3438 {
3439  PUCHAR UserBuffer;
3440 
3441  UNREFERENCED_PARAMETER( IrpContext );
3442 
3443  PAGED_CODE();
3444 
3445  //
3446  // Handle the no buffer case.
3447  //
3448 
3449  if (BufferLength == 0) {
3450 
3451  return NULL;
3452  }
3453 
3454  //
3455  // If there is no system buffer we must have been supplied an Mdl
3456  // describing the users input buffer, which we will now snapshot.
3457  //
3458 
3459  if (Irp->AssociatedIrp.SystemBuffer == NULL) {
3460 
3461  UserBuffer = FatMapUserBuffer( IrpContext, Irp );
3462 
3463  Irp->AssociatedIrp.SystemBuffer = FsRtlAllocatePoolWithQuotaTag( NonPagedPoolNx,
3464  BufferLength,
3466 
3467  //
3468  // Set the flags so that the completion code knows to deallocate the
3469  // buffer.
3470  //
3471 
3473 
3474  _SEH2_TRY {
3475 
3476  RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer,
3477  UserBuffer,
3478  BufferLength );
3479 
3481 
3482  NTSTATUS Status;
3483 
3485  FatRaiseStatus( IrpContext,
3487  } _SEH2_END;
3488  }
3489 
3490  return Irp->AssociatedIrp.SystemBuffer;
3491 }
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG BufferLength
Definition: cdrom.h:989
PVOID FatMapUserBuffer(IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp)
Definition: deviosup.c:3357
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI FsRtlAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:189
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2974
_SEH2_TRY
Definition: create.c:4226
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
Status
Definition: gdiplustypes.h:24
#define TAG_IO_USER_BUFFER
Definition: nodetype.h:184
_SEH2_END
Definition: create.c:4400
#define IRP_BUFFERED_IO
#define IRP_DEALLOCATE_BUFFER
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define PAGED_CODE()

Referenced by FatCommonSetEa().

◆ FatBuildZeroMdl()

PMDL FatBuildZeroMdl ( __in PIRP_CONTEXT  IrpContext,
__in ULONG  Length 
)

Definition at line 3734 of file deviosup.c.

3757 {
3758  PMDL ZeroMdl;
3759  ULONG SavedByteCount;
3760  PPFN_NUMBER Page;
3761  ULONG i;
3762 
3763  UNREFERENCED_PARAMETER( IrpContext );
3764 
3765  //
3766  // Spin down trying to get an MDL which can describe our operation.
3767  //
3768 
3769  while (TRUE) {
3770 
3771  ZeroMdl = IoAllocateMdl( FatData.ZeroPage, Length, FALSE, FALSE, NULL );
3772 
3773  //
3774  // Throttle ourselves to what we've physically allocated. Note that
3775  // we could have started with an odd multiple of this number. If we
3776  // tried for exactly that size and failed, we're toast.
3777  //
3778 
3779  if (ZeroMdl || (Length <= PAGE_SIZE)) {
3780 
3781  break;
3782  }
3783 
3784  //
3785  // Fallback by half and round down to a page multiple.
3786  //
3787 
3788  ASSERT( IrpContext->Vcb->Bpb.BytesPerSector <= PAGE_SIZE );
3790  if (Length < PAGE_SIZE) {
3791  Length = PAGE_SIZE;
3792  }
3793  }
3794 
3795  if (ZeroMdl == NULL) {
3796  return NULL;
3797  }
3798 
3799  //
3800  // If we have throttled all the way down, stop and just build a
3801  // simple MDL describing our previous allocation.
3802  //
3803 
3804  if (Length == PAGE_SIZE) {
3805 
3806  MmBuildMdlForNonPagedPool( ZeroMdl );
3807  return ZeroMdl;
3808  }
3809 
3810  //
3811  // Now we will temporarily lock the allocated pages
3812  // only, and then replicate the page frame numbers through
3813  // the entire Mdl to keep writing the same pages of zeros.
3814  //
3815  // It would be nice if Mm exported a way for us to not have
3816  // to pull the Mdl apart and rebuild it ourselves, but this
3817  // is so bizarre a purpose as to be tolerable.
3818  //
3819 
3820  SavedByteCount = ZeroMdl->ByteCount;
3821  ZeroMdl->ByteCount = PAGE_SIZE;
3822  MmBuildMdlForNonPagedPool( ZeroMdl );
3823 
3824  ZeroMdl->MdlFlags &= ~MDL_SOURCE_IS_NONPAGED_POOL;
3825  ZeroMdl->MdlFlags |= MDL_PAGES_LOCKED;
3826  ZeroMdl->MappedSystemVa = NULL;
3827  ZeroMdl->StartVa = NULL;
3828  ZeroMdl->ByteCount = SavedByteCount;
3829  Page = MmGetMdlPfnArray( ZeroMdl );
3830  for (i = 1; i < (ADDRESS_AND_SIZE_TO_SPAN_PAGES( 0, SavedByteCount )); i++) {
3831  *(Page + i) = *(Page);
3832  }
3833 
3834 
3835  return ZeroMdl;
3836 }
PVOID ZeroPage
Definition: fatstruc.h:162
#define MmGetMdlPfnArray(_Mdl)
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:428
ULONG * PPFN_NUMBER
Definition: ke.h:8
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
FAT_DATA FatData
Definition: fatdata.c:56
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
unsigned int ULONG
Definition: retypes.h:1
#define BlockAlignTruncate(P, V)
Definition: fatprocs.h:3101

◆ FatLockUserBuffer()

VOID FatLockUserBuffer ( IN PIRP_CONTEXT  IrpContext,
IN OUT PIRP  Irp,
IN LOCK_OPERATION  Operation,
IN ULONG  BufferLength 
)

Definition at line 3276 of file deviosup.c.

3309 {
3310  PMDL Mdl = NULL;
3311 
3312  PAGED_CODE();
3313 
3314  if (Irp->MdlAddress == NULL) {
3315 
3316  //
3317  // Allocate the Mdl, and Raise if we fail.
3318  //
3319 
3320  Mdl = IoAllocateMdl( Irp->UserBuffer, BufferLength, FALSE, FALSE, Irp );
3321 
3322  if (Mdl == NULL) {
3323 
3325  }
3326 
3327  //
3328  // Now probe the buffer described by the Irp. If we get an exception,
3329  // deallocate the Mdl and return the appropriate "expected" status.
3330  //
3331 
3332  _SEH2_TRY {
3333 
3334  MmProbeAndLockPages( Mdl,
3335  Irp->RequestorMode,
3336  Operation );
3337 
3339 
3340  NTSTATUS Status;
3341 
3343 
3344  IoFreeMdl( Mdl );
3345  Irp->MdlAddress = NULL;
3346 
3347  FatRaiseStatus( IrpContext,
3349  } _SEH2_END;
3350  }
3351 
3352  UNREFERENCED_PARAMETER( IrpContext );
3353 }
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG BufferLength
Definition: cdrom.h:989
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2974
_SEH2_TRY
Definition: create.c:4226
#define FALSE
Definition: types.h:117
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
Status
Definition: gdiplustypes.h:24
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
_SEH2_END
Definition: create.c:4400
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:935
_In_ FLT_SET_CONTEXT_OPERATION Operation
Definition: fltkernel.h:1468
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define PAGED_CODE()

Referenced by _Requires_lock_held_(), and FatPrePostIrp().

◆ FatMapUserBuffer()

PVOID FatMapUserBuffer ( IN PIRP_CONTEXT  IrpContext,
IN OUT PIRP  Irp 
)

Definition at line 3357 of file deviosup.c.

3382 {
3383  UNREFERENCED_PARAMETER( IrpContext );
3384 
3385  PAGED_CODE();
3386 
3387  //
3388  // If there is no Mdl, then we must be in the Fsd, and we can simply
3389  // return the UserBuffer field from the Irp.
3390  //
3391 
3392  if (Irp->MdlAddress == NULL) {
3393 
3394  return Irp->UserBuffer;
3395 
3396  } else {
3397 
3398  PVOID Address = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute );
3399 
3400  if (Address == NULL) {
3401 
3403  }
3404 
3405  return Address;
3406  }
3407 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define ExRaiseStatus
Definition: ntoskrnl.h:96
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
#define PAGED_CODE()

Referenced by _Requires_lock_held_(), FatBufferUserBuffer(), and FatCommonQueryEa().

◆ FatMultiAsyncCompletionRoutine()

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

Definition at line 2507 of file deviosup.c.

2552 {
2554  PFAT_IO_CONTEXT Context = Contxt;
2555  PIRP MasterIrp = Context->MasterIrp;
2556  BOOLEAN PostRequest = FALSE;
2557 
2558  DebugTrace(+1, Dbg, "FatMultiAsyncCompletionRoutine, Context = %p\n", Context );
2559 
2560  //
2561  // If we got an error (or verify required), remember it in the Irp
2562  //
2563 
2564  if (!NT_SUCCESS( Irp->IoStatus.Status )) {
2565 
2566 #if DBG
2567  if (!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) {
2568  DbgBreakPoint();
2569  }
2570 #endif
2571 
2572 #ifdef SYSCACHE_COMPILE
2573  DbgPrint( "FAT SYSCACHE: MultiAsync (IRP %08x for Master %08x) -> %08x\n", Irp, MasterIrp, Irp->IoStatus );
2574 #endif
2575 
2576  MasterIrp->IoStatus = Irp->IoStatus;
2577 
2578  }
2579 
2580  NT_ASSERT( !(NT_SUCCESS( Irp->IoStatus.Status ) && Irp->IoStatus.Information == 0 ));
2581 
2582  if (InterlockedDecrement(&Context->IrpCount) == 0) {
2583 
2584  FatDoCompletionZero( MasterIrp, Context );
2585 
2586  if (NT_SUCCESS(MasterIrp->IoStatus.Status)) {
2587 
2588  MasterIrp->IoStatus.Information =
2589  Context->Wait.Async.RequestedByteCount;
2590 
2591  NT_ASSERT(MasterIrp->IoStatus.Information != 0);
2592 
2593  //
2594  // Now if this wasn't PagingIo, set either the read or write bit.
2595  //
2596 
2597  if (!FlagOn(MasterIrp->Flags, IRP_PAGING_IO)) {
2598 
2599  SetFlag( Context->Wait.Async.FileObject->Flags,
2600  IoGetCurrentIrpStackLocation(MasterIrp)->MajorFunction == IRP_MJ_READ ?
2602  }
2603 
2604  } else {
2605 
2606  //
2607  // Post STATUS_VERIFY_REQUIRED failures. Only post top level IRPs, because recursive I/Os
2608  // cannot process volume verification.
2609  //
2610 
2611  if (!FlagOn(Context->IrpContextFlags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) &&
2612  (MasterIrp->IoStatus.Status == STATUS_VERIFY_REQUIRED)) {
2613  PostRequest = TRUE;
2614  }
2615 
2616  }
2617 
2618  //
2619  // If this was a special async write, decrement the count. Set the
2620  // event if this was the final outstanding I/O for the file. We will
2621  // also want to queue an APC to deal with any error conditionions.
2622  //
2623  _Analysis_assume_(!(Context->Wait.Async.NonPagedFcb) &&
2624  (ExInterlockedAddUlong( &Context->Wait.Async.NonPagedFcb->OutstandingAsyncWrites,
2625  0xffffffff,
2626  &FatData.GeneralSpinLock ) != 1));
2627  if ((Context->Wait.Async.NonPagedFcb) &&
2628  (ExInterlockedAddUlong( &Context->Wait.Async.NonPagedFcb->OutstandingAsyncWrites,
2629  0xffffffff,
2630  &FatData.GeneralSpinLock ) == 1)) {
2631 
2632  KeSetEvent( Context->Wait.Async.NonPagedFcb->OutstandingAsyncEvent, 0, FALSE );
2633  }
2634 
2635  //
2636  // Now release the resources.
2637  //
2638 
2639  if (Context->Wait.Async.Resource != NULL) {
2640 
2641  ExReleaseResourceForThreadLite( Context->Wait.Async.Resource,
2642  Context->Wait.Async.ResourceThreadId );
2643  }
2644 
2645  if (Context->Wait.Async.Resource2 != NULL) {
2646 
2647  ExReleaseResourceForThreadLite( Context->Wait.Async.Resource2,
2648  Context->Wait.Async.ResourceThreadId );
2649  }
2650 
2651  //
2652  // Mark the master Irp pending
2653  //
2654 
2655  IoMarkIrpPending( MasterIrp );
2656 
2657  //
2658  // and finally, free the context record.
2659  //
2660 
2661  ExFreePool( Context );
2662 
2663  if (PostRequest) {
2664 
2665  PIRP_CONTEXT IrpContext = NULL;
2666 
2667  _SEH2_TRY {
2668 
2669  IrpContext = FatCreateIrpContext(Irp, TRUE );
2670  ClearFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL);
2671  FatFsdPostRequest( IrpContext, Irp );
2673 
2675 
2676  //
2677  // If we failed to post the IRP, we just have to return the failure
2678  // to the user. :(
2679  //
2680 
2681  NOTHING;
2682  } _SEH2_END;
2683  }
2684  }
2685 
2686  DebugTrace(-1, Dbg, "FatMultiAsyncCompletionRoutine -> SUCCESS\n", 0 );
2687 
2689 
2690  return Status;
2691 }
#define DbgPrint
Definition: loader.c:25
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
KSPIN_LOCK GeneralSpinLock
Definition: fatstruc.h:151
IO_STATUS_BLOCK IoStatus
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
void DbgBreakPoint()
Definition: mach.c:553
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
_SEH2_TRY
Definition: create.c:4226
#define FO_FILE_MODIFIED
Definition: iotypes.h:1768
#define FALSE
Definition: types.h:117
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1775
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2289
FAT_DATA FatData
Definition: fatdata.c:56
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
#define InterlockedDecrement
Definition: armddk.h:52
#define NOTHING
Definition: env_spec_w32.h:461
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define Dbg
Definition: deviosup.c:28
#define FatDoCompletionZero(I, C)
Definition: deviosup.c:171
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4400
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define IRP_PAGING_IO
ULONG NTAPI ExInterlockedAddUlong(IN OUT PULONG Addend, IN ULONG Increment, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:88
#define IRP_MJ_READ
Definition: rdpdr.c:46
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
#define IRP_CONTEXT_FLAG_RECURSIVE_CALL
Definition: fatstruc.h:1561
VOID NTAPI ExReleaseResourceForThreadLite(IN PERESOURCE Resource, IN ERESOURCE_THREAD Thread)
Definition: resource.c:1844
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
return STATUS_SUCCESS
Definition: btrfs.c:3014
IoMarkIrpPending(Irp)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define _Analysis_assume_(expr)
Definition: no_sal2.h:10
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ FatMultipleAsync()

VOID FatMultipleAsync ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PIRP  MasterIrp,
IN ULONG  MultipleIrpCount,
IN PIO_RUN  IoRuns 
)

Definition at line 1622 of file deviosup.c.

1680 {
1681  PIRP Irp;
1683  PMDL Mdl;
1684  BOOLEAN Wait;
1686 #ifndef __REACTOS__
1687  BOOLEAN IsAWrite = FALSE;
1688  ULONG Length = 0;
1689 #endif
1690 
1691  ULONG UnwindRunCount = 0;
1692 
1693  BOOLEAN ExceptionExpected = TRUE;
1694 
1695  PAGED_CODE();
1696 
1697  DebugTrace(+1, Dbg, "FatMultipleAsync\n", 0);
1698  DebugTrace( 0, Dbg, "MajorFunction = %08lx\n", IrpContext->MajorFunction );
1699  DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb );
1700  DebugTrace( 0, Dbg, "MasterIrp = %p\n", MasterIrp );
1701  DebugTrace( 0, Dbg, "MultipleIrpCount = %08lx\n", MultipleIrpCount );
1702  DebugTrace( 0, Dbg, "IoRuns = %08lx\n", IoRuns );
1703 
1704  //
1705  // If this I/O originating during FatVerifyVolume, bypass the
1706  // verify logic.
1707  //
1708 
1709  if (Vcb->VerifyThread == KeGetCurrentThread()) {
1710 
1711  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY );
1712  }
1713 
1714  //
1715  // Set up things according to whether this is truely async.
1716  //
1717 
1718  Wait = BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
1719 
1720  Context = IrpContext->FatIoContext;
1721 
1722  //
1723  // Finish initializing Context, for use in Read/Write Multiple Asynch.
1724  //
1725 
1726  Context->MasterIrp = MasterIrp;
1727 
1728  IrpSp = IoGetCurrentIrpStackLocation( MasterIrp );
1729 #ifndef __REACTOS__
1730  IsAWrite = (IrpSp->MajorFunction == IRP_MJ_WRITE);
1731  Length = IrpSp->Parameters.Read.Length;
1732 #endif
1733 
1734  _SEH2_TRY {
1735 
1736  //
1737  // Itterate through the runs, doing everything that can fail
1738  //
1739 
1740  for ( UnwindRunCount = 0;
1741  UnwindRunCount < MultipleIrpCount;
1742  UnwindRunCount++ ) {
1743 
1744  //
1745  // Create an associated IRP, making sure there is one stack entry for
1746  // us, as well.
1747  //
1748 
1749  IoRuns[UnwindRunCount].SavedIrp = 0;
1750 
1751  Irp = IoMakeAssociatedIrp( MasterIrp,
1752  (CCHAR)(Vcb->TargetDeviceObject->StackSize + 1) );
1753 
1754  if (Irp == NULL) {
1755 
1757  }
1758 
1759  IoRuns[UnwindRunCount].SavedIrp = Irp;
1760 
1761  //
1762  // Allocate and build a partial Mdl for the request.
1763  //
1764 
1765  Mdl = IoAllocateMdl( (PCHAR)MasterIrp->UserBuffer +
1766  IoRuns[UnwindRunCount].Offset,
1767  IoRuns[UnwindRunCount].ByteCount,
1768  FALSE,
1769  FALSE,
1770  Irp );
1771 
1772  if (Mdl == NULL) {
1773 
1775  }
1776 
1777  //
1778  // Sanity Check
1779  //
1780 
1781  NT_ASSERT( Mdl == Irp->MdlAddress );
1782 
1783  IoBuildPartialMdl( MasterIrp->MdlAddress,
1784  Mdl,
1785  (PCHAR)MasterIrp->UserBuffer +
1786  IoRuns[UnwindRunCount].Offset,
1787  IoRuns[UnwindRunCount].ByteCount );
1788 
1789  //
1790  // Get the first IRP stack location in the associated Irp
1791  //
1792 
1795 
1796  //
1797  // Setup the Stack location to describe our read.
1798  //
1799 
1800  IrpSp->MajorFunction = IrpContext->MajorFunction;
1801  IrpSp->Parameters.Read.Length = IoRuns[UnwindRunCount].ByteCount;
1802  IrpSp->Parameters.Read.ByteOffset.QuadPart = IoRuns[UnwindRunCount].Vbo;
1803 
1804  //
1805  // Set up the completion routine address in our stack frame.
1806  //
1807 
1809  Wait ?
1812  Context,
1813  TRUE,
1814  TRUE,
1815  TRUE );
1816 
1817  //
1818  // Setup the next IRP stack location in the associated Irp for the disk
1819  // driver beneath us.
1820  //
1821 
1823 
1824  //
1825  // Setup the Stack location to do a read from the disk driver.
1826  //
1827 
1828  IrpSp->MajorFunction = IrpContext->MajorFunction;
1829  IrpSp->Parameters.Read.Length = IoRuns[UnwindRunCount].ByteCount;
1830  IrpSp->Parameters.Read.ByteOffset.QuadPart = IoRuns[UnwindRunCount].Lbo;
1831 
1832  //
1833  // If this Irp is the result of a WriteThough operation,
1834  // tell the device to write it through.
1835  //
1836 
1837  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH )) {
1838 
1840  }
1841 
1842  //
1843  // If this I/O requires override verify, bypass the verify logic.
1844  //
1845 
1846  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY )) {
1847 
1849  }
1850  }
1851 
1852  //
1853  // Now we no longer expect an exception. If the driver raises, we
1854  // must bugcheck, because we do not know how to recover from that
1855  // case.
1856  //
1857 
1858  ExceptionExpected = FALSE;
1859 
1860  //
1861  // We only need to set the associated IRP count in the master irp to
1862  // make it a master IRP. But we set the count to one more than our
1863  // caller requested, because we do not want the I/O system to complete
1864  // the I/O. We also set our own count.
1865  //
1866 
1867  Context->IrpCount = MultipleIrpCount;
1868  MasterIrp->AssociatedIrp.IrpCount = MultipleIrpCount;
1869 
1870  if (Wait) {
1871 
1872  MasterIrp->AssociatedIrp.IrpCount += 1;
1873  }
1874  else if (FlagOn( Context->Wait.Async.ResourceThreadId, 3 )) {
1875 
1876  //
1877  // For async requests if we acquired locks, transition the lock owners to an
1878  // object, since when we return this thread could go away before request
1879  // completion, and the resource package may try to boost priority.
1880  //
1881 
1882  if (Context->Wait.Async.Resource != NULL) {
1883 
1884  ExSetResourceOwnerPointer( Context->Wait.Async.Resource,
1885  (PVOID)Context->Wait.Async.ResourceThreadId );
1886  }
1887 
1888  if (Context->Wait.Async.Resource2 != NULL) {
1889 
1890  ExSetResourceOwnerPointer( Context->Wait.Async.Resource2,
1891  (PVOID)Context->Wait.Async.ResourceThreadId );
1892  }
1893  }
1894 
1895  //
1896  // Back up a copy of the IrpContext flags for later use in async completion.
1897  //
1898 
1899  Context->IrpContextFlags = IrpContext->Flags;
1900 
1901  //
1902  // Now that all the dangerous work is done, issue the read requests
1903  //
1904 
1905  for (UnwindRunCount = 0;
1906  UnwindRunCount < MultipleIrpCount;
1907  UnwindRunCount++) {
1908 
1909  Irp = IoRuns[UnwindRunCount].SavedIrp;
1910 
1911  DebugDoit( FatIoCallDriverCount += 1);
1912 
1913  //
1914  // If IoCallDriver returns an error, it has completed the Irp
1915  // and the error will be caught by our completion routines
1916  // and dealt with as a normal IO error.
1917  //
1918 
1919  (VOID)FatLowLevelReadWrite( IrpContext,
1920  Vcb->TargetDeviceObject,
1921  Irp,
1922  Vcb );
1923  }
1924 
1925  //
1926  // We just issued an IO to the storage stack, update the counters indicating so.
1927  //
1928 
1930 
1931  FatUpdateIOCountersPCW( IsAWrite, Length );
1932  }
1933 
1934  } _SEH2_FINALLY {
1935 
1936  ULONG i;
1937 
1939 
1940  //
1941  // Only allocating the spinlock, making the associated Irps
1942  // and allocating the Mdls can fail.
1943  //
1944 
1945  if ( _SEH2_AbnormalTermination() ) {
1946 
1947  //
1948  // If the driver raised, we are hosed. He is not supposed to raise,
1949  // and it is impossible for us to figure out how to clean up.
1950  //
1951 
1952  if (!ExceptionExpected) {
1953  NT_ASSERT( ExceptionExpected );
1954 #ifdef _MSC_VER
1955 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1956 #endif
1957  FatBugCheck( 0, 0, 0 );
1958  }
1959 
1960  //
1961  // Unwind
1962  //
1963 
1964  for (i = 0; i <= UnwindRunCount; i++) {
1965 
1966  if ( (Irp = IoRuns[i].SavedIrp) != NULL ) {
1967 
1968  if ( Irp->MdlAddress != NULL ) {
1969 
1970  IoFreeMdl( Irp->MdlAddress );
1971  }
1972 
1973  IoFreeIrp( Irp );
1974  }
1975  }
1976  }
1977 
1978  //
1979  // And return to our caller
1980  //
1981 
1982  DebugTrace(-1, Dbg, "FatMultipleAsync -> VOID\n", 0);
1983  } _SEH2_END;
1984 
1985  return;
1986 }
signed char * PCHAR
Definition: retypes.h:7
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define DebugDoit(X)
Definition: fatdata.h:316
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
LOGICAL FatDiskAccountingEnabled
Definition: fatdata.c:129
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1079
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2974
_SEH2_TRY
Definition: create.c:4226
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define FALSE
Definition: types.h:117
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
PIRP NTAPI IoMakeAssociatedIrp(IN PIRP Irp, IN CCHAR StackSize)
Definition: irp.c:1925
#define DebugUnwind(X)
Definition: fatdata.h:315
char CCHAR
Definition: typedefs.h:51
#define Vcb
Definition: cdprocs.h:1415
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
IO_COMPLETION_ROUTINE FatMultiAsyncCompletionRoutine
Definition: deviosup.c:78
#define VOID
Definition: acefi.h:82
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define Dbg
Definition: deviosup.c:28
VOID NTAPI ExSetResourceOwnerPointer(IN PERESOURCE Resource, IN PVOID OwnerPointer)
Definition: resource.c:2045
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4400
IO_COMPLETION_ROUTINE FatMultiSyncCompletionRoutine
Definition: deviosup.c:68
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
_SEH2_FINALLY
Definition: create.c:4371
#define SL_WRITE_THROUGH
Definition: iotypes.h:1804
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
struct tagContext Context
Definition: acpixf.h:1034
unsigned int ULONG
Definition: retypes.h:1
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
VOID FatMultipleAsync(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PIRP MasterIrp, IN ULONG MultipleIrpCount, IN PIO_RUN IoRuns)
Definition: deviosup.c:1622
#define KeGetCurrentThread
Definition: hal.h:44
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
#define IRP_CONTEXT_FLAG_OVERRIDE_VERIFY
Definition: fatstruc.h:1569
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2676
#define FatUpdateIOCountersPCW(IsAWrite, Count)
Definition: deviosup.c:184
#define PAGED_CODE()
IN BOOLEAN Wait
Definition: fatprocs.h:1538
#define NT_ASSERT
Definition: rtlfuncs.h:3312
#define FatLowLevelReadWrite(IRPCONTEXT, DO, IRP, VCB)
Definition: deviosup.c:163

Referenced by _Requires_lock_held_(), and FatMultipleAsync().

◆ FatMultiSyncCompletionRoutine()

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

Definition at line 2406 of file deviosup.c.

2451 {
2452 
2453  PFAT_IO_CONTEXT Context = Contxt;
2454  PIRP MasterIrp = Context->MasterIrp;
2455 
2456  DebugTrace(+1, Dbg, "FatMultiSyncCompletionRoutine, Context = %p\n", Context );
2457 
2458  //
2459  // If we got an error (or verify required), remember it in the Irp
2460  //
2461 
2462  if (!NT_SUCCESS( Irp->IoStatus.Status )) {
2463 
2464 #if DBG
2465  if(!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) {
2466  DbgBreakPoint();
2467  }
2468 #endif
2469 
2470 #ifdef SYSCACHE_COMPILE
2471  DbgPrint( "FAT SYSCACHE: MultiSync (IRP %08x for Master %08x) -> %08x\n", Irp, MasterIrp, Irp->IoStatus );
2472 #endif
2473 
2474  MasterIrp->IoStatus = Irp->IoStatus;
2475  }
2476 
2477  NT_ASSERT( !(NT_SUCCESS( Irp->IoStatus.Status ) && Irp->IoStatus.Information == 0 ));
2478 
2479  //
2480  // We must do this here since IoCompleteRequest won't get a chance
2481  // on this associated Irp.
2482  //
2483 
2484  IoFreeMdl( Irp->MdlAddress );
2485  IoFreeIrp( Irp );
2486 
2487  if (InterlockedDecrement(&Context->IrpCount) == 0) {
2488 
2489  FatDoCompletionZero( MasterIrp, Context );
2490  KeSetEvent( &Context->Wait.SyncEvent, 0, FALSE );
2491  }
2492 
2493  DebugTrace(-1, Dbg, "FatMultiSyncCompletionRoutine -> SUCCESS\n", 0 );
2494 
2496 
2498 }
#define DbgPrint
Definition: loader.c:25
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
IO_STATUS_BLOCK IoStatus
void DbgBreakPoint()
Definition: mach.c:553
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define InterlockedDecrement
Definition: armddk.h:52
#define Dbg
Definition: deviosup.c:28
#define FatDoCompletionZero(I, C)
Definition: deviosup.c:171
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ FatPagingFileCompletionRoutine()

NTSTATUS NTAPI FatPagingFileCompletionRoutine ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp,
_In_reads_opt_(_Inexpressible_("varies")) PVOID  MasterIrp 
)

Definition at line 2898 of file deviosup.c.

2935 {
2936  DebugTrace(+1, Dbg, "FatPagingFileCompletionRoutine, MasterIrp = %p\n", MasterIrp );
2937 
2938  //
2939  // If we got an error (or verify required), remember it in the Irp
2940  //
2941 
2942  NT_ASSERT( !NT_SUCCESS( Irp->IoStatus.Status ));
2943 
2944  //
2945  // If we were invoked with an assoicated Irp, copy the error over.
2946  //
2947 
2948  if (Irp != MasterIrp) {
2949 
2950  ((PIRP)MasterIrp)->IoStatus = Irp->IoStatus;
2951  }
2952 
2953  DebugTrace(-1, Dbg, "FatPagingFileCompletionRoutine => (done)\n", 0 );
2954 
2956 
2957  return FatPagingFileErrorHandler( Irp, NULL );
2958 }
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _IRP * PIRP
NTSTATUS FatPagingFileErrorHandler(IN PIRP Irp, IN PKEVENT Event OPTIONAL)
Definition: deviosup.c:2695
#define Dbg
Definition: deviosup.c:28
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ FatPagingFileCompletionRoutineCatch()

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

Definition at line 2805 of file deviosup.c.

2846 {
2848 
2850 
2851  DebugTrace(+1, Dbg, "FatPagingFileCompletionRoutineCatch, Context = %p\n", Context );
2852 
2853  //
2854  // Cleanup the existing Mdl, perhaps by returning the reserve.
2855  //
2856 
2857  if (Irp->MdlAddress == FatReserveMdl) {
2858 
2859  MmPrepareMdlForReuse( Irp->MdlAddress );
2861 
2862  } else {
2863 
2864  IoFreeMdl( Irp->MdlAddress );
2865  }
2866 
2867  //
2868  // Restore the original Mdl.
2869  //
2870 
2871  Irp->MdlAddress = Context->RestoreMdl;
2872 
2873  DebugTrace(-1, Dbg, "FatPagingFileCompletionRoutine => (done)\n", 0 );
2874 
2875  //
2876  // If the IRP is succeeding or the failure handler did not post off the
2877  // completion, we're done and should set the event to let the master
2878  // know the IRP is his again.
2879  //
2880 
2881  if (NT_SUCCESS( Irp->IoStatus.Status ) ||
2883 
2884  KeSetEvent( &Context->Event, 0, FALSE );
2885  }
2886 
2888 
2889 }
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
KEVENT FatReserveEvent
Definition: fatdata.c:123
struct FAT_PAGING_FILE_CONTEXT * PFAT_PAGING_FILE_CONTEXT
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
NTSTATUS FatPagingFileErrorHandler(IN PIRP Irp, IN PKEVENT Event OPTIONAL)
Definition: deviosup.c:2695
#define Dbg
Definition: deviosup.c:28
#define MmPrepareMdlForReuse(_Mdl)
PMDL FatReserveMdl
Definition: fatdata.c:119
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
return STATUS_SUCCESS
Definition: btrfs.c:3014

◆ FatPagingFileErrorHandler()

NTSTATUS FatPagingFileErrorHandler ( IN PIRP  Irp,
IN PKEVENT Event  OPTIONAL 
)

Definition at line 2695 of file deviosup.c.

2750 {
2751  NTSTATUS Status;
2752 
2753  //
2754  // If this was a media error, we want to chkdsk /r the next time we boot.
2755  //
2756 
2757  if (FsRtlIsTotalDeviceFailure(Irp->IoStatus.Status)) {
2758 
2760 
2761  } else {
2762 
2764 
2765  //
2766  // We are going to try to mark the volume needing recover.
2767  // If we can't get pool, oh well....
2768  //
2769 
2770  Packet = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(CLEAN_AND_DIRTY_VOLUME_PACKET), ' taF');
2771 
2772  if ( Packet ) {
2773 
2775  Packet->Irp = Irp;
2776  Packet->Event = Event;
2777 
2778  ExInitializeWorkItem( &Packet->Item,
2780  Packet );
2781 
2782 #ifdef _MSC_VER
2783 #pragma prefast( suppress:28159, "prefast indicates this is obsolete, but it is ok for fastfat to use it" )
2784 #endif
2786 
2788 
2789  } else {
2790 
2792  }
2793  }
2794 
2795  return Status;
2796 }
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1548
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
BOOLEAN NTAPI FsRtlIsTotalDeviceFailure(IN NTSTATUS NtStatus)
Definition: filter.c:37
LONG NTSTATUS
Definition: precomp.h:26
VOLUME_DEVICE_OBJECT * PVOLUME_DEVICE_OBJECT
Definition: cdstruc.h:775
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:450
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define Vcb
Definition: cdprocs.h:1415
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3202
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Status
Definition: gdiplustypes.h:24
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
WORKER_THREAD_ROUTINE FatFspMarkVolumeDirtyWithRecover
Definition: fatprocs.h:2000
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by FatPagingFileCompletionRoutine(), and FatPagingFileCompletionRoutineCatch().

◆ FatPagingFileIo()

VOID FatPagingFileIo ( IN PIRP  Irp,
IN PFCB  Fcb 
)

Definition at line 211 of file deviosup.c.

236 {
237  //
238  // Declare some local variables for enumeration through the
239  // runs of the file.
240  //
241 
242  VBO Vbo;
244 
245  PMDL Mdl;
246  LBO NextLbo;
247  VBO NextVbo = 0;
248  ULONG NextByteCount;
249  ULONG RemainingByteCount;
250  BOOLEAN MustSucceed;
251 
252  ULONG FirstIndex;
253  ULONG CurrentIndex;
254  ULONG LastIndex;
255 
256  LBO LastLbo;
257  ULONG LastByteCount;
258 
259  BOOLEAN MdlIsReserve = FALSE;
260  BOOLEAN IrpIsMaster = FALSE;
262  LONG IrpCount;
263 
264  PIRP AssocIrp;
266  PIO_STACK_LOCATION NextIrpSp;
267  ULONG BufferOffset;
269 
270 #ifndef __REACTOS__
271  BOOLEAN IsAWrite = FALSE;
272 #endif
273 
274  DebugTrace(+1, Dbg, "FatPagingFileIo\n", 0);
275  DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
276  DebugTrace( 0, Dbg, "Fcb = %p\n", Fcb );
277 
279 
280  //
281  // Initialize some locals.
282  //
283 
284  BufferOffset = 0;
287 
288  Vbo = IrpSp->Parameters.Read.ByteOffset.LowPart;
289  ByteCount = IrpSp->Parameters.Read.Length;
290 #ifndef __REACTOS__
291  IsAWrite = (IrpSp->MajorFunction == IRP_MJ_WRITE);
292 #endif
293 
294  MustSucceed = FatLookupMcbEntry( Fcb->Vcb, &Fcb->Mcb,
295  Vbo,
296  &NextLbo,
297  &NextByteCount,
298  &FirstIndex);
299 
300  //
301  // If this run isn't present, something is very wrong.
302  //
303 
304  if (!MustSucceed) {
305 
306 #ifdef _MSC_VER
307 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
308 #endif
309  FatBugCheck( Vbo, ByteCount, 0 );
310  }
311 
312 #if (NTDDI_VERSION >= NTDDI_WIN8)
313 
314  //
315  // Charge the IO to paging file to current thread
316  //
317 
319 
320  PETHREAD ThreadIssuingIo = PsGetCurrentThread();
321  BOOLEAN IsWriteOperation = FALSE;
322 
323  if (IrpSp->MajorFunction == IRP_MJ_WRITE) {
324  IsWriteOperation = TRUE;
325  }
326 
327  PsUpdateDiskCounters( PsGetThreadProcess( ThreadIssuingIo ),
328  (IsWriteOperation ? 0 : ByteCount ), // bytes to read
329  (IsWriteOperation ? ByteCount : 0), // bytes to write
330  (IsWriteOperation ? 0 : 1), // # of reads
331  (IsWriteOperation ? 1 : 0), // # of writes
332  0 );
333  }
334 #endif
335 
336  // See if the write covers a single valid run, and if so pass
337  // it on.
338  //
339 
340  if ( NextByteCount >= ByteCount ) {
341 
342  DebugTrace( 0, Dbg, "Passing Irp on to Disk Driver\n", 0 );
343 
344  //
345  // Setup the next IRP stack location for the disk driver beneath us.
346  //
347 
348  NextIrpSp = IoGetNextIrpStackLocation( Irp );
349 
350  NextIrpSp->MajorFunction = IrpSp->MajorFunction;
351  NextIrpSp->Parameters.Read.Length = ByteCount;
352  NextIrpSp->Parameters.Read.ByteOffset.QuadPart = NextLbo;
353 
354  //
355  // Since this is Paging file IO, we'll just ignore the verify bit.
356  //
357 
358  SetFlag( NextIrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME );
359 
360  //
361  // Set up the completion routine address in our stack frame.
362  // This is only invoked on error or cancel, and just copies
363  // the error Status into master irp's iosb.
364  //
365  // If the error implies a media problem, it also enqueues a
366  // worker item to write out the dirty bit so that the next
367  // time we run we will do a autochk /r
368  //
369 
372  Irp,
373  FALSE,
374  TRUE,
375  TRUE );
376 
377  //
378  // Issue the read/write request
379  //
380  // If IoCallDriver returns an error, it has completed the Irp
381  // and the error will be dealt with as a normal IO error.
382  //
383 
385 
386  //
387  // We just issued an IO to the storage stack, update the counters indicating so.
388  //
389 
391 
392  FatUpdateIOCountersPCW( IsAWrite, ByteCount );
393  }
394 
395  DebugTrace(-1, Dbg, "FatPagingFileIo -> VOID\n", 0);
396  return;
397  }
398 
399  //
400  // Find out how may runs there are.
401  //
402 
403  MustSucceed = FatLookupMcbEntry( Fcb->Vcb, &Fcb->Mcb,
404  Vbo + ByteCount - 1,
405  &LastLbo,
406  &LastByteCount,
407  &LastIndex);
408 
409  //
410  // If this run isn't present, something is very wrong.
411  //
412 
413  if (!MustSucceed) {
414 
415 #ifdef _MSC_VER
416 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
417 #endif
418  FatBugCheck( Vbo + ByteCount - 1, 1, 0 );
419  }
420 
421  CurrentIndex = FirstIndex;
422 
423  //
424  // Now set up the Irp->IoStatus. It will be modified by the
425  // multi-completion routine in case of error or verify required.
426  //
427 
428  Irp->IoStatus.Status = STATUS_SUCCESS;
429  Irp->IoStatus.Information = ByteCount;
430 
431  //
432  // Loop while there are still byte writes to satisfy. The way we'll work this
433  // is to hope for the best - one associated IRP per run, which will let us be
434  // completely async after launching all the IO.
435  //
436  // IrpCount will indicate the remaining number of associated Irps to launch.
437  //
438  // All we have to do is make sure IrpCount doesn't hit zero before we're building
439  // the very last Irp. If it is positive when we're done, it means we have to
440  // wait for the rest of the associated Irps to come back before we complete the
441  // master by hand.
442  //
443  // This will keep the master from completing early.
444  //
445 
446  Irp->AssociatedIrp.IrpCount = IrpCount = LastIndex - FirstIndex + 1;
447 
448  while (CurrentIndex <= LastIndex) {
449 
450  //
451  // Reset this for unwinding purposes
452  //
453 
454  AssocIrp = NULL;
455 
456  //
457  // If next run is larger than we need, "ya get what ya need".
458  //
459 
460  if (NextByteCount > ByteCount) {
461  NextByteCount = ByteCount;
462  }
463 
464  RemainingByteCount = 0;
465 
466  //
467  // Allocate and build a partial Mdl for the request.
468  //
469 
470  Mdl = IoAllocateMdl( (PCHAR)Irp->UserBuffer + BufferOffset,
471  NextByteCount,
472  FALSE,
473  FALSE,
474  AssocIrp );
475 
476  if (Mdl == NULL) {
477 
478  //
479  // Pick up the reserve MDL
480  //
481 
483 
484  Mdl = FatReserveMdl;
485  MdlIsReserve = TRUE;
486 
487  //
488  // Trim to fit the size of the reserve MDL.
489  //
490 
491  if (NextByteCount > FAT_RESERVE_MDL_SIZE * PAGE_SIZE) {
492 
493  RemainingByteCount = NextByteCount - FAT_RESERVE_MDL_SIZE * PAGE_SIZE;
494  NextByteCount = FAT_RESERVE_MDL_SIZE * PAGE_SIZE;
495  }
496  }
497 
498  IoBuildPartialMdl( Irp->MdlAddress,
499  Mdl,
500  (PCHAR)Irp->UserBuffer + BufferOffset,
501  NextByteCount );
502 
503  //
504  // Now that we have properly bounded this piece of the transfer, it is
505  // time to read/write it. We can simplify life slightly by always
506  // re-using the master IRP for cases where we use the reserve MDL,
507  // since we'll always be synchronous for those and can use a single
508  // completion context on our local stack.
509  //
510  // We also must prevent ourselves from issuing an associated IRP that would
511  // complete the master UNLESS this is the very last IRP we'll issue.
512  //
513  // This logic looks a bit complicated, but is hopefully understandable.
514  //
515 
516  if (!MdlIsReserve &&
517  (IrpCount != 1 ||
518  (CurrentIndex == LastIndex &&
519  RemainingByteCount == 0))) {
520 
521  AssocIrp = IoMakeAssociatedIrp( Irp, (CCHAR)(DeviceObject->StackSize + 1) );
522  }
523 
524  if (AssocIrp == NULL) {
525 
526  AssocIrp = Irp;
527  IrpIsMaster = TRUE;
528 
529  //
530  // We need to drain the associated Irps so we can reliably figure out if
531  // the master Irp is showing a failed status, in which case we bail out
532  // immediately - as opposed to putting the value in the status field in
533  // jeopardy due to our re-use of the master Irp.
534  //
535 
536  while (Irp->AssociatedIrp.IrpCount != IrpCount) {
537 
539  }
540 
541  //
542  // Note that since we failed to launch this associated Irp, that the completion
543  // code at the bottom will take care of completing the master Irp.
544  //
545 
546  if (!NT_SUCCESS(Irp->IoStatus.Status)) {
547 
548  NT_ASSERT( IrpCount );
549  break;
550  }
551 
552  } else {
553 
554  //
555  // Indicate we used an associated Irp.
556  //
557 
558  IrpCount -= 1;
559  }
560 
561  //
562  // With an associated IRP, we must take over the first stack location so
563  // we can have one to put the completion routine on. When re-using the
564  // master IRP, its already there.
565  //
566 
567  if (!IrpIsMaster) {
568 
569  //
570  // Get the first IRP stack location in the associated Irp
571  //
572 
573  IoSetNextIrpStackLocation( AssocIrp );
574  NextIrpSp = IoGetCurrentIrpStackLocation( AssocIrp );
575 
576  //
577  // Setup the Stack location to describe our read.
578  //
579 
580  NextIrpSp->MajorFunction = IrpSp->MajorFunction;
581  NextIrpSp->Parameters.Read.Length = NextByteCount;
582  NextIrpSp->Parameters.Read.ByteOffset.QuadPart = Vbo;
583 
584  //
585  // We also need the VolumeDeviceObject in the Irp stack in case
586  // we take the failure path.
587  //
588 
589  NextIrpSp->DeviceObject = IrpSp->DeviceObject;
590 
591  } else {
592 
593  //
594  // Save the MDL in the IRP and prepare the stack
595  // context for the completion routine.
596  //
597 
599  Context.RestoreMdl = Irp->MdlAddress;
600  }
601 
602  //
603  // And drop our Mdl into the Irp.
604  //
605 
606  AssocIrp->MdlAddress = Mdl;
607 
608  //
609  // Set up the completion routine address in our stack frame.
610  // For true associated IRPs, this is only invoked on error or
611  // cancel, and just copies the error Status into master irp's
612  // iosb.
613  //
614  // If the error implies a media problem, it also enqueues a
615  // worker item to write out the dirty bit so that the next
616  // time we run we will do a autochk /r
617  //
618 
619  if (IrpIsMaster) {
620 
621  IoSetCompletionRoutine( AssocIrp,
623  &Context,
624  TRUE,
625  TRUE,
626  TRUE );
627 
628  } else {
629 
630  IoSetCompletionRoutine( AssocIrp,
632  Irp,
633  FALSE,
634  TRUE,
635  TRUE );
636  }
637 
638  //
639  // Setup the next IRP stack location for the disk driver beneath us.
640  //
641 
642  NextIrpSp = IoGetNextIrpStackLocation( AssocIrp );
643 
644  //
645  // Since this is paging file IO, we'll just ignore the verify bit.
646  //
647 
648  SetFlag( NextIrpSp->Flags, SL_OVERRIDE_VERIFY_VOLUME );
649 
650  //
651  // Setup the Stack location to do a read from the disk driver.
652  //
653 
654  NextIrpSp->MajorFunction = IrpSp->MajorFunction;
655  NextIrpSp->Parameters.Read.Length = NextByteCount;
656  NextIrpSp->Parameters.Read.ByteOffset.QuadPart = NextLbo;
657 
658  (VOID)IoCallDriver( DeviceObject, AssocIrp );
659 
660  //
661  // We just issued an IO to the storage stack, update the counters indicating so.
662  //
663 
665 
666  FatUpdateIOCountersPCW( IsAWrite, (ULONG64)NextByteCount );
667  }
668 
669  //
670  // Wait for the Irp in the catch case and drop the flags.
671  //
672 
673  if (IrpIsMaster) {
674 
676  IrpIsMaster = MdlIsReserve = FALSE;
677 
678  //
679  // If the Irp is showing a failed status, there is no point in continuing.
680  // In doing so, we get to avoid squirreling away the failed status in case
681  // we were to re-use the master irp again.
682  //
683  // Note that since we re-used the master, we must not have issued the "last"
684  // associated Irp, and thus the completion code at the bottom will take care
685  // of that for us.
686  //
687 
688  if (!NT_SUCCESS(Irp->IoStatus.Status)) {
689 
690  NT_ASSERT( IrpCount );
691  break;
692  }
693  }
694 
695  //
696  // Now adjust everything for the next pass through the loop.
697  //
698 
699  Vbo += NextByteCount;
700  BufferOffset += NextByteCount;
701  ByteCount -= NextByteCount;
702 
703  //
704  // Try to lookup the next run, if we are not done and we got
705  // all the way through the current run.
706  //
707 
708  if (RemainingByteCount) {
709 
710  //
711  // Advance the Lbo/Vbo if we have more to do in the current run.
712  //
713 
714  NextLbo += NextByteCount;
715  NextVbo += NextByteCount;
716 
717  NextByteCount = RemainingByteCount;
718 
719  } else {
720 
721  CurrentIndex += 1;
722 
723  if ( CurrentIndex <= LastIndex ) {
724 
725  NT_ASSERT( ByteCount != 0 );
726 
728  CurrentIndex,
729  &NextVbo,
730  &NextLbo,
731  &NextByteCount );
732 
733  NT_ASSERT( NextVbo == Vbo );
734  }
735  }
736  } // while ( CurrentIndex <= LastIndex )
737 
738  //
739  // If we didn't get enough associated Irps going to make this asynchronous, we
740  // twiddle our thumbs and wait for those we did launch to complete.
741  //
742 
743  if (IrpCount) {
744 
745  while (Irp->AssociatedIrp.IrpCount != IrpCount) {
746 
748  }
749 
751  }
752 
753  DebugTrace(-1, Dbg, "FatPagingFileIo -> VOID\n", 0);
754  return;
755 }
signed char * PCHAR
Definition: retypes.h:7
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
LOGICAL FatDiskAccountingEnabled
Definition: fatdata.c:129
ULONG32 VBO
Definition: fat.h:38
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
PEPROCESS __stdcall PsGetThreadProcess(_In_ PETHREAD Thread)
#define FAT_RESERVE_MDL_SIZE
Definition: fatdata.h:70
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
LARGE_INTEGER Fat30Milliseconds
Definition: fatdata.c:70
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
BOOLEAN FatLookupMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN VBO Vbo, OUT PLBO Lbo, OUT PULONG ByteCount OPTIONAL, OUT PULONG Index OPTIONAL)
Definition: fsctrl.c:418
#define FALSE
Definition: types.h:117
#define FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1194
long LONG
Definition: pedump.c:60
LONGLONG LBO
Definition: fat.h:34
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
#define FatBugCheck(A, B, C)
Definition: nodetype.h:104
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
PIRP NTAPI IoMakeAssociatedIrp(IN PIRP Irp, IN CCHAR StackSize)
Definition: irp.c:1925
PDEVICE_OBJECT TargetDeviceObject
Definition: cdstruc.h:523
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
char CCHAR
Definition: typedefs.h:51
KEVENT FatReserveEvent
Definition: fatdata.c:123
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3202
BOOLEAN FatGetNextMcbEntry(IN PVCB Vcb, IN PLARGE_MCB Mcb, IN ULONG RunIndex, OUT PVBO Vbo, OUT PLBO Lbo, OUT PULONG ByteCount)
Definition: fsctrl.c:541
IO_COMPLETION_ROUTINE FatPagingFileCompletionRoutine
Definition: deviosup.c:118
unsigned __int64 ULONG64
Definition: imports.h:198
CD_MCB Mcb
Definition: cdstruc.h:1022
#define VOID
Definition: acefi.h:82
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define Dbg
Definition: deviosup.c:28
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1081
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
PMDL FatReserveMdl
Definition: fatdata.c:119
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
IO_COMPLETION_ROUTINE FatPagingFileCompletionRoutineCatch
Definition: deviosup.c:128
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
struct tagContext Context
Definition: acpixf.h:1034
unsigned int ULONG
Definition: retypes.h:1
PVCB Vcb
Definition: cdstruc.h:939
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
_In_ PFCB Fcb
Definition: cdprocs.h:159
return STATUS_SUCCESS
Definition: btrfs.c:3014
ULONG FcbState
Definition: cdstruc.h:977
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2676
IN PFCB IN VBO Vbo
Definition: fatprocs.h:306
#define FatUpdateIOCountersPCW(IsAWrite, Count)
Definition: deviosup.c:184
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by _Function_class_(), and FatOverflowPagingFileRead().

◆ FatPerformDevIoCtrl()

NTSTATUS FatPerformDevIoCtrl ( IN PIRP_CONTEXT  IrpContext,
IN ULONG  IoControlCode,
IN PDEVICE_OBJECT  Device,
IN PVOID InputBuffer  OPTIONAL,
IN ULONG  InputBufferLength,
OUT PVOID OutputBuffer  OPTIONAL,
IN ULONG  OutputBufferLength,
IN BOOLEAN  InternalDeviceIoControl,
IN BOOLEAN  OverrideVerify,
OUT PIO_STATUS_BLOCK Iosb  OPTIONAL 
)

Definition at line 3621 of file deviosup.c.

3666 {
3667  NTSTATUS Status;
3668  PIRP Irp;
3669  KEVENT Event;
3670  IO_STATUS_BLOCK LocalIosb;
3671  PIO_STATUS_BLOCK IosbToUse = &LocalIosb;
3672 
3673  PAGED_CODE();
3674 
3675  UNREFERENCED_PARAMETER( IrpContext );
3676 
3677  //
3678  // Check if the user gave us an Iosb.
3679  //
3680 
3681  if (ARGUMENT_PRESENT( Iosb )) {
3682 
3683  IosbToUse = Iosb;
3684  }
3685 
3686  IosbToUse->Status = 0;
3687  IosbToUse->Information = 0;
3688 
3690 
3692  Device,
3693  InputBuffer,
3695  OutputBuffer,
3698  &Event,
3699  IosbToUse );
3700 
3701  if (Irp == NULL) {
3702 
3704  }
3705 
3706  if (OverrideVerify) {
3707 
3709  }
3710 
3711  Status = IoCallDriver( Device, Irp );
3712 
3713  //
3714  // We check for device not ready by first checking Status
3715  // and then if status pending was returned, the Iosb status
3716  // value.
3717  //
3718 
3719  if (Status == STATUS_PENDING) {
3720 
3722  Executive,
3723  KernelMode,
3724  FALSE,
3725  (PLARGE_INTEGER)NULL );
3726 
3727  Status = IosbToUse->Status;
3728  }
3729 
3730  return Status;
3731 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2029
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID _In_ ULONG _In_ BOOLEAN InternalDeviceIoControl
Definition: iofuncs.h:713
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
_In_ ULONG IoControlCode
Definition: cdrom.h:1437
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define FALSE
Definition: types.h:117
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:450
smooth NULL
Definition: ftsmooth.c:416
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t OutputBufferLength
Definition: cdrom.h:1437
return Iosb
Definition: create.c:4402
#define STATUS_PENDING
Definition: ntstatus.h:82
#define ARGUMENT_PRESENT(ArgumentPointer)
CHAR InputBuffer[80]
Definition: conmgr.c:33
Status
Definition: gdiplustypes.h:24
#define VOID
Definition: acefi.h:82
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID OutputBuffer
Definition: cdrom.h:1437
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t InputBufferLength
Definition: cdrom.h:1437
#define PAGED_CODE()

Referenced by _Requires_lock_held_(), and FatScanForDataTrack().

◆ FatSingleAsync()

VOID FatSingleAsync ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN LBO  Lbo,
IN ULONG  ByteCount,
IN PIRP  Irp 
)

Definition at line 1990 of file deviosup.c.

2027 {
2030 #ifndef __REACTOS__
2031  BOOLEAN IsAWrite = FALSE;
2032 #endif
2033 
2034  PAGED_CODE();
2035 
2036  DebugTrace(+1, Dbg, "FatSingleAsync\n", 0);
2037  DebugTrace( 0, Dbg, "MajorFunction = %08lx\n", IrpContext->MajorFunction );
2038  DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb );
2039  DebugTrace( 0, Dbg, "Lbo = %08lx\n", Lbo);
2040  DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
2041  DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
2042 
2043  //
2044  // If this I/O originating during FatVerifyVolume, bypass the
2045  // verify logic.
2046  //
2047 
2048  if (Vcb->VerifyThread == KeGetCurrentThread()) {
2049 
2050  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY );
2051  }
2052 
2053  //
2054  // Set up the completion routine address in our stack frame.
2055  //
2056 
2058  FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ?
2061  IrpContext->FatIoContext,
2062  TRUE,
2063  TRUE,
2064  TRUE );
2065 
2066  //
2067  // Setup the next IRP stack location in the associated Irp for the disk
2068  // driver beneath us.
2069  //
2070 
2072 
2073  //
2074  // Setup the Stack location to do a read from the disk driver.
2075  //
2076 
2077  IrpSp->MajorFunction = IrpContext->MajorFunction;
2078  IrpSp->Parameters.Read.Length = ByteCount;
2079  IrpSp->Parameters.Read.ByteOffset.QuadPart = Lbo;
2080 
2081 #ifndef __REACTOS__
2082  IsAWrite = (IrpSp->MajorFunction == IRP_MJ_WRITE);
2083 #endif
2084 
2085  //
2086  // If this Irp is the result of a WriteThough operation,
2087  // tell the device to write it through.
2088  //
2089 
2090  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH )) {
2091 
2093  }
2094 
2095  //
2096  // If this I/O requires override verify, bypass the verify logic.
2097  //
2098 
2099  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY )) {
2100 
2102  }
2103 
2104  //
2105  // For async requests if we acquired locks, transition the lock owners to an
2106  // object, since when we return this thread could go away before request
2107  // completion, and the resource package may try to boost priority.
2108  //
2109 
2110  if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ) &&
2111  FlagOn( IrpContext->FatIoContext->Wait.Async.ResourceThreadId, 3 )) {
2112 
2113  Context = IrpContext->FatIoContext;
2114 
2115  if (Context->Wait.Async.Resource != NULL) {
2116 
2117  ExSetResourceOwnerPointer( Context->Wait.Async.Resource,
2118  (PVOID)Context->Wait.Async.ResourceThreadId );
2119  }
2120 
2121  if (Context->Wait.Async.Resource2 != NULL) {
2122 
2123  ExSetResourceOwnerPointer( Context->Wait.Async.Resource2,
2124  (PVOID)Context->Wait.Async.ResourceThreadId );
2125  }
2126  }
2127 
2128  //
2129  // Back up a copy of the IrpContext flags for later use in async completion.
2130  //
2131 
2132  IrpContext->FatIoContext->IrpContextFlags = IrpContext->Flags;
2133 
2134  //
2135  // Issue the read request
2136  //
2137 
2138  DebugDoit( FatIoCallDriverCount += 1);
2139 
2140  //
2141  // If IoCallDriver returns an error, it has completed the Irp
2142  // and the error will be caught by our completion routines
2143  // and dealt with as a normal IO error.
2144  //
2145 
2146  (VOID)FatLowLevelReadWrite( IrpContext,
2147  Vcb->TargetDeviceObject,
2148  Irp,
2149  Vcb );
2150 
2151  //
2152  // We just issued an IO to the storage stack, update the counters indicating so.
2153  //
2154 
2156 
2157  FatUpdateIOCountersPCW( IsAWrite, ByteCount );
2158  }
2159 
2160  //
2161  // And return to our caller
2162  //
2163 
2164  DebugTrace(-1, Dbg, "FatSingleAsync -> VOID\n", 0);
2165 
2166  return;
2167 }
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define DebugDoit(X)
Definition: fatdata.h:316
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
LOGICAL FatDiskAccountingEnabled
Definition: fatdata.c:129
#define IRP_CONTEXT_FLAG_WRITE_THROUGH
Definition: ext2fs.h:1079
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
IN PFCB IN VBO OUT PLBO Lbo
Definition: fatprocs.h:306
IO_COMPLETION_ROUTINE FatSingleAsyncCompletionRoutine
Definition: deviosup.c:108
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
#define Vcb
Definition: cdprocs.h:1415
IO_COMPLETION_ROUTINE FatSingleSyncCompletionRoutine
Definition: deviosup.c:98
#define VOID
Definition: acefi.h:82
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define Dbg
Definition: deviosup.c:28
VOID NTAPI ExSetResourceOwnerPointer(IN PERESOURCE Resource, IN PVOID OwnerPointer)
Definition: resource.c:2045
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1081
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define SL_WRITE_THROUGH
Definition: iotypes.h:1804
struct tagContext Context
Definition: acpixf.h:1034
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define KeGetCurrentThread
Definition: hal.h:44
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
#define IRP_CONTEXT_FLAG_OVERRIDE_VERIFY
Definition: fatstruc.h:1569
#define FatUpdateIOCountersPCW(IsAWrite, Count)
Definition: deviosup.c:184
#define PAGED_CODE()
#define FatLowLevelReadWrite(IRPCONTEXT, DO, IRP, VCB)
Definition: deviosup.c:163

Referenced by _Requires_lock_held_().

◆ FatSingleAsyncCompletionRoutine()

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

Definition at line 3106 of file deviosup.c.

3143 {
3145 
3146  PFAT_IO_CONTEXT Context = Contxt;
3147  BOOLEAN PostRequest = FALSE;
3148 
3149  DebugTrace(+1, Dbg, "FatSingleAsyncCompletionRoutine, Context = %p\n", Context );
3150 
3151  //
3152  // Fill in the information field correctedly if this worked.
3153  //
3154 
3156 
3157  if (NT_SUCCESS(Irp->IoStatus.Status)) {
3158 
3159  NT_ASSERT( Irp->IoStatus.Information != 0 );
3160  Irp->IoStatus.Information = Context->Wait.Async.RequestedByteCount;
3161  NT_ASSERT( Irp->IoStatus.Information != 0 );
3162 
3163  //
3164  // Now if this wasn't PagingIo, set either the read or write bit.
3165  //
3166 
3167  if (!FlagOn(Irp->Flags, IRP_PAGING_IO)) {
3168 
3169  SetFlag( Context->Wait.Async.FileObject->Flags,
3170  IoGetCurrentIrpStackLocation(Irp)->MajorFunction == IRP_MJ_READ ?
3172  }
3173 
3174  } else {
3175 
3176 #if DBG
3177  if(!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) {
3178  DbgBreakPoint();
3179  }
3180 #endif
3181 
3182 #ifdef SYSCACHE_COMPILE
3183  DbgPrint( "FAT SYSCACHE: SingleAsync (IRP %08x) -> %08x\n", Irp, Irp->IoStatus );
3184 #endif
3185 
3186  //
3187  // Post STATUS_VERIFY_REQUIRED failures. Only post top level IRPs, because recursive I/Os
3188  // cannot process volume verification.
3189  //
3190 
3191  if (!FlagOn(Context->IrpContextFlags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) &&
3192  (Irp->IoStatus.Status == STATUS_VERIFY_REQUIRED)) {
3193  PostRequest = TRUE;
3194  }
3195 
3196  }
3197 
3198  //
3199  // If this was a special async write, decrement the count. Set the
3200  // event if this was the final outstanding I/O for the file. We will
3201  // also want to queue an APC to deal with any error conditionions.
3202  //
3203  _Analysis_assume_(!(Context->Wait.Async.NonPagedFcb) &&
3204  (ExInterlockedAddUlong( &Context->Wait.Async.NonPagedFcb->OutstandingAsyncWrites,
3205  0xffffffff,
3206  &FatData.GeneralSpinLock ) != 1));
3207 
3208  if ((Context->Wait.Async.NonPagedFcb) &&
3209  (ExInterlockedAddUlong( &Context->Wait.Async.NonPagedFcb->OutstandingAsyncWrites,
3210  0xffffffff,
3211  &FatData.GeneralSpinLock ) == 1)) {
3212 
3213  KeSetEvent( Context->Wait.Async.NonPagedFcb->OutstandingAsyncEvent, 0, FALSE );
3214  }
3215 
3216  //
3217  // Now release the resources
3218  //
3219 
3220  if (Context->Wait.Async.Resource != NULL) {
3221 
3222  ExReleaseResourceForThreadLite( Context->Wait.Async.Resource,
3223  Context->Wait.Async.ResourceThreadId );
3224  }
3225 
3226  if (Context->Wait.Async.Resource2 != NULL) {
3227 
3228  ExReleaseResourceForThreadLite( Context->Wait.Async.Resource2,
3229  Context->Wait.Async.ResourceThreadId );
3230  }
3231 
3232  //
3233  // Mark the Irp pending
3234  //
3235 
3236  IoMarkIrpPending( Irp );
3237 
3238  //
3239  // and finally, free the context record.
3240  //
3241 
3242  ExFreePool( Context );
3243 
3244  if (PostRequest) {
3245 
3246  PIRP_CONTEXT IrpContext = NULL;
3247 
3248  _SEH2_TRY {
3249 
3250  IrpContext = FatCreateIrpContext(Irp, TRUE );
3251  ClearFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL);
3252  FatFsdPostRequest( IrpContext, Irp );
3254 
3256 
3257  //
3258  // If we failed to post the IRP, we just have to return the failure
3259  // to the user. :(
3260  //
3261 
3262  NOTHING;
3263  } _SEH2_END;
3264  }
3265 
3266 
3267  DebugTrace(-1, Dbg, "FatSingleAsyncCompletionRoutine -> STATUS_MORE_PROCESSING_REQUIRED\n", 0 );
3268 
3270 
3271  return Status;
3272 }
#define DbgPrint
Definition: loader.c:25
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
LONG NTSTATUS
Definition: precomp.h:26
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
KSPIN_LOCK GeneralSpinLock
Definition: fatstruc.h:151
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
void DbgBreakPoint()
Definition: mach.c:553
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
_SEH2_TRY
Definition: create.c:4226
#define FO_FILE_MODIFIED
Definition: iotypes.h:1768
#define FALSE
Definition: types.h:117
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1775
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2289
FAT_DATA FatData
Definition: fatdata.c:56
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
#define NOTHING
Definition: env_spec_w32.h:461
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define Dbg
Definition: deviosup.c:28
#define FatDoCompletionZero(I, C)
Definition: deviosup.c:171
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4400
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define IRP_PAGING_IO
ULONG NTAPI ExInterlockedAddUlong(IN OUT PULONG Addend, IN ULONG Increment, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:88
#define IRP_MJ_READ
Definition: rdpdr.c:46
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
#define IRP_CONTEXT_FLAG_RECURSIVE_CALL
Definition: fatstruc.h:1561
VOID NTAPI ExReleaseResourceForThreadLite(IN PERESOURCE Resource, IN ERESOURCE_THREAD Thread)
Definition: resource.c:1844
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
return STATUS_SUCCESS
Definition: btrfs.c:3014
IoMarkIrpPending(Irp)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define _Analysis_assume_(expr)
Definition: no_sal2.h:10
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ FatSingleNonAlignedSync()

VOID FatSingleNonAlignedSync ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PUCHAR  Buffer,
IN LBO  Lbo,
IN ULONG  ByteCount,
IN PIRP  Irp 
)

Definition at line 2171 of file deviosup.c.

2212 {
2214 
2215  PMDL Mdl;
2216  PMDL SavedMdl;
2217 #ifndef __REACTOS__
2218  BOOLEAN IsAWrite = FALSE;
2219 #endif
2220 
2221  PAGED_CODE();
2222 
2223  DebugTrace(+1, Dbg, "FatSingleNonAlignedAsync\n", 0);
2224  DebugTrace( 0, Dbg, "MajorFunction = %08lx\n", IrpContext->MajorFunction );
2225  DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb );
2226  DebugTrace( 0, Dbg, "Buffer = %p\n", Buffer );
2227  DebugTrace( 0, Dbg, "Lbo = %08lx\n", Lbo);
2228  DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
2229  DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
2230 
2231  //
2232  // Create a new Mdl describing the buffer, saving the current one in the
2233  // Irp
2234  //
2235 
2236  SavedMdl = Irp->MdlAddress;
2237 
2238  Irp->MdlAddress = 0;
2239 
2240  Mdl = IoAllocateMdl( Buffer,
2241  ByteCount,
2242  FALSE,
2243  FALSE,
2244  Irp );
2245 
2246  if (Mdl == NULL) {
2247 
2248  Irp->MdlAddress = SavedMdl;
2249 
2251  }
2252 
2253  //
2254  // Lock the new Mdl in memory.
2255  //
2256 
2257  _SEH2_TRY {
2258 
2260 
2261  } _SEH2_FINALLY {
2262 
2263  if ( _SEH2_AbnormalTermination() ) {
2264 
2265  IoFreeMdl( Mdl );
2266  Irp->MdlAddress = SavedMdl;
2267  }
2268  } _SEH2_END;
2269 
2270  //
2271  // Set up the completion routine address in our stack frame.
2272  //
2273 
2276  IrpContext->FatIoContext,
2277  TRUE,
2278  TRUE,
2279  TRUE );
2280 
2281  //
2282  // Setup the next IRP stack location in the associated Irp for the disk
2283  // driver beneath us.
2284  //
2285 
2287 
2288  //
2289  // Setup the Stack location to do a read from the disk driver.
2290  //
2291 
2292  IrpSp->MajorFunction = IrpContext->MajorFunction;
2293  IrpSp->Parameters.Read.Length = ByteCount;
2294  IrpSp->Parameters.Read.ByteOffset.QuadPart = Lbo;
2295 
2296 #ifndef __REACTOS__
2297  IsAWrite = (IrpSp->MajorFunction == IRP_MJ_WRITE);
2298 #endif
2299 
2300  //
2301  // If this I/O originating during FatVerifyVolume, bypass the
2302  // verify logic.
2303  //
2304 
2305  if (Vcb->VerifyThread == KeGetCurrentThread()) {
2306 
2307  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY );
2308  }
2309 
2310  //
2311  // If this I/O requires override verify, bypass the verify logic.
2312  //
2313 
2314  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY )) {
2315 
2317  }
2318 
2319  //
2320  // Issue the read request
2321  //
2322 
2323  DebugDoit( FatIoCallDriverCount += 1);
2324 
2325  //
2326  // If IoCallDriver returns an error, it has completed the Irp
2327  // and the error will be caught by our completion routines
2328  // and dealt with as a normal IO error.
2329  //
2330 
2331  _SEH2_TRY {
2332 
2333  (VOID)FatLowLevelReadWrite( IrpContext,
2334  Vcb->TargetDeviceObject,
2335  Irp,
2336  Vcb );
2337 
2338  FatWaitSync( IrpContext );
2339 
2340  } _SEH2_FINALLY {
2341 
2342  MmUnlockPages( Mdl );
2343  IoFreeMdl( Mdl );
2344  Irp->MdlAddress = SavedMdl;
2345  } _SEH2_END;
2346 
2347  //
2348  // We just issued an IO to the storage stack, update the counters indicating so.
2349  //
2350 
2352 
2353  FatUpdateIOCountersPCW( IsAWrite, ByteCount );
2354  }
2355 
2356  //
2357  // And return to our caller
2358  //
2359 
2360  DebugTrace(-1, Dbg, "FatSingleNonAlignedSync -> VOID\n", 0);
2361 
2362  return;
2363 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define DebugDoit(X)
Definition: fatdata.h:316
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
LOGICAL FatDiskAccountingEnabled
Definition: fatdata.c:129
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
IN PFCB IN VBO OUT PLBO Lbo
Definition: fatprocs.h:306
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1439
VOID FatWaitSync(IN PIRP_CONTEXT IrpContext)
Definition: deviosup.c:2367
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2974
_SEH2_TRY
Definition: create.c:4226
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
Definition: bufpool.h:45
#define Vcb
Definition: cdprocs.h:1415
IO_COMPLETION_ROUTINE FatSingleSyncCompletionRoutine
Definition: deviosup.c:98
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define VOID
Definition: acefi.h:82
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define Dbg
Definition: deviosup.c:28
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1081
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4400
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:935
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
_SEH2_FINALLY
Definition: create.c:4371
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define KeGetCurrentThread
Definition: hal.h:44
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
#define IRP_CONTEXT_FLAG_OVERRIDE_VERIFY
Definition: fatstruc.h:1569
#define FatUpdateIOCountersPCW(IsAWrite, Count)
Definition: deviosup.c:184
#define PAGED_CODE()
#define FatLowLevelReadWrite(IRPCONTEXT, DO, IRP, VCB)
Definition: deviosup.c:163

◆ FatSingleSyncCompletionRoutine()

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

Definition at line 3034 of file deviosup.c.

3071 {
3072  PFAT_IO_CONTEXT Context = Contxt;
3073 
3074  DebugTrace(+1, Dbg, "FatSingleSyncCompletionRoutine, Context = %p\n", Context );
3075 
3077 
3078  if (!NT_SUCCESS( Irp->IoStatus.Status )) {
3079 
3080 #if DBG
3081  if(!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) {
3082  DbgBreakPoint();
3083  }
3084 #endif
3085 
3086  }
3087 
3088  NT_ASSERT( !(NT_SUCCESS( Irp->IoStatus.Status ) && Irp->IoStatus.Information == 0 ));
3089 
3090  KeSetEvent( &Context->Wait.SyncEvent, 0, FALSE );
3091 
3092  DebugTrace(-1, Dbg, "FatSingleSyncCompletionRoutine -> STATUS_MORE_PROCESSING_REQUIRED\n", 0 );
3093 
3095 
3097 }
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
void DbgBreakPoint()
Definition: mach.c:553
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Dbg
Definition: deviosup.c:28
#define FatDoCompletionZero(I, C)
Definition: deviosup.c:171
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ FatSpecialSyncCompletionRoutine()

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

Definition at line 2967 of file deviosup.c.

3009 {
3010  PFAT_SYNC_CONTEXT SyncContext = (PFAT_SYNC_CONTEXT)Contxt;
3011 
3013 
3014  DebugTrace(+1, Dbg, "FatSpecialSyncCompletionRoutine, Context = %p\n", Contxt );
3015 
3016  SyncContext->Iosb = Irp->IoStatus;
3017 
3018  KeSetEvent( &SyncContext->Event, 0, FALSE );
3019 
3020  DebugTrace(-1, Dbg, "FatSpecialSyncCompletionRoutine -> STATUS_SUCCESS\n", 0 );
3021 
3023 
3024  return STATUS_SUCCESS;
3025 }
struct _FAT_SYNC_CONTEXT * PFAT_SYNC_CONTEXT
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define FALSE
Definition: types.h:117
IO_STATUS_BLOCK Iosb
Definition: deviosup.c:53
#define Dbg
Definition: deviosup.c:28
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
return STATUS_SUCCESS
Definition: btrfs.c:3014

◆ FatToggleMediaEjectDisable()

NTSTATUS FatToggleMediaEjectDisable ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN BOOLEAN  PreventRemoval 
)

Definition at line 3495 of file deviosup.c.

3521 {
3522  PIRP Irp;
3523  KIRQL SavedIrql;
3524  NTSTATUS Status;
3525  FAT_SYNC_CONTEXT SyncContext;
3526  PREVENT_MEDIA_REMOVAL Prevent;
3527 
3528  UNREFERENCED_PARAMETER( IrpContext );
3529 
3530  //
3531  // If PreventRemoval is the same as VCB_STATE_FLAG_REMOVAL_PREVENTED,
3532  // no-op this call, otherwise toggle the state of the flag.
3533  //
3534 
3535  KeAcquireSpinLock( &FatData.GeneralSpinLock, &SavedIrql );
3536 
3537  if ((PreventRemoval ^
3539 
3540  KeReleaseSpinLock( &FatData.GeneralSpinLock, SavedIrql );
3541 
3542  return STATUS_SUCCESS;
3543 
3544  } else {
3545 
3547 
3548  KeReleaseSpinLock( &FatData.GeneralSpinLock, SavedIrql );
3549  }
3550 
3551  Prevent.PreventMediaRemoval = PreventRemoval;
3552 
3553  KeInitializeEvent( &SyncContext.Event, NotificationEvent, FALSE );
3554 
3555  //
3556  // We build this IRP using a junk Iosb that will receive the final
3557  // completion status since we won't be around for it.
3558  //
3559  // We fill in the UserIosb manually below,
3560  // So passing NULL for the final parameter is ok in this special case.
3561  //
3562 #ifdef _MSC_VER
3563 #pragma warning(suppress: 6387)
3564 #endif
3566  Vcb->TargetDeviceObject,
3567  &Prevent,
3568  sizeof(PREVENT_MEDIA_REMOVAL),
3569  NULL,
3570  0,
3571  FALSE,
3572  NULL,
3573  NULL );
3574 
3575  if ( Irp != NULL ) {
3576 
3577  //
3578  // Use our special completion routine which will remove the requirement that
3579  // the caller must be below APC level. All it tells us is that the Irp got
3580  // back, but will not tell us if it was succesful or not. We don't care,
3581  // and there is of course no fallback if the attempt to prevent removal
3582  // doesn't work for some mysterious reason.
3583  //
3584  // Normally, all IO is done at passive level. However, MM needs to be able
3585  // to issue IO with fast mutexes locked down, which raises us to APC. The
3586  // overlying IRP is set up to complete in yet another magical fashion even
3587  // though APCs are disabled, and any IRPage we do in these cases has to do
3588  // the same. Marking media dirty (and toggling eject state) is one.
3589  //
3590 
3591  Irp->UserIosb = &Irp->IoStatus;
3592 
3595  &SyncContext,
3596  TRUE,
3597  TRUE,
3598  TRUE );
3599 
3600  Status = IoCallDriver( Vcb->TargetDeviceObject, Irp );
3601 
3602  if (Status == STATUS_PENDING) {
3603 
3604  (VOID) KeWaitForSingleObject( &SyncContext.Event,
3605  Executive,
3606  KernelMode,
3607  FALSE,
3608  NULL );
3609 
3610  Status = SyncContext.Iosb.Status;
3611  }
3612 
3613  return Status;
3614  }
3615 
3617 }
#define VCB_STATE_FLAG_REMOVAL_PREVENTED
Definition: fatstruc.h:570
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
LONG NTSTATUS
Definition: precomp.h:26
KSPIN_LOCK GeneralSpinLock
Definition: fatstruc.h:151
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
IO_STATUS_BLOCK Iosb
Definition: deviosup.c:53
FAT_DATA FatData
Definition: fatdata.c:56
#define STATUS_PENDING
Definition: ntstatus.h:82
#define Vcb
Definition: cdprocs.h:1415
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
BOOLEAN PreventMediaRemoval
Definition: ntddstor.h:343
Status
Definition: gdiplustypes.h:24
#define VOID
Definition: acefi.h:82
IO_COMPLETION_ROUTINE FatSpecialSyncCompletionRoutine
Definition: deviosup.c:88
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IOCTL_DISK_MEDIA_REMOVAL
Definition: cdrw_usr.h:176
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by _Requires_lock_held_(), and FatDeferredCleanVolume().

◆ FatUpdateDiskStats()

VOID FatUpdateDiskStats ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp,
IN ULONG  ByteCount 
)

Definition at line 760 of file deviosup.c.

785 {
786  PETHREAD OriginatingThread = NULL;
787  ULONG NumReads = 0;
788  ULONG NumWrites = 0;
789  ULONGLONG BytesToRead = 0;
790  ULONGLONG BytesToWrite = 0;
791 
792  //
793  // Here we attempt to charge the IO back to the originating process.
794  // - These checks are intended to cover following cases:
795  // o Buffered sync reads
796  // o Unbuffered sync read
797  // o Inline metadata reads
798  // o memory mapped reads (in-line faulting of data)
799  //
800 
801  if (IrpContext->MajorFunction == IRP_MJ_READ) {
802 
803  NumReads++;
804  BytesToRead = ByteCount;
805 
806  if ((Irp->Tail.Overlay.Thread != NULL) &&
807  !IoIsSystemThread( Irp->Tail.Overlay.Thread )) {
808 
809  OriginatingThread = Irp->Tail.Overlay.Thread;
810 
811  } else if (!IoIsSystemThread( PsGetCurrentThread() )) {
812 
813  OriginatingThread = PsGetCurrentThread();
814 
815  //
816  // We couldn't find a non-system entity, so this should be charged to system.
817  // Do so only if we are top level.
818  // If we are not top-level then the read was initiated by someone like Cc (read ahead)
819  // who should have already accounted for this IO.
820  //
821 
822  } else if (IoIsSystemThread( PsGetCurrentThread() ) &&
823  (IoGetTopLevelIrp() == Irp)) {
824 
825  OriginatingThread = PsGetCurrentThread();
826  }
827 
828  //
829  // Charge the write to Originating process.
830  // Intended to cover the following writes:
831  // - Unbuffered sync write
832  // - unbuffered async write
833  //
834  // If we re not top-level, then it should already have been accounted for
835  // somewhere else (Cc).
836  //
837 
838  } else if (IrpContext->MajorFunction == IRP_MJ_WRITE) {
839 
840  NumWrites++;
841  BytesToWrite = ByteCount;
842 
843  if (IoGetTopLevelIrp() == Irp) {
844 
845  if ((Irp->Tail.Overlay.Thread != NULL) &&
846  !IoIsSystemThread( Irp->Tail.Overlay.Thread )) {
847 
848  OriginatingThread = Irp->Tail.Overlay.Thread;
849 
850  } else {
851 
852  OriginatingThread = PsGetCurrentThread();
853  }
854 
855  //
856  // For mapped page writes
857  //
858 
860 
861  OriginatingThread = PsGetCurrentThread();
862  }
863  }
864 
865  if (OriginatingThread != NULL) {
866 
867  PsUpdateDiskCounters( PsGetThreadProcess( OriginatingThread ),
868  BytesToRead,
869  BytesToWrite,
870  NumReads,
871  NumWrites,
872  0 );
873  }
874 }
BOOLEAN NTAPI IoIsSystemThread(IN PETHREAD Thread)
Definition: util.c:115
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:61
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_In_ PIRP Irp
Definition: csq.h:116
PEPROCESS __stdcall PsGetThreadProcess(_In_ PETHREAD Thread)
smooth NULL
Definition: ftsmooth.c:416
uint64_t ULONGLONG
Definition: typedefs.h:67
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1081
#define IRP_MJ_READ
Definition: rdpdr.c:46
unsigned int ULONG
Definition: retypes.h:1
#define IRP_MJ_WRITE
Definition: rdpdr.c:47

Referenced by _Requires_lock_held_().

◆ FatWaitSync()

VOID FatWaitSync ( IN PIRP_CONTEXT  IrpContext)

Definition at line 2367 of file deviosup.c.

2386 {
2387  PAGED_CODE();
2388 
2389  DebugTrace(+1, Dbg, "FatWaitSync, Context = %p\n", IrpContext->FatIoContext );
2390 
2391  KeWaitForSingleObject( &IrpContext->FatIoContext->Wait.SyncEvent,
2393 
2394  KeClearEvent( &IrpContext->FatIoContext->Wait.SyncEvent );
2395 
2396  DebugTrace(-1, Dbg, "FatWaitSync -> VOID\n", 0 );
2397 }
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
#define Dbg
Definition: deviosup.c:28
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define PAGED_CODE()

Referenced by _Requires_lock_held_(), and FatSingleNonAlignedSync().

Variable Documentation

◆ FatMultiAsyncCompletionRoutine

NTSTATUS NTAPI FatMultiAsyncCompletionRoutine

Definition at line 78 of file deviosup.c.

Referenced by FatMultipleAsync().

◆ FatMultiSyncCompletionRoutine

NTSTATUS NTAPI FatMultiSyncCompletionRoutine

Definition at line 68 of file deviosup.c.

Referenced by FatMultipleAsync().

◆ FatPagingFileCompletionRoutine

NTSTATUS NTAPI FatPagingFileCompletionRoutine

Definition at line 118 of file deviosup.c.

Referenced by FatPagingFileIo().

◆ FatPagingFileCompletionRoutineCatch

NTSTATUS NTAPI FatPagingFileCompletionRoutineCatch

Definition at line 128 of file deviosup.c.

Referenced by FatPagingFileIo().

◆ FatSingleAsyncCompletionRoutine

NTSTATUS NTAPI FatSingleAsyncCompletionRoutine

Definition at line 108 of file deviosup.c.

Referenced by FatSingleAsync().

◆ FatSingleSyncCompletionRoutine

NTSTATUS NTAPI FatSingleSyncCompletionRoutine

Definition at line 98 of file deviosup.c.

Referenced by FatSingleAsync(), and FatSingleNonAlignedSync().

◆ FatSpecialSyncCompletionRoutine

NTSTATUS NTAPI FatSpecialSyncCompletionRoutine

Definition at line 88 of file deviosup.c.

Referenced by FatToggleMediaEjectDisable().