Source code of Windows XP (NT5)
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.

293 lines
8.7 KiB

  1. /*****************************************************************************
  2. * *
  3. * LL.C *
  4. * *
  5. * Copyright (C) Microsoft Corporation 1989. *
  6. * All Rights reserved. *
  7. * *
  8. ******************************************************************************
  9. * *
  10. * Program Description: Linked list module *
  11. * *
  12. ******************************************************************************
  13. * *
  14. * Revision History: Created 4/15/89 by Robert Bunney *
  15. * *
  16. * *
  17. ******************************************************************************
  18. * *
  19. * Known Bugs: None *
  20. * *
  21. * *
  22. * *
  23. *****************************************************************************/
  24. /*****************************************************************************
  25. * *
  26. * Defines *
  27. * *
  28. *****************************************************************************/
  29. #define NEAR near
  30. #define PRIVATE static
  31. #define publicsw
  32. #define H_ASSERT
  33. #define H_MEM
  34. #include <windows.h>
  35. #include <port1632.h>
  36. #define ALLOC(x) GlobalAlloc(GMEM_MOVEABLE, (LONG)x)
  37. #define FREE(x) GlobalFree(x)
  38. #define LOCK(x) GlobalLock(x)
  39. #define UNLOCK(x) GlobalUnlock(x)
  40. #define ASSERT(x)
  41. #define MEMMOVE(dest, src, cb) QvCopy(dest, src, cb)
  42. #include "ll.h"
  43. /*****************************************************************************
  44. * *
  45. * Typedefs *
  46. * *
  47. *****************************************************************************/
  48. typedef struct
  49. {
  50. HANDLE hNext;
  51. HANDLE hData;
  52. } LLN; /* L inked L ist N ode */
  53. typedef LLN FAR *PLLN;
  54. /*****************************************************************************
  55. * *
  56. * Prototypes *
  57. * *
  58. *****************************************************************************/
  59. PRIVATE HLLN NEAR APIENTRY HLLNAlloc(VOID);
  60. VOID FAR * FAR cdecl QvCopy(VOID FAR *, VOID FAR *, LONG);
  61. /*******************
  62. **
  63. ** Name: LLCreate
  64. **
  65. ** Purpose: Creates a link list
  66. **
  67. ** Arguments: None.
  68. **
  69. ** Returns: Link list. nilLL is returned if an error occurred.
  70. **
  71. *******************/
  72. LL FAR APIENTRY LLCreate(VOID)
  73. {
  74. return HLLNAlloc();
  75. }
  76. /*******************
  77. **
  78. ** Name: InsertLL
  79. **
  80. ** Purpose: Inserts a new node at the head of the linked list
  81. **
  82. ** Arguments: ll - link list
  83. ** vpData - pointer to data to be associated with
  84. ** c - count of the bytes pointed to by vpData
  85. **
  86. ** Returns: TRUE iff insertion is successful.
  87. **
  88. *******************/
  89. BOOL FAR APIENTRY InsertLL(ll, qvData, c)
  90. LL ll;
  91. VOID FAR *qvData;
  92. LONG c;
  93. {
  94. HLLN hlln; /* Handle for the new node */
  95. PLLN pllnCur; /* Head node for linked list */
  96. PLLN pllnNew; /* New node */
  97. HANDLE h; /* Handle to the object data */
  98. VOID FAR *qv; /* Pointer to data block */
  99. ASSERT(c > 0L);
  100. /* Check and lock to get header node*/
  101. if ((ll == nilHAND) || ((pllnCur = (PLLN)LOCK((HANDLE)ll)) == NULL))
  102. return FALSE;
  103. if ((h = (HANDLE)ALLOC(c)) == nilHAND) /* Get handle for data */
  104. {UNLOCK((HANDLE)ll); return FALSE;}
  105. if ((qv = LOCK(h)) == NULL) /* Get pointer to data */
  106. {UNLOCK((HANDLE)ll); FREE(h); return FALSE;}
  107. if ((hlln = HLLNAlloc()) == NULL) /* Get handle to new node */
  108. {UNLOCK((HANDLE)ll); FREE(h); return FALSE;}
  109. if ((pllnNew = (PLLN)LOCK((HANDLE)hlln)) == NULL)/* Get pointer to new node */
  110. {UNLOCK((HANDLE)ll); UNLOCK(h); FREE(h); UNLOCK(hlln); FREE(hlln); return FALSE;}
  111. MEMMOVE(qv, qvData, c); /* Copy data */
  112. UNLOCK(h);
  113. pllnNew->hData = h; /* Insert at head of list */
  114. pllnNew->hNext = pllnCur->hNext;
  115. pllnCur->hNext = hlln;
  116. UNLOCK((HANDLE)ll);
  117. UNLOCK(hlln);
  118. return TRUE;
  119. }
  120. /*******************
  121. **
  122. ** Name: WalkLL
  123. **
  124. ** Purpose: Mechanism for walking the nodes in the linked list
  125. **
  126. ** Arguments: ll - linked list
  127. ** hlln - handle to a linked list node
  128. **
  129. ** Returns: a handle to a link list node or NIL_HLLN if at the
  130. ** end of the list (or an error).
  131. **
  132. ** Notes: To get the first node, pass NIL_HLLN as the hlln - further
  133. ** calls should use the HLLN returned by this function.
  134. **
  135. *******************/
  136. HLLN FAR APIENTRY WalkLL(ll, hlln)
  137. LL ll;
  138. HLLN hlln;
  139. {
  140. PLLN plln; /* node in linked list */
  141. HLLN hllnT;
  142. if (hlln == nilHLLN) /* First time called */
  143. hlln = ll;
  144. if ((hlln == nilHAND) || ((plln = (PLLN)LOCK((HANDLE)hlln)) == NULL))
  145. return nilHAND;
  146. hllnT = plln->hNext;
  147. UNLOCK(hlln);
  148. return hllnT;
  149. }
  150. /*******************
  151. **
  152. ** Name: QVLockHLLN
  153. **
  154. ** Purpose: Locks a LL node returning a pointer to the data
  155. **
  156. ** Arguments: hlln - handle to a linked list node
  157. **
  158. ** Returns: pointer to data or NULL if an error occurred
  159. **
  160. *******************/
  161. VOID FAR * FAR QVLockHLLN(hlln)
  162. HLLN hlln;
  163. {
  164. PLLN plln;
  165. VOID FAR * qv;
  166. /* Lock node */
  167. if ((hlln == nilHAND) || ((plln = (PLLN)LOCK((HANDLE)hlln)) == NULL))
  168. return NULL;
  169. qv = LOCK(plln->hData); /* Get pointer to data */
  170. UNLOCK(hlln);
  171. return qv;
  172. }
  173. /*******************
  174. **
  175. ** Name: QVUnlockHLLN
  176. **
  177. ** Purpose: Unlocks a LL node
  178. **
  179. ** Arguments: hlln - handle to a link list node
  180. **
  181. ** Returns: TRUE iff the handle is successfully locked.
  182. **
  183. *******************/
  184. VOID FAR UnlockHLLN(hlln)
  185. HLLN hlln;
  186. {
  187. PLLN plln; /* Pointer to the node */
  188. if ((hlln == nilHAND) || ((plln = (PLLN)LOCK((HANDLE)hlln)) == NULL))
  189. return;
  190. UNLOCK(plln->hData);
  191. UNLOCK(hlln);
  192. return;
  193. }
  194. /*******************
  195. **
  196. ** Name: HLLNAlloc
  197. **
  198. ** Purpose: Allocates a link list node
  199. **
  200. ** Arguments: Nothing.
  201. **
  202. ** Returns: A new new node with hNext and hData set to nilHAND
  203. **
  204. **
  205. ** Method:
  206. **
  207. *******************/
  208. PRIVATE HLLN NEAR APIENTRY HLLNAlloc(VOID)
  209. {
  210. HANDLE h;
  211. PLLN plln;
  212. if ((h = ALLOC(sizeof(LLN))) != nilHAND)
  213. {
  214. if ((plln = (PLLN) LOCK(h)) != NULL)
  215. {
  216. plln->hNext = nilHAND;
  217. plln->hData = nilHAND;
  218. UNLOCK(h);
  219. }
  220. else
  221. {
  222. FREE(h);
  223. h = nilHAND;
  224. }
  225. }
  226. return (LL)h;
  227. }
  228. /*******************
  229. **
  230. ** Name: DestroyLL
  231. **
  232. ** Purpose: Deletes a LL and all of its contents
  233. **
  234. ** Arguments: ll - linked list
  235. **
  236. ** Returns: Nothing.
  237. **
  238. *******************/
  239. VOID FAR APIENTRY DestroyLL(ll)
  240. LL ll;
  241. {
  242. HLLN hllnNow = ll;
  243. HLLN hllnNext;
  244. PLLN plln;
  245. do
  246. {
  247. hllnNext = WalkLL(ll, hllnNow);
  248. plln = (PLLN)LOCK(hllnNow);
  249. ASSERT(plln);
  250. FREE(plln->hData);
  251. UNLOCK(hllnNow);
  252. FREE(hllnNow);
  253. hllnNow = hllnNext;
  254. } while (hllnNow != nilHLLN);
  255. }