ReactOS  0.4.14-dev-317-g96040ec
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:325
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; \
}
#define C(name, bit)
Definition: cpu.h:208
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
#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

Definition at line 171 of file deviosup.c.

◆ FatLowLevelReadWrite

#define FatLowLevelReadWrite (   IRPCONTEXT,
  DO,
  IRP,
  VCB 
)
Value:
( \
IoCallDriver((DO),(IRP)) \
)
IRP
Definition: iotypes.h:2463
#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:1015

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 #ifndef __REACTOS__
1061  if (MmGetSystemAddressForMdlSafe( Mdl, NormalPagePriority | MdlMappingNoExecute ) == NULL) {
1062 #else
1064 #endif
1065 
1067  }
1068  }
1069 
1070 
1071  //
1072  // Try to lookup the first run. If there is just a single run,
1073  // we may just be able to pass it on.
1074  //
1075 
1076  FatLookupFileAllocation( IrpContext,
1077  FcbOrDcb,
1078  StartingVbo,
1079  &NextLbo,
1080  &NextByteCount,
1081  &NextIsAllocated,
1082  &EndOnMax,
1083  &FirstIndex );
1084 
1085  //
1086  // We just added the allocation, thus there must be at least
1087  // one entry in the mcb corresponding to our write, ie.
1088  // NextIsAllocated must be true. If not, the pre-existing file
1089  // must have an allocation error.
1090  //
1091 
1092  if ( !NextIsAllocated ) {
1093 
1094  FatPopUpFileCorrupt( IrpContext, FcbOrDcb );
1095 
1097  }
1098 
1099  NT_ASSERT( NextByteCount != 0 );
1100 
1101  //
1102  // If the request was not aligned correctly, read in the first
1103  // part first.
1104  //
1105 
1106 
1107  //
1108  // See if the write covers a single valid run, and if so pass
1109  // it on. We must bias this by the byte that is lost at the
1110  // end of the maximal file.
1111  //
1112 
1113  if ( NextByteCount >= ByteCount - (EndOnMax ? 1 : 0)) {
1114 
1115  if (FlagOn(Irp->Flags, IRP_PAGING_IO)) {
1116  CollectDiskIoStats(FcbOrDcb->Vcb, IrpContext->MajorFunction,
1117  FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_USER_IO), 1);
1118  } else {
1119 
1120  PFILE_SYSTEM_STATISTICS Stats =
1122 
1123  if (IrpContext->MajorFunction == IRP_MJ_READ) {
1124  Stats->Fat.NonCachedDiskReads += 1;
1125  } else {
1126  Stats->Fat.NonCachedDiskWrites += 1;
1127  }
1128  }
1129 
1130  DebugTrace( 0, Dbg, "Passing 1 Irp on to Disk Driver\n", 0 );
1131 
1132  FatSingleAsync( IrpContext,
1133  FcbOrDcb->Vcb,
1134  NextLbo,
1135  ByteCount,
1136  Irp );
1137 
1138  } else {
1139 
1140  //
1141  // If there we can't wait, and there are more runs than we can handle,
1142  // we will have to post this request.
1143  //
1144 
1145  FatLookupFileAllocation( IrpContext,
1146  FcbOrDcb,
1147  StartingVbo + ByteCount - 1,
1148  &LastLbo,
1149  &LastByteCount,
1150  &LastIsAllocated,
1151  &EndOnMax,
1152  &LastIndex );
1153 
1154  //
1155  // Since we already added the allocation for the whole
1156  // write, assert that we find runs until ByteCount == 0
1157  // Otherwise this file is corrupt.
1158  //
1159 
1160  if ( !LastIsAllocated ) {
1161 
1162  FatPopUpFileCorrupt( IrpContext, FcbOrDcb );
1163 
1165  }
1166 
1167  if (LastIndex - FirstIndex + 1 > FAT_MAX_IO_RUNS_ON_STACK) {
1168 
1170  (LastIndex - FirstIndex + 1) * sizeof(IO_RUN),
1171  TAG_IO_RUNS );
1172 
1173  } else {
1174 
1175  IoRuns = StackIoRuns;
1176  }
1177 
1178  NT_ASSERT( LastIndex != FirstIndex );
1179 
1180  CurrentIndex = FirstIndex;
1181 
1182  //
1183  // Loop while there are still byte writes to satisfy.
1184  //
1185 
1186  while (CurrentIndex <= LastIndex) {
1187 
1188 
1189  NT_ASSERT( NextByteCount != 0);
1190  NT_ASSERT( ByteCount != 0);
1191 
1192  //
1193  // If next run is larger than we need, "ya get what you need".
1194  //
1195 
1196  if (NextByteCount > ByteCount) {
1197  NextByteCount = ByteCount;
1198  }
1199 
1200  //
1201  // Now that we have properly bounded this piece of the
1202  // transfer, it is time to write it.
1203  //
1204  // We remember each piece of a parallel run by saving the
1205  // essential information in the IoRuns array. The tranfers
1206  // are started up in parallel below.
1207  //
1208 
1209  IoRuns[NextRun].Vbo = StartingVbo;
1210  IoRuns[NextRun].Lbo = NextLbo;
1211  IoRuns[NextRun].Offset = BufferOffset;
1212  IoRuns[NextRun].ByteCount = NextByteCount;
1213  NextRun += 1;
1214 
1215  //
1216  // Now adjust everything for the next pass through the loop.
1217  //
1218 
1219  StartingVbo += NextByteCount;
1220  BufferOffset += NextByteCount;
1221  ByteCount -= NextByteCount;
1222 
1223  //
1224  // Try to lookup the next run (if we are not done).
1225  //
1226 
1227  CurrentIndex += 1;
1228 
1229  if ( CurrentIndex <= LastIndex ) {
1230 
1231  NT_ASSERT( ByteCount != 0 );
1232 
1234  CurrentIndex,
1235  &NextVbo,
1236  &NextLbo,
1237  &NextByteCount );
1238 
1239 
1240  NT_ASSERT(NextVbo == StartingVbo);
1241 
1242 
1243  }
1244 
1245  } // while ( CurrentIndex <= LastIndex )
1246 
1247  //
1248  // Now set up the Irp->IoStatus. It will be modified by the
1249  // multi-completion routine in case of error or verify required.
1250  //
1251 
1252  Irp->IoStatus.Status = STATUS_SUCCESS;
1253  Irp->IoStatus.Information = OriginalByteCount;
1254 
1255  if (FlagOn(Irp->Flags, IRP_PAGING_IO)) {
1256  CollectDiskIoStats(FcbOrDcb->Vcb, IrpContext->MajorFunction,
1257  FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_USER_IO), NextRun);
1258  }
1259 
1260  //
1261  // OK, now do the I/O.
1262  //
1263 
1264  _SEH2_TRY {
1265 
1266  DebugTrace( 0, Dbg, "Passing Multiple Irps on to Disk Driver\n", 0 );
1267 
1268  FatMultipleAsync( IrpContext,
1269  FcbOrDcb->Vcb,
1270  Irp,
1271  NextRun,
1272  IoRuns );
1273 
1274  } _SEH2_FINALLY {
1275 
1276  if (IoRuns != StackIoRuns) {
1277 
1278  ExFreePool( IoRuns );
1279  }
1280  } _SEH2_END;
1281  }
1282 
1283  if (!Wait) {
1284 
1285  DebugTrace(-1, Dbg, "FatNonCachedIo -> STATUS_PENDING\n", 0);
1286  return STATUS_PENDING;
1287  }
1288 
1289  FatWaitSync( IrpContext );
1290 
1291 
1292  DebugTrace(-1, Dbg, "FatNonCachedIo -> 0x%08lx\n", Irp->IoStatus.Status);
1293  return Irp->IoStatus.Status;
1294 }
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:323
#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:3288
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:2375
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2965
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
ULONG NonCachedDiskWrites
Definition: winioctl.h:685
#define PAGED_CODE()
Definition: video.h:57
IN PIRP IN PFCB IN ULONG IN ULONG IN ULONG UserByteCount
Definition: fatprocs.h:580
_SEH2_TRY
Definition: create.c:4250
ULONG NonCachedWriteBytes
Definition: winioctl.h:683
FAT_STATISTICS Fat
Definition: fatstruc.h:601
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:325
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:297
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN OUT PBOOLEAN EndOnMax
Definition: fatprocs.h:297
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
ULONG NumberProcessors
Definition: fatstruc.h:80
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:402
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1061
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:4424
_SEH2_FINALLY
Definition: create.c:4395
#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:1630
IN PIRP IN PFCB IN ULONG IN ULONG IN ULONG IN ULONG StreamFlags
Definition: fatprocs.h:580
return STATUS_SUCCESS
Definition: btrfs.c:2938
#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:1998
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
IN BOOLEAN Wait
Definition: fatprocs.h:1529
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ FatBufferUserBuffer()

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

