ReactOS 0.4.15-dev-7994-gb388cb6
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:
{ \
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
struct _VCB VCB
FAT_DATA FatData
Definition: fatdata.c:56
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:341
ULONG NumberProcessors
Definition: fatstruc.h:81

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(c)
Definition: builtin.c:4556
Definition: terminate.cpp:24
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define I(s)
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18

Definition at line 171 of file deviosup.c.

◆ FatLowLevelReadWrite

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

Definition at line 163 of file deviosup.c.

◆ FatUpdateIOCountersPCW

#define FatUpdateIOCountersPCW (   IsAWrite,
  Count 
)
Value:
FsRtlUpdateDiskCounters( ((IsAWrite) ? 0 : (Count) ), \
((IsAWrite) ? (Count) : 0) )
int Count
Definition: noreturn.cpp:7

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

◆ FatBufferUserBuffer()

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

Definition at line 3411 of file deviosup.c.

3438{
3439 PUCHAR UserBuffer;
3440
3441 UNREFERENCED_PARAMETER( IrpContext );
3442
3443 PAGED_CODE();
3444
3445 //
3446 // Handle the no buffer case.
3447 //
3448
3449 if (BufferLength == 0) {
3450
3451 return NULL;
3452 }
3453
3454 //
3455 // If there is no system buffer we must have been supplied an Mdl
3456 // describing the users input buffer, which we will now snapshot.
3457 //
3458
3459 if (Irp->AssociatedIrp.SystemBuffer == NULL) {
3460
3461 UserBuffer = FatMapUserBuffer( IrpContext, Irp );
3462
3463 Irp->AssociatedIrp.SystemBuffer = FsRtlAllocatePoolWithQuotaTag( NonPagedPoolNx,
3466
3467 //
3468 // Set the flags so that the completion code knows to deallocate the
3469 // buffer.
3470 //
3471
3473
3474 _SEH2_TRY {
3475
3476 RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer,
3477 UserBuffer,
3478 BufferLength );
3479
3481
3483
3485 FatRaiseStatus( IrpContext,
3487 } _SEH2_END;
3488 }
3489
3490 return Irp->AssociatedIrp.SystemBuffer;
3491}
LONG NTSTATUS
Definition: precomp.h:26
#define TAG_IO_USER_BUFFER
Definition: nodetype.h:184
PVOID FatMapUserBuffer(IN PIRP_CONTEXT IrpContext, IN OUT PIRP Irp)
Definition: deviosup.c:3357
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
PVOID NTAPI FsRtlAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:189
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
#define IRP_DEALLOCATE_BUFFER
#define IRP_BUFFERED_IO

Referenced by FatCommonSetEa().

◆ FatBuildZeroMdl()

PMDL FatBuildZeroMdl ( __in PIRP_CONTEXT  IrpContext,
__in ULONG  Length 
)

Definition at line 3734 of file deviosup.c.

3757{
3758 PMDL ZeroMdl;
3759 ULONG SavedByteCount;
3761 ULONG i;
3762
3763 UNREFERENCED_PARAMETER( IrpContext );
3764
3765 //
3766 // Spin down trying to get an MDL which can describe our operation.
3767 //
3768
3769 while (TRUE) {
3770
3772
3773 //
3774 // Throttle ourselves to what we've physically allocated. Note that
3775 // we could have started with an odd multiple of this number. If we
3776 // tried for exactly that size and failed, we're toast.
3777 //
3778
3779 if (ZeroMdl || (Length <= PAGE_SIZE)) {
3780
3781 break;
3782 }
3783
3784 //
3785 // Fallback by half and round down to a page multiple.
3786 //
3787
3788 ASSERT( IrpContext->Vcb->Bpb.BytesPerSector <= PAGE_SIZE );
3790 if (Length < PAGE_SIZE) {
3791 Length = PAGE_SIZE;
3792 }
3793 }
3794
3795 if (ZeroMdl == NULL) {
3796 return NULL;
3797 }
3798
3799 //
3800 // If we have throttled all the way down, stop and just build a
3801 // simple MDL describing our previous allocation.
3802 //
3803
3804 if (Length == PAGE_SIZE) {
3805
3806 MmBuildMdlForNonPagedPool( ZeroMdl );
3807 return ZeroMdl;
3808 }
3809
3810 //
3811 // Now we will temporarily lock the allocated pages
3812 // only, and then replicate the page frame numbers through
3813 // the entire Mdl to keep writing the same pages of zeros.
3814 //
3815 // It would be nice if Mm exported a way for us to not have
3816 // to pull the Mdl apart and rebuild it ourselves, but this
3817 // is so bizarre a purpose as to be tolerable.
3818 //
3819
3820 SavedByteCount = ZeroMdl->ByteCount;
3821 ZeroMdl->ByteCount = PAGE_SIZE;
3822 MmBuildMdlForNonPagedPool( ZeroMdl );
3823
3824 ZeroMdl->MdlFlags &= ~MDL_SOURCE_IS_NONPAGED_POOL;
3825 ZeroMdl->MdlFlags |= MDL_PAGES_LOCKED;
3826 ZeroMdl->MappedSystemVa = NULL;
3827 ZeroMdl->StartVa = NULL;
3828 ZeroMdl->ByteCount = SavedByteCount;
3829 Page = MmGetMdlPfnArray( ZeroMdl );
3830 for (i = 1; i < (ADDRESS_AND_SIZE_TO_SPAN_PAGES( 0, SavedByteCount )); i++) {
3831 *(Page + i) = *(Page);
3832 }
3833
3834
3835 return ZeroMdl;
3836}
#define TRUE
Definition: types.h:120
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define BlockAlignTruncate(P, V)
Definition: fatprocs.h:3104
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
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:424
#define ASSERT(a)
Definition: mode.c:44
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
ULONG * PPFN_NUMBER
Definition: ke.h:9
PVOID ZeroPage
Definition: fatstruc.h:163
#define MmGetMdlPfnArray(_Mdl)
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19

◆ FatLockUserBuffer()

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

Definition at line 3276 of file deviosup.c.

3309{
3310 PMDL Mdl = NULL;
3311
3312 PAGED_CODE();
3313
3314 if (Irp->MdlAddress == NULL) {
3315
3316 //
3317 // Allocate the Mdl, and Raise if we fail.
3318 //
3319
3320 Mdl = IoAllocateMdl( Irp->UserBuffer, BufferLength, FALSE, FALSE, Irp );
3321
3322 if (Mdl == NULL) {
3323
3325 }
3326
3327 //
3328 // Now probe the buffer described by the Irp. If we get an exception,
3329 // deallocate the Mdl and return the appropriate "expected" status.
3330 //
3331
3332 _SEH2_TRY {
3333
3335 Irp->RequestorMode,
3336 Operation );
3337
3339
3341
3343
3344 IoFreeMdl( Mdl );
3345 Irp->MdlAddress = NULL;
3346
3347 FatRaiseStatus( IrpContext,
3349 } _SEH2_END;
3350 }
3351
3352 UNREFERENCED_PARAMETER( IrpContext );
3353}
FP_OP Operation
Definition: fpcontrol.c:150
#define IoFreeMdl
Definition: fxmdl.h:89
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931

Referenced by _Requires_lock_held_(), and FatPrePostIrp().

◆ FatMapUserBuffer()

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

Definition at line 3357 of file deviosup.c.

3382{
3383 UNREFERENCED_PARAMETER( IrpContext );
3384
3385 PAGED_CODE();
3386
3387 //
3388 // If there is no Mdl, then we must be in the Fsd, and we can simply
3389 // return the UserBuffer field from the Irp.
3390 //
3391
3392 if (Irp->MdlAddress == NULL) {
3393
3394 return Irp->UserBuffer;
3395
3396 } else {
3397
3398 PVOID Address = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority | MdlMappingNoExecute );
3399
3400 if (Address == NULL) {
3401
3403 }
3404
3405 return Address;
3406 }
3407}
#define ExRaiseStatus
Definition: ntoskrnl.h:114
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 2507 of file deviosup.c.

