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.

300 lines
6.8 KiB

  1. /*****************************************************************************
  2. *
  3. * DIList.c
  4. *
  5. * Copyright (c) 1997 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * Abstract:
  8. *
  9. * List management. Really, array management, since our lists
  10. * never get very big.
  11. *
  12. * We call them "GPA"s, which stands for "Growable Pointer Array".
  13. *
  14. * There is a more general GXA gizmo in Dr Watson, but we don't
  15. * need it yet. So far, all we need to track is unsorted
  16. * lists of pointers.
  17. *
  18. * Yes, there exists a matching concept in COMCTL32, but we can't
  19. * use it because
  20. *
  21. * (1) it's not documented,
  22. * (2) COMCTL32 puts them into shared memory, which is just
  23. * begging for a memory leak.
  24. *
  25. * Contents:
  26. *
  27. * GPA_Init
  28. * GPA_Term
  29. *
  30. *****************************************************************************/
  31. #include "dinputpr.h"
  32. /*****************************************************************************
  33. *
  34. * The sqiffle for this file.
  35. *
  36. *****************************************************************************/
  37. #define sqfl sqflGpa
  38. /*****************************************************************************
  39. *
  40. * @doc INTERNAL
  41. *
  42. * @func HRESULT | GPA_Print |
  43. *
  44. * Print state of the growing pointer array.
  45. *
  46. * @parm HGPA | hgpa |
  47. *
  48. * @returns void
  49. *
  50. *****************************************************************************/
  51. void INTERNAL
  52. GPA_Print(HGPA hgpa)
  53. {
  54. int ipv;
  55. for (ipv = 0; ipv < hgpa->cpv; ipv++)
  56. {
  57. // 7/18/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers.
  58. SquirtSqflPtszV( sqflError,
  59. TEXT("ipv=%d,hgpa->rgpv[ipv]=%p"),
  60. ipv, hgpa->rgpv[ipv]);
  61. }
  62. }
  63. /*****************************************************************************
  64. *
  65. * @doc INTERNAL
  66. *
  67. * @func HRESULT | GPA_Append |
  68. *
  69. * Add a new item to the growing pointer array.
  70. *
  71. * Note that we add 8 after doubling, so that we don't get
  72. * stuck if cxAlloc is zero.
  73. *
  74. * @parm HGPA | hgpa |
  75. *
  76. * Handle to pointer array.
  77. *
  78. * @parm PV | pv |
  79. *
  80. * Pointer to add.
  81. *
  82. * @returns
  83. *
  84. * Returns a COM error code.
  85. *
  86. *****************************************************************************/
  87. STDMETHODIMP
  88. GPA_Append(HGPA hgpa, PV pv)
  89. {
  90. HRESULT hres;
  91. if (hgpa->cpv >= hgpa->cpvAlloc) {
  92. hres = ReallocCbPpv(cbX(PV) * (hgpa->cpvAlloc * 2 + 8),
  93. &hgpa->rgpv);
  94. // Prefix: Whistler 45077.
  95. if (FAILED(hres) || ( hgpa->rgpv == NULL) ) {
  96. goto done;
  97. }
  98. hgpa->cpvAlloc = hgpa->cpvAlloc * 2 + 8;
  99. }
  100. //hgpa->rgpv[hgpa->cpv++] = pv;
  101. hgpa->rgpv[hgpa->cpv] = pv;
  102. InterlockedIncrement(&hgpa->cpv);
  103. hres = S_OK;
  104. done:;
  105. //GPA_Print(hgpa);
  106. return hres;
  107. }
  108. /*****************************************************************************
  109. *
  110. * @doc INTERNAL
  111. *
  112. * @func BOOL | GPA_FindPtr |
  113. *
  114. * Determine whether a pointer is in the GPA.
  115. *
  116. * @parm HGPA | hgpa |
  117. *
  118. * Handle to pointer array.
  119. *
  120. * @parm PV | pv |
  121. *
  122. * Pointer to locate.
  123. *
  124. * @returns
  125. *
  126. * Returns a COM error code on failure.
  127. *
  128. * On success, returns the number of items left in the GPA.
  129. *
  130. *****************************************************************************/
  131. BOOL EXTERNAL
  132. GPA_FindPtr(HGPA hgpa, PV pv)
  133. {
  134. BOOL fRc;
  135. int ipv;
  136. for (ipv = 0; ipv < hgpa->cpv; ipv++) {
  137. if (hgpa->rgpv[ipv] == pv) {
  138. fRc = TRUE;
  139. goto done;
  140. }
  141. }
  142. fRc = FALSE;
  143. done:;
  144. return fRc;
  145. }
  146. /*****************************************************************************
  147. *
  148. * @doc INTERNAL
  149. *
  150. * @func HRESULT | GPA_DeletePtr |
  151. *
  152. * Remove the indicated pointer from the GPA. The order of
  153. * the remaining items is unspecified.
  154. *
  155. * Note that CEm_LL_ThreadProc assumes that no items before
  156. * the deleted item are affected by the deletion.
  157. *
  158. * @parm HGPA | hgpa |
  159. *
  160. * Handle to pointer array.
  161. *
  162. * @parm PV | pv |
  163. *
  164. * Pointer to delete.
  165. *
  166. * @returns
  167. *
  168. * Returns a COM error code on failure.
  169. *
  170. * On success, returns the number of items left in the GPA.
  171. *
  172. *****************************************************************************/
  173. STDMETHODIMP
  174. GPA_DeletePtr(HGPA hgpa, PV pv)
  175. {
  176. HRESULT hres;
  177. int ipv;
  178. for (ipv = 0; ipv < hgpa->cpv; ipv++) {
  179. if (hgpa->rgpv[ipv] == pv) {
  180. //hgpa->rgpv[ipv] = hgpa->rgpv[--hgpa->cpv];
  181. InterlockedDecrement(&hgpa->cpv);
  182. hgpa->rgpv[ipv] = hgpa->rgpv[hgpa->cpv];
  183. hres = hgpa->cpv;
  184. goto done;
  185. }
  186. }
  187. hres = E_FAIL;
  188. done:;
  189. //GPA_Print(hgpa);
  190. return hres;
  191. }
  192. /*****************************************************************************
  193. *
  194. * @doc INTERNAL
  195. *
  196. * @func HRESULT | GPA_Clone |
  197. *
  198. * Copy the contents of one GPA to another.
  199. *
  200. * @parm HGPA | hgpaDst |
  201. *
  202. * Handle to destination pointer array.
  203. *
  204. * @parm HGPA | hgpaSrc |
  205. *
  206. * Handle to source pointer array.
  207. *
  208. *****************************************************************************/
  209. STDMETHODIMP
  210. GPA_Clone(HGPA hgpaDst, HGPA hgpaSrc)
  211. {
  212. HRESULT hres;
  213. hres = AllocCbPpv(cbCxX(hgpaSrc->cpv, PV), &hgpaDst->rgpv);
  214. if (SUCCEEDED(hres)) {
  215. CopyMemory(hgpaDst->rgpv, hgpaSrc->rgpv, cbCxX(hgpaSrc->cpv, PV));
  216. hgpaDst->cpv = hgpaSrc->cpv;
  217. hgpaDst->cpvAlloc = hgpaSrc->cpvAlloc;
  218. }
  219. return hres;
  220. }
  221. /*****************************************************************************
  222. *
  223. * @doc INTERNAL
  224. *
  225. * @func void | GPA_Init |
  226. *
  227. * Initialize a GPA structure with no elements.
  228. *
  229. * @parm HGPA | hgpa |
  230. *
  231. * Handle to pointer array.
  232. *
  233. *****************************************************************************/
  234. void EXTERNAL
  235. GPA_Init(HGPA hgpa)
  236. {
  237. hgpa->rgpv = 0;
  238. hgpa->cpv = 0;
  239. hgpa->cpvAlloc = 0;
  240. }
  241. /*****************************************************************************
  242. *
  243. * @doc INTERNAL
  244. *
  245. * @func void | GPA_Term |
  246. *
  247. * Clean up an existing GPA.
  248. *
  249. * @parm HGPA | hgpa |
  250. *
  251. * Handle to pointer array.
  252. *
  253. *****************************************************************************/
  254. void EXTERNAL
  255. GPA_Term(HGPA hgpa)
  256. {
  257. FreePpv(&hgpa->rgpv);
  258. GPA_Init(hgpa);
  259. }