Definition at line 3427 of file deviosup.c.

3454 {
3455  PUCHAR UserBuffer;
3456 
3457  UNREFERENCED_PARAMETER( IrpContext );
3458 
3459  PAGED_CODE();
3460 
3461  //
3462  // Handle the no buffer case.
3463  //
3464 
3465  if (BufferLength == 0) {
3466 
3467  return NULL;
3468  }
3469 
3470  //
3471  // If there is no system buffer we must have been supplied an Mdl
3472  // describing the users input buffer, which we will now snapshot.
3473  //
3474 
3475  if (Irp->AssociatedIrp.SystemBuffer == NULL) {
3476 
3477  UserBuffer = FatMapUserBuffer( IrpContext, Irp );
3478 
3479 #ifndef __REACTOS__
3480  Irp->AssociatedIrp.SystemBuffer = FsRtlAllocatePoolWithQuotaTag( NonPagedPoolNx,
3481 #else
3482  Irp->AssociatedIrp.SystemBuffer = FsRtlAllocatePoolWithQuotaTag( NonPagedPool,
3483 #endif
3484  BufferLength,
3486 
3487  //
3488  // Set the flags so that the completion code knows to deallocate the
3489  // buffer.
3490  //
3491 
3493 
3494  _SEH2_TRY {
3495 
3496  RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer,
3497  UserBuffer,
3498  BufferLength );
3499 
3501 
3502  NTSTATUS Status;
3503 
3505  FatRaiseStatus( IrpContext,
3507  } _SEH2_END;
3508  }
3509 
3510  return Irp->AssociatedIrp.SystemBuffer;
3511 }
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
PVOID FatMapUserBuffer(IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp)
Definition: deviosup.c:3369
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
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:2965
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#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:4424
#define IRP_BUFFERED_IO
#define IRP_DEALLOCATE_BUFFER
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12

Referenced by FatCommonSetEa().

◆ FatBuildZeroMdl()

PMDL FatBuildZeroMdl ( __in PIRP_CONTEXT  IrpContext,
__in ULONG  Length 
)

Definition at line 3754 of file deviosup.c.

3777 {
3778  PMDL ZeroMdl;
3779  ULONG SavedByteCount;
3780  PPFN_NUMBER Page;
3781  ULONG i;
3782 
3783  UNREFERENCED_PARAMETER( IrpContext );
3784 
3785  //
3786  // Spin down trying to get an MDL which can describe our operation.
3787  //
3788 
3789  while (TRUE) {
3790 
3791  ZeroMdl = IoAllocateMdl( FatData.ZeroPage, Length, FALSE, FALSE, NULL );
3792 
3793  //
3794  // Throttle ourselves to what we've physically allocated. Note that
3795  // we could have started with an odd multiple of this number. If we
3796  // tried for exactly that size and failed, we're toast.
3797  //
3798 
3799  if (ZeroMdl || (Length <= PAGE_SIZE)) {
3800 
3801  break;
3802  }
3803 
3804  //
3805  // Fallback by half and round down to a page multiple.
3806  //
3807 
3808  ASSERT( IrpContext->Vcb->Bpb.BytesPerSector <= PAGE_SIZE );
3810  if (Length < PAGE_SIZE) {
3811  Length = PAGE_SIZE;
3812  }
3813  }
3814 
3815  if (ZeroMdl == NULL) {
3816  return NULL;
3817  }
3818 
3819  //
3820  // If we have throttled all the way down, stop and just build a
3821  // simple MDL describing our previous allocation.
3822  //
3823 
3824  if (Length == PAGE_SIZE) {
3825 
3826  MmBuildMdlForNonPagedPool( ZeroMdl );
3827  return ZeroMdl;
3828  }
3829 
3830  //
3831  // Now we will temporarily lock the allocated pages
3832  // only, and then replicate the page frame numbers through
3833  // the entire Mdl to keep writing the same pages of zeros.
3834  //
3835  // It would be nice if Mm exported a way for us to not have
3836  // to pull the Mdl apart and rebuild it ourselves, but this
3837  // is so bizzare a purpose as to be tolerable.
3838  //
3839 
3840  SavedByteCount = ZeroMdl->ByteCount;
3841  ZeroMdl->ByteCount = PAGE_SIZE;
3842  MmBuildMdlForNonPagedPool( ZeroMdl );
3843 
3844  ZeroMdl->MdlFlags &= ~MDL_SOURCE_IS_NONPAGED_POOL;
3845  ZeroMdl->MdlFlags |= MDL_PAGES_LOCKED;
3846  ZeroMdl->MappedSystemVa = NULL;
3847  ZeroMdl->StartVa = NULL;
3848  ZeroMdl->ByteCount = SavedByteCount;
3849  Page = MmGetMdlPfnArray( ZeroMdl );
3850  for (i = 1; i < (ADDRESS_AND_SIZE_TO_SPAN_PAGES( 0, SavedByteCount )); i++) {
3851  *(Page + i) = *(Page);
3852  }
3853 
3854 
3855  return ZeroMdl;
3856 }
#define TRUE
Definition: types.h:120
PVOID ZeroPage
Definition: fatstruc.h:162
#define MmGetMdlPfnArray(_Mdl)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
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
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:3092

◆ FatLockUserBuffer()

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

Definition at line 3288 of file deviosup.c.

3321 {
3322  PMDL Mdl = NULL;
3323 
3324  PAGED_CODE();
3325 
3326  if (Irp->MdlAddress == NULL) {
3327 
3328  //
3329  // Allocate the Mdl, and Raise if we fail.
3330  //
3331 
3332  Mdl = IoAllocateMdl( Irp->UserBuffer, BufferLength, FALSE, FALSE, Irp );
3333 
3334  if (Mdl == NULL) {
3335 
3337  }
3338 
3339  //
3340  // Now probe the buffer described by the Irp. If we get an exception,
3341  // deallocate the Mdl and return the appropriate "expected" status.
3342  //
3343 
3344  _SEH2_TRY {
3345 
3346  MmProbeAndLockPages( Mdl,
3347  Irp->RequestorMode,
3348  Operation );
3349 
3351 
3352  NTSTATUS Status;
3353 
3355 
3356  IoFreeMdl( Mdl );
3357  Irp->MdlAddress = NULL;
3358 
3359  FatRaiseStatus( IrpContext,
3361  } _SEH2_END;
3362  }
3363 
3364  UNREFERENCED_PARAMETER( IrpContext );
3365 }
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
LONG NTSTATUS
Definition: precomp.h:26
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2965
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#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:4424
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

Referenced by _Requires_lock_held_(), and FatPrePostIrp().

◆ FatMapUserBuffer()

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

Definition at line 3369 of file deviosup.c.

3394 {
3395  UNREFERENCED_PARAMETER( IrpContext );
3396 
3397  PAGED_CODE();
3398 
3399  //
3400  // If there is no Mdl, then we must be in the Fsd, and we can simply
3401  // return the UserBuffer field from the Irp.
3402  //
3403 
3404  if (Irp->MdlAddress == NULL) {
3405 
3406  return Irp->UserBuffer;
3407 
3408  } else {
3409 
3410 #ifndef __REACTOS__
3411  PVOID Address = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute );
3412 #else
3414 #endif
3415 
3416  if (Address == NULL) {
3417 
3419  }
3420 
3421  return Address;
3422  }
3423 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define ExRaiseStatus
Definition: ntoskrnl.h:96
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68

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 2515 of file deviosup.c.

2560 {
2562  PFAT_IO_CONTEXT Context = Contxt;
2563  PIRP MasterIrp = Context->MasterIrp;
2564  BOOLEAN PostRequest = FALSE;
2565 
2566  DebugTrace(+1, Dbg, "FatMultiAsyncCompletionRoutine, Context = %p\n", Context );
2567 
2568  //
2569  // If we got an error (or verify required), remember it in the Irp
2570  //
2571 
2572  if (!NT_SUCCESS( Irp->IoStatus.Status )) {
2573 
2574 #if DBG
2575  if (!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) {
2576  DbgBreakPoint();
2577  }
2578 #endif
2579 
2580 #ifdef SYSCACHE_COMPILE
2581  DbgPrint( "FAT SYSCACHE: MultiAsync (IRP %08x for Master %08x) -> %08x\n", Irp, MasterIrp, Irp->IoStatus );
2582 #endif
2583 
2584  MasterIrp->IoStatus = Irp->IoStatus;
2585 
2586  }
2587 
2588  NT_ASSERT( !(NT_SUCCESS( Irp->IoStatus.Status ) && Irp->IoStatus.Information == 0 ));
2589 
2590  if (InterlockedDecrement(&Context->IrpCount) == 0) {
2591 
2592  FatDoCompletionZero( MasterIrp, Context );
2593 
2594  if (NT_SUCCESS(MasterIrp->IoStatus.Status)) {
2595 
2596  MasterIrp->IoStatus.Information =
2597  Context->Wait.Async.RequestedByteCount;
2598 
2599  NT_ASSERT(MasterIrp->IoStatus.Information != 0);
2600 
2601  //
2602  // Now if this wasn't PagingIo, set either the read or write bit.
2603  //
2604 
2605  if (!FlagOn(MasterIrp->Flags, IRP_PAGING_IO)) {
2606 
2607  SetFlag( Context->Wait.Async.FileObject->Flags,
2608  IoGetCurrentIrpStackLocation(MasterIrp)->MajorFunction == IRP_MJ_READ ?
2610  }
2611 
2612  } else {
2613 
2614  //
2615  // Post STATUS_VERIFY_REQUIRED failures. Only post top level IRPs, because recursive I/Os
2616  // cannot process volume verification.
2617  //
2618 
2619  if (!FlagOn(Context->IrpContextFlags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) &&
2620  (MasterIrp->IoStatus.Status == STATUS_VERIFY_REQUIRED)) {
2621  PostRequest = TRUE;
2622  }
2623 
2624  }
2625 
2626  //
2627  // If this was a special async write, decrement the count. Set the
2628  // event if this was the final outstanding I/O for the file. We will
2629  // also want to queue an APC to deal with any error conditionions.
2630  //
2631  _Analysis_assume_(!(Context->Wait.Async.NonPagedFcb) &&
2632  (ExInterlockedAddUlong( &Context->Wait.Async.NonPagedFcb->OutstandingAsyncWrites,
2633  0xffffffff,
2634  &FatData.GeneralSpinLock ) != 1));
2635  if ((Context->Wait.Async.NonPagedFcb) &&
2636  (ExInterlockedAddUlong( &Context->Wait.Async.NonPagedFcb->OutstandingAsyncWrites,
2637  0xffffffff,
2638  &FatData.GeneralSpinLock ) == 1)) {
2639 
2640  KeSetEvent( Context->Wait.Async.NonPagedFcb->OutstandingAsyncEvent, 0, FALSE );
2641  }
2642 
2643  //
2644  // Now release the resources.
2645  //
2646 
2647  if (Context->Wait.Async.Resource != NULL) {
2648 
2649  ExReleaseResourceForThreadLite( Context->Wait.Async.Resource,
2650  Context->Wait.Async.ResourceThreadId );
2651  }
2652 
2653  if (Context->Wait.Async.Resource2 != NULL) {
2654 
2655  ExReleaseResourceForThreadLite( Context->Wait.Async.Resource2,
2656  Context->Wait.Async.ResourceThreadId );
2657  }
2658 
2659  //
2660  // Mark the master Irp pending
2661  //
2662 
2663  IoMarkIrpPending( MasterIrp );
2664 
2665  //
2666  // and finally, free the context record.
2667  //
2668 
2669  ExFreePool( Context );
2670 
2671  if (PostRequest) {
2672 
2673  PIRP_CONTEXT IrpContext = NULL;
2674 
2675  _SEH2_TRY {
2676 
2677  IrpContext = FatCreateIrpContext(Irp, TRUE );
2678  ClearFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL);
2679  FatFsdPostRequest( IrpContext, Irp );
2681 
2683 
2684  //
2685  // If we failed to post the IRP, we just have to return the failure
2686  // to the user. :(
2687  //
2688 
2689  NOTHING;
2690  } _SEH2_END;
2691  }
2692  }
2693 
2694  DebugTrace(-1, Dbg, "FatMultiAsyncCompletionRoutine -> SUCCESS\n", 0 );
2695 
2697 
2698  return Status;
2699 }
#define TRUE
Definition: types.h:120
#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:323
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:4250
#define FO_FILE_MODIFIED
Definition: iotypes.h:1745
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1752
#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:2300
FAT_DATA FatData
Definition: fatdata.c:56
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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)
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4424
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
#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:2938
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 1630 of file deviosup.c.

1688 {
1689  PIRP Irp;
1691  PMDL Mdl;
1692  BOOLEAN Wait;
1694 #ifndef __REACTOS__
1695  BOOLEAN IsAWrite = FALSE;
1696  ULONG Length = 0;
1697 #endif
1698 
1699  ULONG UnwindRunCount = 0;
1700 
1701  BOOLEAN ExceptionExpected = TRUE;
1702 
1703  PAGED_CODE();
1704 
1705  DebugTrace(+1, Dbg, "FatMultipleAsync\n", 0);
1706  DebugTrace( 0, Dbg, "MajorFunction = %08lx\n", IrpContext->MajorFunction );
1707  DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb );
1708  DebugTrace( 0, Dbg, "MasterIrp = %p\n", MasterIrp );
1709  DebugTrace( 0, Dbg, "MultipleIrpCount = %08lx\n", MultipleIrpCount );
1710  DebugTrace( 0, Dbg, "IoRuns = %08lx\n", IoRuns );
1711 
1712  //
1713  // If this I/O originating during FatVerifyVolume, bypass the
1714  // verify logic.
1715  //
1716 
1717  if (Vcb->VerifyThread == KeGetCurrentThread()) {
1718 
1719  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY );
1720  }
1721 
1722  //
1723  // Set up things according to whether this is truely async.
1724  //
1725 
1726  Wait = BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
1727 
1728  Context = IrpContext->FatIoContext;
1729 
1730  //
1731  // Finish initializing Context, for use in Read/Write Multiple Asynch.
1732  //
1733 
1734  Context->MasterIrp = MasterIrp;
1735 
1736  IrpSp = IoGetCurrentIrpStackLocation( MasterIrp );
1737 #ifndef __REACTOS__
1738  IsAWrite = (IrpSp->MajorFunction == IRP_MJ_WRITE);
1739  Length = IrpSp->Parameters.Read.Length;
1740 #endif
1741 
1742  _SEH2_TRY {
1743 
1744  //
1745  // Itterate through the runs, doing everything that can fail
1746  //
1747 
1748  for ( UnwindRunCount = 0;
1749  UnwindRunCount < MultipleIrpCount;
1750  UnwindRunCount++ ) {
1751 
1752  //
1753  // Create an associated IRP, making sure there is one stack entry for
1754  // us, as well.
1755  //
1756 
1757  IoRuns[UnwindRunCount].SavedIrp = 0;
1758 
1759  Irp = IoMakeAssociatedIrp( MasterIrp,
1760  (CCHAR)(Vcb->TargetDeviceObject->StackSize + 1) );
1761 
1762  if (Irp == NULL) {
1763 
1765  }
1766 
1767  IoRuns[UnwindRunCount].SavedIrp = Irp;
1768 
1769  //
1770  // Allocate and build a partial Mdl for the request.
1771  //
1772 
1773  Mdl = IoAllocateMdl( (PCHAR)MasterIrp->UserBuffer +
1774  IoRuns[UnwindRunCount].Offset,
1775  IoRuns[UnwindRunCount].ByteCount,
1776  FALSE,
1777  FALSE,
1778  Irp );
1779 
1780  if (Mdl == NULL) {
1781 
1783  }
1784 
1785  //
1786  // Sanity Check
1787  //
1788 
1789  NT_ASSERT( Mdl == Irp->MdlAddress );
1790 
1791  IoBuildPartialMdl( MasterIrp->MdlAddress,
1792  Mdl,
1793  (PCHAR)MasterIrp->UserBuffer +
1794  IoRuns[UnwindRunCount].Offset,
1795  IoRuns[UnwindRunCount].ByteCount );
1796 
1797  //
1798  // Get the first IRP stack location in the associated Irp
1799  //
1800 
1803 
1804  //
1805  // Setup the Stack location to describe our read.
1806  //
1807 
1808  IrpSp->MajorFunction = IrpContext->MajorFunction;
1809  IrpSp->Parameters.Read.Length = IoRuns[UnwindRunCount].ByteCount;
1810  IrpSp->Parameters.Read.ByteOffset.QuadPart = IoRuns[UnwindRunCount].Vbo;
1811 
1812  //
1813  // Set up the completion routine address in our stack frame.
1814  //
1815 
1817  Wait ?
1820  Context,
1821  TRUE,
1822  TRUE,
1823  TRUE );
1824 
1825  //
1826  // Setup the next IRP stack location in the associated Irp for the disk
1827  // driver beneath us.
1828  //
1829 
1831 
1832  //
1833  // Setup the Stack location to do a read from the disk driver.
1834  //
1835 
1836  IrpSp->MajorFunction = IrpContext->MajorFunction;
1837  IrpSp->Parameters.Read.Length = IoRuns[UnwindRunCount].ByteCount;
1838  IrpSp->Parameters.Read.ByteOffset.QuadPart = IoRuns[UnwindRunCount].Lbo;
1839 
1840  //
1841  // If this Irp is the result of a WriteThough operation,
1842  // tell the device to write it through.
1843  //
1844 
1845  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH )) {
1846 
1848  }
1849 
1850  //
1851  // If this I/O requires override verify, bypass the verify logic.
1852  //
1853 
1854  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY )) {
1855 
1857  }
1858  }
1859 
1860  //
1861  // Now we no longer expect an exception. If the driver raises, we
1862  // must bugcheck, because we do not know how to recover from that
1863  // case.
1864  //
1865 
1866  ExceptionExpected = FALSE;
1867 
1868  //
1869  // We only need to set the associated IRP count in the master irp to
1870  // make it a master IRP. But we set the count to one more than our
1871  // caller requested, because we do not want the I/O system to complete
1872  // the I/O. We also set our own count.
1873  //
1874 
1875  Context->IrpCount = MultipleIrpCount;
1876  MasterIrp->AssociatedIrp.IrpCount = MultipleIrpCount;
1877 
1878  if (Wait) {
1879 
1880  MasterIrp->AssociatedIrp.IrpCount += 1;
1881  }
1882  else if (FlagOn( Context->Wait.Async.ResourceThreadId, 3 )) {
1883 
1884  //
1885  // For async requests if we acquired locks, transition the lock owners to an
1886  // object, since when we return this thread could go away before request
1887  // completion, and the resource package may try to boost priority.
1888  //
1889 
1890  if (Context->Wait.Async.Resource != NULL) {
1891 
1892  ExSetResourceOwnerPointer( Context->Wait.Async.Resource,
1893  (PVOID)Context->Wait.Async.ResourceThreadId );
1894  }
1895 
1896  if (Context->Wait.Async.Resource2 != NULL) {
1897 
1898  ExSetResourceOwnerPointer( Context->Wait.Async.Resource2,
1899  (PVOID)Context->Wait.Async.ResourceThreadId );
1900  }
1901  }
1902 
1903  //
1904  // Back up a copy of the IrpContext flags for later use in async completion.
1905  //
1906 
1907  Context->IrpContextFlags = IrpContext->Flags;
1908 
1909  //
1910  // Now that all the dangerous work is done, issue the read requests
1911  //
1912 
1913  for (UnwindRunCount = 0;
1914  UnwindRunCount < MultipleIrpCount;
1915  UnwindRunCount++) {
1916 
1917  Irp = IoRuns[UnwindRunCount].SavedIrp;
1918 
1919  DebugDoit( FatIoCallDriverCount += 1);
1920 
1921  //
1922  // If IoCallDriver returns an error, it has completed the Irp
1923  // and the error will be caught by our completion routines
1924  // and dealt with as a normal IO error.
1925  //
1926 
1927  (VOID)FatLowLevelReadWrite( IrpContext,
1928  Vcb->TargetDeviceObject,
1929  Irp,
1930  Vcb );
1931  }
1932 
1933  //
1934  // We just issued an IO to the storage stack, update the counters indicating so.
1935  //
1936 
1938 
1939  FatUpdateIOCountersPCW( IsAWrite, Length );
1940  }
1941 
1942  } _SEH2_FINALLY {
1943 
1944  ULONG i;
1945 
1947 
1948  //
1949  // Only allocating the spinlock, making the associated Irps
1950  // and allocating the Mdls can fail.
1951  //
1952 
1953  if ( _SEH2_AbnormalTermination() ) {
1954 
1955  //
1956  // If the driver raised, we are hosed. He is not supposed to raise,
1957  // and it is impossible for us to figure out how to clean up.
1958  //
1959 
1960  if (!ExceptionExpected) {
1961  NT_ASSERT( ExceptionExpected );
1962 #ifdef _MSC_VER
1963 #pragma prefast( suppress:28159, "things are seriously wrong if we get here" )
1964 #endif
1965  FatBugCheck( 0, 0, 0 );
1966  }
1967 
1968  //
1969  // Unwind
1970  //
1971 
1972  for (i = 0; i <= UnwindRunCount; i++) {
1973 
1974  if ( (Irp = IoRuns[i].SavedIrp) != NULL ) {
1975 
1976  if ( Irp->MdlAddress != NULL ) {
1977 
1978  IoFreeMdl( Irp->MdlAddress );
1979  }
1980 
1981  IoFreeIrp( Irp );
1982  }
1983  }
1984  }
1985 
1986  //
1987  // And return to our caller
1988  //
1989 
1990  DebugTrace(-1, Dbg, "FatMultipleAsync -> VOID\n", 0);
1991  } _SEH2_END;
1992 
1993  return;
1994 }
signed char * PCHAR
Definition: retypes.h:7
#define TRUE
Definition: types.h:120
#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 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:2965
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
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 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:1780
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:50
#define Vcb
Definition: cdprocs.h:1425
_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:2647
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:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4424
IO_COMPLETION_ROUTINE FatMultiSyncCompletionRoutine
Definition: deviosup.c:68
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
_SEH2_FINALLY
Definition: create.c:4395
#define SL_WRITE_THROUGH
Definition: iotypes.h:1781
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
struct tagContext Context
Definition: acpixf.h:1024
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:1630
#define KeGetCurrentThread
Definition: hal.h:44
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
#define IRP_CONTEXT_FLAG_OVERRIDE_VERIFY
Definition: fatstruc.h:1569
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2632
#define FatUpdateIOCountersPCW(IsAWrite, Count)
Definition: deviosup.c:184
IN BOOLEAN Wait
Definition: fatprocs.h:1529
#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 2414 of file deviosup.c.