2552{
2554 PFAT_IO_CONTEXT Context = Contxt;
2555 PIRP MasterIrp = Context->MasterIrp;
2556 BOOLEAN PostRequest = FALSE;
2557
2558 DebugTrace(+1, Dbg, "FatMultiAsyncCompletionRoutine, Context = %p\n", Context );
2559
2560 //
2561 // If we got an error (or verify required), remember it in the Irp
2562 //
2563
2564 if (!NT_SUCCESS( Irp->IoStatus.Status )) {
2565
2566#if DBG
2567 if (!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) {
2568 DbgBreakPoint();
2569 }
2570#endif
2571
2572#ifdef SYSCACHE_COMPILE
2573 DbgPrint( "FAT SYSCACHE: MultiAsync (IRP %08x for Master %08x) -> %08x\n", Irp, MasterIrp, Irp->IoStatus );
2574#endif
2575
2576 MasterIrp->IoStatus = Irp->IoStatus;
2577
2578 }
2579
2580 NT_ASSERT( !(NT_SUCCESS( Irp->IoStatus.Status ) && Irp->IoStatus.Information == 0 ));
2581
2582 if (InterlockedDecrement(&Context->IrpCount) == 0) {
2583
2584 FatDoCompletionZero( MasterIrp, Context );
2585
2586 if (NT_SUCCESS(MasterIrp->IoStatus.Status)) {
2587
2588 MasterIrp->IoStatus.Information =
2589 Context->Wait.Async.RequestedByteCount;
2590
2591 NT_ASSERT(MasterIrp->IoStatus.Information != 0);
2592
2593 //
2594 // Now if this wasn't PagingIo, set either the read or write bit.
2595 //
2596
2597 if (!FlagOn(MasterIrp->Flags, IRP_PAGING_IO)) {
2598
2599 SetFlag( Context->Wait.Async.FileObject->Flags,
2602 }
2603
2604 } else {
2605
2606 //
2607 // Post STATUS_VERIFY_REQUIRED failures. Only post top level IRPs, because recursive I/Os
2608 // cannot process volume verification.
2609 //
2610
2611 if (!FlagOn(Context->IrpContextFlags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) &&
2612 (MasterIrp->IoStatus.Status == STATUS_VERIFY_REQUIRED)) {
2613 PostRequest = TRUE;
2614 }
2615
2616 }
2617
2618 //
2619 // If this was a special async write, decrement the count. Set the
2620 // event if this was the final outstanding I/O for the file. We will
2621 // also want to queue an APC to deal with any error conditionions.
2622 //
2623 _Analysis_assume_(!(Context->Wait.Async.NonPagedFcb) &&
2624 (ExInterlockedAddUlong( &Context->Wait.Async.NonPagedFcb->OutstandingAsyncWrites,
2625 0xffffffff,
2626 &FatData.GeneralSpinLock ) != 1));
2627 if ((Context->Wait.Async.NonPagedFcb) &&
2628 (ExInterlockedAddUlong( &Context->Wait.Async.NonPagedFcb->OutstandingAsyncWrites,
2629 0xffffffff,
2630 &FatData.GeneralSpinLock ) == 1)) {
2631
2632 KeSetEvent( Context->Wait.Async.NonPagedFcb->OutstandingAsyncEvent, 0, FALSE );
2633 }
2634
2635 //
2636 // Now release the resources.
2637 //
2638
2639 if (Context->Wait.Async.Resource != NULL) {
2640
2641 ExReleaseResourceForThreadLite( Context->Wait.Async.Resource,
2642 Context->Wait.Async.ResourceThreadId );
2643 }
2644
2645 if (Context->Wait.Async.Resource2 != NULL) {
2646
2647 ExReleaseResourceForThreadLite( Context->Wait.Async.Resource2,
2648 Context->Wait.Async.ResourceThreadId );
2649 }
2650
2651 //
2652 // Mark the master Irp pending
2653 //
2654
2655 IoMarkIrpPending( MasterIrp );
2656
2657 //
2658 // and finally, free the context record.
2659 //
2660
2662
2663 if (PostRequest) {
2664
2665 PIRP_CONTEXT IrpContext = NULL;
2666
2667 _SEH2_TRY {
2668
2669 IrpContext = FatCreateIrpContext(Irp, TRUE );
2670 ClearFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL);
2671 FatFsdPostRequest( IrpContext, Irp );
2673
2675
2676 //
2677 // If we failed to post the IRP, we just have to return the failure
2678 // to the user. :(
2679 //
2680
2681 NOTHING;
2682 } _SEH2_END;
2683 }
2684 }
2685
2686 DebugTrace(-1, Dbg, "FatMultiAsyncCompletionRoutine -> SUCCESS\n", 0 );
2687
2689
2690 return Status;
2691}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define InterlockedDecrement
Definition: armddk.h:52
#define ExReleaseResourceForThreadLite(res, thrdID)
Definition: env_spec_w32.h:635
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FatDoCompletionZero(I, C)
Definition: deviosup.c:171
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
NTSTATUS FatFsdPostRequest(IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
Definition: workque.c:229
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2301
#define IRP_CONTEXT_FLAG_RECURSIVE_CALL
Definition: fatstruc.h:1566
#define DbgPrint
Definition: hal.h:12
NTSYSAPI void WINAPI DbgBreakPoint(void)
#define NOTHING
Definition: input_list.c:10
ULONG NTAPI ExInterlockedAddUlong(IN OUT PULONG Addend, IN ULONG Increment, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:88
IoMarkIrpPending(Irp)
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
KSPIN_LOCK GeneralSpinLock
Definition: fatstruc.h:152
IO_STATUS_BLOCK IoStatus
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1795
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788

◆ FatMultipleAsync()

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

Definition at line 1622 of file deviosup.c.

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

Referenced by _Requires_lock_held_(), and FatMultipleAsync().

◆ FatMultiSyncCompletionRoutine()

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

Definition at line 2406 of file deviosup.c.

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

◆ FatPagingFileCompletionRoutine()

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

Definition at line 2898 of file deviosup.c.

2935{
2936 DebugTrace(+1, Dbg, "FatPagingFileCompletionRoutine, MasterIrp = %p\n", MasterIrp );
2937
2938 //
2939 // If we got an error (or verify required), remember it in the Irp
2940 //
2941
2942 NT_ASSERT( !NT_SUCCESS( Irp->IoStatus.Status ));
2943
2944 //
2945 // If we were invoked with an assoicated Irp, copy the error over.
2946 //
2947
2948 if (Irp != MasterIrp) {
2949
2950 ((PIRP)MasterIrp)->IoStatus = Irp->IoStatus;
2951 }
2952
2953 DebugTrace(-1, Dbg, "FatPagingFileCompletionRoutine => (done)\n", 0 );
2954
2956
2958}
struct _IRP * PIRP
NTSTATUS FatPagingFileErrorHandler(IN PIRP Irp, IN PKEVENT Event OPTIONAL)
Definition: deviosup.c:2695

◆ FatPagingFileCompletionRoutineCatch()

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

Definition at line 2805 of file deviosup.c.

2846{
2848
2850
2851 DebugTrace(+1, Dbg, "FatPagingFileCompletionRoutineCatch, Context = %p\n", Context );
2852
2853 //
2854 // Cleanup the existing Mdl, perhaps by returning the reserve.
2855 //
2856
2857 if (Irp->MdlAddress == FatReserveMdl) {
2858
2859 MmPrepareMdlForReuse( Irp->MdlAddress );
2861
2862 } else {
2863
2864 IoFreeMdl( Irp->MdlAddress );
2865 }
2866
2867 //
2868 // Restore the original Mdl.
2869 //
2870
2871 Irp->MdlAddress = Context->RestoreMdl;
2872
2873 DebugTrace(-1, Dbg, "FatPagingFileCompletionRoutine => (done)\n", 0 );
2874
2875 //
2876 // If the IRP is succeeding or the failure handler did not post off the
2877 // completion, we're done and should set the event to let the master
2878 // know the IRP is his again.
2879 //
2880
2881 if (NT_SUCCESS( Irp->IoStatus.Status ) ||
2883
2884 KeSetEvent( &Context->Event, 0, FALSE );
2885 }
2886
2888
2889}
struct FAT_PAGING_FILE_CONTEXT * PFAT_PAGING_FILE_CONTEXT
KEVENT FatReserveEvent
Definition: fatdata.c:123
PMDL FatReserveMdl
Definition: fatdata.c:119
#define MmPrepareMdlForReuse(_Mdl)

◆ FatPagingFileErrorHandler()

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

Definition at line 2695 of file deviosup.c.

2750{
2752
2753 //
2754 // If this was a media error, we want to chkdsk /r the next time we boot.
2755 //
2756
2757 if (FsRtlIsTotalDeviceFailure(Irp->IoStatus.Status)) {
2758
2760
2761 } else {
2762
2764
2765 //
2766 // We are going to try to mark the volume needing recover.
2767 // If we can't get pool, oh well....
2768 //
2769
2770 Packet = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(CLEAN_AND_DIRTY_VOLUME_PACKET), ' taF');
2771
2772 if ( Packet ) {
2773
2775 Packet->Irp = Irp;
2776 Packet->Event = Event;
2777
2780 Packet );
2781
2782#ifdef _MSC_VER
2783#pragma prefast( suppress:28159, "prefast indicates this is obsolete, but it is ok for fastfat to use it" )
2784#endif
2786
2788
2789 } else {
2790
2792 }
2793 }
2794
2795 return Status;
2796}
VOLUME_DEVICE_OBJECT * PVOLUME_DEVICE_OBJECT
Definition: cdstruc.h:769
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
WORKER_THREAD_ROUTINE FatFspMarkVolumeDirtyWithRecover
Definition: fatprocs.h:2000
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1549
BOOLEAN NTAPI FsRtlIsTotalDeviceFailure(IN NTSTATUS NtStatus)
Definition: filter.c:37
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ CriticalWorkQueue
Definition: extypes.h:189

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
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
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
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
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
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
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}
PEPROCESS __stdcall PsGetThreadProcess(_In_ PETHREAD Thread)
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
IO_COMPLETION_ROUTINE FatPagingFileCompletionRoutineCatch
Definition: deviosup.c:128
IO_COMPLETION_ROUTINE FatPagingFileCompletionRoutine
Definition: deviosup.c:118
LARGE_INTEGER Fat30Milliseconds
Definition: fatdata.c:70
#define FAT_RESERVE_MDL_SIZE
Definition: fatdata.h:70
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
IN PFCB IN VBO Vbo
Definition: fatprocs.h:307
#define FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1195
unsigned __int64 ULONG64
Definition: imports.h:198
#define KernelMode
Definition: asm.h:34
@ SynchronizationEvent
#define IoCompleteRequest
Definition: irp.c:1240
#define IoCallDriver
Definition: irp.c:1225
long LONG
Definition: pedump.c:60
ULONG FcbState
Definition: cdstruc.h:971
PDEVICE_OBJECT TargetDeviceObject
Definition: cdstruc.h:517
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
@ Executive
Definition: ketypes.h:415

