Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

830 lines
26 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. RxContx.h
  5. Abstract:
  6. This module defines RxContext data structure. This structure is used to
  7. describe an Irp whil it is being processed and contains state information
  8. that allows global resources to be released as the irp is completed.
  9. Author:
  10. Joe Linn [JoeLinn] 19-aug-1994
  11. Revision History:
  12. Balan Sethu Raman [SethuR] 11-4-95
  13. Notes:
  14. The RX_CONTEXT is a data structure to which additional information provided
  15. by the various mini redirectors need to be attached. This can be done in one
  16. of the following three ways
  17. 1) Allow for context pointers to be defined as part of the RX_CONTEXT which
  18. the mini redirectors can use to squirrel away their information. This
  19. implies that every time an RX_CONTEXT is allocated/destroyed the mini
  20. redirector has to perform an associated allocation/destruction.
  21. Since RX_CONTEXT's are created/destroyed in great numbers, this is not an
  22. acceptable solution.
  23. 2) The second approach consists of over allocating RX_CONTEXT's by a
  24. prespecified amount for each mini redirector which is then reserved for
  25. use by the mini redirector. Such an approach avoids the additional
  26. allocation/destruction but complicates the RX_CONTEXT management code in
  27. the wrapper.
  28. 3) The third approach ( the one that is implemented ) consists of allocating
  29. a prespecfied area which is the same for all mini redirectors as part of
  30. each RX_CONTEXT. This is an unformatted area on top of which any desired
  31. structure can be imposed by the various mini redirectors. Such an approach
  32. overcomes the disadvantages associated with (1) and (2).
  33. All mini redirector writers must try and define the associated mini redirector
  34. contexts to fit into this area. Those mini redirectors who violate this
  35. rule will incur a significant performance penalty.
  36. --*/
  37. #ifndef _RX_CONTEXT_STRUCT_DEFINED_
  38. #define _RX_CONTEXT_STRUCT_DEFINED_
  39. #ifndef RDBSS_TRACKER
  40. #error tracker must be defined right now
  41. #endif
  42. #define RX_TOPLEVELIRP_CONTEXT_SIGNATURE ('LTxR')
  43. typedef struct _RX_TOPLEVELIRP_CONTEXT {
  44. union {
  45. #ifndef __cplusplus
  46. LIST_ENTRY;
  47. #endif // __cplusplus
  48. LIST_ENTRY ListEntry;
  49. };
  50. ULONG Signature;
  51. PRDBSS_DEVICE_OBJECT RxDeviceObject;
  52. PRX_CONTEXT RxContext;
  53. PIRP Irp;
  54. ULONG Flags;
  55. PVOID Previous;
  56. PETHREAD Thread;
  57. } RX_TOPLEVELIRP_CONTEXT, *PRX_TOPLEVELIRP_CONTEXT;
  58. BOOLEAN
  59. RxTryToBecomeTheTopLevelIrp (
  60. IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext,
  61. IN PIRP Irp,
  62. IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
  63. IN BOOLEAN ForceTopLevel
  64. );
  65. VOID
  66. __RxInitializeTopLevelIrpContext (
  67. IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext,
  68. IN PIRP Irp,
  69. IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
  70. IN ULONG Flags
  71. );
  72. #define RxInitializeTopLevelIrpContext(a,b,c) {__RxInitializeTopLevelIrpContext(a,b,c,0);}
  73. PIRP
  74. RxGetTopIrpIfRdbssIrp (
  75. VOID
  76. );
  77. PRDBSS_DEVICE_OBJECT
  78. RxGetTopDeviceObjectIfRdbssIrp (
  79. VOID
  80. );
  81. VOID
  82. RxUnwindTopLevelIrp (
  83. IN OUT PRX_TOPLEVELIRP_CONTEXT TopLevelContext
  84. );
  85. BOOLEAN
  86. RxIsThisTheTopLevelIrp (
  87. IN PIRP Irp
  88. );
  89. #ifdef RDBSS_TRACKER
  90. typedef struct _RX_FCBTRACKER_CALLINFO {
  91. ULONG AcquireRelease;
  92. USHORT SavedTrackerValue;
  93. USHORT LineNumber;
  94. PSZ FileName;
  95. ULONG Flags;
  96. } RX_FCBTRACKER_CALLINFO, *PRX_FCBTRACKER_CALLINFO;
  97. #define RDBSS_TRACKER_HISTORY_SIZE 32
  98. #endif
  99. #define MRX_CONTEXT_FIELD_COUNT 4
  100. #define MRX_CONTEXT_SIZE (sizeof(PVOID) * MRX_CONTEXT_FIELD_COUNT)
  101. //
  102. // Define rxdriver dispatch routine type....almost all of the important routine
  103. // will have this type.
  104. //
  105. typedef
  106. NTSTATUS
  107. (NTAPI *PRX_DISPATCH) (
  108. IN PRX_CONTEXT RxContext,
  109. IN PIRP Irp
  110. );
  111. //
  112. // predeclare dfs types
  113. //
  114. typedef struct _DFS_NAME_CONTEXT_ *PDFS_NAME_CONTEXT;
  115. typedef struct _NT_CREATE_PARAMETERS {
  116. ACCESS_MASK DesiredAccess;
  117. LARGE_INTEGER AllocationSize;
  118. ULONG FileAttributes;
  119. ULONG ShareAccess;
  120. ULONG Disposition;
  121. ULONG CreateOptions;
  122. PIO_SECURITY_CONTEXT SecurityContext;
  123. SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
  124. PVOID DfsContext;
  125. PDFS_NAME_CONTEXT DfsNameContext;
  126. } NT_CREATE_PARAMETERS, *PNT_CREATE_PARAMETERS;
  127. typedef struct _RX_CONTEXT {
  128. //
  129. // the node type, size and reference count, aka standard header
  130. //
  131. NODE_TYPE_CODE NodeTypeCode;
  132. NODE_BYTE_SIZE NodeByteSize;
  133. ULONG ReferenceCount;
  134. //
  135. // the list entry to wire the context to the list of active contexts
  136. //
  137. LIST_ENTRY ContextListEntry;
  138. //
  139. // Major and minor function of the IRP associated with the context
  140. //
  141. UCHAR MajorFunction;
  142. UCHAR MinorFunction;
  143. //
  144. // this is similar to the same field in Irps; it
  145. // allows callback routines for async operations
  146. // to know whether to do asynchronous work or not
  147. //
  148. BOOLEAN PendingReturned;
  149. //
  150. // indicates if the associated request is to be posted to a RDBSS worker thread.
  151. //
  152. BOOLEAN PostRequest;
  153. //
  154. // Originating Device (required for workque algorithms)
  155. // not currently used but could be used for local minis
  156. //
  157. PDEVICE_OBJECT RealDevice;
  158. //
  159. // ptr to the originating Irp
  160. //
  161. PIRP CurrentIrp;
  162. //
  163. // ptr to the IRP stack location
  164. //
  165. PIO_STACK_LOCATION CurrentIrpSp;
  166. //
  167. // ptr to the FCB and FOBX, derived from the context pointers in the
  168. // file object associated with the IRP
  169. //
  170. PMRX_FCB pFcb;
  171. PMRX_FOBX pFobx;
  172. PMRX_SRV_OPEN pRelevantSrvOpen;
  173. PNON_PAGED_FCB NonPagedFcb;
  174. //
  175. // device object calldown (not irpsp.....)
  176. //
  177. PRDBSS_DEVICE_OBJECT RxDeviceObject;
  178. //
  179. // The original thread in which the request was initiated and the last
  180. // thread in which some processing associated with the context was done
  181. //
  182. PETHREAD OriginalThread;
  183. PETHREAD LastExecutionThread;
  184. PVOID LockManagerContext;
  185. //
  186. // One word of the context is given to rdbss for dbg information
  187. //
  188. PVOID RdbssDbgExtension;
  189. RX_SCAVENGER_ENTRY ScavengerEntry;
  190. //
  191. // global serial number for this operation
  192. //
  193. ULONG SerialNumber;
  194. //
  195. // used by minirdrs to see if multiple calls are part
  196. // of the same larger operation and (therefore) more cacheable
  197. //
  198. ULONG FobxSerialNumber;
  199. ULONG Flags;
  200. BOOLEAN FcbResourceAcquired;
  201. BOOLEAN FcbPagingIoResourceAcquired;
  202. UCHAR MustSucceedDescriptorNumber;
  203. //
  204. // mostly you want the individual components...sometimes it's nice as a pair
  205. // used to record the status when you can't just return it; e.g., when
  206. // RXSTATUS is not an appropriate return type or if the consumer of the
  207. // status didn't call directly (lowiocompletions). minirdrs will not need
  208. // to set the information directly
  209. //
  210. union {
  211. struct {
  212. union {
  213. NTSTATUS StoredStatus;
  214. PVOID StoredStatusAlignment;
  215. };
  216. ULONG_PTR InformationToReturn;
  217. };
  218. IO_STATUS_BLOCK IoStatusBlock;
  219. };
  220. //
  221. // the context fields provided for use by the mini redirectors
  222. // this is defined as a union to force longlong alignment
  223. //
  224. union {
  225. ULONGLONG ForceLonglongAligmentDummyField;
  226. PVOID MRxContext[MRX_CONTEXT_FIELD_COUNT];
  227. };
  228. //
  229. // The following field is included to fix the problem related to write only
  230. // opens. This introduces a new field for the mini redirector to squirrel
  231. // some state. This is redundant and should be removed after Windows 2000.
  232. // Having a unique field reduces the impact of the change that we are making
  233. // to the specific code path. It will be ideal to use one of the MRXContext
  234. // fields defined above
  235. //
  236. PVOID WriteOnlyOpenRetryContext;
  237. //
  238. // the cancellation routine to be invoked, set by the mini redirector
  239. //
  240. PMRX_CALLDOWN MRxCancelRoutine;
  241. //
  242. // private dispatch, if any. used in fspdisp
  243. //
  244. PRX_DISPATCH ResumeRoutine;
  245. //
  246. // for posting to worker threads
  247. // the minirdr can use this for posting within the minirdr
  248. // a potential problem can arise if the minirdr relies on this both
  249. // for queueing async stuff and for queueing cancel stuff
  250. //
  251. //
  252. // The OverflowListEntry is used for queueing items to the overflow queue.
  253. // This is seperate now to allow us to distinguish between an item in the overflow
  254. // queue and one in the active work queue (for cancellation logic)
  255. //
  256. RX_WORK_QUEUE_ITEM WorkQueueItem;
  257. LIST_ENTRY OverflowListEntry;
  258. //
  259. // this event is used for synchronous operations
  260. // that have to i/f with an underlying async service. it can be used
  261. // by the minirdr with the following provisions:
  262. // 1) on entering the minirdr through lowio, it is set to the
  263. // nonsignaled state (but a wise user will reset it before using
  264. // it....particularly if it's used multiple times.
  265. // 2) if you are returning STATUS_PENDING on a sync operation, you must
  266. // return with it set to the nonsignaled state; that is, either
  267. // you don't use it or you reset it in this case
  268. //
  269. KEVENT SyncEvent;
  270. //
  271. // this is a list head of operations that are to be released on completion
  272. //
  273. LIST_ENTRY BlockedOperations;
  274. //
  275. // this is the mutex that controls serialization of the blocked operations
  276. //
  277. PFAST_MUTEX BlockedOpsMutex;
  278. //
  279. // these links are used to serialize pipe operations on a
  280. // per-file-object basis AND FOR LOTS OF OTHER STUFF
  281. //
  282. LIST_ENTRY RxContextSerializationQLinks;
  283. union {
  284. struct {
  285. union {
  286. FS_INFORMATION_CLASS FsInformationClass;
  287. FILE_INFORMATION_CLASS FileInformationClass;
  288. };
  289. PVOID Buffer;
  290. union {
  291. LONG Length;
  292. LONG LengthRemaining;
  293. };
  294. BOOLEAN ReplaceIfExists;
  295. BOOLEAN AdvanceOnly;
  296. } Info;
  297. struct {
  298. UNICODE_STRING SuppliedPathName;
  299. NET_ROOT_TYPE NetRootType;
  300. PIO_SECURITY_CONTEXT pSecurityContext;
  301. } PrefixClaim;
  302. };
  303. //
  304. // THIS UNION MUST BE LAST....AT SOME POINT, WE MAY START ALLOCATING
  305. // SMALLER PER OPERATION!
  306. //
  307. union{
  308. struct {
  309. NT_CREATE_PARAMETERS NtCreateParameters; // a copy of the createparameters
  310. ULONG ReturnedCreateInformation;
  311. PWCH CanonicalNameBuffer; // if the canonical name is larger than available buffer
  312. PRX_PREFIX_ENTRY NetNamePrefixEntry; // the entry returned by the lookup....for dereferencing
  313. PMRX_SRV_CALL pSrvCall; // Server Call being used
  314. PMRX_NET_ROOT pNetRoot; // Net Root being used
  315. PMRX_V_NET_ROOT pVNetRoot; // Virtual Net Root
  316. //PMRX_SRV_OPEN pSrvOpen; // Server Open
  317. PVOID EaBuffer;
  318. ULONG EaLength;
  319. ULONG SdLength;
  320. ULONG PipeType;
  321. ULONG PipeReadMode;
  322. ULONG PipeCompletionMode;
  323. USHORT Flags;
  324. NET_ROOT_TYPE Type; // Type of Net Root(Pipe/File/Mailslot..)
  325. BOOLEAN FcbAcquired;
  326. BOOLEAN TryForScavengingOnSharingViolation;
  327. BOOLEAN ScavengingAlreadyTried;
  328. BOOLEAN ThisIsATreeConnectOpen;
  329. BOOLEAN TreeConnectOpenDeferred;
  330. UNICODE_STRING TransportName;
  331. UNICODE_STRING UserName;
  332. UNICODE_STRING Password;
  333. UNICODE_STRING UserDomainName;
  334. } Create;
  335. struct {
  336. ULONG FileIndex;
  337. BOOLEAN RestartScan;
  338. BOOLEAN ReturnSingleEntry;
  339. BOOLEAN IndexSpecified;
  340. BOOLEAN InitialQuery;
  341. } QueryDirectory;
  342. struct {
  343. PMRX_V_NET_ROOT pVNetRoot;
  344. } NotifyChangeDirectory;
  345. struct {
  346. PUCHAR UserEaList;
  347. ULONG UserEaListLength;
  348. ULONG UserEaIndex;
  349. BOOLEAN RestartScan;
  350. BOOLEAN ReturnSingleEntry;
  351. BOOLEAN IndexSpecified;
  352. } QueryEa;
  353. struct {
  354. SECURITY_INFORMATION SecurityInformation;
  355. ULONG Length;
  356. } QuerySecurity;
  357. struct {
  358. SECURITY_INFORMATION SecurityInformation;
  359. PSECURITY_DESCRIPTOR SecurityDescriptor;
  360. } SetSecurity;
  361. struct {
  362. ULONG Length;
  363. PSID StartSid;
  364. PFILE_GET_QUOTA_INFORMATION SidList;
  365. ULONG SidListLength;
  366. BOOLEAN RestartScan;
  367. BOOLEAN ReturnSingleEntry;
  368. BOOLEAN IndexSpecified;
  369. } QueryQuota;
  370. struct {
  371. ULONG Length;
  372. } SetQuota;
  373. struct {
  374. PV_NET_ROOT VNetRoot;
  375. PSRV_CALL SrvCall;
  376. PNET_ROOT NetRoot;
  377. } DosVolumeFunction;
  378. struct {
  379. ULONG FlagsForLowIo;
  380. LOWIO_CONTEXT LowIoContext; // the LOWIO parameters
  381. }; // no name here....
  382. LUID FsdUid;
  383. } ;
  384. //
  385. // CODE.IMPROVEMENT remove this to wrapperdbgprivates
  386. //
  387. PWCH AlsoCanonicalNameBuffer; // if the canonical name is larger than available buffer
  388. PUNICODE_STRING LoudCompletionString;
  389. #ifdef RDBSS_TRACKER
  390. LONG AcquireReleaseFcbTrackerX;
  391. ULONG TrackerHistoryPointer;
  392. RX_FCBTRACKER_CALLINFO TrackerHistory[RDBSS_TRACKER_HISTORY_SIZE];
  393. #endif
  394. #if DBG
  395. ULONG ShadowCritOwner;
  396. #endif
  397. } RX_CONTEXT, *PRX_CONTEXT;
  398. typedef enum {
  399. RX_CONTEXT_FLAG_FROM_POOL = 0x00000001,
  400. RX_CONTEXT_FLAG_WAIT = 0x00000002,
  401. RX_CONTEXT_FLAG_WRITE_THROUGH = 0x00000004,
  402. RX_CONTEXT_FLAG_FLOPPY = 0x00000008,
  403. RX_CONTEXT_FLAG_RECURSIVE_CALL = 0x00000010,
  404. RX_CONTEXT_FLAG_THIS_DEVICE_TOP_LEVEL = 0x00000020,
  405. RX_CONTEXT_FLAG_DEFERRED_WRITE = 0x00000040,
  406. RX_CONTEXT_FLAG_VERIFY_READ = 0x00000080,
  407. RX_CONTEXT_FLAG_STACK_IO_CONTEZT = 0x00000100,
  408. RX_CONTEXT_FLAG_IN_FSP = 0x00000200,
  409. RX_CONTEXT_FLAG_CREATE_MAILSLOT = 0x00000400,
  410. RX_CONTEXT_FLAG_MAILSLOT_REPARSE = 0x00000800,
  411. RX_CONTEXT_FLAG_ASYNC_OPERATION = 0x00001000,
  412. RX_CONTEXT_FLAG_NO_COMPLETE_FROM_FSP = 0x00002000,
  413. RX_CONTEXT_FLAG_POST_ON_STABLE_CONDITION = 0x00004000,
  414. RX_CONTEXT_FLAG_FSP_DELAYED_OVERFLOW_QUEUE = 0x00008000,
  415. RX_CONTEXT_FLAG_FSP_CRITICAL_OVERFLOW_QUEUE = 0x00010000,
  416. RX_CONTEXT_FLAG_MINIRDR_INVOKED = 0x00020000,
  417. RX_CONTEXT_FLAG_WAITING_FOR_RESOURCE = 0x00040000,
  418. RX_CONTEXT_FLAG_CANCELLED = 0x00080000,
  419. RX_CONTEXT_FLAG_SYNC_EVENT_WAITERS = 0x00100000,
  420. RX_CONTEXT_FLAG_NO_PREPOSTING_NEEDED = 0x00200000,
  421. RX_CONTEXT_FLAG_BYPASS_VALIDOP_CHECK = 0x00400000,
  422. RX_CONTEXT_FLAG_BLOCKED_PIPE_RESUME = 0x00800000,
  423. RX_CONTEXT_FLAG_IN_SERIALIZATION_QUEUE = 0x01000000,
  424. RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT = 0x02000000,
  425. RX_CONTEXT_FLAG_NEEDRECONNECT = 0x04000000,
  426. RX_CONTEXT_FLAG_MUST_SUCCEED = 0x08000000,
  427. RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING = 0x10000000,
  428. RX_CONTEXT_FLAG_MUST_SUCCEED_ALLOCATED = 0x20000000,
  429. RX_CONTEXT_FLAG_MINIRDR_INITIATED = 0x80000000,
  430. } RX_CONTEXT_FLAGS;
  431. #define RX_CONTEXT_PRESERVED_FLAGS (RX_CONTEXT_FLAG_FROM_POOL | \
  432. RX_CONTEXT_FLAG_MUST_SUCCEED_ALLOCATED | \
  433. RX_CONTEXT_FLAG_IN_FSP)
  434. #define RX_CONTEXT_INITIALIZATION_FLAGS (RX_CONTEXT_FLAG_WAIT | \
  435. RX_CONTEXT_FLAG_MUST_SUCCEED | \
  436. RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING)
  437. typedef enum {
  438. RX_CONTEXT_CREATE_FLAG_UNC_NAME = 0x1,
  439. RX_CONTEXT_CREATE_FLAG_STRIPPED_TRAILING_BACKSLASH = 0x2,
  440. RX_CONTEXT_CREATE_FLAG_ADDEDBACKSLASH = 0x4,
  441. RX_CONTEXT_CREATE_FLAG_REPARSE = 0x8,
  442. RX_CONTEXT_CREATE_FLAG_SPECIAL_PATH = 0x10,
  443. } RX_CONTEXT_CREATE_FLAGS;
  444. typedef enum {
  445. RXCONTEXT_FLAG4LOWIO_PIPE_OPERATION = 0x1,
  446. RXCONTEXT_FLAG4LOWIO_PIPE_SYNC_OPERATION = 0x2,
  447. RXCONTEXT_FLAG4LOWIO_READAHEAD = 0x4,
  448. RXCONTEXT_FLAG4LOWIO_THIS_READ_ENLARGED = 0x8,
  449. RXCONTEXT_FLAG4LOWIO_THIS_IO_BUFFERED = 0x10,
  450. RXCONTEXT_FLAG4LOWIO_LOCK_FCB_RESOURCE_HELD = 0x20,
  451. RXCONTEXT_FLAG4LOWIO_LOCK_WAS_QUEUED_IN_LOCKMANAGER = 0x40,
  452. RXCONTEXT_FLAG4LOWIO_THIS_IO_FAST = 0x80,
  453. RXCONTEXT_FLAG4LOWIO_LOCK_OPERATION_COMPLETED = 0x100
  454. #ifdef __cplusplus
  455. } RX_CONTEXT_LOWIO_FLAGS;
  456. #else // !__cplusplus
  457. } RX_CONTEXT_CREATE_FLAGS;
  458. #endif // __cplusplus
  459. //
  460. // Macros used to control whether the wrapper breakpoints on an exception
  461. //
  462. #if DBG
  463. #define RxSaveAndSetExceptionNoBreakpointFlag( RXCONTEXT,OLDFLAG ) { \
  464. OLDFLAG = FlagOn( RxContext->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT );\
  465. SetFlag( RxContext->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT ); \
  466. }
  467. #define RxRestoreExceptionNoBreakpointFlag( RXCONTEXT,OLDFLAG ) { \
  468. ClearFlag( RxContext->Flags, RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT ); \
  469. SetFlag( RxContext->Flags, OLDFLAG ); \
  470. }
  471. #else
  472. #define RxSaveAndSetExceptionNoBreakpointFlag(RXCONTEXT,OLDFLAG)
  473. #define RxRestoreExceptionNoBreakpointFlag(RXCONTEXT,OLDFLAG)
  474. #endif
  475. //
  476. // a macro used to ensure that a context hasn't been freed during a wait
  477. //
  478. #if DBG
  479. VOID
  480. __RxItsTheSameContext(
  481. PRX_CONTEXT RxContext,
  482. ULONG CapturedRxContextSerialNumber,
  483. ULONG Line,
  484. PSZ File
  485. );
  486. #define RxItsTheSameContext() {__RxItsTheSameContext(RxContext,CapturedRxContextSerialNumber,__LINE__,__FILE__);}
  487. #else
  488. #define RxItsTheSameContext() {NOTHING;}
  489. #endif
  490. extern NPAGED_LOOKASIDE_LIST RxContextLookasideList;
  491. //
  492. // Macros used in the RDBSS to wrap mini rdr calldowns
  493. //
  494. #define MINIRDR_CALL_THROUGH(STATUS,DISPATCH,FUNC,ARGLIST) \
  495. { \
  496. ASSERT(DISPATCH); \
  497. ASSERT( NodeType(DISPATCH) == RDBSS_NTC_MINIRDR_DISPATCH ); \
  498. if (DISPATCH->FUNC == NULL) { \
  499. STATUS = STATUS_NOT_IMPLEMENTED; \
  500. } else { \
  501. RxDbgTrace(0, Dbg, ("MiniRdr Calldown - %s\n",#FUNC)); \
  502. STATUS = DISPATCH->FUNC ARGLIST; \
  503. } \
  504. }
  505. #define MINIRDR_CALL(STATUS,CONTEXT,DISPATCH,FUNC,ARGLIST) \
  506. { \
  507. ASSERT(DISPATCH); \
  508. ASSERT( NodeType(DISPATCH) == RDBSS_NTC_MINIRDR_DISPATCH ); \
  509. if ( DISPATCH->FUNC == NULL) { \
  510. STATUS = STATUS_NOT_IMPLEMENTED; \
  511. } else { \
  512. if (!BooleanFlagOn((CONTEXT)->Flags,RX_CONTEXT_FLAG_CANCELLED)) { \
  513. RxDbgTrace(0, Dbg, ("MiniRdr Calldown - %s\n",#FUNC)); \
  514. RtlZeroMemory(&((CONTEXT)->MRxContext[0]), \
  515. sizeof((CONTEXT)->MRxContext)); \
  516. STATUS = DISPATCH->FUNC ARGLIST; \
  517. } else { \
  518. STATUS = STATUS_CANCELLED; \
  519. } \
  520. } \
  521. }
  522. //
  523. // VOID
  524. // RxWaitSync (
  525. // IN PRX_CONTEXT RxContext
  526. // )
  527. //
  528. #define RxWaitSync( RxContext ) \
  529. RxDbgTrace(+1, Dbg, ("RxWaitSync, RxContext = %08lx\n", (RxContext))); \
  530. (RxContext)->Flags |= RX_CONTEXT_FLAG_SYNC_EVENT_WAITERS; \
  531. KeWaitForSingleObject( &(RxContext)->SyncEvent, \
  532. Executive, KernelMode, FALSE, NULL ); \
  533. RxDbgTrace(-1, Dbg, ("RxWaitSync -> VOID\n", 0 ))
  534. //
  535. // VOID
  536. // RxSignalSynchronousWaiter (
  537. // IN PRX_CONTEXT RxContext
  538. // )
  539. //
  540. #define RxSignalSynchronousWaiter( RxContext ) \
  541. (RxContext)->Flags &= ~RX_CONTEXT_FLAG_SYNC_EVENT_WAITERS; \
  542. KeSetEvent( &(RxContext)->SyncEvent, 0, FALSE )
  543. #define RxInsertContextInSerializationQueue( SerializationQueue, RxContext ) \
  544. (RxContext)->Flags |= RX_CONTEXT_FLAG_IN_SERIALIZATION_QUEUE; \
  545. InsertTailList( SerializationQueue, &((RxContext)->RxContextSerializationQLinks ))
  546. INLINE
  547. PRX_CONTEXT
  548. RxRemoveFirstContextFromSerializationQueue (
  549. PLIST_ENTRY SerializationQueue
  550. )
  551. {
  552. if (IsListEmpty( SerializationQueue )) {
  553. return NULL;
  554. } else {
  555. PRX_CONTEXT Context = (PRX_CONTEXT)(CONTAINING_RECORD( SerializationQueue->Flink,
  556. RX_CONTEXT,
  557. RxContextSerializationQLinks ));
  558. RemoveEntryList( SerializationQueue->Flink );
  559. Context->RxContextSerializationQLinks.Flink = NULL;
  560. Context->RxContextSerializationQLinks.Blink = NULL;
  561. return Context;
  562. }
  563. }
  564. //
  565. // The following macros provide a mechanism for doing an en masse transfer
  566. // from one list onto another. This provides a powerful paradigm for dealing
  567. // with DPC level processing of lists.
  568. //
  569. #define RxTransferList( Destination, Source ) \
  570. if (IsListEmpty( (Source) )) { \
  571. InitializeListHead( (Destination) ); \
  572. } else { \
  573. *(Destination) = *(Source); \
  574. (Destination)->Flink->Blink = (Destination); \
  575. (Destination)->Blink->Flink = (Destination); \
  576. InitializeListHead( (Source) ); \
  577. }
  578. #define RxTransferListWithMutex( Destination, Source, Mutex ) \
  579. { \
  580. ExAcquireFastMutex( Mutex ); \
  581. RxTransferList( Destination, Source ); \
  582. ExReleaseFastMutex( Mutex ); \
  583. }
  584. VOID
  585. RxInitializeRxContexter (
  586. VOID
  587. );
  588. VOID
  589. RxUninitializeRxContexter (
  590. VOID
  591. );
  592. NTSTATUS
  593. RxCancelNotifyChangeDirectoryRequestsForVNetRoot (
  594. PV_NET_ROOT VNetRoot,
  595. BOOLEAN ForceFilesClosed
  596. );
  597. VOID
  598. RxCancelNotifyChangeDirectoryRequestsForFobx (
  599. PFOBX Fobx
  600. );
  601. NTSTATUS
  602. NTAPI
  603. RxSetMinirdrCancelRoutine (
  604. IN OUT PRX_CONTEXT RxContext,
  605. IN PMRX_CALLDOWN MRxCancelRoutine
  606. );
  607. VOID
  608. NTAPI
  609. RxInitializeContext (
  610. IN PIRP Irp,
  611. IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
  612. IN ULONG InitialContextFlags,
  613. IN OUT PRX_CONTEXT RxContext
  614. );
  615. PRX_CONTEXT
  616. NTAPI
  617. RxCreateRxContext (
  618. IN PIRP Irp,
  619. IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
  620. IN ULONG InitialContextFlags
  621. );
  622. VOID
  623. NTAPI
  624. RxPrepareContextForReuse (
  625. IN OUT PRX_CONTEXT RxContext
  626. );
  627. VOID
  628. NTAPI
  629. RxDereferenceAndDeleteRxContext_Real (
  630. IN PRX_CONTEXT RxContext
  631. );
  632. VOID
  633. NTAPI
  634. RxReinitializeContext (
  635. IN OUT PRX_CONTEXT RxContext
  636. );
  637. #if DBG
  638. #define RxDereferenceAndDeleteRxContext(RXCONTEXT) { \
  639. RxDereferenceAndDeleteRxContext_Real((RXCONTEXT)); \
  640. (RXCONTEXT) = NULL; \
  641. }
  642. #else
  643. #define RxDereferenceAndDeleteRxContext(RXCONTEXT) { \
  644. RxDereferenceAndDeleteRxContext_Real((RXCONTEXT)); \
  645. }
  646. #endif //
  647. extern FAST_MUTEX RxContextPerFileSerializationMutex;
  648. NTSTATUS
  649. NTAPI
  650. __RxSynchronizeBlockingOperations (
  651. IN OUT PRX_CONTEXT RxContext,
  652. IN PFCB Fcb,
  653. IN OUT PLIST_ENTRY BlockingIoQ,
  654. IN BOOLEAN DropFcbLock
  655. );
  656. #define RxSynchronizeBlockingOperationsAndDropFcbLock(RXCONTEXT,FCB,IOQUEUE) \
  657. __RxSynchronizeBlockingOperations(RXCONTEXT,FCB,IOQUEUE,TRUE)
  658. #define RxSynchronizeBlockingOperations(RXCONTEXT,FCB,IOQUEUE) \
  659. __RxSynchronizeBlockingOperations(RXCONTEXT,FCB,IOQUEUE,FALSE)
  660. VOID
  661. NTAPI
  662. RxResumeBlockedOperations_Serially (
  663. IN OUT PRX_CONTEXT RxContext,
  664. IN OUT PLIST_ENTRY BlockingIoQ
  665. );
  666. VOID
  667. RxResumeBlockedOperations_ALL (
  668. IN OUT PRX_CONTEXT RxContext
  669. );
  670. VOID
  671. RxCancelBlockingOperation (
  672. IN OUT PRX_CONTEXT RxContext,
  673. IN PIRP Irp
  674. );
  675. VOID
  676. RxRemoveOperationFromBlockingQueue (
  677. IN OUT PRX_CONTEXT RxContext
  678. );
  679. #endif // _RX_CONTEXT_STRUCT_DEFINED_