Windows NT 4.0 source code leak
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.

337 lines
7.5 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. fspdisp.h
  5. Abstract:
  6. This module defines the data structures and routines used for the FSP
  7. dispatching code.
  8. Author:
  9. Larry Osterman (LarryO) 13-Aug-1990
  10. Revision History:
  11. 13-Aug-1990 LarryO
  12. Created
  13. --*/
  14. #ifndef _FSPDISP_
  15. #define _FSPDISP_
  16. //
  17. //
  18. // The WORK_QUEUE structure describes all the information needed to manage
  19. // FSP worker threads.
  20. //
  21. // FSP worker threads are managed with the routines:
  22. //
  23. // RdrQueueToWorkerThread(
  24. // RdrDequeueInWorkerThread(
  25. // RdrInitializeWorkerQueue(
  26. //
  27. //
  28. typedef
  29. struct _WORK_QUEUE {
  30. ULONG Signature;
  31. //
  32. // The following field controls exclusive access to the WorkQueue.
  33. //
  34. KSPIN_LOCK SpinLock;
  35. //
  36. // The following field contains the queue header of the work queue.
  37. //
  38. LIST_ENTRY Queue;
  39. //
  40. // The following field specifies a kernel event that the FSP will block
  41. // on waiting on requests.
  42. //
  43. KEVENT Event;
  44. //
  45. // The number of requests queued to this work queue.
  46. //
  47. LONG NumberOfRequests;
  48. //
  49. // The number of threads servicing this work queue.
  50. //
  51. LONG NumberOfThreads;
  52. //
  53. // The maximum number of threads that can be created for this work queue.
  54. //
  55. LONG MaximumThreads;
  56. BOOLEAN QueueInitialized;
  57. BOOLEAN SpinningUp;
  58. //
  59. // Routine to call at thread creation.
  60. //
  61. PKSTART_ROUTINE StartRoutine;
  62. //
  63. // Context for the new thread.
  64. //
  65. PVOID StartContext;
  66. //
  67. // Time after which the redir will destroy a worker thread.
  68. //
  69. LARGE_INTEGER ThreadIdleLimit;
  70. } WORK_QUEUE, *PWORK_QUEUE;
  71. //
  72. // Define communications data area between FSD and FSP. This is done through
  73. // the use of a Device Object. This model allows one device object to be
  74. // created for each volume that is/has been mounted in the system. That is,
  75. // each time a volume is mounted, the file system creates a device object to
  76. // represent it so that the I/O system can vector directly to the proper file
  77. // system. The file system then uses information in the device object and in
  78. // the file object to locate and synchronize access to its database of open
  79. // file data structures (often called File Control Blocks - or, FCBs), Volume
  80. // Control Blocks (VCBs), Map Control Blocks (MCBs), etc.
  81. //
  82. // The event and spinlock will be used to control access to the queue of IRPs.
  83. // The IRPs are passed from the FSD to the FSP by inserting them onto the work
  84. // queue in an interlocked manner and then setting the event to the Signaled
  85. // state. The event is an autoclearing type so the FSP simply wakes up when
  86. // the event is Signaled and begins processing entries in the queue.
  87. //
  88. // Other data in this record should contain any information which both the FSD
  89. // and the FSP need to share. For example, a list of all of the open files
  90. // might be something that both should be able to see. Notice that all data
  91. // placed in this area must be allocated from paged or non-paged pool.
  92. //
  93. typedef struct _FS_DEVICE_OBJECT {
  94. DEVICE_OBJECT DeviceObject;
  95. //
  96. // This WORK_QUEUE structure defines the queue structures for the
  97. // redirector IRP worker threads.
  98. //
  99. WORK_QUEUE IrpWorkQueue;
  100. //
  101. // The cache manager callbacks structure describes the callback routines
  102. // that the redirector provides for the cache manager.
  103. //
  104. CACHE_MANAGER_CALLBACKS CacheManagerCallbacks;
  105. } FS_DEVICE_OBJECT, *PFS_DEVICE_OBJECT;
  106. //
  107. // When there is a redirector operation that must be processed at task
  108. // time, the caller should take a "WORK_HEADER" structure, fill it in
  109. // with a task time completion routine (a PWORKFUNCTION).
  110. //
  111. // The completion routine will be called from one of a number of
  112. // redirector generic worker threads to complete the operation at a later
  113. // time.
  114. //
  115. //
  116. struct _WORK_HEADER;
  117. typedef
  118. VOID
  119. (*PWORKFUNCTION)(
  120. struct _WORK_HEADER *Header
  121. );
  122. //
  123. // The WORK_ITEM structure is passed into the FSP dispatching code as the
  124. // item to be enqueued.
  125. //
  126. typedef struct _WORK_ITEM {
  127. LIST_ENTRY Queue; // LIST_ENTRY to chain requests.
  128. PIRP Irp; // Irp associated with request (OPTIONAL)
  129. } WORK_ITEM, *PWORK_ITEM;
  130. typedef struct _WORK_HEADER {
  131. WORK_ITEM WorkItem;
  132. PWORKFUNCTION WorkerFunction;
  133. } WORK_HEADER, *PWORK_HEADER;
  134. //
  135. // IRP Context.
  136. //
  137. // The IRP context is a wrapper that used when passing an IRP from the
  138. // redirectors FSD to its FSP.
  139. //
  140. typedef
  141. struct _IRP_CONTEXT {
  142. WORK_HEADER WorkHeader;
  143. PIRP Irp;
  144. PFS_DEVICE_OBJECT DeviceObject;
  145. } IRP_CONTEXT, *PIRP_CONTEXT;
  146. extern KSPIN_LOCK IrpContextInterlock;
  147. extern LIST_ENTRY IrpContextList;
  148. extern ULONG IrpContextCount;
  149. //
  150. // Define those routines used in the FSP.
  151. //
  152. VOID
  153. RdrFspDispatch(
  154. IN PWORK_HEADER WorkHeader
  155. );
  156. VOID
  157. RdrFsdPostToFsp(
  158. IN PFS_DEVICE_OBJECT DeviceObject,
  159. IN PIRP Irp
  160. );
  161. NTSTATUS
  162. RdrpInitializeFsp(
  163. VOID
  164. );
  165. #define RdrpUninitializeFsp( ) { \
  166. RdrUninitializeWorkQueue(&RdrDeviceObject->IrpWorkQueue); \
  167. RdrUninitializeIrpContext(); \
  168. }
  169. //
  170. // Other redirector routines
  171. //
  172. //PWORK_HEADER
  173. //RdrFspDequeueThreadWorker(
  174. // IN PWORK_QUEUE WorkQueue
  175. // );
  176. //NTSTATUS
  177. //RdrPostToIrpWorkerThread(
  178. // IN PWORK_HEADER WorkHeader
  179. // );
  180. PWORK_HEADER
  181. RdrFspDequeueIrp(
  182. VOID
  183. );
  184. NTSTATUS
  185. RdrQueueToWorkerThread(
  186. PWORK_QUEUE WorkQueue,
  187. PWORK_ITEM Entry,
  188. BOOLEAN NotifyScavenger
  189. );
  190. PWORK_ITEM
  191. RdrDequeueInWorkerThread (
  192. PWORK_QUEUE WorkQueue,
  193. PBOOLEAN FirstCall
  194. );
  195. NTSTATUS
  196. RdrInitializeWorkQueue(
  197. IN PWORK_QUEUE WorkQueue,
  198. IN ULONG MaximumNumberOfThreads,
  199. IN ULONG WorkThreadIdleLimit,
  200. IN PKSTART_ROUTINE StartRoutine,
  201. IN PVOID StartContext
  202. );
  203. VOID
  204. RdrUninitializeWorkQueue(
  205. IN PWORK_QUEUE WorkQueue
  206. );
  207. // NTSTATUS
  208. // RdrSetMaximumThreadsWorkQueue(
  209. // IN PWORK_QUEUE WorkQueue,
  210. // IN ULONG MaximumNumberOfThreads
  211. // );
  212. #define RdrSetMaximumThreadsWorkQueue( _WorkQueue, _MaximumNumberOfThreads ) \
  213. (_WorkQueue)->MaximumThreads = (_MaximumNumberOfThreads);
  214. VOID
  215. RdrSpinUpWorkQueue (
  216. IN PWORK_QUEUE WorkQueue
  217. );
  218. VOID
  219. RdrCancelQueuedIrpsForFile (
  220. IN PFILE_OBJECT FileObject,
  221. IN PWORK_QUEUE WorkQueue
  222. );
  223. VOID
  224. RdrCancelQueuedIrp (
  225. IN PDEVICE_OBJECT DeviceObject,
  226. IN PIRP Irp
  227. );
  228. PIRP_CONTEXT
  229. RdrAllocateIrpContext(
  230. VOID
  231. );
  232. //VOID
  233. //RdrFreeIrpContext(
  234. // PIRP_CONTEXT IrpContext
  235. // );
  236. #define RdrFreeIrpContext(_irpcontext) \
  237. ExInterlockedInsertTailList(&IrpContextList, (PLIST_ENTRY)(_irpcontext), \
  238. &IrpContextInterlock)
  239. #define RdrInitializeIrpContext( ) { \
  240. KeInitializeSpinLock(&IrpContextInterlock); \
  241. InitializeListHead(&IrpContextList); \
  242. }
  243. #define RdrUninitializeIrpContext( ) \
  244. while (!IsListEmpty(&IrpContextList)) { \
  245. PIRP_CONTEXT IrpContext = (PIRP_CONTEXT)RemoveHeadList(&IrpContextList); \
  246. FREE_POOL(IrpContext); \
  247. } \
  248. VOID
  249. RdrQueueWorkItem(
  250. IN PWORK_QUEUE_ITEM WorkItem,
  251. IN WORK_QUEUE_TYPE QueueType
  252. );
  253. VOID
  254. RdrpInitializeWorkQueue(
  255. VOID
  256. );
  257. #endif // _FSPDISP_