Referenced by _Function_class_(), and FatOverflowPagingFileRead().

◆ FatPerformDevIoCtrl()

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

Definition at line 3621 of file deviosup.c.

3666{
3668 PIRP Irp;
3669 KEVENT Event;
3670 IO_STATUS_BLOCK LocalIosb;
3671 PIO_STATUS_BLOCK IosbToUse = &LocalIosb;
3672
3673 PAGED_CODE();
3674
3675 UNREFERENCED_PARAMETER( IrpContext );
3676
3677 //
3678 // Check if the user gave us an Iosb.
3679 //
3680
3681 if (ARGUMENT_PRESENT( Iosb )) {
3682
3683 IosbToUse = Iosb;
3684 }
3685
3686 IosbToUse->Status = 0;
3687 IosbToUse->Information = 0;
3688
3690
3692 Device,
3698 &Event,
3699 IosbToUse );
3700
3701 if (Irp == NULL) {
3702
3704 }
3705
3706 if (OverrideVerify) {
3707
3709 }
3710
3712
3713 //
3714 // We check for device not ready by first checking Status
3715 // and then if status pending was returned, the Iosb status
3716 // value.
3717 //
3718
3719 if (Status == STATUS_PENDING) {
3720
3722 Executive,
3723 KernelMode,
3724 FALSE,
3726
3727 Status = IosbToUse->Status;
3728 }
3729
3730 return Status;
3731}
return Iosb
Definition: create.c:4402
#define ARGUMENT_PRESENT(ArgumentPointer)
@ NotificationEvent
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
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID _In_ ULONG _In_ BOOLEAN InternalDeviceIoControl
Definition: iofuncs.h:720

