1 #ifndef _RX_CONTEXT_STRUCT_DEFINED_ 2 #define _RX_CONTEXT_STRUCT_DEFINED_ 3 4 #define RX_TOPLEVELIRP_CONTEXT_SIGNATURE 'LTxR' 5 6 typedef struct _RX_TOPLEVELIRP_CONTEXT 7 { 8 union 9 { 10 #ifndef __cplusplus 11 LIST_ENTRY; 12 #endif 13 LIST_ENTRY ListEntry; 14 }; 15 ULONG Signature; 16 PRDBSS_DEVICE_OBJECT RxDeviceObject; 17 PRX_CONTEXT RxContext; 18 PIRP Irp; 19 ULONG Flags; 20 PVOID Previous; 21 PETHREAD Thread; 22 } RX_TOPLEVELIRP_CONTEXT, *PRX_TOPLEVELIRP_CONTEXT; 23 24 BOOLEAN 25 RxTryToBecomeTheTopLevelIrp( 26 _Inout_ PRX_TOPLEVELIRP_CONTEXT TopLevelContext, 27 _In_ PIRP Irp, 28 _In_ PRDBSS_DEVICE_OBJECT RxDeviceObject, 29 _In_ BOOLEAN ForceTopLevel); 30 31 VOID 32 __RxInitializeTopLevelIrpContext( 33 _Inout_ PRX_TOPLEVELIRP_CONTEXT TopLevelContext, 34 _In_ PIRP Irp, 35 _In_ PRDBSS_DEVICE_OBJECT RxDeviceObject, 36 _In_ ULONG Flags); 37 38 #define RxInitializeTopLevelIrpContext(a,b,c) __RxInitializeTopLevelIrpContext(a,b,c,0) 39 40 PIRP 41 RxGetTopIrpIfRdbssIrp( 42 VOID); 43 44 PRDBSS_DEVICE_OBJECT 45 RxGetTopDeviceObjectIfRdbssIrp( 46 VOID); 47 48 VOID 49 RxUnwindTopLevelIrp( 50 _Inout_ PRX_TOPLEVELIRP_CONTEXT TopLevelContext); 51 52 BOOLEAN 53 RxIsThisTheTopLevelIrp( 54 _In_ PIRP Irp); 55 56 #ifdef RDBSS_TRACKER 57 typedef struct _RX_FCBTRACKER_CALLINFO 58 { 59 ULONG AcquireRelease; 60 USHORT SavedTrackerValue; 61 USHORT LineNumber; 62 PSZ FileName; 63 ULONG Flags; 64 } RX_FCBTRACKER_CALLINFO, *PRX_FCBTRACKER_CALLINFO; 65 #define RDBSS_TRACKER_HISTORY_SIZE 32 66 #endif 67 68 #define MRX_CONTEXT_FIELD_COUNT 4 69 70 #if (_WIN32_WINNT >= 0x0600) 71 typedef 72 NTSTATUS 73 (NTAPI *PRX_DISPATCH) ( 74 _In_ PRX_CONTEXT RxContext, 75 _In_ PIRP Irp); 76 #else 77 typedef 78 NTSTATUS 79 (NTAPI *PRX_DISPATCH) ( 80 _In_ PRX_CONTEXT RxContext); 81 #endif 82 83 typedef struct _DFS_NAME_CONTEXT_ *PDFS_NAME_CONTEXT; 84 85 typedef struct _NT_CREATE_PARAMETERS 86 { 87 ACCESS_MASK DesiredAccess; 88 LARGE_INTEGER AllocationSize; 89 ULONG FileAttributes; 90 ULONG ShareAccess; 91 ULONG Disposition; 92 ULONG CreateOptions; 93 PIO_SECURITY_CONTEXT SecurityContext; 94 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; 95 PVOID DfsContext; 96 PDFS_NAME_CONTEXT DfsNameContext; 97 } NT_CREATE_PARAMETERS, *PNT_CREATE_PARAMETERS; 98 99 typedef struct _RX_CONTEXT 100 { 101 NODE_TYPE_CODE NodeTypeCode; 102 NODE_BYTE_SIZE NodeByteSize; 103 volatile ULONG ReferenceCount; 104 LIST_ENTRY ContextListEntry; 105 UCHAR MajorFunction; 106 UCHAR MinorFunction; 107 BOOLEAN PendingReturned; 108 BOOLEAN PostRequest; 109 PDEVICE_OBJECT RealDevice; 110 PIRP CurrentIrp; 111 PIO_STACK_LOCATION CurrentIrpSp; 112 PMRX_FCB pFcb; 113 PMRX_FOBX pFobx; 114 PMRX_SRV_OPEN pRelevantSrvOpen; 115 PNON_PAGED_FCB NonPagedFcb; 116 PRDBSS_DEVICE_OBJECT RxDeviceObject; 117 PETHREAD OriginalThread; 118 PETHREAD LastExecutionThread; 119 volatile PVOID LockManagerContext; 120 PVOID RdbssDbgExtension; 121 RX_SCAVENGER_ENTRY ScavengerEntry; 122 ULONG SerialNumber; 123 ULONG FobxSerialNumber; 124 ULONG Flags; 125 BOOLEAN FcbResourceAcquired; 126 BOOLEAN FcbPagingIoResourceAcquired; 127 UCHAR MustSucceedDescriptorNumber; 128 union 129 { 130 struct 131 { 132 union 133 { 134 NTSTATUS StoredStatus; 135 PVOID StoredStatusAlignment; 136 }; 137 ULONG_PTR InformationToReturn; 138 }; 139 IO_STATUS_BLOCK IoStatusBlock; 140 }; 141 union 142 { 143 ULONGLONG ForceLonglongAligmentDummyField; 144 PVOID MRxContext[MRX_CONTEXT_FIELD_COUNT]; 145 }; 146 PVOID WriteOnlyOpenRetryContext; 147 PMRX_CALLDOWN MRxCancelRoutine; 148 PRX_DISPATCH ResumeRoutine; 149 RX_WORK_QUEUE_ITEM WorkQueueItem; 150 LIST_ENTRY OverflowListEntry; 151 KEVENT SyncEvent; 152 LIST_ENTRY BlockedOperations; 153 PFAST_MUTEX BlockedOpsMutex; 154 LIST_ENTRY RxContextSerializationQLinks; 155 union 156 { 157 struct 158 { 159 union 160 { 161 FS_INFORMATION_CLASS FsInformationClass; 162 FILE_INFORMATION_CLASS FileInformationClass; 163 }; 164 PVOID Buffer; 165 union 166 { 167 LONG Length; 168 LONG LengthRemaining; 169 }; 170 BOOLEAN ReplaceIfExists; 171 BOOLEAN AdvanceOnly; 172 } Info; 173 struct 174 { 175 UNICODE_STRING SuppliedPathName; 176 NET_ROOT_TYPE NetRootType; 177 PIO_SECURITY_CONTEXT pSecurityContext; 178 } PrefixClaim; 179 }; 180 union 181 { 182 struct 183 { 184 NT_CREATE_PARAMETERS NtCreateParameters; 185 ULONG ReturnedCreateInformation; 186 PWCH CanonicalNameBuffer; 187 PRX_PREFIX_ENTRY NetNamePrefixEntry; 188 PMRX_SRV_CALL pSrvCall; 189 PMRX_NET_ROOT pNetRoot; 190 PMRX_V_NET_ROOT pVNetRoot; 191 PVOID EaBuffer; 192 ULONG EaLength; 193 ULONG SdLength; 194 ULONG PipeType; 195 ULONG PipeReadMode; 196 ULONG PipeCompletionMode; 197 USHORT Flags; 198 NET_ROOT_TYPE Type; 199 UCHAR RdrFlags; 200 BOOLEAN FcbAcquired; 201 BOOLEAN TryForScavengingOnSharingViolation; 202 BOOLEAN ScavengingAlreadyTried; 203 BOOLEAN ThisIsATreeConnectOpen; 204 BOOLEAN TreeConnectOpenDeferred; 205 UNICODE_STRING TransportName; 206 UNICODE_STRING UserName; 207 UNICODE_STRING Password; 208 UNICODE_STRING UserDomainName; 209 } Create; 210 struct 211 { 212 ULONG FileIndex; 213 BOOLEAN RestartScan; 214 BOOLEAN ReturnSingleEntry; 215 BOOLEAN IndexSpecified; 216 BOOLEAN InitialQuery; 217 } QueryDirectory; 218 struct 219 { 220 PMRX_V_NET_ROOT pVNetRoot; 221 } NotifyChangeDirectory; 222 struct 223 { 224 PUCHAR UserEaList; 225 ULONG UserEaListLength; 226 ULONG UserEaIndex; 227 BOOLEAN RestartScan; 228 BOOLEAN ReturnSingleEntry; 229 BOOLEAN IndexSpecified; 230 } QueryEa; 231 struct 232 { 233 SECURITY_INFORMATION SecurityInformation; 234 ULONG Length; 235 } QuerySecurity; 236 struct 237 { 238 SECURITY_INFORMATION SecurityInformation; 239 PSECURITY_DESCRIPTOR SecurityDescriptor; 240 } SetSecurity; 241 struct 242 { 243 ULONG Length; 244 PSID StartSid; 245 PFILE_GET_QUOTA_INFORMATION SidList; 246 ULONG SidListLength; 247 BOOLEAN RestartScan; 248 BOOLEAN ReturnSingleEntry; 249 BOOLEAN IndexSpecified; 250 } QueryQuota; 251 struct 252 { 253 ULONG Length; 254 } SetQuota; 255 struct 256 { 257 PV_NET_ROOT VNetRoot; 258 PSRV_CALL SrvCall; 259 PNET_ROOT NetRoot; 260 } DosVolumeFunction; 261 struct { 262 ULONG FlagsForLowIo; 263 LOWIO_CONTEXT LowIoContext; 264 }; 265 LUID FsdUid; 266 }; 267 PWCH AlsoCanonicalNameBuffer; 268 PUNICODE_STRING LoudCompletionString; 269 #ifdef RDBSS_TRACKER 270 volatile LONG AcquireReleaseFcbTrackerX; 271 volatile ULONG TrackerHistoryPointer; 272 RX_FCBTRACKER_CALLINFO TrackerHistory[RDBSS_TRACKER_HISTORY_SIZE]; 273 #endif 274 #if DBG 275 ULONG ShadowCritOwner; 276 #endif 277 } RX_CONTEXT, *PRX_CONTEXT; 278 279 typedef enum 280 { 281 RX_CONTEXT_FLAG_FROM_POOL = 0x00000001, 282 RX_CONTEXT_FLAG_WAIT = 0x00000002, 283 RX_CONTEXT_FLAG_WRITE_THROUGH = 0x00000004, 284 RX_CONTEXT_FLAG_FLOPPY = 0x00000008, 285 RX_CONTEXT_FLAG_RECURSIVE_CALL = 0x00000010, 286 RX_CONTEXT_FLAG_THIS_DEVICE_TOP_LEVEL = 0x00000020, 287 RX_CONTEXT_FLAG_DEFERRED_WRITE = 0x00000040, 288 RX_CONTEXT_FLAG_VERIFY_READ = 0x00000080, 289 RX_CONTEXT_FLAG_STACK_IO_CONTEZT = 0x00000100, 290 RX_CONTEXT_FLAG_IN_FSP = 0x00000200, 291 RX_CONTEXT_FLAG_CREATE_MAILSLOT = 0x00000400, 292 RX_CONTEXT_FLAG_MAILSLOT_REPARSE = 0x00000800, 293 RX_CONTEXT_FLAG_ASYNC_OPERATION = 0x00001000, 294 RX_CONTEXT_FLAG_NO_COMPLETE_FROM_FSP = 0x00002000, 295 RX_CONTEXT_FLAG_POST_ON_STABLE_CONDITION = 0x00004000, 296 RX_CONTEXT_FLAG_FSP_DELAYED_OVERFLOW_QUEUE = 0x00008000, 297 RX_CONTEXT_FLAG_FSP_CRITICAL_OVERFLOW_QUEUE = 0x00010000, 298 RX_CONTEXT_FLAG_MINIRDR_INVOKED = 0x00020000, 299 RX_CONTEXT_FLAG_WAITING_FOR_RESOURCE = 0x00040000, 300 RX_CONTEXT_FLAG_CANCELLED = 0x00080000, 301 RX_CONTEXT_FLAG_SYNC_EVENT_WAITERS = 0x00100000, 302 RX_CONTEXT_FLAG_NO_PREPOSTING_NEEDED = 0x00200000, 303 RX_CONTEXT_FLAG_BYPASS_VALIDOP_CHECK = 0x00400000, 304 RX_CONTEXT_FLAG_BLOCKED_PIPE_RESUME = 0x00800000, 305 RX_CONTEXT_FLAG_IN_SERIALIZATION_QUEUE = 0x01000000, 306 RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT = 0x02000000, 307 RX_CONTEXT_FLAG_NEEDRECONNECT = 0x04000000, 308 RX_CONTEXT_FLAG_MUST_SUCCEED = 0x08000000, 309 RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING = 0x10000000, 310 RX_CONTEXT_FLAG_MUST_SUCCEED_ALLOCATED = 0x20000000, 311 RX_CONTEXT_FLAG_MINIRDR_INITIATED = 0x80000000, 312 } RX_CONTEXT_FLAGS; 313 314 #define RX_CONTEXT_PRESERVED_FLAGS (RX_CONTEXT_FLAG_FROM_POOL | \ 315 RX_CONTEXT_FLAG_MUST_SUCCEED_ALLOCATED | \ 316 RX_CONTEXT_FLAG_IN_FSP) 317 318 #define RX_CONTEXT_INITIALIZATION_FLAGS (RX_CONTEXT_FLAG_WAIT | \ 319 RX_CONTEXT_FLAG_MUST_SUCCEED | \ 320 RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING) 321 322 typedef enum 323 { 324 RX_CONTEXT_CREATE_FLAG_UNC_NAME = 0x1, 325 RX_CONTEXT_CREATE_FLAG_STRIPPED_TRAILING_BACKSLASH = 0x2, 326 RX_CONTEXT_CREATE_FLAG_ADDEDBACKSLASH = 0x4, 327 RX_CONTEXT_CREATE_FLAG_REPARSE = 0x8, 328 RX_CONTEXT_CREATE_FLAG_SPECIAL_PATH = 0x10, 329 } RX_CONTEXT_CREATE_FLAGS; 330 331 typedef enum { 332 RXCONTEXT_FLAG4LOWIO_PIPE_OPERATION = 0x1, 333 RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION = 0x2, 334 RXCONTEXT_FLAG4LOWIO_READAHEAD = 0x4, 335 RXCONTEXT_FLAG4LOWIO_THIS_READ_ENLARGED = 0x8, 336 RXCONTEXT_FLAG4LOWIO_THIS_IO_BUFFERED = 0x10, 337 RXCONTEXT_FLAG4LOWIO_LOCK_FCB_RESOURCE_HELD = 0x20, 338 RXCONTEXT_FLAG4LOWIO_LOCK_WAS_QUEUED_IN_LOCKMANAGER = 0x40, 339 RXCONTEXT_FLAG4LOWIO_THIS_IO_FAST = 0x80, 340 RXCONTEXT_FLAG4LOWIO_LOCK_OPERATION_COMPLETED = 0x100, 341 RXCONTEXT_FLAG4LOWIO_LOCK_BUFFERED_ON_ENTRY = 0x200 342 } RX_CONTEXT_LOWIO_FLAGS; 343 344 #if DBG 345 #define RxSaveAndSetExceptionNoBreakpointFlag(R, F) \ 346 { \ 347 F = FlagOn(R->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT); \ 348 SetFlag(R->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT); \ 349 } 350 351 #define RxRestoreExceptionNoBreakpointFlag(R, F) \ 352 { \ 353 ClearFlag(R->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT); \ 354 SetFlag(R->Flags, F); \ 355 } 356 #else 357 #define RxSaveAndSetExceptionNoBreakpointFlag(R, F) 358 #define RxRestoreExceptionNoBreakpointFlag(R, F) 359 #endif 360 361 #if DBG 362 VOID 363 __RxItsTheSameContext( 364 _In_ PRX_CONTEXT RxContext, 365 _In_ ULONG CapturedRxContextSerialNumber, 366 _In_ ULONG Line, 367 _In_ PCSTR File); 368 #define RxItsTheSameContext() { __RxItsTheSameContext(RxContext, CapturedRxContextSerialNumber, __LINE__, __FILE__); } 369 #else 370 #define RxItsTheSameContext() { NOTHING; } 371 #endif 372 373 extern NPAGED_LOOKASIDE_LIST RxContextLookasideList; 374 375 #define MINIRDR_CALL_THROUGH(STATUS, DISPATCH, FUNC, ARGLIST) \ 376 { \ 377 ASSERT(DISPATCH); \ 378 ASSERT(NodeType(DISPATCH) == RDBSS_NTC_MINIRDR_DISPATCH); \ 379 if (DISPATCH->FUNC == NULL) \ 380 { \ 381 STATUS = STATUS_NOT_IMPLEMENTED; \ 382 } \ 383 else \ 384 { \ 385 STATUS = DISPATCH->FUNC ARGLIST; \ 386 } \ 387 } 388 389 #define MINIRDR_CALL(STATUS, CONTEXT, DISPATCH, FUNC, ARGLIST) \ 390 { \ 391 ASSERT(DISPATCH); \ 392 ASSERT(NodeType(DISPATCH) == RDBSS_NTC_MINIRDR_DISPATCH); \ 393 if (DISPATCH->FUNC == NULL) \ 394 { \ 395 STATUS = STATUS_NOT_IMPLEMENTED; \ 396 } \ 397 else \ 398 { \ 399 if (!BooleanFlagOn((CONTEXT)->Flags, RX_CONTEXT_FLAG_CANCELLED)) \ 400 { \ 401 RtlZeroMemory(&((CONTEXT)->MRxContext[0]), \ 402 sizeof((CONTEXT)->MRxContext)); \ 403 STATUS = DISPATCH->FUNC ARGLIST; \ 404 } \ 405 else \ 406 { \ 407 STATUS = STATUS_CANCELLED; \ 408 } \ 409 } \ 410 } 411 412 #define RxWaitSync(RxContext) \ 413 (RxContext)->Flags |= RX_CONTEXT_FLAG_SYNC_EVENT_WAITERS; \ 414 KeWaitForSingleObject(&(RxContext)->SyncEvent, \ 415 Executive, KernelMode, FALSE, NULL) 416 417 #define RxSignalSynchronousWaiter(RxContext) \ 418 (RxContext)->Flags &= ~RX_CONTEXT_FLAG_SYNC_EVENT_WAITERS; \ 419 KeSetEvent(&(RxContext)->SyncEvent, 0, FALSE) 420 421 #define RxInsertContextInSerializationQueue(SerializationQueue, RxContext) \ 422 (RxContext)->Flags |= RX_CONTEXT_FLAG_IN_SERIALIZATION_QUEUE; \ 423 InsertTailList(SerializationQueue, &((RxContext)->RxContextSerializationQLinks)) 424 425 FORCEINLINE 426 PRX_CONTEXT 427 RxRemoveFirstContextFromSerializationQueue( 428 PLIST_ENTRY SerializationQueue) 429 { 430 if (IsListEmpty(SerializationQueue)) 431 { 432 return NULL; 433 } 434 else 435 { 436 PRX_CONTEXT Context = CONTAINING_RECORD(SerializationQueue->Flink, 437 RX_CONTEXT, 438 RxContextSerializationQLinks); 439 440 RemoveEntryList(SerializationQueue->Flink); 441 442 Context->RxContextSerializationQLinks.Flink = NULL; 443 Context->RxContextSerializationQLinks.Blink = NULL; 444 445 return Context; 446 } 447 } 448 449 #define RxTransferList(Destination, Source) \ 450 if (IsListEmpty((Source))) \ 451 InitializeListHead((Destination)); \ 452 else \ 453 { \ 454 *(Destination) = *(Source); \ 455 (Destination)->Flink->Blink = (Destination); \ 456 (Destination)->Blink->Flink = (Destination); \ 457 InitializeListHead((Source)); \ 458 } 459 460 #define RxTransferListWithMutex(Destination, Source, Mutex) \ 461 { \ 462 ExAcquireFastMutex(Mutex); \ 463 RxTransferList(Destination, Source); \ 464 ExReleaseFastMutex(Mutex); \ 465 } 466 467 NTSTATUS 468 RxCancelNotifyChangeDirectoryRequestsForVNetRoot( 469 PV_NET_ROOT VNetRoot, 470 BOOLEAN ForceFilesClosed); 471 472 VOID 473 RxCancelNotifyChangeDirectoryRequestsForFobx( 474 PFOBX Fobx 475 ); 476 477 VOID 478 NTAPI 479 RxInitializeContext( 480 _In_ PIRP Irp, 481 _In_ PRDBSS_DEVICE_OBJECT RxDeviceObject, 482 _In_ ULONG InitialContextFlags, 483 _Inout_ PRX_CONTEXT RxContext); 484 485 PRX_CONTEXT 486 NTAPI 487 RxCreateRxContext( 488 _In_ PIRP Irp, 489 _In_ PRDBSS_DEVICE_OBJECT RxDeviceObject, 490 _In_ ULONG InitialContextFlags); 491 492 VOID 493 NTAPI 494 RxPrepareContextForReuse( 495 _Inout_ PRX_CONTEXT RxContext); 496 497 VOID 498 NTAPI 499 RxDereferenceAndDeleteRxContext_Real( 500 _In_ PRX_CONTEXT RxContext); 501 502 VOID 503 NTAPI 504 RxReinitializeContext( 505 _Inout_ PRX_CONTEXT RxContext); 506 507 #if DBG 508 #define RxDereferenceAndDeleteRxContext(RXCONTEXT) \ 509 { \ 510 RxDereferenceAndDeleteRxContext_Real((RXCONTEXT)); \ 511 (RXCONTEXT) = NULL; \ 512 } 513 #else 514 #define RxDereferenceAndDeleteRxContext(RXCONTEXT) \ 515 { \ 516 RxDereferenceAndDeleteRxContext_Real((RXCONTEXT)); \ 517 } 518 #endif 519 520 VOID 521 NTAPI 522 RxResumeBlockedOperations_Serially( 523 _Inout_ PRX_CONTEXT RxContext, 524 _Inout_ PLIST_ENTRY BlockingIoQ); 525 526 VOID 527 RxResumeBlockedOperations_ALL( 528 _Inout_ PRX_CONTEXT RxContext); 529 530 #endif 531