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.

256 lines
5.2 KiB

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // propmisc.c
  4. //
  5. // Misc. Property set rotuines
  6. //
  7. // Change history:
  8. //
  9. // Date Who What
  10. // --------------------------------------------------------------------------
  11. // 07/30/94 B. Wentz Created file
  12. //
  13. ////////////////////////////////////////////////////////////////////////////////
  14. #include "priv.h"
  15. #pragma hdrstop
  16. ////////////////////////////////////////////////////////////////////////////////
  17. //
  18. // LpllCreateList
  19. //
  20. // Purpose:
  21. // Create a linked list with dwc elements.
  22. //
  23. ////////////////////////////////////////////////////////////////////////////////
  24. LPLLIST
  25. LpllCreate
  26. (LPLLIST *lplpll, // Head
  27. LPLLCACHE lpllcache, // Cache
  28. DWORD dwc, // Number of nodes to create
  29. DWORD cbNode) // Size of each node
  30. {
  31. LPLLIST lpllT;
  32. LPLLIST lpllCur;
  33. if ((lplpll == NULL) ||
  34. (dwc < 1) ||
  35. (cbNode < sizeof(LLIST)))
  36. return NULL;
  37. lpllCur = *lplpll = PvMemAlloc(cbNode);
  38. if (lpllCur == NULL)
  39. {
  40. return NULL;
  41. }
  42. FillBuf (lpllCur, 0, cbNode);
  43. lpllCur->lpllistPrev = NULL;
  44. dwc--;
  45. while (dwc)
  46. {
  47. lpllT = PvMemAlloc(cbNode);
  48. if (lpllT == NULL)
  49. goto Fail;
  50. FillBuf (lpllT, 0, cbNode);
  51. lpllT->lpllistPrev = lpllCur;
  52. lpllCur->lpllistNext = lpllT;
  53. lpllCur = lpllT;
  54. dwc--;
  55. } // while
  56. lpllCur->lpllistNext = NULL;
  57. lpllcache->lpllist = NULL;
  58. return *lplpll;
  59. Fail :
  60. lpllCur = *lplpll;
  61. while (lpllCur != NULL)
  62. {
  63. lpllT = lpllCur;
  64. lpllCur = lpllCur->lpllistNext;
  65. VFreeMemP(lpllT, cbNode);
  66. }
  67. return NULL;
  68. } // LpllCreateList
  69. ////////////////////////////////////////////////////////////////////////////////
  70. //
  71. // LpllGetNode
  72. //
  73. // Purpose:
  74. // Gets a node from the list
  75. //
  76. ////////////////////////////////////////////////////////////////////////////////
  77. LPLLIST
  78. LpllGetNode
  79. (LPLLIST lpllist, // The head
  80. LPLLCACHE lpllcache, // The cache
  81. DWORD idw) // Index of node to get -- 1 based
  82. {
  83. DWORD i = idw;
  84. if ((lpllcache->lpllist != NULL) && (lpllcache->idw == idw))
  85. {
  86. return lpllcache->lpllist;
  87. }
  88. while ((i > 1) && (lpllist != NULL))
  89. {
  90. lpllist = lpllist->lpllistNext;
  91. i--;
  92. }
  93. if (lpllist != NULL)
  94. {
  95. lpllcache->idw = idw;
  96. lpllcache->lpllist = lpllist;
  97. }
  98. return lpllist;
  99. } // LpllGetNode
  100. ////////////////////////////////////////////////////////////////////////////////
  101. //
  102. // LpllDeleteNode
  103. //
  104. // Purpose:
  105. // Delete a node from the list
  106. //
  107. ////////////////////////////////////////////////////////////////////////////////
  108. LPLLIST
  109. LpllDeleteNode
  110. (LPLLIST lpllist, // Head
  111. LPLLCACHE lpllcache, // Cache
  112. DWORD idw, // Index -- 1 based
  113. DWORD cbNode, // Size of node
  114. void (*lpfnFreeNode)(LPLLIST) // Free a node
  115. )
  116. {
  117. LPLLIST lpT;
  118. LPLLIST lpNext;
  119. BOOL fHead;
  120. // Check the cache
  121. if ((lpllcache->lpllist != NULL) && (lpllcache->idw == idw))
  122. {
  123. lpT = lpllcache->lpllist;
  124. lpllcache->lpllist = NULL;
  125. }
  126. else
  127. {
  128. lpT = LpllGetNode (lpllist, lpllcache, idw);
  129. }
  130. if (lpT == NULL) // We couldn't find the node
  131. {
  132. return lpT;
  133. }
  134. fHead = lpT->lpllistPrev == NULL;
  135. // Delete the node from the list
  136. if (lpT->lpllistPrev != NULL)
  137. {
  138. lpT->lpllistPrev->lpllistNext = lpT->lpllistNext;
  139. }
  140. if ((lpNext = lpT->lpllistNext) != NULL)
  141. {
  142. lpT->lpllistNext->lpllistPrev = lpT->lpllistPrev;
  143. }
  144. // Delete the string & node
  145. (*lpfnFreeNode) (lpT);
  146. VFreeMemP(lpT, cbNode);
  147. // If the head was deleted, return the new one.
  148. return (fHead ? lpNext : lpllist);
  149. } // LpllDeleteNode
  150. ////////////////////////////////////////////////////////////////////////////////
  151. //
  152. // LpllInsertNode
  153. //
  154. // Purpose:
  155. // Insert a node into the list
  156. //
  157. ////////////////////////////////////////////////////////////////////////////////
  158. LPLLIST PASCAL
  159. LpllInsertNode
  160. (LPLLIST lpllist, // Head
  161. LPLLCACHE lpllcache, // Cache
  162. DWORD idw, // index
  163. DWORD cbNode) // Size of node
  164. {
  165. LPLLIST lpT;
  166. LPLLIST lpOrigHead;
  167. BOOL fHead;
  168. DWORD idwOrig;
  169. if ((lpOrigHead = lpllist) == NULL)
  170. {
  171. return NULL;
  172. }
  173. idwOrig = idw;
  174. Assert ((idw > 0));
  175. idw--;
  176. while ((idw) && (lpllist->lpllistNext != NULL))
  177. {
  178. lpllist = lpllist->lpllistNext;
  179. idw--;
  180. }
  181. lpT = PvMemAlloc(cbNode);
  182. if (lpT == NULL)
  183. {
  184. return NULL;
  185. }
  186. FillBuf (lpT, 0, cbNode);
  187. // If the new node was to be inserted at the end, idw would not
  188. // be zero, the while loop would have fallen out because Next was NULL
  189. if (idw)
  190. {
  191. fHead = FALSE;
  192. lpT->lpllistPrev = lpllist;
  193. lpT->lpllistNext = NULL;
  194. lpllist->lpllistNext = lpT;
  195. }
  196. else
  197. {
  198. fHead = (lpllist == lpOrigHead);
  199. lpT->lpllistPrev = lpllist->lpllistPrev;
  200. if (lpllist->lpllistPrev != NULL)
  201. {
  202. lpllist->lpllistPrev->lpllistNext = lpT;
  203. }
  204. lpT->lpllistNext = lpllist;
  205. lpllist->lpllistPrev = lpT;
  206. }
  207. // Update the cache
  208. lpllcache->idw = idwOrig;
  209. lpllcache->lpllist = lpT;
  210. return (fHead ? lpT : lpOrigHead);
  211. } // LpllInsertNode