Referenced by _Requires_lock_held_(), and FatScanForDataTrack().

◆ FatSingleAsync()

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

Definition at line 1990 of file deviosup.c.

2027{
2030#ifndef __REACTOS__
2031 BOOLEAN IsAWrite = FALSE;
2032#endif
2033
2034 PAGED_CODE();
2035
2036 DebugTrace(+1, Dbg, "FatSingleAsync\n", 0);
2037 DebugTrace( 0, Dbg, "MajorFunction = %08lx\n", IrpContext->MajorFunction );
2038 DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb );
2039 DebugTrace( 0, Dbg, "Lbo = %08lx\n", Lbo);
2040 DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
2041 DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
2042
2043 //
2044 // If this I/O originating during FatVerifyVolume, bypass the
2045 // verify logic.
2046 //
2047
2048 if (Vcb->VerifyThread == KeGetCurrentThread()) {
2049
2050 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY );
2051 }
2052
2053 //
2054 // Set up the completion routine address in our stack frame.
2055 //
2056
2058 FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ?
2061 IrpContext->FatIoContext,
2062 TRUE,
2063 TRUE,
2064 TRUE );
2065
2066 //
2067 // Setup the next IRP stack location in the associated Irp for the disk
2068 // driver beneath us.
2069 //
2070
2072
2073 //
2074 // Setup the Stack location to do a read from the disk driver.
2075 //
2076
2077 IrpSp->MajorFunction = IrpContext->MajorFunction;
2078 IrpSp->Parameters.Read.Length = ByteCount;
2079 IrpSp->Parameters.Read.ByteOffset.QuadPart = Lbo;
2080
2081#ifndef __REACTOS__
2082 IsAWrite = (IrpSp->MajorFunction == IRP_MJ_WRITE);
2083#endif
2084
2085 //
2086 // If this Irp is the result of a WriteThough operation,
2087 // tell the device to write it through.
2088 //
2089
2090 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WRITE_THROUGH )) {
2091
2093 }
2094
2095 //
2096 // If this I/O requires override verify, bypass the verify logic.
2097 //
2098
2099 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY )) {
2100
2102 }
2103
2104 //
2105 // For async requests if we acquired locks, transition the lock owners to an
2106 // object, since when we return this thread could go away before request
2107 // completion, and the resource package may try to boost priority.
2108 //
2109
2110 if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ) &&
2111 FlagOn( IrpContext->FatIoContext->Wait.Async.ResourceThreadId, 3 )) {
2112
2113 Context = IrpContext->FatIoContext;
2114
2115 if (Context->Wait.Async.Resource != NULL) {
2116
2117 ExSetResourceOwnerPointer( Context->Wait.Async.Resource,
2118 (PVOID)Context->Wait.Async.ResourceThreadId );
2119 }
2120
2121 if (Context->Wait.Async.Resource2 != NULL) {
2122
2123 ExSetResourceOwnerPointer( Context->Wait.Async.Resource2,
2124 (PVOID)Context->Wait.Async.ResourceThreadId );
2125 }
2126 }
2127
2128 //
2129 // Back up a copy of the IrpContext flags for later use in async completion.
2130 //
2131
2132 IrpContext->FatIoContext->IrpContextFlags = IrpContext->Flags;
2133
2134 //
2135 // Issue the read request
2136 //
2137
2138 DebugDoit( FatIoCallDriverCount += 1);
2139
2140 //
2141 // If IoCallDriver returns an error, it has completed the Irp
2142 // and the error will be caught by our completion routines
2143 // and dealt with as a normal IO error.
2144 //
2145
2146 (VOID)FatLowLevelReadWrite( IrpContext,
2147 Vcb->TargetDeviceObject,
2148 Irp,
2149 Vcb );
2150
2151 //
2152 // We just issued an IO to the storage stack, update the counters indicating so.
2153 //
2154
2156
2157 FatUpdateIOCountersPCW( IsAWrite, ByteCount );
2158 }
2159
2160 //
2161 // And return to our caller
2162 //
2163
2164 DebugTrace(-1, Dbg, "FatSingleAsync -> VOID\n", 0);
2165
2166 return;
2167}
IO_COMPLETION_ROUTINE FatSingleAsyncCompletionRoutine
Definition: deviosup.c:108
IO_COMPLETION_ROUTINE FatSingleSyncCompletionRoutine
Definition: deviosup.c:98
IN PFCB IN VBO OUT PLBO Lbo
Definition: fatprocs.h:308