2459 {
2460 
2461  PFAT_IO_CONTEXT Context = Contxt;
2462  PIRP MasterIrp = Context->MasterIrp;
2463 
2464  DebugTrace(+1, Dbg, "FatMultiSyncCompletionRoutine, Context = %p\n", Context );
2465 
2466  //
2467  // If we got an error (or verify required), remember it in the Irp
2468  //
2469 
2470  if (!NT_SUCCESS( Irp->IoStatus.Status )) {
2471 
2472 #if DBG
2473  if(!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) {
2474  DbgBreakPoint();
2475  }
2476 #endif
2477 
2478 #ifdef SYSCACHE_COMPILE
2479  DbgPrint( "FAT SYSCACHE: MultiSync (IRP %08x for Master %08x) -> %08x\n", Irp, MasterIrp, Irp->IoStatus );
2480 #endif
2481 
2482  MasterIrp->IoStatus = Irp->IoStatus;
2483  }
2484 
2485  NT_ASSERT( !(NT_SUCCESS( Irp->IoStatus.Status ) && Irp->IoStatus.Information == 0 ));
2486 
2487  //
2488  // We must do this here since IoCompleteRequest won't get a chance
2489  // on this associated Irp.
2490  //
2491 
2492  IoFreeMdl( Irp->MdlAddress );
2493  IoFreeIrp( Irp );
2494 
2495  if (InterlockedDecrement(&Context->IrpCount) == 0) {
2496 
2497  FatDoCompletionZero( MasterIrp, Context );
2498  KeSetEvent( &Context->Wait.SyncEvent, 0, FALSE );
2499  }
2500 
2501  DebugTrace(-1, Dbg, "FatMultiSyncCompletionRoutine -> SUCCESS\n", 0 );
2502 
2504 
2506 }
#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:323
#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 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: fatprocs.h:1560
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 2910 of file deviosup.c.

