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.

354 lines
7.4 KiB

  1. /***************************************************************************
  2. Copyright (c) 2002 Microsoft Corporation
  3. Module Name:
  4. irplist.H
  5. Abstract:
  6. Private interface for Smartcard Driver Utility Library
  7. Environment:
  8. Kernel Mode Only
  9. Notes:
  10. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  11. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  12. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  13. PURPOSE.
  14. Copyright (c) 2001 Microsoft Corporation. All Rights Reserved.
  15. Revision History:
  16. 05/14/2002 : created
  17. Authors:
  18. Randy Aull
  19. ****************************************************************************/
  20. #ifndef __IRPLIST_H__
  21. #define __IRPLIST_H__
  22. typedef struct _LOCKED_LIST {
  23. LIST_ENTRY ListHead;
  24. KSPIN_LOCK SpinLock;
  25. PKSPIN_LOCK ListLock;
  26. LONG Count;
  27. } LOCKED_LIST, *PLOCKED_LIST;
  28. typedef BOOLEAN (*PFNLOCKED_LIST_PROCESS)(PVOID Context, PLIST_ENTRY ListEntry);
  29. #define INIT_LOCKED_LIST(l) \
  30. { \
  31. InitializeListHead(&(l)->ListHead); \
  32. KeInitializeSpinLock(&(l)->SpinLock); \
  33. (l)->ListLock = &(l)->SpinLock; \
  34. (l)->Count = 0; \
  35. }
  36. void
  37. LockedList_Init(
  38. PLOCKED_LIST LockedList,
  39. PKSPIN_LOCK ListLock
  40. );
  41. void
  42. LockedList_EnqueueHead(
  43. PLOCKED_LIST LockedList,
  44. PLIST_ENTRY ListEntry
  45. );
  46. void
  47. LockedList_EnqueueTail(
  48. PLOCKED_LIST LockedList,
  49. PLIST_ENTRY ListEntry
  50. );
  51. void
  52. LockedList_EnqueueAfter(
  53. PLOCKED_LIST LockedList,
  54. PLIST_ENTRY Entry,
  55. PLIST_ENTRY Location
  56. );
  57. PLIST_ENTRY
  58. LockedList_RemoveHead(
  59. PLOCKED_LIST LockedList
  60. );
  61. PLIST_ENTRY
  62. LockedList_RemoveEntryLocked(
  63. PLOCKED_LIST LockedList,
  64. PLIST_ENTRY Entry
  65. );
  66. PLIST_ENTRY
  67. LockedList_RemoveEntry(
  68. PLOCKED_LIST LockedList,
  69. PLIST_ENTRY Entry
  70. );
  71. LONG
  72. LockedList_GetCount(
  73. PLOCKED_LIST LockedList
  74. );
  75. LONG
  76. LockedList_Drain(
  77. PLOCKED_LIST LockedList,
  78. PLIST_ENTRY DrainListHead
  79. );
  80. BOOLEAN
  81. List_Process(
  82. PLIST_ENTRY ListHead,
  83. PFNLOCKED_LIST_PROCESS Process,
  84. PVOID ProcessContext
  85. );
  86. BOOLEAN
  87. LockedList_ProcessLocked(
  88. PLOCKED_LIST LockedList,
  89. PFNLOCKED_LIST_PROCESS Process,
  90. PVOID ProcessContext
  91. );
  92. BOOLEAN
  93. LockedList_Process(
  94. PLOCKED_LIST LockedList,
  95. BOOLEAN LockAtPassive,
  96. PFNLOCKED_LIST_PROCESS Process,
  97. PVOID ProcessContext
  98. );
  99. #define LL_LOCK(l, k) KeAcquireSpinLock((l)->ListLock, (k))
  100. #define LL_UNLOCK(l, k) KeReleaseSpinLock((l)->ListLock, (k))
  101. #define LL_LOCK_AT_DPC(l) KeAcquireSpinLockAtDpcLevel((l)->ListLock)
  102. #define LL_UNLOCK_FROM_DPC(l) KeReleaseSpinLockFromDpcLevel((l)->ListLock)
  103. #define LL_GET_COUNT(l) (l)->Count
  104. #define LL_ADD_TAIL(l, e) \
  105. { \
  106. InsertTailList(&(l)->ListHead, (e));\
  107. (l)->Count++; \
  108. }
  109. #define LL_ADD_TAIL_REF(l, e, r) \
  110. { \
  111. LL_ADD_TAIL(l, e); \
  112. RefObj_AddRef(r); \
  113. }
  114. #define LL_ADD_HEAD(l, e) \
  115. { \
  116. InsertHeadList(&(l)->ListHead, (e));\
  117. (l)->Count++; \
  118. }
  119. #define LL_ADD_HEAD_REF(l, e, r) \
  120. { \
  121. LL_ADD_HEAD(l, e); \
  122. RefObj_AddRef(r); \
  123. }
  124. #define LL_REMOVE_HEAD(l) RemoveHeadList(&(l)->ListHead); (l)->Count--
  125. #define LL_REMOVE_TAIL(l) RemoveTailList(&(l)->ListHead); (l)->Count--
  126. #define IRP_LIST_INDEX (3)
  127. typedef
  128. NTSTATUS
  129. (*PIRP_COMPLETION_ROUTINE) (
  130. IN PDEVICE_OBJECT DeviceObject,
  131. IN PIRP Irp,
  132. IN NTSTATUS Status
  133. );
  134. typedef struct _IRP_LIST {
  135. LOCKED_LIST LockedList;
  136. PDRIVER_CANCEL CancelRoutine;
  137. //
  138. // Routiune to call from the CancelRoutine when the IRP is cancelled
  139. //
  140. PIRP_COMPLETION_ROUTINE IrpCompletionRoutine;
  141. //
  142. // IRP_LIST assumes that the remove lock logic is done outside of enqueue /
  143. // dequeue / cancel because the caller of XXX_Enqueue will have no way of
  144. // knowing if the remlock was acquired if it returns !NT_SUCCESS()
  145. //
  146. // PIO_REMOVE_LOCK IoRemoveLock;
  147. } IRP_LIST, *PIRP_LIST;
  148. #define IRP_LIST_FROM_IRP(irp) \
  149. (PIRP_LIST) ((irp)->Tail.Overlay.DriverContext[IRP_LIST_INDEX])
  150. //
  151. // void
  152. // IrpList_Init(
  153. // PIRP_LIST IrpList,
  154. // PDRIVER_CANCEL CancelRoutine,
  155. // PIRP_COMPLETION_ROUTINE IrpCompletionRoutine
  156. // );
  157. //
  158. #define IrpList_Init(i, c, r) IrpList_InitEx(i, &(i)->LockedList.SpinLock, c, r)
  159. void
  160. IrpList_InitEx(
  161. PIRP_LIST IrpList,
  162. PKSPIN_LOCK ListLock,
  163. PDRIVER_CANCEL CancelRoutine,
  164. PIRP_COMPLETION_ROUTINE IrpCompletionRoutine
  165. );
  166. //
  167. // Return values:
  168. // STATUS_PENDING: Irp has been enqueued (not the current irp) and cannot be
  169. // touched
  170. //
  171. // !NT_SUCCESS(status): (includes STATUS_CANCELLED) Remove lock could not be
  172. // acquired or the Irp was cancelled, complete the IRP
  173. //
  174. NTSTATUS
  175. IrpList_EnqueueEx(
  176. PIRP_LIST IrpList,
  177. PIRP Irp,
  178. BOOLEAN StoreListInIrp
  179. );
  180. //
  181. // NTSTATUS
  182. // IrpList_Enqueue(
  183. // PIRP_LIST IrpList,
  184. // PIRP Irp
  185. // );
  186. //
  187. #define IrpList_Enqueue(list, irp) \
  188. IrpList_EnqueueEx(list, irp, TRUE)
  189. //
  190. // IrpList_IsEmptyLocked(PIRP_LIST list)
  191. //
  192. // Returns TRUE or FALSE
  193. //
  194. #define IrpList_IsEmptyLocked(list) \
  195. ((list)->LockedList.ListHead.Flink == (&(list)->LockedList.ListHead))
  196. //
  197. // Enqueue an irp while the IRP_LIST's spin lock is being held. This function
  198. // will not use the remove lock to acquire or release the irp. Same return
  199. // values as IrpList_EnqueueEx.
  200. //
  201. NTSTATUS
  202. IrpList_EnqueueLocked(
  203. PIRP_LIST IrpList,
  204. PIRP Irp,
  205. BOOLEAN StoreListInIrp,
  206. BOOLEAN InsertTail
  207. );
  208. PIRP
  209. IrpList_Dequeue(
  210. PIRP_LIST IrpList
  211. );
  212. PIRP
  213. IrpList_DequeueLocked(
  214. PIRP_LIST IrpList
  215. );
  216. BOOLEAN
  217. IrpList_DequeueIrpLocked(
  218. PIRP_LIST IrpList,
  219. PIRP Irp
  220. );
  221. BOOLEAN
  222. IrpList_DequeueIrp(
  223. PIRP_LIST IrpList,
  224. PIRP Irp
  225. );
  226. typedef
  227. BOOLEAN
  228. (*PFNPROCESSIRP)(
  229. PVOID Context,
  230. PIRP Irp
  231. );
  232. ULONG
  233. IrpList_ProcessAndDrainLocked(
  234. PIRP_LIST IrpList,
  235. PFNPROCESSIRP FnProcessIrp,
  236. PVOID Context,
  237. PLIST_ENTRY DrainHead
  238. );
  239. ULONG
  240. IrpList_ProcessAndDrain(
  241. PIRP_LIST IrpList,
  242. PFNPROCESSIRP FnProcessIrp,
  243. PVOID Context,
  244. PLIST_ENTRY DrainHead
  245. );
  246. ULONG
  247. IrpList_ProcessAndDrainLocked(
  248. PIRP_LIST IrpList,
  249. PFNPROCESSIRP FnProcessIrp,
  250. PVOID Context,
  251. PLIST_ENTRY DrainHead
  252. );
  253. ULONG
  254. IrpList_Drain(
  255. PIRP_LIST IrpList,
  256. PLIST_ENTRY DrainHead
  257. );
  258. ULONG
  259. IrpList_DrainLocked(
  260. PIRP_LIST IrpList,
  261. PLIST_ENTRY DrainHead
  262. );
  263. ULONG
  264. IrpList_DrainLockedByFileObject(
  265. PIRP_LIST IrpList,
  266. PLIST_ENTRY DrainHead,
  267. PFILE_OBJECT FileObject
  268. );
  269. void
  270. IrpList_HandleCancel(
  271. PIRP_LIST IrpList,
  272. PDEVICE_OBJECT DeviceObject,
  273. PIRP Irp
  274. );
  275. void
  276. IrpList_CancelRoutine(
  277. PDEVICE_OBJECT DeviceObject,
  278. PIRP Irp
  279. );
  280. #endif