Referenced by _Requires_lock_held_().

◆ FatSingleAsyncCompletionRoutine()

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

Definition at line 3106 of file deviosup.c.

3143{
3145
3146 PFAT_IO_CONTEXT Context = Contxt;
3147 BOOLEAN PostRequest = FALSE;
3148
3149 DebugTrace(+1, Dbg, "FatSingleAsyncCompletionRoutine, Context = %p\n", Context );
3150
3151 //
3152 // Fill in the information field correctedly if this worked.
3153 //
3154
3156
3157 if (NT_SUCCESS(Irp->IoStatus.Status)) {
3158
3159 NT_ASSERT( Irp->IoStatus.Information != 0 );
3160 Irp->IoStatus.Information = Context->Wait.Async.RequestedByteCount;
3161 NT_ASSERT( Irp->IoStatus.Information != 0 );
3162
3163 //
3164 // Now if this wasn't PagingIo, set either the read or write bit.
3165 //
3166
3167 if (!FlagOn(Irp->Flags, IRP_PAGING_IO)) {
3168
3169 SetFlag( Context->Wait.Async.FileObject->Flags,
3172 }
3173
3174 } else {
3175
3176#if DBG
3177 if(!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) {
3178 DbgBreakPoint();
3179 }
3180#endif
3181
3182#ifdef SYSCACHE_COMPILE
3183 DbgPrint( "FAT SYSCACHE: SingleAsync (IRP %08x) -> %08x\n", Irp, Irp->IoStatus );
3184#endif
3185
3186 //
3187 // Post STATUS_VERIFY_REQUIRED failures. Only post top level IRPs, because recursive I/Os
3188 // cannot process volume verification.
3189 //
3190
3191 if (!FlagOn(Context->IrpContextFlags, IRP_CONTEXT_FLAG_RECURSIVE_CALL) &&
3192 (Irp->IoStatus.Status == STATUS_VERIFY_REQUIRED)) {
3193 PostRequest = TRUE;
3194 }
3195
3196 }
3197
3198 //
3199 // If this was a special async write, decrement the count. Set the
3200 // event if this was the final outstanding I/O for the file. We will
3201 // also want to queue an APC to deal with any error conditionions.
3202 //
3203 _Analysis_assume_(!(Context->Wait.Async.NonPagedFcb) &&
3204 (ExInterlockedAddUlong( &Context->Wait.Async.NonPagedFcb->OutstandingAsyncWrites,
3205 0xffffffff,
3206 &FatData.GeneralSpinLock ) != 1));
3207
3208 if ((Context->Wait.Async.NonPagedFcb) &&
3209 (ExInterlockedAddUlong( &Context->Wait.Async.NonPagedFcb->OutstandingAsyncWrites,
3210 0xffffffff,
3211 &FatData.GeneralSpinLock ) == 1)) {
3212
3213 KeSetEvent( Context->Wait.Async.NonPagedFcb->OutstandingAsyncEvent, 0, FALSE );
3214 }
3215
3216 //
3217 // Now release the resources
3218 //
3219
3220 if (Context->Wait.Async.Resource != NULL) {
3221
3222 ExReleaseResourceForThreadLite( Context->Wait.Async.Resource,
3223 Context->Wait.Async.ResourceThreadId );
3224 }
3225
3226 if (Context->Wait.Async.Resource2 != NULL) {
3227
3228 ExReleaseResourceForThreadLite( Context->Wait.Async.Resource2,
3229 Context->Wait.Async.ResourceThreadId );
3230 }
3231
3232 //
3233 // Mark the Irp pending
3234 //
3235
3237
3238 //
3239 // and finally, free the context record.
3240 //
3241
3243
3244 if (PostRequest) {
3245
3246 PIRP_CONTEXT IrpContext = NULL;
3247
3248 _SEH2_TRY {
3249
3250 IrpContext = FatCreateIrpContext(Irp, TRUE );
3251 ClearFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_RECURSIVE_CALL);
3252 FatFsdPostRequest( IrpContext, Irp );
3254
3256
3257 //
3258 // If we failed to post the IRP, we just have to return the failure
3259 // to the user. :(
3260 //
3261
3262 NOTHING;
3263 } _SEH2_END;
3264 }
3265
3266
3267 DebugTrace(-1, Dbg, "FatSingleAsyncCompletionRoutine -> STATUS_MORE_PROCESSING_REQUIRED\n", 0 );
3268
3270
3271 return Status;
3272}