2947 {
2948  DebugTrace(+1, Dbg, "FatPagingFileCompletionRoutine, MasterIrp = %p\n", MasterIrp );
2949 
2950  //
2951  // If we got an error (or verify required), remember it in the Irp
2952  //
2953 
2954  NT_ASSERT( !NT_SUCCESS( Irp->IoStatus.Status ));
2955 
2956  //
2957  // If we were invoked with an assoicated Irp, copy the error over.
2958  //
2959 
2960  if (Irp != MasterIrp) {
2961 
2962  ((PIRP)MasterIrp)->IoStatus = Irp->IoStatus;
2963  }
2964 
2965  DebugTrace(-1, Dbg, "FatPagingFileCompletionRoutine => (done)\n", 0 );
2966 
2968 
2969  return FatPagingFileErrorHandler( Irp, NULL );
2970 }
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS FatPagingFileErrorHandler(IN PIRP Irp, IN PKEVENT Event OPTIONAL)
Definition: deviosup.c:2703
#define Dbg
Definition: deviosup.c:28
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
PVOID PIRP
Definition: usb.h:38
#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 2817 of file deviosup.c.

2858 {
2860 
2862 
2863  DebugTrace(+1, Dbg, "FatPagingFileCompletionRoutineCatch, Context = %p\n", Context );
2864 
2865  //
2866  // Cleanup the existing Mdl, perhaps by returning the reserve.
2867  //
2868 
2869  if (Irp->MdlAddress == FatReserveMdl) {
2870 
2871  MmPrepareMdlForReuse( Irp->MdlAddress );
2873 
2874  } else {
2875 
2876  IoFreeMdl( Irp->MdlAddress );
2877  }
2878 
2879  //
2880  // Restore the original Mdl.
2881  //
2882 
2883  Irp->MdlAddress = Context->RestoreMdl;
2884 
2885  DebugTrace(-1, Dbg, "FatPagingFileCompletionRoutine => (done)\n", 0 );
2886 
2887  //
2888  // If the IRP is succeeding or the failure handler did not post off the
2889  // completion, we're done and should set the event to let the master
2890  // know the IRP is his again.
2891  //
2892 
2893  if (NT_SUCCESS( Irp->IoStatus.Status ) ||
2895 
2896  KeSetEvent( &Context->Event, 0, FALSE );
2897  }
2898 
2900 
2901 }
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#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 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:2703
#define Dbg
Definition: deviosup.c:28
#define MmPrepareMdlForReuse(_Mdl)
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
PMDL FatReserveMdl
Definition: fatdata.c:119
return STATUS_SUCCESS
Definition: btrfs.c:2938

