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.

584 lines
15 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. umrx.h
  5. Abstract:
  6. This module defines the types and functions which make up the reflector
  7. library. These functions are used by the miniredirs to reflect calls upto
  8. the user mode.
  9. Author:
  10. Rohan Kumar [rohank] 14-March-1999
  11. Revision History:
  12. --*/
  13. #ifndef _UMRX_H_
  14. #define _UMRX_H_
  15. #include "align.h"
  16. #include "status.h"
  17. //
  18. // Unreferenced local variable.
  19. //
  20. #pragma warning(error:4101)
  21. IMPORTANT_STRUCTURE(UMRX_ASYNCENGINE_CONTEXT);
  22. IMPORTANT_STRUCTURE(UMRX_DEVICE_OBJECT);
  23. //
  24. // The BUGBUG macro expands to NOTHING. Its basically used to describe problems
  25. // associated with the current code.
  26. //
  27. #define BUGBUG(_x_)
  28. //
  29. // The argument signatures that are used in a lot of the reflector and miniredir
  30. // functions.
  31. //
  32. #define UMRX_ASYNCENGINE_ARGUMENT_SIGNATURE \
  33. PUMRX_ASYNCENGINE_CONTEXT AsyncEngineContext, \
  34. PRX_CONTEXT RxContext
  35. //
  36. // The arguments that are passed to a lof of the reflector and miniredir
  37. // functions.
  38. //
  39. #define UMRX_ASYNCENGINE_ARGUMENTS AsyncEngineContext,RxContext
  40. //
  41. // The global list of all the currently active AsyncEngineContexts and the
  42. // resource that is used to synchronize access to it.
  43. //
  44. extern LIST_ENTRY UMRxAsyncEngineContextList;
  45. extern ERESOURCE UMRxAsyncEngineContextListLock;
  46. //
  47. // The ASYNCENG_HISTORY structure which is used to keep track of the history
  48. // of AsyncEngineContext structure.
  49. //
  50. #define UMRX_ASYNCENG_HISTORY_SIZE 32
  51. typedef struct _ASYNCENG_HISTORY {
  52. ULONG Next;
  53. ULONG Submits;
  54. struct {
  55. ULONG Longs[2];
  56. } Markers[UMRX_ASYNCENG_HISTORY_SIZE];
  57. } ASYNCENG_HISTORY, *PASYNCENG_HISTORY;
  58. //
  59. // This macro defines the flags of the AsyncEngineContext strucutre.
  60. //
  61. #define UMRX_ASYNCENG_DEFINE_CTX_FLAG(a, c) \
  62. RX_DEFINE_FLAG(UMRX_ASYNCENG_CTX_FLAG_##a, c, 0xffff)
  63. typedef enum {
  64. UMRX_ASYNCENG_DEFINE_CTX_FLAG(ASYNC_OPERATION, 0)
  65. } UMRX_ASYNCENG_CONTEXT_FLAGS;
  66. //
  67. // The prototype of the ContextFormatRoutine specified by the Miniredir.
  68. //
  69. typedef
  70. NTSTATUS
  71. (*PUMRX_ASYNCENG_CONTEXT_FORMAT_ROUTINE) (
  72. PUMRX_ASYNCENGINE_CONTEXT AsyncEngineContext,
  73. USHORT FormatContext
  74. );
  75. //
  76. // The prototype of the continuation routine specified by the Miniredir.
  77. //
  78. typedef
  79. NTSTATUS
  80. (*PUMRX_ASYNCENG_CONTINUE_ROUTINE) (
  81. UMRX_ASYNCENGINE_ARGUMENT_SIGNATURE
  82. );
  83. //
  84. // The prototype of the format routine specified by the Miniredir.
  85. //
  86. typedef
  87. NTSTATUS
  88. (*PUMRX_ASYNCENG_USERMODE_FORMAT_ROUTINE) (
  89. UMRX_ASYNCENGINE_ARGUMENT_SIGNATURE,
  90. PUMRX_USERMODE_WORKITEM_HEADER WorkItem,
  91. ULONG WorkItemLength,
  92. PULONG_PTR ReturnedLength
  93. );
  94. //
  95. // The prototype of the precompletion routine specified by the Miniredir.
  96. //
  97. typedef
  98. BOOL
  99. (*PUMRX_ASYNCENG_USERMODE_PRECOMPLETION_ROUTINE) (
  100. UMRX_ASYNCENGINE_ARGUMENT_SIGNATURE,
  101. PUMRX_USERMODE_WORKITEM_HEADER WorkItem,
  102. ULONG WorkItemLength,
  103. BOOL OperationCancelled
  104. );
  105. //
  106. // The various states of an AsyncEngineContext.
  107. //
  108. typedef enum _UMRX_ASYNCENGINE_CONTEXT_STATE {
  109. UMRxAsyncEngineContextAllocated = 0,
  110. UMRxAsyncEngineContextInUserMode,
  111. UMRxAsyncEngineContextBackFromUserMode,
  112. UMRxAsyncEngineContextCancelled
  113. } UMRX_ASYNCENGINE_CONTEXT_STATE;
  114. //
  115. // The AsyncEngineContext strucutre that is shared across all the miniredirs.
  116. // It contains information common to all the miniredirs.
  117. //
  118. typedef struct _UMRX_ASYNCENGINE_CONTEXT {
  119. //
  120. // The header below is a common header which is present at the start of all
  121. // the data strucutres manipulated by the RDBSS and the MiniRedirs. It is
  122. // used for debugging purposes and for keeping track of the number of times
  123. // a node (data structure) has been referenced.
  124. //
  125. MRX_NORMAL_NODE_HEADER;
  126. //
  127. // This listEntry is used to insert the AsyncEngineContext into the global
  128. // UMRxAsyncEngineContextList list.
  129. //
  130. LIST_ENTRY ActiveContextsListEntry;
  131. UMRX_ASYNCENGINE_CONTEXT_STATE AsyncEngineContextState;
  132. //
  133. // Is this context handling a synchronous or an asynchronous operation?
  134. //
  135. BOOL AsyncOperation;
  136. //
  137. // If this is an AsyncOperation, then RxLowIoCompletion is called only if
  138. // this is set to TRUE. Some operations like CreateSrvCall are Async but
  139. // do not need LowIoCompletion to be called.
  140. //
  141. BOOL ShouldCallLowIoCompletion;
  142. //
  143. // Was IoMarkIrpPending called on the Irp that is being handled by this
  144. // AsyncEngineContext?
  145. //
  146. BOOL ContextMarkedPending;
  147. //
  148. // The system tick count when this context was created. This value is used
  149. // in timing out requests that take more than a specified time.
  150. //
  151. LARGE_INTEGER CreationTimeInTickCount;
  152. //
  153. // The RxContext data structure that is passed in by the RDBSS. It describes
  154. // an Irp while it is being processed and contains state information that
  155. // allows global resources to be released as the Irp is completed.
  156. //
  157. PRX_CONTEXT RxContext;
  158. //
  159. // The context ptr that saves the incoming (from RDBSS) state of
  160. // MRxContext[0] (which is a field of the RxContext data structure).
  161. //
  162. PVOID SavedMinirdrContextPtr;
  163. //
  164. // Pointer to IRP used to call down to the underlying file system.
  165. //
  166. PIRP CalldownIrp;
  167. //
  168. // The I/O status block is set to indicate the status of a given I/O
  169. // request.
  170. //
  171. union {
  172. IO_STATUS_BLOCK;
  173. IO_STATUS_BLOCK IoStatusBlock;
  174. };
  175. //
  176. // The work item which is queued to be completed.
  177. //
  178. RX_WORK_QUEUE_ITEM WorkQueueItem;
  179. //
  180. // Flags that set and indicate the state of the AsyncEngineContext.
  181. //
  182. USHORT Flags;
  183. BOOLEAN FileInformationCached;
  184. BOOLEAN FileNotExists;
  185. BOOLEAN ParentDirInfomationCached;
  186. BOOLEAN ParentDirIsEncrypted;
  187. //
  188. // The continuation routine which is to be called for this I/O request.
  189. //
  190. PUMRX_ASYNCENG_CONTINUE_ROUTINE Continuation;
  191. //
  192. // List of shared memory allocations for this context. All are freed when
  193. // this context is freed.
  194. //
  195. LIST_ENTRY AllocationList;
  196. //
  197. // The UserMode structure.
  198. //
  199. struct {
  200. //
  201. // The work entry thats inserted into the Queue of the
  202. // UMRdrDeviceObject.
  203. //
  204. LIST_ENTRY WorkQueueLinks;
  205. //
  206. // The routine that formats the arguments of the I/O request which is
  207. // reflected to the usermode.
  208. //
  209. PUMRX_ASYNCENG_USERMODE_FORMAT_ROUTINE FormatRoutine;
  210. //
  211. // The routine that is called (to do some final cleanup etc.)just before
  212. // an I/O operation that was sent to the usermode gets completed.
  213. //
  214. //
  215. PUMRX_ASYNCENG_USERMODE_PRECOMPLETION_ROUTINE PrecompletionRoutine;
  216. //
  217. // The event used to signal a thread waiting for a MID to be freed up.
  218. //
  219. KEVENT WaitForMidEvent;
  220. //
  221. // The serial number set before sending this conttext to the user mode.
  222. //
  223. ULONG CallUpSerialNumber;
  224. //
  225. // The MID value of the context.
  226. //
  227. USHORT CallUpMid;
  228. union {
  229. struct {
  230. //
  231. //
  232. //
  233. PBYTE CapturedOutputBuffer;
  234. };
  235. //
  236. //
  237. //
  238. ULONG SetInfoBufferLength;
  239. };
  240. } UserMode;
  241. //
  242. // The context passed to the function called in the context of a worker
  243. // thread.
  244. //
  245. PVOID PostedOpContext;
  246. //
  247. // The completion status of a posted operation. Operations get posted to
  248. // worker threads created by RDBSS.
  249. //
  250. NTSTATUS PostedOpStatus;
  251. //
  252. // This is set to the global serialnumber (for this operation) of RxContext.
  253. //
  254. ULONG SerialNumber;
  255. //
  256. // Used to keep track of the history of the operations on the AsynEngCtx.
  257. //
  258. ASYNCENG_HISTORY History;
  259. //
  260. // This is set to the CurrentIrp in RxContext which points to the
  261. // origination irp.
  262. //
  263. PIRP RxContextCapturedRequestPacket;
  264. } UMRX_ASYNCENGINE_CONTEXT, *PUMRX_ASYNCENGINE_CONTEXT;
  265. #define SIZEOF_UMRX_ASYNCENGINE_CONTEXT sizeof(UMRX_ASYNCENGINE_CONTEXT)
  266. //
  267. // The API of the reflector library exposed to the miniredirs. These are the
  268. // only functions of the library that the miniredirs should use to reflect
  269. // the requests to the user mode.
  270. //
  271. NTSTATUS
  272. UMRxInitializeDeviceObject(
  273. OUT PUMRX_DEVICE_OBJECT UMRefDeviceObject,
  274. IN USHORT MaxNumberMids,
  275. IN USHORT InitialMids,
  276. IN SIZE_T HeapSize
  277. );
  278. NTSTATUS
  279. UMRxCleanUpDeviceObject(
  280. PUMRX_DEVICE_OBJECT DeviceObject
  281. );
  282. NTSTATUS
  283. UMRxAsyncEngOuterWrapper(
  284. IN PRX_CONTEXT RxContext,
  285. IN ULONG AdditionalBytes,
  286. IN PUMRX_ASYNCENG_CONTEXT_FORMAT_ROUTINE ContextFormatRoutine,
  287. USHORT FormatContext,
  288. IN PUMRX_ASYNCENG_CONTINUE_ROUTINE Continuation,
  289. IN PSZ RoutineName
  290. );
  291. NTSTATUS
  292. UMRxSubmitAsyncEngUserModeRequest(
  293. UMRX_ASYNCENGINE_ARGUMENT_SIGNATURE,
  294. PUMRX_ASYNCENG_USERMODE_FORMAT_ROUTINE FormatRoutine,
  295. PUMRX_ASYNCENG_USERMODE_PRECOMPLETION_ROUTINE PrecompletionRoutine
  296. );
  297. BOOLEAN
  298. UMRxFinalizeAsyncEngineContext(
  299. IN OUT PUMRX_ASYNCENGINE_CONTEXT *AEContext
  300. );
  301. NTSTATUS
  302. UMRxAsyncEngineCalldownIrpCompletion (
  303. IN PDEVICE_OBJECT DeviceObject,
  304. IN PIRP CalldownIrp,
  305. IN OUT PVOID Context
  306. );
  307. typedef
  308. NTSTATUS
  309. (*PUMRX_POSTABLE_OPERATION) (
  310. IN OUT PUMRX_ASYNCENGINE_CONTEXT AsyncEngineContext
  311. );
  312. NTSTATUS
  313. UMRxPostOperation (
  314. UMRX_ASYNCENGINE_ARGUMENT_SIGNATURE,
  315. IN OUT PVOID PostedOpContext,
  316. IN PUMRX_POSTABLE_OPERATION Operation
  317. );
  318. PBYTE
  319. UMRxAllocateSecondaryBuffer (
  320. IN OUT PUMRX_ASYNCENGINE_CONTEXT AsyncEngineContext,
  321. SIZE_T Length
  322. );
  323. NTSTATUS
  324. UMRxFreeSecondaryBuffer (
  325. IN OUT PUMRX_ASYNCENGINE_CONTEXT AsyncEngineContext,
  326. PBYTE Buffer
  327. );
  328. VOID
  329. UMRxReleaseCapturedThreads (
  330. IN OUT PUMRX_DEVICE_OBJECT UMRdrDeviceObject
  331. );
  332. VOID
  333. UMRxAssignWork (
  334. IN PUMRX_DEVICE_OBJECT UMRdrDeviceObject,
  335. IN OUT PUMRX_USERMODE_WORKITEM_HEADER InputWorkItem,
  336. IN ULONG InputWorkItemLength,
  337. IN OUT PUMRX_USERMODE_WORKITEM_HEADER OutputWorkItem,
  338. IN ULONG OutputWorkItemLength,
  339. OUT PIO_STATUS_BLOCK IoStatus
  340. );
  341. NTSTATUS
  342. UMRxResumeAsyncEngineContext(
  343. IN OUT PRX_CONTEXT RxContext
  344. );
  345. NTSTATUS
  346. UMRxImpersonateClient(
  347. IN PSECURITY_CLIENT_CONTEXT SecurityClientContext,
  348. IN OUT PUMRX_USERMODE_WORKITEM_HEADER WorkItemHeader
  349. );
  350. NTSTATUS
  351. UMRxReadDWORDFromTheRegistry(
  352. IN PWCHAR RegKey,
  353. IN PWCHAR ValueToRead,
  354. OUT LPDWORD DataRead
  355. );
  356. #define UMRxRevertClient() PsRevertToSelf()
  357. //
  358. // Macro definitions used by the reflector and the miniredirs.
  359. //
  360. //
  361. // Check to see if we have a correct AsyncEngineContext node.
  362. //
  363. #define ASSERT_ASYNCENG_CONTEXT(__p) \
  364. ASSERT(NodeType(__p) == UMRX_NTC_ASYNCENGINE_CONTEXT)
  365. //
  366. // This macro is used to do the async completion for read/write/locks. Note
  367. // that the call to lowiocompletion will try to complete the irp thereby
  368. // freeing the user's mdl. We use this macro so that there will be only one
  369. // version of this code. When we combine the start routines, this will be
  370. // unmacroed.
  371. //
  372. #define UMRxAsyncEngAsyncCompletionIfNecessary(AECTX, RXCONTEXT) { \
  373. if (ContinueEntryCount > 1) { \
  374. BOOLEAN FinalizationComplete; \
  375. if (FALSE) { DbgBreakPoint(); } \
  376. (RXCONTEXT)->StoredStatus = NtStatus; \
  377. RxLowIoCompletion((RXCONTEXT)); \
  378. FinalizationComplete = UMRxFinalizeAsyncEngineContext(&(AECTX)); \
  379. ASSERT(!FinalizationComplete); \
  380. } \
  381. }
  382. //
  383. // This macro allows one to execute conditional debugging code.
  384. //
  385. #if DBG
  386. #define DEBUG_ONLY_CODE(x) x
  387. #else
  388. #define DEBUG_ONLY_CODE(x)
  389. #endif
  390. //
  391. // The heap is shared between kernel and user but only the kernel component
  392. // allocates and frees into the heap.
  393. //
  394. typedef struct _UMRX_SHARED_HEAP {
  395. LIST_ENTRY HeapListEntry;
  396. PBYTE VirtualMemoryBuffer;
  397. SIZE_T VirtualMemoryLength;
  398. PVOID Heap;
  399. ULONG HeapAllocationCount;
  400. BOOLEAN HeapFull;
  401. } UMRX_SHARED_HEAP, * PUMRX_SHARED_HEAP;
  402. //
  403. // NodeType Codes.
  404. //
  405. #define UMRX_NTC_ASYNCENGINE_CONTEXT ((USHORT)0xedd0)
  406. //
  407. // This strucutre defines the fields which the reflector and the miniredir can
  408. // share and is encapsulated in the miniredirs device object. The miniredirs
  409. // device object may contain some other fields which are specific to its
  410. // operation.
  411. //
  412. typedef struct _UMRX_DEVICE_OBJECT {
  413. //
  414. // The RDBSS's device object structure.
  415. //
  416. union {
  417. RDBSS_DEVICE_OBJECT;
  418. RDBSS_DEVICE_OBJECT RxDeviceObject;
  419. };
  420. //
  421. // The max size of the heap that can be allocated.
  422. //
  423. SIZE_T NewHeapSize;
  424. //
  425. // List of shared heaps created by worker threads.
  426. //
  427. LIST_ENTRY SharedHeapList;
  428. //
  429. // Used to synchronize the heap allocation/deletion, creation/destruction.
  430. //
  431. ERESOURCE HeapLock;
  432. //
  433. // Mid atlas and its management and synchronization.
  434. //
  435. struct {
  436. PRX_MID_ATLAS MidAtlas;
  437. FAST_MUTEX MidManagementMutex;
  438. LIST_ENTRY WaitingForMidListhead;
  439. };
  440. struct {
  441. //
  442. // The Queue of the device object where the requests which need reflection
  443. // wait.
  444. //
  445. KQUEUE Queue;
  446. //
  447. // Used to synchronize the KQUEUE insertions.
  448. //
  449. ERESOURCE QueueLock;
  450. //
  451. // The timeout value used by the worker threads when waiting on the
  452. // KQUEUE for requests to be taken to user mode.
  453. //
  454. LARGE_INTEGER TimeOut;
  455. //
  456. // Used to release the worker threads which are waiting on the KQUEUE.
  457. // Once the worker threads are released, no requests can be reflected.
  458. //
  459. LIST_ENTRY PoisonEntry;
  460. //
  461. // Used to signal the thread (which comes down with an IOCTL to release
  462. // the worker threads) waiting for all the worker threads to be
  463. // released.
  464. //
  465. KEVENT RunDownEvent;
  466. //
  467. // Number of worker threads waiting on the KQUEUE.
  468. //
  469. ULONG NumberOfWorkerThreads;
  470. //
  471. // Number of workitems (requests to be reflected) in the queue.
  472. //
  473. ULONG NumberOfWorkItems;
  474. //
  475. // Are the worker threads still willing to take the requests.
  476. //
  477. BOOLEAN WorkersAccepted;
  478. } Q;
  479. //
  480. // Always incremented and assigned to the AsyncEngineContext's serial
  481. // number.
  482. //
  483. ULONG NextSerialNumber;
  484. } UMRX_DEVICE_OBJECT, *PUMRX_DEVICE_OBJECT;
  485. #endif //_UMRX_H_