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.

401 lines
8.9 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (c) Microsoft Corporation 1992 - 1996
  6. //
  7. // File: kerblist.cxx
  8. //
  9. // Contents: Common list code for the Kerberos package
  10. //
  11. //
  12. // History: 16-April-1996 Created MikeSw
  13. // 26-Sep-1998 ChandanS
  14. // Added more debugging support etc.
  15. // 03-May-1999 ChandanS
  16. // Changes from code review
  17. //
  18. //------------------------------------------------------------------------
  19. #include <kerb.hxx>
  20. #include <kerbp.h>
  21. #if DBG
  22. static TCHAR THIS_FILE[]=TEXT(__FILE__);
  23. #endif
  24. //+-------------------------------------------------------------------------
  25. //
  26. // Function: KerbInitializeList
  27. //
  28. // Synopsis: Initializes a kerberos list by initializing the lock
  29. // and the list entry.
  30. //
  31. // Effects:
  32. //
  33. // Arguments: List - List to initialize
  34. // Enum - lock's ordinal number for safe locking
  35. //
  36. // Requires:
  37. //
  38. // Returns: STATUS_SUCCESS on success or errors from
  39. // RtlInitializeResources
  40. //
  41. // Notes:
  42. //
  43. //
  44. //--------------------------------------------------------------------------
  45. #if DBG
  46. NTSTATUS
  47. KerbSafeInitializeList(
  48. IN PKERBEROS_LIST List,
  49. IN DWORD Enum
  50. )
  51. #else
  52. NTSTATUS
  53. KerbSafeInitializeList(
  54. IN PKERBEROS_LIST List
  55. )
  56. #endif
  57. {
  58. NTSTATUS Status = STATUS_SUCCESS;
  59. InitializeListHead(&List->List);
  60. Status = SafeInitializeCriticalSection(
  61. &List->Lock,
  62. Enum
  63. );
  64. return(Status);
  65. }
  66. //+-------------------------------------------------------------------------
  67. //
  68. // Function: KerbFreeList
  69. //
  70. // Synopsis: Frees a kerberos list by deleting the associated
  71. // critical section.
  72. //
  73. // Effects: List - the list to free.
  74. //
  75. // Arguments:
  76. //
  77. // Requires:
  78. //
  79. // Returns: none
  80. //
  81. // Notes: The list must be empty before freeing it.
  82. //
  83. //
  84. //--------------------------------------------------------------------------
  85. VOID
  86. KerbFreeList(
  87. IN PKERBEROS_LIST List
  88. )
  89. {
  90. //
  91. // Make sure the list is empty first
  92. //
  93. // if (IsListEmpty(&List->List))
  94. // {
  95. // RtlDeleteCriticalSection(&List->Lock);
  96. // }
  97. // else
  98. // {
  99. // DsysAssert(FALSE);
  100. // }
  101. }
  102. //+-------------------------------------------------------------------------
  103. //
  104. // Function: KerbInitializeListEntry
  105. //
  106. // Synopsis: Initializes a newly created list entry for later
  107. // insertion onto the list.
  108. //
  109. // Effects: The reference count is set to one and the links are set
  110. // to NULL.
  111. //
  112. // Arguments: ListEntry - the list entry to initialize
  113. //
  114. // Requires:
  115. //
  116. // Returns: none
  117. //
  118. // Notes:
  119. //
  120. //
  121. //--------------------------------------------------------------------------
  122. VOID
  123. KerbInitializeListEntry(
  124. IN OUT PKERBEROS_LIST_ENTRY ListEntry
  125. )
  126. {
  127. ListEntry->ReferenceCount = 1;
  128. ListEntry->Next.Flink = ListEntry->Next.Blink = NULL;
  129. }
  130. //+-------------------------------------------------------------------------
  131. //
  132. // Function: KerbInsertListEntry
  133. //
  134. // Synopsis: Inserts an entry into a kerberos list
  135. //
  136. // Effects: increments the reference count on the entry - if the
  137. // list entry was formly referenced it remains referenced.
  138. //
  139. // Arguments: ListEntry - the entry to insert
  140. // List - the list in which to insert the ListEntry
  141. //
  142. // Requires:
  143. //
  144. // Returns: nothing
  145. //
  146. // Notes:
  147. //
  148. //
  149. //--------------------------------------------------------------------------
  150. VOID
  151. KerbInsertListEntry(
  152. IN PKERBEROS_LIST_ENTRY ListEntry,
  153. IN PKERBEROS_LIST List
  154. )
  155. {
  156. ListEntry->ReferenceCount++;
  157. SafeEnterCriticalSection(&List->Lock);
  158. KerbValidateList(List);
  159. InsertHeadList(
  160. &List->List,
  161. &ListEntry->Next
  162. );
  163. KerbValidateList(List);
  164. SafeLeaveCriticalSection(&List->Lock);
  165. }
  166. //+-------------------------------------------------------------------------
  167. //
  168. // Function: KerbInsertListEntryTail
  169. //
  170. // Synopsis: Inserts an entry into a kerberos list at the end
  171. //
  172. // Effects: increments the reference count on the entry - if the
  173. // list entry was formly referenced it remains referenced.
  174. //
  175. // Arguments: ListEntry - the entry to insert
  176. // List - the list in which to insert the ListEntry
  177. //
  178. // Requires:
  179. //
  180. // Returns: nothing
  181. //
  182. // Notes:
  183. //
  184. //
  185. //--------------------------------------------------------------------------
  186. VOID
  187. KerbInsertListEntryTail(
  188. IN PKERBEROS_LIST_ENTRY ListEntry,
  189. IN PKERBEROS_LIST List
  190. )
  191. {
  192. ListEntry->ReferenceCount++;
  193. SafeEnterCriticalSection(&List->Lock);
  194. KerbValidateList(List);
  195. InsertTailList(
  196. &List->List,
  197. &ListEntry->Next
  198. );
  199. KerbValidateList(List);
  200. SafeLeaveCriticalSection(&List->Lock);
  201. }
  202. //+-------------------------------------------------------------------------
  203. //
  204. // Function: KerbReferenceListEntry
  205. //
  206. // Synopsis: References a list entry. If the flag RemoveFromList
  207. // has been specified, the entry is unlinked from the
  208. // list.
  209. //
  210. // Effects: bumps the reference count on the entry (unless it is
  211. // being removed from the list)
  212. //
  213. // Arguments:
  214. //
  215. // Requires: The list must be locked when calling this routine
  216. //
  217. // Returns:
  218. //
  219. // Notes:
  220. //
  221. //
  222. //--------------------------------------------------------------------------
  223. VOID
  224. KerbReferenceListEntry(
  225. IN PKERBEROS_LIST List,
  226. IN PKERBEROS_LIST_ENTRY ListEntry,
  227. IN BOOLEAN RemoveFromList
  228. )
  229. {
  230. KerbValidateList(List);
  231. //
  232. // If it has already been removed from the list
  233. // don't do it again.
  234. //
  235. if (RemoveFromList && ((ListEntry->Next.Flink != NULL) &&
  236. (ListEntry->Next.Blink != NULL)))
  237. {
  238. RemoveEntryList(&ListEntry->Next);
  239. ListEntry->Next.Flink = NULL;
  240. ListEntry->Next.Blink = NULL;
  241. }
  242. else if ((ListEntry->Next.Flink !=NULL) && (ListEntry->Next.Blink != NULL))
  243. {
  244. RemoveEntryList( &ListEntry->Next );
  245. InsertHeadList(
  246. &List->List,
  247. &ListEntry->Next
  248. );
  249. ListEntry->ReferenceCount++;
  250. }
  251. else
  252. {
  253. //
  254. // This is valid since several callers may have gotten a valid list
  255. // entry and may want to delete it indepenently for whatever reason.
  256. //
  257. ListEntry->ReferenceCount++;
  258. }
  259. KerbValidateList(List);
  260. }
  261. //+-------------------------------------------------------------------------
  262. //
  263. // Function: KerbDereferenceListEntry
  264. //
  265. // Synopsis: Dereferences a list entry and returns a flag indicating
  266. // whether the entry should be freed.
  267. //
  268. // Effects: decrements reference count on list entry
  269. //
  270. // Arguments: ListEntry - the list entry to dereference
  271. // List - the list containing the list entry
  272. //
  273. // Requires:
  274. //
  275. // Returns: TRUE - the list entry should be freed
  276. // FALSE - the list entry is still referenced
  277. //
  278. // Notes:
  279. //
  280. //
  281. //--------------------------------------------------------------------------
  282. BOOLEAN
  283. KerbDereferenceListEntry(
  284. IN PKERBEROS_LIST_ENTRY ListEntry,
  285. IN PKERBEROS_LIST List
  286. )
  287. {
  288. BOOLEAN DeleteEntry = FALSE;
  289. SafeEnterCriticalSection(&List->Lock);
  290. KerbValidateList(List);
  291. ListEntry->ReferenceCount -= 1;
  292. if (ListEntry->ReferenceCount == 0)
  293. {
  294. DeleteEntry = TRUE;
  295. }
  296. KerbValidateList(List);
  297. SafeLeaveCriticalSection(&List->Lock);
  298. return(DeleteEntry);
  299. }
  300. #if DBG
  301. //+-------------------------------------------------------------------------
  302. //
  303. // Function: KerbValidateListEx
  304. //
  305. // Synopsis: Validates that a list is valid
  306. //
  307. // Effects: traverses a list to make sure it is has no loops
  308. //
  309. // Arguments: List - The list to validate
  310. //
  311. // Requires:
  312. //
  313. // Returns: none
  314. //
  315. // Notes: This routine assumes there are less than 50000 entries
  316. // in the list.
  317. //
  318. //
  319. //--------------------------------------------------------------------------
  320. VOID
  321. KerbValidateListEx(
  322. IN PKERBEROS_LIST List
  323. )
  324. {
  325. ULONG Entries = 0;
  326. PLIST_ENTRY ListEntry;
  327. for (ListEntry = List->List.Flink ;
  328. ListEntry != &List->List ;
  329. ListEntry = ListEntry->Flink )
  330. {
  331. if (++Entries > 50000) {
  332. DebugLog((DEB_ERROR,"List 0x%x is looping - more than 50,000 entries found. %ws, line %d\n", List, THIS_FILE, __LINE__));
  333. DbgBreakPoint();
  334. break;
  335. }
  336. }
  337. }
  338. #endif // DBG