◆ FatPagingFileErrorHandler()

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

Definition at line 2703 of file deviosup.c.

2758 {
2759  NTSTATUS Status;
2760 
2761  //
2762  // If this was a media error, we want to chkdsk /r the next time we boot.
2763  //
2764 
2765  if (FsRtlIsTotalDeviceFailure(Irp->IoStatus.Status)) {
2766 
2768 
2769  } else {
2770 
2772 
2773  //
2774  // We are going to try to mark the volume needing recover.
2775  // If we can't get pool, oh well....
2776  //
2777 
2778 #ifndef __REACTOS__
2779  Packet = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(CLEAN_AND_DIRTY_VOLUME_PACKET), ' taF');
2780 #else
2782 #endif
2783 
2784  if ( Packet ) {
2785 
2787  Packet->Irp = Irp;
2788  Packet->Event = Event;
2789 
2790  ExInitializeWorkItem( &Packet->Item,
2792  Packet );
2793 
2794 #ifdef _MSC_VER
2795 #pragma prefast( suppress:28159, "prefast indicates this is obsolete, but it is ok for fastfat to use it" )
2796 #endif
2798 
2800 
2801  } else {
2802 
2804  }
2805  }
2806 
2807  return Status;
2808 }
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:435
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define Vcb
Definition: cdprocs.h:1425
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
#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:2745
WORKER_THREAD_ROUTINE FatFspMarkVolumeDirtyWithRecover
Definition: fatprocs.h:1991
return STATUS_SUCCESS
Definition: btrfs.c:2938

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 TRUE
Definition: types.h:120
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_In_ PIRP Irp
Definition: csq.h:116
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:515
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:568
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 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:1780
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:50
KEVENT FatReserveEvent
Definition: fatdata.c:123
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2867
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:2647
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1061
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#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:4157
IO_COMPLETION_ROUTINE FatPagingFileCompletionRoutineCatch
Definition: deviosup.c:128
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
struct tagContext Context
Definition: acpixf.h:1024
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:2772
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2938
ULONG FcbState
Definition: cdstruc.h:977
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2632
IN PFCB IN VBO Vbo
Definition: fatprocs.h:297
#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 3641 of file deviosup.c.