◆ FatSingleNonAlignedSync()

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

Definition at line 2171 of file deviosup.c.

2212{
2214
2215 PMDL Mdl;
2216 PMDL SavedMdl;
2217#ifndef __REACTOS__
2218 BOOLEAN IsAWrite = FALSE;
2219#endif
2220
2221 PAGED_CODE();
2222
2223 DebugTrace(+1, Dbg, "FatSingleNonAlignedAsync\n", 0);
2224 DebugTrace( 0, Dbg, "MajorFunction = %08lx\n", IrpContext->MajorFunction );
2225 DebugTrace( 0, Dbg, "Vcb = %p\n", Vcb );
2226 DebugTrace( 0, Dbg, "Buffer = %p\n", Buffer );
2227 DebugTrace( 0, Dbg, "Lbo = %08lx\n", Lbo);
2228 DebugTrace( 0, Dbg, "ByteCount = %08lx\n", ByteCount);
2229 DebugTrace( 0, Dbg, "Irp = %p\n", Irp );
2230
2231 //
2232 // Create a new Mdl describing the buffer, saving the current one in the
2233 // Irp
2234 //
2235
2236 SavedMdl = Irp->MdlAddress;
2237
2238 Irp->MdlAddress = 0;
2239
2241 ByteCount,
2242 FALSE,
2243 FALSE,
2244 Irp );
2245
2246 if (Mdl == NULL) {
2247
2248 Irp->MdlAddress = SavedMdl;
2249
2251 }
2252
2253 //
2254 // Lock the new Mdl in memory.
2255 //
2256
2257 _SEH2_TRY {
2258
2260
2261 } _SEH2_FINALLY {
2262
2263 if ( _SEH2_AbnormalTermination() ) {
2264
2265 IoFreeMdl( Mdl );
2266 Irp->MdlAddress = SavedMdl;
2267 }
2268 } _SEH2_END;
2269
2270 //
2271 // Set up the completion routine address in our stack frame.
2272 //
2273
2276 IrpContext->FatIoContext,
2277 TRUE,
2278 TRUE,
2279 TRUE );
2280
2281 //
2282 // Setup the next IRP stack location in the associated Irp for the disk
2283 // driver beneath us.
2284 //
2285
2287
2288 //
2289 // Setup the Stack location to do a read from the disk driver.
2290 //
2291
2292 IrpSp->MajorFunction = IrpContext->MajorFunction;
2293 IrpSp->Parameters.Read.Length = ByteCount;
2294 IrpSp->Parameters.Read.ByteOffset.QuadPart = Lbo;
2295
2296#ifndef __REACTOS__
2297 IsAWrite = (IrpSp->MajorFunction == IRP_MJ_WRITE);
2298#endif
2299
2300 //
2301 // If this I/O originating during FatVerifyVolume, bypass the
2302 // verify logic.
2303 //
2304
2305 if (Vcb->VerifyThread == KeGetCurrentThread()) {
2306
2307 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY );
2308 }
2309
2310 //
2311 // If this I/O requires override verify, bypass the verify logic.
2312 //
2313
2314 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_OVERRIDE_VERIFY )) {
2315
2317 }
2318
2319 //
2320 // Issue the read request
2321 //
2322
2323 DebugDoit( FatIoCallDriverCount += 1);
2324
2325 //
2326 // If IoCallDriver returns an error, it has completed the Irp
2327 // and the error will be caught by our completion routines
2328 // and dealt with as a normal IO error.
2329 //
2330
2331 _SEH2_TRY {
2332
2333 (VOID)FatLowLevelReadWrite( IrpContext,
2334 Vcb->TargetDeviceObject,
2335 Irp,
2336 Vcb );
2337
2338 FatWaitSync( IrpContext );
2339
2340 } _SEH2_FINALLY {
2341
2342 MmUnlockPages( Mdl );
2343 IoFreeMdl( Mdl );
2344 Irp->MdlAddress = SavedMdl;
2345 } _SEH2_END;
2346
2347 //
2348 // We just issued an IO to the storage stack, update the counters indicating so.
2349 //
2350
2352
2353 FatUpdateIOCountersPCW( IsAWrite, ByteCount );
2354 }
2355
2356 //
2357 // And return to our caller
2358 //
2359
2360 DebugTrace(-1, Dbg, "FatSingleNonAlignedSync -> VOID\n", 0);
2361
2362 return;
2363}
Definition: bufpool.h:45
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435

