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.

612 lines
11 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. growlist.c
  5. Abstract:
  6. Simple buffer management functions that maintenence of a list of binary
  7. objects.
  8. Author:
  9. 08-Aug-1997 jimschm Created
  10. Revision History:
  11. marcw 2-Sep-1999 Moved over from Win9xUpg project.
  12. --*/
  13. #include "pch.h"
  14. #include "commonp.h"
  15. #define INSERT_LAST 0xffffffff
  16. PBYTE
  17. pGlAdd (
  18. IN OUT PGROWLIST GrowList,
  19. IN UINT InsertBefore,
  20. IN PBYTE DataToAdd, OPTIONAL
  21. IN UINT SizeOfData,
  22. IN UINT NulBytesToAdd
  23. )
  24. /*++
  25. Routine Description:
  26. pGlAdd allocates memory for a binary block by using a pool, and then expands
  27. an array of pointers, maintaining a quick-access list.
  28. Arguments:
  29. GrowList - Specifies the list to add the entry to
  30. InsertBefore - Specifies the index of the array element to insert
  31. before, or INSERT_LIST to append.
  32. DataToAdd - Specifies the binary block of data to add.
  33. SizeOfData - Specifies the size of data.
  34. NulBytesToAdd - Specifies the number of nul bytes to add to the buffer
  35. Return Value:
  36. A pointer to the binary block if data was copied into the list, 1 if a list
  37. item was created but no data was set for the item, or NULL if an error
  38. occurred.
  39. --*/
  40. {
  41. PBYTE *Item;
  42. PBYTE *InsertAt;
  43. PBYTE Data;
  44. UINT OldEnd;
  45. UINT Size;
  46. UINT TotalSize;
  47. TotalSize = SizeOfData + NulBytesToAdd;
  48. MYASSERT (TotalSize || !DataToAdd);
  49. //
  50. // Expand list array
  51. //
  52. OldEnd = GrowList->ListArray.End;
  53. Item = (PBYTE *) GbGrow (&GrowList->ListArray, sizeof (PBYTE));
  54. if (!Item) {
  55. DEBUGMSG ((DBG_WARNING, "GrowList: Could not allocate array item"));
  56. return NULL;
  57. }
  58. //
  59. // Copy data
  60. //
  61. if (DataToAdd || NulBytesToAdd) {
  62. Data = FAST_MALLOC (TotalSize);
  63. if (!Data) {
  64. GrowList->ListArray.End = OldEnd;
  65. DEBUGMSG ((DBG_WARNING, "GrowList: Could not allocate data block"));
  66. return NULL;
  67. }
  68. if (DataToAdd) {
  69. CopyMemory (Data, DataToAdd, SizeOfData);
  70. }
  71. if (NulBytesToAdd) {
  72. ZeroMemory (Data + SizeOfData, NulBytesToAdd);
  73. }
  74. } else {
  75. Data = NULL;
  76. }
  77. //
  78. // Adjust array
  79. //
  80. Size = GlGetSize (GrowList);
  81. if (InsertBefore >= Size) {
  82. //
  83. // Append mode
  84. //
  85. *Item = Data;
  86. } else {
  87. //
  88. // Insert mode
  89. //
  90. InsertAt = (PBYTE *) (GrowList->ListArray.Buf) + InsertBefore;
  91. MoveMemory (&InsertAt[1], InsertAt, (Size - InsertBefore) * sizeof (PBYTE));
  92. *InsertAt = Data;
  93. }
  94. return Data ? Data : (PBYTE) 1;
  95. }
  96. VOID
  97. GlFree (
  98. IN PGROWLIST GrowList
  99. )
  100. /*++
  101. Routine Description:
  102. GlFree frees the resources allocated by a GROWLIST.
  103. Arguments:
  104. GrowList - Specifies the list to clean up
  105. Return Value:
  106. none
  107. --*/
  108. {
  109. if (!GrowList) {
  110. return;
  111. }
  112. GlReset (GrowList);
  113. GbFree (&GrowList->ListArray);
  114. ZeroMemory (GrowList, sizeof (GROWLIST));
  115. }
  116. VOID
  117. GlReset (
  118. IN OUT PGROWLIST GrowList
  119. )
  120. /*++
  121. Routine Description:
  122. GlReset empties the grow list but does not destroy the index buffer or pool.
  123. It is used to efficiently reuse a list.
  124. Arguments:
  125. GrowList - Specifies the list to clean up
  126. Return Value:
  127. none
  128. --*/
  129. {
  130. UINT u;
  131. UINT count;
  132. PBYTE *dataPtr;
  133. if (!GrowList) {
  134. MYASSERT (FALSE);
  135. return;
  136. }
  137. count = GlGetSize (GrowList);
  138. dataPtr = (PBYTE *) (GrowList->ListArray.Buf);
  139. for (u = 0 ; u < count ; u++) {
  140. FAST_FREE (dataPtr[u]);
  141. }
  142. GrowList->ListArray.End = 0;
  143. }
  144. PBYTE
  145. GlGetItem (
  146. IN PGROWLIST GrowList,
  147. IN UINT Index
  148. )
  149. /*++
  150. Routine Description:
  151. GlGetItem returns a pointer to the block of data for item specified by
  152. Index.
  153. Arguments:
  154. GrowList - Specifies the list to access
  155. Index - Specifies zero-based index of item in list to access
  156. Return Value:
  157. A pointer to the item's data, or NULL if the Index does not
  158. represent an actual item.
  159. --*/
  160. {
  161. PBYTE *ItemPtr;
  162. UINT Size;
  163. Size = GlGetSize (GrowList);
  164. if (Index >= Size) {
  165. return NULL;
  166. }
  167. ItemPtr = (PBYTE *) (GrowList->ListArray.Buf);
  168. MYASSERT(ItemPtr);
  169. return ItemPtr[Index];
  170. }
  171. UINT
  172. GlGetSize (
  173. IN PGROWLIST GrowList
  174. )
  175. /*++
  176. Routine Description:
  177. GlGetSize calculates the number of items in the list.
  178. Arguments:
  179. GrowList - Specifies the list to calculate the size of
  180. Return Value:
  181. The number of items in the list, or zero if the list is empty.
  182. --*/
  183. {
  184. return GrowList->ListArray.End / sizeof (PBYTE);
  185. }
  186. PBYTE
  187. RealGlAppend (
  188. IN OUT PGROWLIST GrowList,
  189. IN PBYTE DataToAppend, OPTIONAL
  190. IN UINT SizeOfData
  191. )
  192. /*++
  193. Routine Description:
  194. GlAppend appends a black of data as a new list item.
  195. Arguments:
  196. GrowList - Specifies the list to modify
  197. DataToAppend - Specifies a block of data to be copied
  198. SizeOfData - Specifies the number of bytes in DataToAppend
  199. Return Value:
  200. A pointer to the binary block if data was copied into the list, 1 if a list
  201. item was created but no data was set for the item, or NULL if an error
  202. occurred.
  203. --*/
  204. {
  205. return pGlAdd (GrowList, INSERT_LAST, DataToAppend, SizeOfData, 0);
  206. }
  207. PBYTE
  208. RealGlAppendAddNul (
  209. IN OUT PGROWLIST GrowList,
  210. IN PBYTE DataToAppend, OPTIONAL
  211. IN UINT SizeOfData
  212. )
  213. /*++
  214. Routine Description:
  215. GlAppend appends a black of data as a new list item and appends two zero
  216. bytes (used for string termination).
  217. Arguments:
  218. GrowList - Specifies the list to modify
  219. DataToAppend - Specifies a block of data to be copied
  220. SizeOfData - Specifies the number of bytes in DataToAppend
  221. Return Value:
  222. A pointer to the binary block if data was copied into the list, 1 if a list
  223. item was created but no data was set for the item, or NULL if an error
  224. occurred.
  225. --*/
  226. {
  227. return pGlAdd (GrowList, INSERT_LAST, DataToAppend, SizeOfData, 2);
  228. }
  229. PBYTE
  230. RealGlInsert (
  231. IN OUT PGROWLIST GrowList,
  232. IN UINT Index,
  233. IN PBYTE DataToInsert, OPTIONAL
  234. IN UINT SizeOfData
  235. )
  236. /*++
  237. Routine Description:
  238. GlAppend inserts a black of data as a new list item, before the specified
  239. Index.
  240. Arguments:
  241. GrowList - Specifies the list to modify
  242. Index - Specifies the zero-based index of item to insert ahead of.
  243. DataToInsert - Specifies a block of data to be copied
  244. SizeOfData - Specifies the number of bytes in DataToInsert
  245. Return Value:
  246. A pointer to the binary block if data was copied into the list, 1 if a list
  247. item was created but no data was set for the item, or NULL if an error
  248. occurred.
  249. --*/
  250. {
  251. UINT Size;
  252. Size = GlGetSize (GrowList);
  253. if (Index > Size) {
  254. return NULL;
  255. }
  256. return pGlAdd (GrowList, Index, DataToInsert, SizeOfData, 0);
  257. }
  258. PBYTE
  259. RealGlInsertAddNul (
  260. IN OUT PGROWLIST GrowList,
  261. IN UINT Index,
  262. IN PBYTE DataToInsert, OPTIONAL
  263. IN UINT SizeOfData
  264. )
  265. /*++
  266. Routine Description:
  267. GlAppend inserts a block of data as a new list item, before the specified
  268. Index. Two zero bytes are appended to the block of data (used for string
  269. termination).
  270. Arguments:
  271. GrowList - Specifies the list to modify
  272. Index - Specifies the zero-based index of item to insert ahead of.
  273. DataToInsert - Specifies a block of data to be copied
  274. SizeOfData - Specifies the number of bytes in DataToInsert
  275. Return Value:
  276. A pointer to the binary block if data was copied into the list, 1 if a list
  277. item was created but no data was set for the item, or NULL if an error
  278. occurred.
  279. --*/
  280. {
  281. UINT Size;
  282. Size = GlGetSize (GrowList);
  283. if (Index > Size) {
  284. return NULL;
  285. }
  286. return pGlAdd (GrowList, Index, DataToInsert, SizeOfData, 2);
  287. }
  288. BOOL
  289. GlDeleteItem (
  290. IN OUT PGROWLIST GrowList,
  291. IN UINT Index
  292. )
  293. /*++
  294. Routine Description:
  295. GlDeleteItem removes an item from the list.
  296. Arguments:
  297. GrowList - Specifies the list to modify
  298. Index - Specifies the zero-based index of the item to remove.
  299. Return Value:
  300. TRUE if the data block was removed from the list, or FALSE if
  301. Index is invalid.
  302. --*/
  303. {
  304. UINT Size;
  305. PBYTE *DeleteAt;
  306. Size = GlGetSize (GrowList);
  307. if (Size <= Index) {
  308. return FALSE;
  309. }
  310. DeleteAt = (PBYTE *) (GrowList->ListArray.Buf) + Index;
  311. if (*DeleteAt) {
  312. FAST_FREE (*DeleteAt);
  313. }
  314. Size--;
  315. if (Size > Index) {
  316. MoveMemory (DeleteAt, &DeleteAt[1], (Size - Index) * sizeof (PBYTE));
  317. }
  318. GrowList->ListArray.End = Size * sizeof (PBYTE);
  319. return TRUE;
  320. }
  321. BOOL
  322. GlResetItem (
  323. IN OUT PGROWLIST GrowList,
  324. IN UINT Index
  325. )
  326. /*++
  327. Routine Description:
  328. GlResetItem sets the list pointer of the specified item to NULL, freeing the
  329. memory associated with the item's data.
  330. Arguments:
  331. GrowList - Specifies the list to modify
  332. Index - Specifies the zero-based index of the item to reset.
  333. Return Value:
  334. TRUE if the data block was freed and the list element was nulled,
  335. or FALSE if Index is invalid.
  336. --*/
  337. {
  338. UINT Size;
  339. PBYTE *ResetAt;
  340. Size = GlGetSize (GrowList);
  341. if (Size <= Index) {
  342. return FALSE;
  343. }
  344. ResetAt = (PBYTE *) (GrowList->ListArray.Buf) + Index;
  345. if (*ResetAt) {
  346. FAST_FREE (*ResetAt);
  347. }
  348. *ResetAt = NULL;
  349. return TRUE;
  350. }
  351. PBYTE
  352. RealGlSetItem (
  353. IN OUT PGROWLIST GrowList,
  354. IN UINT Index,
  355. IN PCBYTE DataToCopy,
  356. IN UINT DataSize
  357. )
  358. /*++
  359. Routine Description:
  360. GlSetItem replaces the data associated with a list item.
  361. Arguments:
  362. GrowList - Specifies the list to modify
  363. Index - Specifies the zero-based index of the item to remove.
  364. DataToCopy - Specifies data to associate with the list item
  365. DataSize - Specifies the size of Data
  366. Return Value:
  367. A pointer to the binary block if data was copied into the list, 1 if a list
  368. item was created but no data was set for the item, or NULL if an error
  369. occurred.
  370. --*/
  371. {
  372. UINT Size;
  373. PBYTE *ReplaceAt;
  374. PBYTE Data;
  375. MYASSERT (DataSize || !DataToCopy);
  376. Size = GlGetSize (GrowList);
  377. if (Size <= Index) {
  378. return NULL;
  379. }
  380. //
  381. // Copy data
  382. //
  383. if (DataToCopy) {
  384. Data = FAST_MALLOC (DataSize);
  385. if (!Data) {
  386. DEBUGMSG ((DBG_WARNING, "GrowList: Could not allocate data block (2)"));
  387. return NULL;
  388. }
  389. CopyMemory (Data, DataToCopy, DataSize);
  390. } else {
  391. Data = NULL;
  392. }
  393. //
  394. // Update list pointer
  395. //
  396. ReplaceAt = (PBYTE *) (GrowList->ListArray.Buf) + Index;
  397. if (*ReplaceAt) {
  398. FAST_FREE (*ReplaceAt);
  399. }
  400. *ReplaceAt = Data;
  401. return Data ? Data : (PBYTE) 1;
  402. }