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
RxRemoveFirstContextFromSerializationQueue(PLIST_ENTRY SerializationQueue)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 extern FAST_MUTEX RxContextPerFileSerializationMutex;
521
522 VOID
523 NTAPI
524 RxResumeBlockedOperations_Serially(
525 _Inout_ PRX_CONTEXT RxContext,
526 _Inout_ PLIST_ENTRY BlockingIoQ);
527
528 VOID
529 RxResumeBlockedOperations_ALL(
530 _Inout_ PRX_CONTEXT RxContext);
531
532 #if (_WIN32_WINNT >= 0x0600)
533 VOID
534 RxCancelBlockingOperation(
535 _Inout_ PRX_CONTEXT RxContext,
536 _In_ PIRP Irp);
537 #else
538 VOID
539 RxCancelBlockingOperation(
540 _Inout_ PRX_CONTEXT RxContext);
541 #endif
542
543 VOID
544 RxRemoveOperationFromBlockingQueue(
545 _Inout_ PRX_CONTEXT RxContext);
546
547 #endif
548