xref: /reactos/sdk/include/ddk/rxcontx.h (revision a9124b41)
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