◆ FatSingleSyncCompletionRoutine()

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

Definition at line 3034 of file deviosup.c.

3071{
3072 PFAT_IO_CONTEXT Context = Contxt;
3073
3074 DebugTrace(+1, Dbg, "FatSingleSyncCompletionRoutine, Context = %p\n", Context );
3075
3077
3078 if (!NT_SUCCESS( Irp->IoStatus.Status )) {
3079
3080#if DBG
3081 if(!( NT_SUCCESS( FatBreakOnInterestingIoCompletion ) || Irp->IoStatus.Status != FatBreakOnInterestingIoCompletion )) {
3082 DbgBreakPoint();
3083 }
3084#endif
3085
3086 }
3087
3088 NT_ASSERT( !(NT_SUCCESS( Irp->IoStatus.Status ) && Irp->IoStatus.Information == 0 ));
3089
3090 KeSetEvent( &Context->Wait.SyncEvent, 0, FALSE );
3091
3092 DebugTrace(-1, Dbg, "FatSingleSyncCompletionRoutine -> STATUS_MORE_PROCESSING_REQUIRED\n", 0 );
3093
3095
3097}

◆ FatSpecialSyncCompletionRoutine()

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

Definition at line 2967 of file deviosup.c.

3009{
3010 PFAT_SYNC_CONTEXT SyncContext = (PFAT_SYNC_CONTEXT)Contxt;
3011
3013
3014 DebugTrace(+1, Dbg, "FatSpecialSyncCompletionRoutine, Context = %p\n", Contxt );
3015
3016 SyncContext->Iosb = Irp->IoStatus;
3017
3018 KeSetEvent( &SyncContext->Event, 0, FALSE );
3019
3020 DebugTrace(-1, Dbg, "FatSpecialSyncCompletionRoutine -> STATUS_SUCCESS\n", 0 );
3021
3023
3024 return STATUS_SUCCESS;
3025}
struct _FAT_SYNC_CONTEXT * PFAT_SYNC_CONTEXT
IO_STATUS_BLOCK Iosb
Definition: deviosup.c:53

