Source code of Windows XP (NT5)
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.

731 lines
24 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. // Define rxdriver dispatch routine type....almost all of the important routine
  102. // will have this type.
  103. typedef
  104. NTSTATUS
  105. (NTAPI *PRX_DISPATCH) ( RXCOMMON_SIGNATURE );
  106. typedef struct _NT_CREATE_PARAMETERS {
  107. ACCESS_MASK DesiredAccess;
  108. LARGE_INTEGER AllocationSize;
  109. ULONG FileAttributes;
  110. ULONG ShareAccess;
  111. ULONG Disposition;
  112. ULONG CreateOptions;
  113. PIO_SECURITY_CONTEXT SecurityContext;
  114. SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
  115. PVOID DfsContext;
  116. PVOID DfsNameContext;
  117. } NT_CREATE_PARAMETERS, *PNT_CREATE_PARAMETERS;
  118. typedef struct _RX_CONTEXT {
  119. // the node type, size and reference count, aka standard header
  120. NODE_TYPE_CODE NodeTypeCode;
  121. NODE_BYTE_SIZE NodeByteSize;
  122. ULONG ReferenceCount;
  123. // the list entry to wire the context to the list of active contexts
  124. LIST_ENTRY ContextListEntry;
  125. // Major and minor function of the IRP associated with the context
  126. UCHAR MajorFunction;
  127. UCHAR MinorFunction;
  128. // this is similar to the same field in Irps; it
  129. // allows callback routines for async operations
  130. // to know whether to do asynchronous work or not
  131. BOOLEAN PendingReturned;
  132. // indicates if the associated request is to be posted to a RDBSS worker thread.
  133. BOOLEAN PostRequest;
  134. // Originating Device (required for workque algorithms)
  135. // not currently used but could be used for local minis
  136. PDEVICE_OBJECT RealDevice;
  137. // ptr to the originating Irp
  138. PIRP CurrentIrp;
  139. // ptr to the IRP stack location
  140. PIO_STACK_LOCATION CurrentIrpSp;
  141. // ptr to the FCB and FOBX, derived from the context pointers in the
  142. // file object associated with the IRP
  143. PMRX_FCB pFcb;
  144. PMRX_FOBX pFobx;
  145. PMRX_SRV_OPEN pRelevantSrvOpen;
  146. PNON_PAGED_FCB NonPagedFcb;
  147. // device object calldown (not irpsp.....)
  148. PRDBSS_DEVICE_OBJECT RxDeviceObject;
  149. // The original thread in which the request was initiated and the last
  150. // thread in which some processing associated with the context was done
  151. PETHREAD OriginalThread;
  152. PETHREAD LastExecutionThread;
  153. PVOID LockManagerContext;
  154. // One word of the context is given to rdbss for dbg information
  155. PVOID RdbssDbgExtension;
  156. RX_SCAVENGER_ENTRY ScavengerEntry;
  157. // global serial number for this operation
  158. ULONG SerialNumber;
  159. // used by minirdrs to see if multiple calls are part
  160. // of the same larger operation and (therefore) more cacheable
  161. ULONG FobxSerialNumber;
  162. ULONG Flags;
  163. BOOLEAN FcbResourceAcquired;
  164. BOOLEAN FcbPagingIoResourceAcquired;
  165. UCHAR MustSucceedDescriptorNumber;
  166. // mostly you want the individual components...sometimes it's nice as a pair
  167. // used to record the status when you can't just return it; e.g., when
  168. // RXSTATUS is not an appropriate return type or if the consumer of the
  169. // status didn't call directly (lowiocompletions). minirdrs will not need
  170. // to set the information directly
  171. union {
  172. struct {
  173. union {
  174. NTSTATUS StoredStatus;
  175. PVOID StoredStatusAlignment;
  176. };
  177. ULONG_PTR InformationToReturn;
  178. };
  179. IO_STATUS_BLOCK IoStatusBlock;
  180. };
  181. // the context fields provided for use by the mini redirectors
  182. // this is defined as a union to force longlong alignment
  183. union {
  184. ULONGLONG ForceLonglongAligmentDummyField;
  185. PVOID MRxContext[MRX_CONTEXT_FIELD_COUNT];
  186. };
  187. // The following field is included to fix the problem related to write only
  188. // opens. This introduces a new field for the mini redirector to squirrel
  189. // some state. This is redundant and should be removed after Windows 2000.
  190. // Having a unique field reduces the impact of the change that we are making
  191. // to the specific code path. It will be ideal to use one of the MRXContext
  192. // fields defined above
  193. PVOID WriteOnlyOpenRetryContext;
  194. // the cancellation routine to be invoked, set by the mini redirector
  195. PMRX_CALLDOWN MRxCancelRoutine;
  196. // private dispatch, if any. used in fspdisp
  197. PRX_DISPATCH ResumeRoutine;
  198. // for posting to worker threads
  199. // the minirdr can use this for posting within the minirdr
  200. // a potential problem can arise if the minirdr relies on this both
  201. // for queueing async stuff and for queueing cancel stuff
  202. // The OverflowListEntry is used for queueing items to the overflow queue.
  203. // This is seperate now to allow us to distinguish between an item in the overflow
  204. // queue and one in the active work queue (for cancellation logic)
  205. RX_WORK_QUEUE_ITEM WorkQueueItem;
  206. LIST_ENTRY OverflowListEntry;
  207. // this event is used for synchronous operations
  208. // that have to i/f with an underlying async service. it can be used
  209. // by the minirdr with the following provisions:
  210. // 1) on entering the minirdr through lowio, it is set to the
  211. // nonsignaled state (but a wise user will reset it before using
  212. // it....particularly if it's used multiple times.
  213. // 2) if you are returning STATUS_PENDING on a sync operation, you must
  214. // return with it set to the nonsignaled state; that is, either
  215. // you don't use it or you reset it in this case
  216. KEVENT SyncEvent;
  217. //this is a list head of operations that are to be released on completion
  218. LIST_ENTRY BlockedOperations;
  219. //this is the mutex that controls serialization of the blocked operations
  220. PFAST_MUTEX BlockedOpsMutex;
  221. // these links are used to serialize pipe operations on a
  222. //per-file-object basis AND FOR LOTS OF OTHER STUFF
  223. LIST_ENTRY RxContextSerializationQLinks;
  224. union {
  225. struct {
  226. union {
  227. FS_INFORMATION_CLASS FsInformationClass;
  228. FILE_INFORMATION_CLASS FileInformationClass;
  229. };
  230. PVOID Buffer;
  231. union {
  232. LONG Length;
  233. LONG LengthRemaining;
  234. };
  235. BOOLEAN ReplaceIfExists;
  236. BOOLEAN AdvanceOnly;
  237. } Info;
  238. struct {
  239. UNICODE_STRING SuppliedPathName;
  240. NET_ROOT_TYPE NetRootType;
  241. PIO_SECURITY_CONTEXT pSecurityContext;
  242. } PrefixClaim;
  243. };
  244. // THIS UNION MUST BE LAST....AT SOME POINT, WE MAY START ALLOCATING
  245. // SMALLER PER OPERATION!
  246. union{
  247. struct {
  248. NT_CREATE_PARAMETERS NtCreateParameters; // a copy of the createparameters
  249. ULONG ReturnedCreateInformation;
  250. PWCH CanonicalNameBuffer; // if the canonical name is larger than available buffer
  251. PRX_PREFIX_ENTRY NetNamePrefixEntry; // the entry returned by the lookup....for dereferencing
  252. PMRX_SRV_CALL pSrvCall; // Server Call being used
  253. PMRX_NET_ROOT pNetRoot; // Net Root being used
  254. PMRX_V_NET_ROOT pVNetRoot; // Virtual Net Root
  255. //PMRX_SRV_OPEN pSrvOpen; // Server Open
  256. PVOID EaBuffer;
  257. ULONG EaLength;
  258. ULONG SdLength;
  259. ULONG PipeType;
  260. ULONG PipeReadMode;
  261. ULONG PipeCompletionMode;
  262. USHORT Flags;
  263. NET_ROOT_TYPE Type; // Type of Net Root(Pipe/File/Mailslot..)
  264. BOOLEAN FcbAcquired;
  265. BOOLEAN TryForScavengingOnSharingViolation;
  266. BOOLEAN ScavengingAlreadyTried;
  267. BOOLEAN ThisIsATreeConnectOpen;
  268. BOOLEAN TreeConnectOpenDeferred;
  269. UNICODE_STRING TransportName;
  270. UNICODE_STRING UserName;
  271. UNICODE_STRING Password;
  272. UNICODE_STRING UserDomainName;
  273. } Create;
  274. struct {
  275. ULONG FileIndex;
  276. BOOLEAN RestartScan;
  277. BOOLEAN ReturnSingleEntry;
  278. BOOLEAN IndexSpecified;
  279. BOOLEAN InitialQuery;
  280. } QueryDirectory;
  281. struct {
  282. PMRX_V_NET_ROOT pVNetRoot;
  283. } NotifyChangeDirectory;
  284. struct {
  285. PUCHAR UserEaList;
  286. ULONG UserEaListLength;
  287. ULONG UserEaIndex;
  288. BOOLEAN RestartScan;
  289. BOOLEAN ReturnSingleEntry;
  290. BOOLEAN IndexSpecified;
  291. } QueryEa;
  292. struct {
  293. SECURITY_INFORMATION SecurityInformation;
  294. ULONG Length;
  295. } QuerySecurity;
  296. struct {
  297. SECURITY_INFORMATION SecurityInformation;
  298. PSECURITY_DESCRIPTOR SecurityDescriptor;
  299. } SetSecurity;
  300. struct {
  301. ULONG Length;
  302. PSID StartSid;
  303. PFILE_GET_QUOTA_INFORMATION SidList;
  304. ULONG SidListLength;
  305. BOOLEAN RestartScan;
  306. BOOLEAN ReturnSingleEntry;
  307. BOOLEAN IndexSpecified;
  308. } QueryQuota;
  309. struct {
  310. ULONG Length;
  311. } SetQuota;
  312. struct {
  313. PV_NET_ROOT VNetRoot;
  314. PSRV_CALL SrvCall;
  315. PNET_ROOT NetRoot;
  316. } DosVolumeFunction;
  317. struct {
  318. ULONG FlagsForLowIo;
  319. LOWIO_CONTEXT LowIoContext; // the LOWIO parameters
  320. }; //no name here....
  321. LUID FsdUid;
  322. } ;
  323. //CODE.IMPROVEMENT remove this to wrapperdbgprivates
  324. PWCH AlsoCanonicalNameBuffer; // if the canonical name is larger than available buffer
  325. PUNICODE_STRING LoudCompletionString;
  326. #ifdef RDBSS_TRACKER
  327. LONG AcquireReleaseFcbTrackerX;
  328. ULONG TrackerHistoryPointer;
  329. #endif
  330. #ifdef RDBSS_TRACKER
  331. RX_FCBTRACKER_CALLINFO TrackerHistory[RDBSS_TRACKER_HISTORY_SIZE];
  332. #endif
  333. ULONG dwShadowCritOwner;
  334. } RX_CONTEXT;
  335. #define RX_DEFINE_RXC_FLAG(a,c) RX_DEFINE_FLAG(RX_CONTEXT_FLAG_##a,c,0xffffffff)
  336. typedef enum {
  337. RX_DEFINE_RXC_FLAG(FROM_POOL, 0)
  338. RX_DEFINE_RXC_FLAG(WAIT, 1)
  339. RX_DEFINE_RXC_FLAG(WRITE_THROUGH, 2)
  340. RX_DEFINE_RXC_FLAG(FLOPPY, 3)
  341. RX_DEFINE_RXC_FLAG(RECURSIVE_CALL, 4)
  342. RX_DEFINE_RXC_FLAG(THIS_DEVICE_TOP_LEVEL, 5)
  343. RX_DEFINE_RXC_FLAG(DEFERRED_WRITE, 6)
  344. RX_DEFINE_RXC_FLAG(VERIFY_READ, 7)
  345. RX_DEFINE_RXC_FLAG(STACK_IO_CONTEZT, 8)
  346. RX_DEFINE_RXC_FLAG(IN_FSP, 9)
  347. RX_DEFINE_RXC_FLAG(CREATE_MAILSLOT, 10)
  348. RX_DEFINE_RXC_FLAG(MAILSLOT_REPARSE, 11)
  349. RX_DEFINE_RXC_FLAG(ASYNC_OPERATION, 12)
  350. RX_DEFINE_RXC_FLAG(NO_COMPLETE_FROM_FSP, 13)
  351. RX_DEFINE_RXC_FLAG(POST_ON_STABLE_CONDITION, 14)
  352. RX_DEFINE_RXC_FLAG(FSP_DELAYED_OVERFLOW_QUEUE, 15)
  353. RX_DEFINE_RXC_FLAG(FSP_CRITICAL_OVERFLOW_QUEUE, 16)
  354. RX_DEFINE_RXC_FLAG(MINIRDR_INVOKED, 17)
  355. RX_DEFINE_RXC_FLAG(WAITING_FOR_RESOURCE, 18)
  356. RX_DEFINE_RXC_FLAG(CANCELLED, 19)
  357. RX_DEFINE_RXC_FLAG(SYNC_EVENT_WAITERS, 20)
  358. RX_DEFINE_RXC_FLAG(NO_PREPOSTING_NEEDED, 21)
  359. RX_DEFINE_RXC_FLAG(BYPASS_VALIDOP_CHECK, 22)
  360. RX_DEFINE_RXC_FLAG(BLOCKED_PIPE_RESUME, 23)
  361. RX_DEFINE_RXC_FLAG(IN_SERIALIZATION_QUEUE, 24)
  362. RX_DEFINE_RXC_FLAG(NO_EXCEPTION_BREAKPOINT, 25)
  363. RX_DEFINE_RXC_FLAG(NEEDRECONNECT, 26)
  364. RX_DEFINE_RXC_FLAG(MUST_SUCCEED, 27)
  365. RX_DEFINE_RXC_FLAG(MUST_SUCCEED_NONBLOCKING, 28)
  366. RX_DEFINE_RXC_FLAG(MUST_SUCCEED_ALLOCATED, 29)
  367. RX_DEFINE_RXC_FLAG(MINIRDR_INITIATED, 31)
  368. } RX_CONTEXT_FLAGS;
  369. #define RX_CONTEXT_PRESERVED_FLAGS (RX_CONTEXT_FLAG_FROM_POOL | \
  370. RX_CONTEXT_FLAG_MUST_SUCCEED_ALLOCATED | \
  371. RX_CONTEXT_FLAG_IN_FSP)
  372. #define RX_CONTEXT_INITIALIZATION_FLAGS (RX_CONTEXT_FLAG_WAIT | \
  373. RX_CONTEXT_FLAG_MUST_SUCCEED | \
  374. RX_CONTEXT_FLAG_MUST_SUCCEED_NONBLOCKING)
  375. #define RX_DEFINE_RXC_CREATE_FLAG(a,c) RX_DEFINE_FLAG(RX_CONTEXT_CREATE_FLAG_##a,c,0xffff)
  376. typedef enum {
  377. RX_DEFINE_RXC_CREATE_FLAG(UNC_NAME, 0)
  378. RX_DEFINE_RXC_CREATE_FLAG(STRIPPED_TRAILING_BACKSLASH, 1)
  379. RX_DEFINE_RXC_CREATE_FLAG(ADDEDBACKSLASH, 2)
  380. RX_DEFINE_RXC_CREATE_FLAG(REPARSE,3)
  381. RX_DEFINE_RXC_CREATE_FLAG(SPECIAL_PATH, 4)
  382. } RX_CONTEXT_CREATE_FLAGS;
  383. #define RX_DEFINE_RXC_LOWIO_FLAG(a,c) RX_DEFINE_FLAG(RXCONTEXT_FLAG4LOWIO_##a,c,0xffffffff)
  384. typedef enum {
  385. RX_DEFINE_RXC_LOWIO_FLAG(PIPE_OPERATION, 0)
  386. RX_DEFINE_RXC_LOWIO_FLAG(PIPE_SYNC_OPERATION, 1)
  387. RX_DEFINE_RXC_LOWIO_FLAG(READAHEAD, 2)
  388. RX_DEFINE_RXC_LOWIO_FLAG(THIS_READ_ENLARGED, 3)
  389. RX_DEFINE_RXC_LOWIO_FLAG(THIS_IO_BUFFERED, 4)
  390. RX_DEFINE_RXC_LOWIO_FLAG(LOCK_FCB_RESOURCE_HELD, 5)
  391. RX_DEFINE_RXC_LOWIO_FLAG(LOCK_WAS_QUEUED_IN_LOCKMANAGER, 6)
  392. #ifdef __cplusplus
  393. } RX_CONTEXT_LOWIO_FLAGS;
  394. #else // !__cplusplus
  395. } RX_CONTEXT_CREATE_FLAGS;
  396. #endif // __cplusplus
  397. // Macros used to control whether the wrapper breakpoints on an exception
  398. #if DBG
  399. #define RxSaveAndSetExceptionNoBreakpointFlag(RXCONTEXT,_yyy){ \
  400. _yyy = RxContext->Flags & RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT; \
  401. RxContext->Flags |= RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT; \
  402. }
  403. #define RxRestoreExceptionNoBreakpointFlag(RXCONTEXT,_yyy){ \
  404. RxContext->Flags &= ~RX_CONTEXT_FLAG_NO_EXCEPTION_BREAKPOINT; \
  405. RxContext->Flags |= _yyy; \
  406. }
  407. #else
  408. #define RxSaveAndSetExceptionNoBreakpointFlag(_xxx,_yyy)
  409. #define RxRestoreExceptionNoBreakpointFlag(_xxx,_yyy)
  410. #endif
  411. // a macro used to ensure that a context hasn't been freed during a wait
  412. #if DBG
  413. VOID
  414. __RxItsTheSameContext(
  415. PRX_CONTEXT RxContext,
  416. ULONG CapturedRxContextSerialNumber,
  417. ULONG Line,
  418. PSZ File
  419. );
  420. #define RxItsTheSameContext() {__RxItsTheSameContext(RxContext,CapturedRxContextSerialNumber,__LINE__,__FILE__);}
  421. #else
  422. #define RxItsTheSameContext() {NOTHING;}
  423. #endif
  424. extern NPAGED_LOOKASIDE_LIST RxContextLookasideList;
  425. // Macros used in the RDBSS to wrap mini rdr calldowns
  426. #define MINIRDR_CALL_THROUGH(STATUS,DISPATCH,FUNC,ARGLIST) \
  427. { \
  428. ASSERT(DISPATCH); \
  429. ASSERT( NodeType(DISPATCH) == RDBSS_NTC_MINIRDR_DISPATCH ); \
  430. if (DISPATCH->FUNC == NULL) { \
  431. STATUS = STATUS_NOT_IMPLEMENTED; \
  432. } else { \
  433. RxDbgTrace(0, Dbg, ("MiniRdr Calldown - %s\n",#FUNC)); \
  434. STATUS = DISPATCH->FUNC ARGLIST; \
  435. } \
  436. }
  437. #define MINIRDR_CALL(STATUS,CONTEXT,DISPATCH,FUNC,ARGLIST) \
  438. { \
  439. ASSERT(DISPATCH); \
  440. ASSERT( NodeType(DISPATCH) == RDBSS_NTC_MINIRDR_DISPATCH ); \
  441. if ( DISPATCH->FUNC == NULL) { \
  442. STATUS = STATUS_NOT_IMPLEMENTED; \
  443. } else { \
  444. if (!BooleanFlagOn((CONTEXT)->Flags,RX_CONTEXT_FLAG_CANCELLED)) { \
  445. RxDbgTrace(0, Dbg, ("MiniRdr Calldown - %s\n",#FUNC)); \
  446. RtlZeroMemory(&((CONTEXT)->MRxContext[0]), \
  447. sizeof((CONTEXT)->MRxContext)); \
  448. STATUS = DISPATCH->FUNC ARGLIST; \
  449. } else { \
  450. STATUS = STATUS_CANCELLED; \
  451. } \
  452. } \
  453. }
  454. //VOID
  455. //RxWaitSync (
  456. // IN PRX_CONTEXT RxContext
  457. // )
  458. #define RxWaitSync(RxContext) \
  459. RxDbgTrace(+1, Dbg, ("RxWaitSync, RxContext = %08lx\n", (RxContext))); \
  460. (RxContext)->Flags |= RX_CONTEXT_FLAG_SYNC_EVENT_WAITERS; \
  461. KeWaitForSingleObject( &(RxContext)->SyncEvent, \
  462. Executive, KernelMode, FALSE, NULL ); \
  463. RxDbgTrace(-1, Dbg, ("RxWaitSync -> VOID\n", 0 ))
  464. //VOID
  465. //RxSignalSynchronousWaiter (
  466. // IN PRX_CONTEXT RxContext
  467. // )
  468. #define RxSignalSynchronousWaiter(RxContext) \
  469. (RxContext)->Flags &= ~RX_CONTEXT_FLAG_SYNC_EVENT_WAITERS; \
  470. KeSetEvent( &(RxContext)->SyncEvent, 0, FALSE )
  471. #define RxInsertContextInSerializationQueue(pSerializationQueue,RxContext) \
  472. (RxContext)->Flags |= RX_CONTEXT_FLAG_IN_SERIALIZATION_QUEUE; \
  473. InsertTailList(pSerializationQueue,&((RxContext)->RxContextSerializationQLinks))
  474. INLINE PRX_CONTEXT
  475. RxRemoveFirstContextFromSerializationQueue(PLIST_ENTRY pSerializationQueue)
  476. {
  477. if (IsListEmpty(pSerializationQueue)) {
  478. return NULL;
  479. } else {
  480. PRX_CONTEXT pContext = (PRX_CONTEXT)(CONTAINING_RECORD(pSerializationQueue->Flink,
  481. RX_CONTEXT,
  482. RxContextSerializationQLinks));
  483. RemoveEntryList(pSerializationQueue->Flink);
  484. pContext->RxContextSerializationQLinks.Flink = NULL;
  485. pContext->RxContextSerializationQLinks.Blink = NULL;
  486. return pContext;
  487. }
  488. }
  489. // The following macros provide a mechanism for doing an en masse transfer
  490. // from one list onto another. This provides a powerful paradigm for dealing
  491. // with DPC level processing of lists.
  492. #define RxTransferList(pDestination,pSource) \
  493. if (IsListEmpty((pSource))) { \
  494. InitializeListHead((pDestination)); \
  495. } else { \
  496. *(pDestination) = *(pSource); \
  497. (pDestination)->Flink->Blink = (pDestination); \
  498. (pDestination)->Blink->Flink = (pDestination); \
  499. InitializeListHead((pSource)); \
  500. }
  501. #define RxTransferListWithMutex(pDestination,pSource,pMutex) \
  502. { \
  503. ExAcquireFastMutex(pMutex); \
  504. RxTransferList(pDestination,pSource); \
  505. ExReleaseFastMutex(pMutex); \
  506. }
  507. VOID RxInitializeRxContexter(void);
  508. VOID RxUninitializeRxContexter(void);
  509. NTSTATUS
  510. RxCancelNotifyChangeDirectoryRequestsForVNetRoot(
  511. PV_NET_ROOT pVNetRoot,
  512. BOOLEAN ForceFilesClosed
  513. );
  514. VOID
  515. RxCancelNotifyChangeDirectoryRequestsForFobx(
  516. PFOBX pFobx);
  517. NTSTATUS
  518. NTAPI
  519. RxSetMinirdrCancelRoutine(
  520. IN OUT PRX_CONTEXT RxContext,
  521. IN PMRX_CALLDOWN MRxCancelRoutine);
  522. VOID
  523. NTAPI
  524. RxInitializeContext(
  525. IN PIRP Irp,
  526. IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
  527. IN ULONG InitialContextFlags,
  528. IN OUT PRX_CONTEXT RxContext);
  529. PRX_CONTEXT
  530. NTAPI
  531. RxCreateRxContext (
  532. IN PIRP Irp,
  533. IN PRDBSS_DEVICE_OBJECT RxDeviceObject,
  534. IN ULONG InitialContextFlags
  535. );
  536. VOID
  537. NTAPI
  538. RxPrepareContextForReuse(
  539. IN OUT PRX_CONTEXT RxContext);
  540. VOID
  541. NTAPI
  542. RxDereferenceAndDeleteRxContext_Real (
  543. IN PRX_CONTEXT RxContext
  544. );
  545. VOID
  546. NTAPI
  547. RxReinitializeContext(
  548. IN OUT PRX_CONTEXT RxContext);
  549. #if DBG
  550. #define RxDereferenceAndDeleteRxContext(RXCONTEXT) { \
  551. RxDereferenceAndDeleteRxContext_Real((RXCONTEXT)); \
  552. (RXCONTEXT) = NULL; \
  553. }
  554. #else
  555. #define RxDereferenceAndDeleteRxContext(RXCONTEXT) { \
  556. RxDereferenceAndDeleteRxContext_Real((RXCONTEXT)); \
  557. }
  558. #endif //
  559. extern FAST_MUTEX RxContextPerFileSerializationMutex;
  560. NTSTATUS
  561. NTAPI
  562. __RxSynchronizeBlockingOperationsMaybeDroppingFcbLock(
  563. IN OUT PRX_CONTEXT RxContext,
  564. IN OUT PLIST_ENTRY BlockingIoQ,
  565. IN BOOLEAN DropFcbLock
  566. );
  567. #define RxSynchronizeBlockingOperationsAndDropFcbLock(__x,__y) \
  568. __RxSynchronizeBlockingOperationsMaybeDroppingFcbLock(__x,__y,TRUE)
  569. #define RxSynchronizeBlockingOperations(__x,__y) \
  570. __RxSynchronizeBlockingOperationsMaybeDroppingFcbLock(__x,__y,FALSE)
  571. VOID
  572. NTAPI
  573. RxResumeBlockedOperations_Serially(
  574. IN OUT PRX_CONTEXT RxContext,
  575. IN OUT PLIST_ENTRY BlockingIoQ
  576. );
  577. VOID
  578. RxResumeBlockedOperations_ALL(
  579. IN OUT PRX_CONTEXT RxContext
  580. );
  581. VOID
  582. RxCancelBlockingOperation(
  583. IN OUT PRX_CONTEXT RxContext);
  584. VOID
  585. RxRemoveOperationFromBlockingQueue(
  586. IN OUT PRX_CONTEXT RxContext);
  587. #endif // _RX_CONTEXT_STRUCT_DEFINED_