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.

362 lines
6.2 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 1999
  3. Module Name:
  4. linklist.cxx
  5. Abstract:
  6. Implements a linked list for Destination Reachability.
  7. Author:
  8. Gopal Parupudi <GopalP>
  9. [Notes:]
  10. optional-notes
  11. Revision History:
  12. GopalP 10/30/1997 Start.
  13. --*/
  14. #include <precomp.hxx>
  15. #define WCHAR_Y ((WCHAR) 'Y')
  16. #define WCHAR_N ((WCHAR) 'N')
  17. #define WCHAR_X ((WCHAR) '-')
  18. NODE::NODE()
  19. {
  20. Next = NULL;
  21. Prev = NULL;
  22. Destination = NULL;
  23. SubId = ~0;
  24. cRef = 1;
  25. State = UNTRIED;
  26. }
  27. NODE::NODE(DWORD Id, PWCHAR Dest, PDWORD pdwStatus)
  28. {
  29. *pdwStatus = ERROR_SUCCESS;
  30. Next = NULL;
  31. Prev = NULL;
  32. // Make a copy of the Destination name
  33. size_t size = wcslen(Dest) + 1;
  34. Destination = (PWCHAR) new WCHAR[size];
  35. if (Destination != NULL)
  36. {
  37. StringCchCopyW(Destination, size, Dest);
  38. }
  39. else
  40. {
  41. *pdwStatus = ERROR_OUTOFMEMORY;
  42. }
  43. SubId = Id;
  44. cRef = 1;
  45. State = UNTRIED;
  46. }
  47. NODE::~NODE()
  48. {
  49. if (Destination != NULL)
  50. {
  51. delete Destination;
  52. }
  53. }
  54. LIST::LIST()
  55. {
  56. pHead = NULL;
  57. cElements = 0;
  58. InitializeCriticalSection(&ListLock);
  59. }
  60. LIST::~LIST()
  61. {
  62. DeleteAll();
  63. DeleteCriticalSection(&ListLock);
  64. }
  65. DWORD
  66. LIST::Insert(
  67. PNODE pNew
  68. )
  69. {
  70. ASSERT(pNew != NULL);
  71. ASSERT(pNew->Destination != NULL);
  72. RequestLock();
  73. //
  74. // See if it is already present. Find() will add a reference to the
  75. // destination if it is already present in the list.
  76. //
  77. if (NULL != Find(pNew->Destination, TRUE))
  78. {
  79. ReleaseLock();
  80. Print();
  81. return ERROR_ALREADY_EXISTS;
  82. }
  83. pNew->Next = pHead;
  84. if (pHead != NULL)
  85. {
  86. pHead->Prev = pNew;
  87. }
  88. pHead = pNew;
  89. cElements++;
  90. ReleaseLock();
  91. Print();
  92. return ERROR_SUCCESS;
  93. }
  94. DWORD
  95. LIST::InsertByDest(
  96. PWCHAR lpszDest
  97. )
  98. {
  99. DWORD dwStatus = ERROR_SUCCESS;
  100. PNODE pNode = NULL;
  101. // Insert into the global list
  102. pNode = new NODE(99, lpszDest, &dwStatus);
  103. if ( (dwStatus != ERROR_SUCCESS)
  104. || (pNode == NULL))
  105. {
  106. if (pNode)
  107. {
  108. delete pNode;
  109. }
  110. return ERROR_OUTOFMEMORY;
  111. }
  112. dwStatus = Insert(pNode);
  113. if (ERROR_ALREADY_EXISTS == dwStatus)
  114. {
  115. delete pNode;
  116. }
  117. return dwStatus;
  118. }
  119. inline void
  120. LIST::Delete(
  121. PNODE pDelete
  122. )
  123. {
  124. // Should be always called with the ListLock held.
  125. if (0 != pDelete->Release())
  126. {
  127. Print();
  128. return;
  129. }
  130. if (pDelete->Next != NULL)
  131. {
  132. pDelete->Next->Prev = pDelete->Prev;
  133. }
  134. if (pDelete->Prev != NULL)
  135. {
  136. pDelete->Prev->Next = pDelete->Next;
  137. }
  138. if (pDelete == pHead)
  139. {
  140. pHead = pDelete->Next;
  141. }
  142. delete pDelete;
  143. cElements--;
  144. Print();
  145. }
  146. BOOL
  147. LIST::DeleteByDest(
  148. PWCHAR lpszDest
  149. )
  150. {
  151. PNODE pTemp = NULL;
  152. RequestLock();
  153. pTemp = pHead;
  154. while (pTemp != NULL)
  155. {
  156. if (wcscmp(pTemp->Destination, lpszDest) == 0)
  157. {
  158. Delete(pTemp);
  159. ReleaseLock();
  160. return TRUE;
  161. }
  162. pTemp = pTemp->Next;
  163. }
  164. ReleaseLock();
  165. return FALSE;
  166. }
  167. BOOL
  168. LIST::DeleteById(
  169. DWORD Id
  170. )
  171. {
  172. PNODE pTemp = NULL;
  173. RequestLock();
  174. pTemp = pHead;
  175. while (pTemp != NULL)
  176. {
  177. if (pTemp->SubId == Id)
  178. {
  179. Delete(pTemp);
  180. ReleaseLock();
  181. return TRUE;
  182. }
  183. pTemp = pTemp->Next;
  184. }
  185. ReleaseLock();
  186. return FALSE;
  187. }
  188. void
  189. LIST::DeleteAll(
  190. void
  191. )
  192. {
  193. PNODE pTemp, pDelete;
  194. RequestLock();
  195. pTemp = pHead;
  196. while (pTemp != NULL)
  197. {
  198. pDelete = pTemp;
  199. pTemp = pTemp->Next;
  200. delete pDelete;
  201. cElements--;
  202. }
  203. ASSERT(cElements == 0);
  204. ReleaseLock();
  205. }
  206. PNODE
  207. LIST::Find(
  208. PWCHAR lpszDest,
  209. BOOL bAddReference
  210. )
  211. {
  212. PNODE pTemp = NULL;
  213. RequestLock();
  214. pTemp = pHead;
  215. while (pTemp != NULL)
  216. {
  217. if (wcscmp(pTemp->Destination, lpszDest) == 0)
  218. {
  219. if (TRUE == bAddReference)
  220. {
  221. pTemp->AddRef();
  222. }
  223. ReleaseLock();
  224. return pTemp;
  225. }
  226. pTemp = pTemp->Next;
  227. }
  228. ReleaseLock();
  229. return NULL;
  230. }
  231. BOOL
  232. LIST::IsEmpty(
  233. void
  234. )
  235. {
  236. RequestLock();
  237. if (pHead == NULL)
  238. {
  239. ASSERT(cElements == 0);
  240. ReleaseLock();
  241. return TRUE;
  242. }
  243. ReleaseLock();
  244. return FALSE;
  245. }
  246. void
  247. LIST::Print(
  248. void
  249. )
  250. {
  251. #ifdef DBG
  252. PNODE pTemp;
  253. SensPrintA(SENS_INFO, ("\n\t|----------------------------------------------------------|\n"));
  254. SensPrintA(SENS_INFO, ("\t| R E A C H A B I L I T Y L I S T |\n"));
  255. SensPrintA(SENS_INFO, ("\t|----------------------------------------------------------|\n"));
  256. SensPrintA(SENS_INFO, ("\t|----------------------------------------------------------|\n"));
  257. SensPrintA(SENS_INFO, ("\t| cRef | Reachable | Destination |\n"));
  258. SensPrintA(SENS_INFO, ("\t|----------------------------------------------------------|\n"));
  259. RequestLock();
  260. pTemp = pHead;
  261. while (pTemp != NULL)
  262. {
  263. SensPrintW(SENS_INFO, (L"\t| %3d | %c | %s\n",
  264. pTemp->cRef,
  265. (pTemp->State == REACHABLE) ? WCHAR_Y : ((pTemp->State == UNTRIED) ? WCHAR_X : WCHAR_N),
  266. pTemp->Destination ? pTemp->Destination : L"<NULL>")
  267. );
  268. pTemp = pTemp->Next;
  269. }
  270. ReleaseLock();
  271. SensPrintA(SENS_INFO, ("\t|----------------------------------------------------------|\n\n"));
  272. #else
  273. // Nothing
  274. #endif // DBG
  275. }