◆ FatToggleMediaEjectDisable()

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

Definition at line 3495 of file deviosup.c.

3521{
3522 PIRP Irp;
3523 KIRQL SavedIrql;
3525 FAT_SYNC_CONTEXT SyncContext;
3526 PREVENT_MEDIA_REMOVAL Prevent;
3527
3528 UNREFERENCED_PARAMETER( IrpContext );
3529
3530 //
3531 // If PreventRemoval is the same as VCB_STATE_FLAG_REMOVAL_PREVENTED,
3532 // no-op this call, otherwise toggle the state of the flag.
3533 //
3534
3536
3537 if ((PreventRemoval ^
3539
3541
3542 return STATUS_SUCCESS;
3543
3544 } else {
3545
3547
3549 }
3550
3551 Prevent.PreventMediaRemoval = PreventRemoval;
3552
3554
3555 //
3556 // We build this IRP using a junk Iosb that will receive the final
3557 // completion status since we won't be around for it.
3558 //
3559 // We fill in the UserIosb manually below,
3560 // So passing NULL for the final parameter is ok in this special case.
3561 //
3562#ifdef _MSC_VER
3563#pragma warning(suppress: 6387)
3564#endif
3566 Vcb->TargetDeviceObject,
3567 &Prevent,
3568 sizeof(PREVENT_MEDIA_REMOVAL),
3569 NULL,
3570 0,
3571 FALSE,
3572 NULL,
3573 NULL );
3574
3575 if ( Irp != NULL ) {
3576
3577 //
3578 // Use our special completion routine which will remove the requirement that
3579 // the caller must be below APC level. All it tells us is that the Irp got
3580 // back, but will not tell us if it was succesful or not. We don't care,
3581 // and there is of course no fallback if the attempt to prevent removal
3582 // doesn't work for some mysterious reason.
3583 //
3584 // Normally, all IO is done at passive level. However, MM needs to be able
3585 // to issue IO with fast mutexes locked down, which raises us to APC. The
3586 // overlying IRP is set up to complete in yet another magical fashion even
3587 // though APCs are disabled, and any IRPage we do in these cases has to do
3588 // the same. Marking media dirty (and toggling eject state) is one.
3589 //
3590
3591 Irp->UserIosb = &Irp->IoStatus;
3592
3595 &SyncContext,
3596 TRUE,
3597 TRUE,
3598 TRUE );
3599
3600 Status = IoCallDriver( Vcb->TargetDeviceObject, Irp );
3601
3602 if (Status == STATUS_PENDING) {
3603
3604 (VOID) KeWaitForSingleObject( &SyncContext.Event,
3605 Executive,
3606 KernelMode,
3607 FALSE,
3608 NULL );
3609
3610 Status = SyncContext.Iosb.Status;
3611 }
3612
3613 return Status;
3614 }
3615
3617}
#define IOCTL_DISK_MEDIA_REMOVAL
Definition: cdrw_usr.h:176
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
IO_COMPLETION_ROUTINE FatSpecialSyncCompletionRoutine
Definition: deviosup.c:88
#define VCB_STATE_FLAG_REMOVAL_PREVENTED
Definition: fatstruc.h:571
BOOLEAN PreventMediaRemoval
Definition: ntddstor.h:343

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}
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:61
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
BOOLEAN NTAPI IoIsSystemThread(IN PETHREAD Thread)
Definition: util.c:115
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by _Requires_lock_held_().

◆ FatWaitSync()

VOID FatWaitSync ( IN PIRP_CONTEXT  IrpContext)

Definition at line 2367 of file deviosup.c.

2386{
2387 PAGED_CODE();
2388
2389 DebugTrace(+1, Dbg, "FatWaitSync, Context = %p\n", IrpContext->FatIoContext );
2390
2391 KeWaitForSingleObject( &IrpContext->FatIoContext->Wait.SyncEvent,
2393
2394 KeClearEvent( &IrpContext->FatIoContext->Wait.SyncEvent );
2395
2396 DebugTrace(-1, Dbg, "FatWaitSync -> VOID\n", 0 );
2397}
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().