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