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.

375 lines
8.3 KiB

  1. // Copyright (c) 1997-2002 Microsoft Corporation
  2. //
  3. // Module:
  4. //
  5. // common utility
  6. //
  7. // Abstract:
  8. //
  9. // NT list api wrapper.
  10. //
  11. // The NT list API is a very efficient and robust list API because:
  12. //
  13. // a) all operations are guarenteed to succeed in constant time without
  14. // any branch instructions
  15. //
  16. // b) memory is used in an optimum way since LIST_ENTRY structures
  17. // are embedded into the objects stored in the list. This means
  18. // that the heap does not get fragmented with list nodes. It also
  19. // allows entries to be removed/transferred/moved without ever
  20. // having to free or reallocate a list node.
  21. //
  22. // One drawback to the NT list API is that it comes with a learning curve
  23. // for most people.
  24. //
  25. // This header defines a wrapper of the NT list API to:
  26. //
  27. // - Allow for easy instrumentation. Modules that use this API can be
  28. // specially purposed to store state with the lists, nodes, etc.
  29. //
  30. // - Clarify the NT list API by separating the concept of a list from
  31. // a node in a list. Although both are LIST_ENTRY's in the NT list
  32. // API, there are subtle differences. For example, the head
  33. // of a list is not embedded into any other structure the way the
  34. // entries in a list are.
  35. //
  36. // Author:
  37. //
  38. // pmay 3-Apr-2002
  39. //
  40. // Environment:
  41. //
  42. // Kernel/user mode
  43. //
  44. // Revision History:
  45. //
  46. #pragma once
  47. #ifndef NSULIST_H
  48. #define NSULIST_H
  49. #include "Nsu.h"
  50. #ifdef __cplusplus
  51. extern "C" {
  52. #endif
  53. typedef LIST_ENTRY NSU_LIST_ENTRY;
  54. typedef PLIST_ENTRY PNSU_LIST_ENTRY;
  55. typedef LIST_ENTRY NSU_LIST;
  56. typedef PLIST_ENTRY PNSU_LIST;
  57. typedef struct _NSU_LIST_ITERATOR
  58. {
  59. PNSU_LIST pList;
  60. PNSU_LIST_ENTRY pCurrentEntry;
  61. } NSU_LIST_ITERATOR, * PNSU_LIST_ITERATOR;
  62. // Description:
  63. //
  64. // API's to manipulate lists
  65. //
  66. VOID
  67. FORCEINLINE
  68. NsuListInitialize(
  69. OUT PNSU_LIST pList)
  70. {
  71. InitializeListHead(pList);
  72. }
  73. BOOL
  74. FORCEINLINE
  75. NsuListIsEmpty(
  76. IN PNSU_LIST pList)
  77. {
  78. return IsListEmpty(pList);
  79. }
  80. PNSU_LIST_ENTRY
  81. FORCEINLINE
  82. NsuListGetFront(
  83. IN PNSU_LIST pList)
  84. {
  85. return pList->Flink;
  86. }
  87. PNSU_LIST_ENTRY
  88. FORCEINLINE
  89. NsuListGetBack(
  90. IN PNSU_LIST pList)
  91. {
  92. return pList->Blink;
  93. }
  94. VOID
  95. FORCEINLINE
  96. NsuListInsertFront(
  97. IN PNSU_LIST pList,
  98. PNSU_LIST_ENTRY pEntry)
  99. {
  100. InsertHeadList(pList, pEntry);
  101. }
  102. VOID
  103. FORCEINLINE
  104. NsuListInsertBack(
  105. IN PNSU_LIST pList,
  106. PNSU_LIST_ENTRY pEntry)
  107. {
  108. InsertTailList(pList, pEntry);
  109. }
  110. PNSU_LIST_ENTRY
  111. FORCEINLINE
  112. NsuListRemoveFront(
  113. IN PNSU_LIST pList)
  114. {
  115. PNSU_LIST_ENTRY pEntry;
  116. if (IsListEmpty(pList))
  117. {
  118. return NULL;
  119. }
  120. pEntry = pList->Flink;
  121. RemoveEntryList(pEntry);
  122. InitializeListHead(pEntry);
  123. return pEntry;
  124. }
  125. PNSU_LIST_ENTRY
  126. FORCEINLINE
  127. NsuListRemoveBack(
  128. IN PNSU_LIST pList)
  129. {
  130. PNSU_LIST_ENTRY pEntry;
  131. if (IsListEmpty(pList))
  132. {
  133. return NULL;
  134. }
  135. pEntry = pList->Blink;
  136. RemoveEntryList(pEntry);
  137. InitializeListHead(pEntry);
  138. return pEntry;
  139. }
  140. // Description:
  141. //
  142. // API's to manipulate entries (nodes) in a list
  143. //
  144. #define NsuListEntryGetData(Address, Type, Field) \
  145. CONTAINING_RECORD(Address, Type, Field)
  146. VOID
  147. FORCEINLINE
  148. NsuListEntryInitialize(
  149. OUT PNSU_LIST_ENTRY pEntry)
  150. {
  151. InitializeListHead(pEntry);
  152. }
  153. BOOL
  154. FORCEINLINE
  155. NsuListEntryIsMember(
  156. IN PNSU_LIST_ENTRY pEntry)
  157. {
  158. return IsListEmpty(pEntry);
  159. }
  160. VOID
  161. FORCEINLINE
  162. NsuListEntryRemove(
  163. IN PNSU_LIST_ENTRY pEntry)
  164. {
  165. RemoveEntryList(pEntry);
  166. InitializeListHead(pEntry);
  167. }
  168. VOID
  169. FORCEINLINE
  170. NsuListEntryInsertBefore(
  171. IN PNSU_LIST_ENTRY pEntryInList,
  172. IN PNSU_LIST_ENTRY pEntryToInsert)
  173. {
  174. InsertTailList(pEntryInList, pEntryToInsert);
  175. }
  176. VOID
  177. FORCEINLINE
  178. NsuListEntryInsertAfter(
  179. IN PNSU_LIST_ENTRY pEntryInList,
  180. IN PNSU_LIST_ENTRY pEntryToInsert)
  181. {
  182. InsertHeadList(pEntryInList, pEntryToInsert);
  183. }
  184. // Description:
  185. //
  186. // API's to iterate over lists
  187. //
  188. // Sample for using the iterator (includes removing during iteration):
  189. //
  190. // NSU_LIST List;
  191. // NSU_LIST_ITERATOR Iterator;
  192. // NSU_LIST_ENTRY* pEntry;
  193. //
  194. // NsuListIteratorInitialize(&Iterator, &List, NULL);
  195. // while ( !NsuListIteratorAtEnd(&Iterator) )
  196. // {
  197. // pEntry = NsuListIteratorCurrent(&Iterator))
  198. // pData = NsuListEntryGetData(pEntry, Type, Field);
  199. //
  200. // NsuListIteratorNext(&Iterator); // advance before any removing
  201. //
  202. // if (NeedToRemove(pData))
  203. // {
  204. // NsuListEntryRemove(pEntry);
  205. // }
  206. // }
  207. //
  208. VOID
  209. FORCEINLINE
  210. NsuListIteratorInitialize(
  211. OUT PNSU_LIST_ITERATOR pIterator,
  212. IN PNSU_LIST pList,
  213. IN OPTIONAL PNSU_LIST_ENTRY pEntryInList) // NULL = start at front
  214. {
  215. pIterator->pList = pList;
  216. pIterator->pCurrentEntry = (pEntryInList) ? pEntryInList : pList->Flink;
  217. }
  218. BOOL
  219. FORCEINLINE
  220. NsuListIteratorAtEnd(
  221. IN PNSU_LIST_ITERATOR pIterator)
  222. {
  223. return (pIterator->pList == pIterator->pCurrentEntry);
  224. }
  225. PNSU_LIST_ENTRY
  226. FORCEINLINE
  227. NsuListIteratorCurrent(
  228. IN PNSU_LIST_ITERATOR pIterator)
  229. {
  230. return pIterator->pCurrentEntry;
  231. }
  232. VOID
  233. FORCEINLINE
  234. NsuListIteratorReset(
  235. IN PNSU_LIST_ITERATOR pIterator)
  236. {
  237. pIterator->pCurrentEntry = pIterator->pList->Flink;
  238. }
  239. VOID
  240. FORCEINLINE
  241. NsuListIteratorNext(
  242. IN PNSU_LIST_ITERATOR pIterator)
  243. {
  244. pIterator->pCurrentEntry = pIterator->pCurrentEntry->Flink;
  245. }
  246. VOID
  247. FORCEINLINE
  248. NsuListIteratorPrev(
  249. IN PNSU_LIST_ITERATOR pIterator)
  250. {
  251. pIterator->pCurrentEntry = pIterator->pCurrentEntry->Blink;
  252. }
  253. // This wrapper does not work correctly in all cases and needs to be fixed. For now just
  254. // use the C versions of everything
  255. /*
  256. // Description:
  257. //
  258. // C++ List api wrapper
  259. //
  260. #ifdef __cplusplus
  261. class NsuListEntry
  262. {
  263. public:
  264. NsuListEntry() { NsuListEntryInitialize(&m_Entry); }
  265. ~NsuListEntry() { RtlZeroMemory(&m_Entry, sizeof(m_Entry)); }
  266. PNSU_LIST_ENTRY Get() { return &m_Entry; }
  267. VOID Set(PNSU_LIST_ENTRY pEntry) { m_Entry = *pEntry; }
  268. BOOL IsMember() { return NsuListEntryIsMember(Get()); }
  269. VOID Remove() { return NsuListEntryRemove(&m_Entry); }
  270. VOID InsertBefore(NsuListEntry* pSrc) { return NsuListEntryInsertBefore((PNSU_LIST_ENTRY)pSrc, &m_Entry); }
  271. VOID InsertAfter(NsuListEntry* pSrc) { return NsuListEntryInsertAfter((PNSU_LIST_ENTRY)pSrc, &m_Entry); }
  272. private:
  273. NSU_LIST_ENTRY m_Entry;
  274. };
  275. class NsuList
  276. {
  277. public:
  278. NsuList() { NsuListInitialize(&m_Head); }
  279. PNSU_LIST Get() { return &m_Head; }
  280. PNSU_LIST GetFront(NsuListEntry& lEntry) { return NsuListGetFront(&m_Head); }
  281. PNSU_LIST GetBack(NsuListEntry& lEntry) { return NsuListGetBack(&m_Head); }
  282. VOID RemoveFront(OUT OPTIONAL NsuListEntry* pEntry) { pEntry = (NsuListEntry*)NsuListRemoveFront(&m_Head); }
  283. VOID RemoveBack(OUT OPTIONAL NsuListEntry* pEntry) { pEntry = (NsuListEntry*)NsuListRemoveBack(&m_Head); }
  284. VOID InsertFront(NsuListEntry* pEntry) { NsuListInsertFront(&m_Head, (PNSU_LIST_ENTRY)pEntry); }
  285. VOID InsertBack(NsuListEntry* pEntry) { NsuListInsertBack(&m_Head, (PNSU_LIST_ENTRY)pEntry); }
  286. VOID MoveToFront(NsuListEntry* pEntry);
  287. VOID MoveToBack(NsuListEntry* pEntry);
  288. private:
  289. NSU_LIST m_Head;
  290. };
  291. class NsuListIterator
  292. {
  293. public:
  294. NsuListIterator(NsuList* pList);
  295. PNSU_LIST_ITERATOR Get() { return &m_Iterator; }
  296. VOID Reset() { return NsuListIteratorReset(&(NSU_LIST_ITERATOR)m_Iterator); }
  297. VOID Next() { NsuListIteratorNext(&(NSU_LIST_ITERATOR)m_Iterator); }
  298. VOID Prev() { NsuListIteratorPrev(&(NSU_LIST_ITERATOR)m_Iterator); }
  299. NsuListEntry* Current() { return (NsuListEntry*)NsuListIteratorCurrent(&(NSU_LIST_ITERATOR)m_Iterator); }
  300. BOOL AtEnd() { return NsuListIteratorAtEnd(&(NSU_LIST_ITERATOR)m_Iterator); }
  301. private:
  302. NSU_LIST_ITERATOR m_Iterator;
  303. };
  304. inline NsuListIterator::NsuListIterator(NsuList* pList)
  305. {
  306. NsuListIteratorInitialize(&(NSU_LIST_ITERATOR)m_Iterator, (PNSU_LIST)pList, 0);
  307. }
  308. #endif
  309. */
  310. #ifdef __cplusplus
  311. }
  312. #endif
  313. #endif // NSULIST_H