3686 {
3687  NTSTATUS Status;
3688  PIRP Irp;
3689  KEVENT Event;
3690  IO_STATUS_BLOCK LocalIosb;
3691  PIO_STATUS_BLOCK IosbToUse = &LocalIosb;
3692 
3693  PAGED_CODE();
3694 
3695  UNREFERENCED_PARAMETER( IrpContext );
3696 
3697  //
3698  // Check if the user gave us an Iosb.
3699  //
3700 
3701  if (ARGUMENT_PRESENT( Iosb )) {
3702 
3703  IosbToUse = Iosb;
3704  }
3705 
3706  IosbToUse->Status = 0;
3707  IosbToUse->Information = 0;
3708 
3710 
3712  Device,
3713  InputBuffer,
3715  OutputBuffer,
3718  &Event,
3719  IosbToUse );
3720 
3721  if (Irp == NULL) {
3722 
3724  }
3725 
3726  if (OverrideVerify) {
3727 
3729  }
3730 
3731  Status = IoCallDriver( Device, Irp );
3732 
3733  //
3734  // We check for device not ready by first checking Status
3735  // and then if status pending was returned, the Iosb status
3736  // value.
3737  //
3738 
3739  if (Status == STATUS_PENDING) {
3740 
3742  Executive,
3743  KernelMode,
3744  FALSE,
3745  (PLARGE_INTEGER)NULL );
3746 
3747  Status = IosbToUse->Status;
3748  }
3749 
3750  return Status;
3751 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG IoControlCode
Definition: fltkernel.h:1383
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
_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
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG _In_ ULONG OutputBufferLength
Definition: fltkernel.h:1374
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 PAGED_CODE()
Definition: video.h:57
CHAR InputBuffer[80]
Definition: conmgr.c:33
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
smooth NULL
Definition: ftsmooth.c:416
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
return Iosb
Definition: create.c:4426
#define STATUS_PENDING
Definition: ntstatus.h:82
#define ARGUMENT_PRESENT(ArgumentPointer)
#define VOID
Definition: acefi.h:82
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG InputBufferLength
Definition: fltkernel.h:1372
Status
Definition: gdiplustypes.h:24
#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

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 1998 of file deviosup.c.

2035 {
2038 #ifndef __REACTOS__
2039  BOOLEAN IsAWrite = FALSE;
2040 #endif
2041 
2042  PAGED_CODE();
2043 
2044  DebugTrace(+1, Dbg, "FatSingleAsync\n", 0);
2045  DebugTrace( 0, Dbg, "MajorFunction = %08lx\n", IrpContext->MajorFunction );
2046  DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb );
2047  DebugTrace( 0, Dbg, "Lbo = %08lx\n", Lbo);
2048  DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
2049  DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
2050 
2051  //
2052  // If this I/O originating during FatVerifyVolume, bypass the
2053  // verify logic.
2054  //
2055 
2056  if (Vcb->VerifyThread == KeGetCurrentThread()) {
2057 
2058  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY );
2059  }
2060 
2061  //
2062  // Set up the completion routine address in our stack frame.
2063  //
2064 
2066  FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ?
2069  IrpContext->FatIoContext,
2070  TRUE,
2071  TRUE,
2072  TRUE );
2073 
2074  //
2075  // Setup the next IRP stack location in the associated Irp for the disk
2076  // driver beneath us.
2077  //
2078 
2080 
2081  //
2082  // Setup the Stack location to do a read from the disk driver.
2083  //
2084 
2085  IrpSp->MajorFunction = IrpContext->MajorFunction;
2086  IrpSp->Parameters.Read.Length = ByteCount;
2087  IrpSp->Parameters.Read.ByteOffset.QuadPart = Lbo;
2088 
2089 #ifndef __REACTOS__
2090  IsAWrite = (IrpSp->MajorFunction == IRP_MJ_WRITE);
2091 #endif
2092 
2093  //
2094  // If this Irp is the result of a WriteThough operation,
2095  // tell the device to write it through.
2096  //
2097 
2098  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH )) {
2099 
2101  }
2102 
2103  //
2104  // If this I/O requires override verify, bypass the verify logic.
2105  //
2106 
2107  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY )) {
2108 
2110  }
2111 
2112  //
2113  // For async requests if we acquired locks, transition the lock owners to an
2114  // object, since when we return this thread could go away before request
2115  // completion, and the resource package may try to boost priority.
2116  //
2117 
2118  if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ) &&
2119  FlagOn( IrpContext->FatIoContext->Wait.Async.ResourceThreadId, 3 )) {
2120 
2121  Context = IrpContext->FatIoContext;
2122 
2123  if (Context->Wait.Async.Resource != NULL) {
2124 
2125  ExSetResourceOwnerPointer( Context->Wait.Async.Resource,
2126  (PVOID)Context->Wait.Async.ResourceThreadId );
2127  }
2128 
2129  if (Context->Wait.Async.Resource2 != NULL) {
2130 
2131  ExSetResourceOwnerPointer( Context->Wait.Async.Resource2,
2132  (PVOID)Context->Wait.Async.ResourceThreadId );
2133  }
2134  }
2135 
2136  //
2137  // Back up a copy of the IrpContext flags for later use in async completion.
2138  //
2139 
2140  IrpContext->FatIoContext->IrpContextFlags = IrpContext->Flags;
2141 
2142  //
2143  // Issue the read request
2144  //
2145 
2146  DebugDoit( FatIoCallDriverCount += 1);
2147 
2148  //
2149  // If IoCallDriver returns an error, it has completed the Irp
2150  // and the error will be caught by our completion routines
2151  // and dealt with as a normal IO error.
2152  //
2153 
2154  (VOID)FatLowLevelReadWrite( IrpContext,
2155  Vcb->TargetDeviceObject,
2156  Irp,
2157  Vcb );
2158 
2159  //
2160  // We just issued an IO to the storage stack, update the counters indicating so.
2161  //
2162 
2164 
2165  FatUpdateIOCountersPCW( IsAWrite, ByteCount );
2166  }
2167 
2168  //
2169  // And return to our caller
2170  //
2171 
2172  DebugTrace(-1, Dbg, "FatSingleAsync -> VOID\n", 0);
2173 
2174  return;
2175 }
#define TRUE
Definition: types.h:120
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define DebugDoit(X)
Definition: fatdata.h:316
_In_ PIRP Irp
Definition: csq.h:116
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:297
IO_COMPLETION_ROUTINE FatSingleAsyncCompletionRoutine
Definition: deviosup.c:108
#define PAGED_CODE()
Definition: video.h:57
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
#define Vcb
Definition: cdprocs.h:1425
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:2647
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1061
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
#define SL_WRITE_THROUGH
Definition: iotypes.h:1781
struct tagContext Context
Definition: acpixf.h:1024
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define KeGetCurrentThread
Definition: hal.h:44
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
#define IRP_CONTEXT_FLAG_OVERRIDE_VERIFY
Definition: fatstruc.h:1569
#define FatUpdateIOCountersPCW(IsAWrite, Count)
Definition: deviosup.c:184
#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 3118 of file deviosup.c.

3155 {
3157 
3158  PFAT_IO_CONTEXT Context = Contxt;
3159  BOOLEAN PostRequest = FALSE;
3160 
3161  DebugTrace(+1, Dbg, "FatSingleAsyncCompletionRoutine, Context = %p\n", Context );
3162 
3163  //
3164  // Fill in the information field correctedly if this worked.
3165  //
3166 
3168 
3169  if (NT_SUCCESS(Irp->IoStatus.Status)) {
3170 
3171  NT_ASSERT( Irp->IoStatus.Information != 0 );
3172  Irp->IoStatus.Information = Context->Wait.Async.RequestedByteCount;
3173  NT_ASSERT( Irp->IoStatus.Information != 0 );
3174 
3175  //
3176  // Now if this wasn't PagingIo, set either the read or write bit.
3177  //
3178 
3179  if (!FlagOn(Irp->Flags, IRP_PAGING_IO)) {
3180 
3181  SetFlag( Context->Wait.Async.FileObject->Flags,
3182  IoGetCurrentIrpStackLocation(Irp)->MajorFunction == IRP_MJ_READ ?
3184  }
3185 
3186  } else {
3187 
3188 #if DBG
3189  if(!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) {
3190  DbgBreakPoint();
3191  }
3192 #endif
3193 
3194 #ifdef SYSCACHE_COMPILE
3195  DbgPrint( "FAT SYSCACHE: SingleAsync (IRP %08x) -> %08x\n", Irp, Irp->IoStatus );
3196 #endif
3197 
3198  //
3199  // Post STATUS_VERIFY_REQUIRED failures. Only post top level IRPs, because recursive I/Os
3200  // cannot process volume verification.
3201  //
3202 
3203  if (!FlagOn(Context->IrpContextFlags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) &&
3204  (Irp->IoStatus.Status == STATUS_VERIFY_REQUIRED)) {
3205  PostRequest = TRUE;
3206  }
3207 
3208  }
3209 
3210  //
3211  // If this was a special async write, decrement the count. Set the
3212  // event if this was the final outstanding I/O for the file. We will
3213  // also want to queue an APC to deal with any error conditionions.
3214  //
3215  _Analysis_assume_(!(Context->Wait.Async.NonPagedFcb) &&
3216  (ExInterlockedAddUlong( &Context->Wait.Async.NonPagedFcb->OutstandingAsyncWrites,
3217  0xffffffff,
3218  &FatData.GeneralSpinLock ) != 1));
3219 
3220  if ((Context->Wait.Async.NonPagedFcb) &&
3221  (ExInterlockedAddUlong( &Context->Wait.Async.NonPagedFcb->OutstandingAsyncWrites,
3222  0xffffffff,
3223  &FatData.GeneralSpinLock ) == 1)) {
3224 
3225  KeSetEvent( Context->Wait.Async.NonPagedFcb->OutstandingAsyncEvent, 0, FALSE );
3226  }
3227 
3228  //
3229  // Now release the resources
3230  //
3231 
3232  if (Context->Wait.Async.Resource != NULL) {
3233 
3234  ExReleaseResourceForThreadLite( Context->Wait.Async.Resource,
3235  Context->Wait.Async.ResourceThreadId );
3236  }
3237 
3238  if (Context->Wait.Async.Resource2 != NULL) {
3239 
3240  ExReleaseResourceForThreadLite( Context->Wait.Async.Resource2,
3241  Context->Wait.Async.ResourceThreadId );
3242  }
3243 
3244  //
3245  // Mark the Irp pending
3246  //
3247 
3248  IoMarkIrpPending( Irp );
3249 
3250  //
3251  // and finally, free the context record.
3252  //
3253 
3254  ExFreePool( Context );
3255 
3256  if (PostRequest) {
3257 
3258  PIRP_CONTEXT IrpContext = NULL;
3259 
3260  _SEH2_TRY {
3261 
3262  IrpContext = FatCreateIrpContext(Irp, TRUE );
3263  ClearFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL);
3264  FatFsdPostRequest( IrpContext, Irp );
3266 
3268 
3269  //
3270  // If we failed to post the IRP, we just have to return the failure
3271  // to the user. :(
3272  //
3273 
3274  NOTHING;
3275  } _SEH2_END;
3276  }
3277 
3278 
3279  DebugTrace(-1, Dbg, "FatSingleAsyncCompletionRoutine -> STATUS_MORE_PROCESSING_REQUIRED\n", 0 );
3280 
3282 
3283  return Status;
3284 }
#define TRUE
Definition: types.h:120
#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:323
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:4250
#define FO_FILE_MODIFIED
Definition: iotypes.h:1745
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1752
#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:2300
FAT_DATA FatData
Definition: fatdata.c:56
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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)
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4424
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
#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:2938
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 2179 of file deviosup.c.

2220 {
2222 
2223  PMDL Mdl;
2224  PMDL SavedMdl;
2225 #ifndef __REACTOS__
2226  BOOLEAN IsAWrite = FALSE;
2227 #endif
2228 
2229  PAGED_CODE();
2230 
2231  DebugTrace(+1, Dbg, "FatSingleNonAlignedAsync\n", 0);
2232  DebugTrace( 0, Dbg, "MajorFunction = %08lx\n", IrpContext->MajorFunction );
2233  DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb );
2234  DebugTrace( 0, Dbg, "Buffer = %p\n", Buffer );
2235  DebugTrace( 0, Dbg, "Lbo = %08lx\n", Lbo);
2236  DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
2237  DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
2238 
2239  //
2240  // Create a new Mdl describing the buffer, saving the current one in the
2241  // Irp
2242  //
2243 
2244  SavedMdl = Irp->MdlAddress;
2245 
2246  Irp->MdlAddress = 0;
2247 
2248  Mdl = IoAllocateMdl( Buffer,
2249  ByteCount,
2250  FALSE,
2251  FALSE,
2252  Irp );
2253 
2254  if (Mdl == NULL) {
2255 
2256  Irp->MdlAddress = SavedMdl;
2257 
2259  }
2260 
2261  //
2262  // Lock the new Mdl in memory.
2263  //
2264 
2265  _SEH2_TRY {
2266 
2268 
2269  } _SEH2_FINALLY {
2270 
2271  if ( _SEH2_AbnormalTermination() ) {
2272 
2273  IoFreeMdl( Mdl );
2274  Irp->MdlAddress = SavedMdl;
2275  }
2276  } _SEH2_END;
2277 
2278  //
2279  // Set up the completion routine address in our stack frame.
2280  //
2281 
2284  IrpContext->FatIoContext,
2285  TRUE,
2286  TRUE,
2287  TRUE );
2288 
2289  //
2290  // Setup the next IRP stack location in the associated Irp for the disk
2291  // driver beneath us.
2292  //
2293 
2295 
2296  //
2297  // Setup the Stack location to do a read from the disk driver.
2298  //
2299 
2300  IrpSp->MajorFunction = IrpContext->MajorFunction;
2301  IrpSp->Parameters.Read.Length = ByteCount;
2302  IrpSp->Parameters.Read.ByteOffset.QuadPart = Lbo;
2303 
2304 #ifndef __REACTOS__
2305  IsAWrite = (IrpSp->MajorFunction == IRP_MJ_WRITE);
2306 #endif
2307 
2308  //
2309  // If this I/O originating during FatVerifyVolume, bypass the
2310  // verify logic.
2311  //
2312 
2313  if (Vcb->VerifyThread == KeGetCurrentThread()) {
2314 
2315  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY );
2316  }
2317 
2318  //
2319  // If this I/O requires override verify, bypass the verify logic.
2320  //
2321 
2322  if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY )) {
2323 
2325  }
2326 
2327  //
2328  // Issue the read request
2329  //
2330 
2331  DebugDoit( FatIoCallDriverCount += 1);
2332 
2333  //
2334  // If IoCallDriver returns an error, it has completed the Irp
2335  // and the error will be caught by our completion routines
2336  // and dealt with as a normal IO error.
2337  //
2338 
2339  _SEH2_TRY {
2340 
2341  (VOID)FatLowLevelReadWrite( IrpContext,
2342  Vcb->TargetDeviceObject,
2343  Irp,
2344  Vcb );
2345 
2346  FatWaitSync( IrpContext );
2347 
2348  } _SEH2_FINALLY {
2349 
2350  MmUnlockPages( Mdl );
2351  IoFreeMdl( Mdl );
2352  Irp->MdlAddress = SavedMdl;
2353  } _SEH2_END;
2354 
2355  //
2356  // We just issued an IO to the storage stack, update the counters indicating so.
2357  //
2358 
2360 
2361  FatUpdateIOCountersPCW( IsAWrite, ByteCount );
2362  }
2363 
2364  //
2365  // And return to our caller
2366  //
2367 
2368  DebugTrace(-1, Dbg, "FatSingleNonAlignedSync -> VOID\n", 0);
2369 
2370  return;
2371 }
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define DebugDoit(X)
Definition: fatdata.h:316
_In_ PIRP Irp
Definition: csq.h:116
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:297
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1439
VOID FatWaitSync(IN PIRP_CONTEXT IrpContext)
Definition: deviosup.c:2375
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2965
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
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:1780
Definition: bufpool.h:45
#define Vcb
Definition: cdprocs.h:1425
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:2647
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1061
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:4424
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:4157
_SEH2_FINALLY
Definition: create.c:4395
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define KeGetCurrentThread
Definition: hal.h:44
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
#define IRP_CONTEXT_FLAG_OVERRIDE_VERIFY
Definition: fatstruc.h:1569
#define FatUpdateIOCountersPCW(IsAWrite, Count)
Definition: deviosup.c:184
#define FatLowLevelReadWrite(IRPCONTEXT, DO, IRP, VCB)
Definition: deviosup.c:163

Referenced by _Requires_lock_held_().

◆ FatSingleSyncCompletionRoutine()

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

Definition at line 3046 of file deviosup.c.

3083 {
3084  PFAT_IO_CONTEXT Context = Contxt;
3085 
3086  DebugTrace(+1, Dbg, "FatSingleSyncCompletionRoutine, Context = %p\n", Context );
3087 
3089 
3090  if (!NT_SUCCESS( Irp->IoStatus.Status )) {
3091 
3092 #if DBG
3093  if(!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) {
3094  DbgBreakPoint();
3095  }
3096 #endif
3097 
3098  }
3099 
3100  NT_ASSERT( !(NT_SUCCESS( Irp->IoStatus.Status ) && Irp->IoStatus.Information == 0 ));
3101 
3102  KeSetEvent( &Context->Wait.SyncEvent, 0, FALSE );
3103 
3104  DebugTrace(-1, Dbg, "FatSingleSyncCompletionRoutine -> STATUS_MORE_PROCESSING_REQUIRED\n", 0 );
3105 
3107 
3109 }
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#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 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: fatprocs.h:1560
#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 2979 of file deviosup.c.

3021 {
3022  PFAT_SYNC_CONTEXT SyncContext = (PFAT_SYNC_CONTEXT)Contxt;
3023 
3025 
3026  DebugTrace(+1, Dbg, "FatSpecialSyncCompletionRoutine, Context = %p\n", Contxt );
3027 
3028  SyncContext->Iosb = Irp->IoStatus;
3029 
3030  KeSetEvent( &SyncContext->Event, 0, FALSE );
3031 
3032  DebugTrace(-1, Dbg, "FatSpecialSyncCompletionRoutine -> STATUS_SUCCESS\n", 0 );
3033 
3035 
3036  return STATUS_SUCCESS;
3037 }
struct _FAT_SYNC_CONTEXT * PFAT_SYNC_CONTEXT
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#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
IO_STATUS_BLOCK Iosb
Definition: deviosup.c:53
#define Dbg
Definition: deviosup.c:28
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
return STATUS_SUCCESS
Definition: btrfs.c:2938

◆ FatToggleMediaEjectDisable()

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

Definition at line 3515 of file deviosup.c.

3541 {
3542  PIRP Irp;
3543  KIRQL SavedIrql;
3544  NTSTATUS Status;
3545  FAT_SYNC_CONTEXT SyncContext;
3546  PREVENT_MEDIA_REMOVAL Prevent;
3547 
3548  UNREFERENCED_PARAMETER( IrpContext );
3549 
3550  //
3551  // If PreventRemoval is the same as VCB_STATE_FLAG_REMOVAL_PREVENTED,
3552  // no-op this call, otherwise toggle the state of the flag.
3553  //
3554 
3555  KeAcquireSpinLock( &FatData.GeneralSpinLock, &SavedIrql );
3556 
3557  if ((PreventRemoval ^
3559 
3560  KeReleaseSpinLock( &FatData.GeneralSpinLock, SavedIrql );
3561 
3562  return STATUS_SUCCESS;
3563 
3564  } else {
3565 
3567 
3568  KeReleaseSpinLock( &FatData.GeneralSpinLock, SavedIrql );
3569  }
3570 
3571  Prevent.PreventMediaRemoval = PreventRemoval;
3572 
3573  KeInitializeEvent( &SyncContext.Event, NotificationEvent, FALSE );
3574 
3575  //
3576  // We build this IRP using a junk Iosb that will receive the final
3577  // completion status since we won't be around for it.
3578  //
3579  // We fill in the UserIosb manually below,
3580  // So passing NULL for the final parameter is ok in this special case.
3581  //
3582 #ifdef _MSC_VER
3583 #pragma warning(suppress: 6387)
3584 #endif
3586  Vcb->TargetDeviceObject,
3587  &Prevent,
3588  sizeof(PREVENT_MEDIA_REMOVAL),
3589  NULL,
3590  0,
3591  FALSE,
3592  NULL,
3593  NULL );
3594 
3595  if ( Irp != NULL ) {
3596 
3597  //
3598  // Use our special completion routine which will remove the requirement that
3599  // the caller must be below APC level. All it tells us is that the Irp got
3600  // back, but will not tell us if it was succesful or not. We don't care,
3601  // and there is of course no fallback if the attempt to prevent removal
3602  // doesn't work for some mysterious reason.
3603  //
3604  // Normally, all IO is done at passive level. However, MM needs to be able
3605  // to issue IO with fast mutexes locked down, which raises us to APC. The
3606  // overlying IRP is set up to complete in yet another magical fashion even
3607  // though APCs are disabled, and any IRPage we do in these cases has to do
3608  // the same. Marking media dirty (and toggling eject state) is one.
3609  //
3610 
3611  Irp->UserIosb = &Irp->IoStatus;
3612 
3615  &SyncContext,
3616  TRUE,
3617  TRUE,
3618  TRUE );
3619 
3620  Status = IoCallDriver( Vcb->TargetDeviceObject, Irp );
3621 
3622  if (Status == STATUS_PENDING) {
3623 
3624  (VOID) KeWaitForSingleObject( &SyncContext.Event,
3625  Executive,
3626  KernelMode,
3627  FALSE,
3628  NULL );
3629 
3630  Status = SyncContext.Iosb.Status;
3631  }
3632 
3633  return Status;
3634  }
3635 
3637 }
#define VCB_STATE_FLAG_REMOVAL_PREVENTED
Definition: fatstruc.h:570
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#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:515
UCHAR KIRQL
Definition: env_spec_w32.h:591
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:1425
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
BOOLEAN PreventMediaRemoval
Definition: ntddstor.h:251
#define VOID
Definition: acefi.h:82
IO_COMPLETION_ROUTINE FatSpecialSyncCompletionRoutine
Definition: deviosup.c:88
Status
Definition: gdiplustypes.h:24
#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:2938

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:65
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1061
#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 2375 of file deviosup.c.

2394 {
2395  PAGED_CODE();
2396 
2397  DebugTrace(+1, Dbg, "FatWaitSync, Context = %p\n", IrpContext->FatIoContext );
2398 
2399  KeWaitForSingleObject( &IrpContext->FatIoContext->Wait.SyncEvent,
2401 
2402  KeClearEvent( &IrpContext->FatIoContext->Wait.SyncEvent );
2403 
2404  DebugTrace(-1, Dbg, "FatWaitSync -> VOID\n", 0 );
2405 }
#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 PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
#define Dbg
Definition: deviosup.c:28
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22

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().