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.

542 lines
9.8 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. growbuf.c
  5. Abstract:
  6. Simple buffer management functions that allow variable blocks to
  7. be added as an array. (Initially used to build a SID array, where
  8. each SID can be a different size.)
  9. Author:
  10. Jim Schmidt (jimschm) 05-Feb-1997
  11. Revision History:
  12. jimschm 11-Aug-1998 Added GrowBufAppendString
  13. calinn 15-Jan-1998 modified MultiSzAppend
  14. --*/
  15. #include "pch.h"
  16. #define DEFAULT_GROW_SIZE 8192
  17. PBYTE
  18. RealGrowBuffer (
  19. IN OUT PGROWBUFFER GrowBuf,
  20. IN DWORD SpaceNeeded
  21. )
  22. /*++
  23. Routine Description:
  24. GrowBuffer makes sure there is enough bytes in the buffer
  25. to accomodate SpaceNeeded. It allocates an initial buffer
  26. when no buffer is allocated, and it reallocates the buffer
  27. in increments of GrowBuf->Size (or DEFAULT_GROW_SIZE) when
  28. needed.
  29. Arguments:
  30. GrowBuf - A pointer to a GROWBUFFER structure.
  31. Initialize this structure to zero for
  32. the first call to GrowBuffer.
  33. SpaceNeeded - The number of free bytes needed in the buffer
  34. Return Value:
  35. A pointer to the SpaceNeeded bytes, or NULL if a memory allocation
  36. error occurred.
  37. --*/
  38. {
  39. PBYTE NewBuffer;
  40. DWORD TotalSpaceNeeded;
  41. DWORD GrowTo;
  42. MYASSERT(SpaceNeeded);
  43. if (!GrowBuf->Buf) {
  44. GrowBuf->Size = 0;
  45. GrowBuf->End = 0;
  46. }
  47. if (!GrowBuf->GrowSize) {
  48. GrowBuf->GrowSize = DEFAULT_GROW_SIZE;
  49. }
  50. TotalSpaceNeeded = GrowBuf->End + SpaceNeeded;
  51. if (TotalSpaceNeeded > GrowBuf->Size) {
  52. GrowTo = (TotalSpaceNeeded + GrowBuf->GrowSize) - (TotalSpaceNeeded % GrowBuf->GrowSize);
  53. } else {
  54. GrowTo = 0;
  55. }
  56. if (!GrowBuf->Buf) {
  57. GrowBuf->Buf = (PBYTE) MemAlloc (g_hHeap, 0, GrowTo);
  58. if (!GrowBuf->Buf) {
  59. DEBUGMSG ((DBG_ERROR, "GrowBuffer: Initial alloc failed"));
  60. return NULL;
  61. }
  62. GrowBuf->Size = GrowTo;
  63. } else if (GrowTo) {
  64. NewBuffer = MemReAlloc (g_hHeap, 0, GrowBuf->Buf, GrowTo);
  65. if (!NewBuffer) {
  66. DEBUGMSG ((DBG_ERROR, "GrowBuffer: Realloc failed"));
  67. return NULL;
  68. }
  69. GrowBuf->Size = GrowTo;
  70. GrowBuf->Buf = NewBuffer;
  71. }
  72. NewBuffer = GrowBuf->Buf + GrowBuf->End;
  73. GrowBuf->End += SpaceNeeded;
  74. return NewBuffer;
  75. }
  76. PBYTE
  77. RealGrowBufferReserve (
  78. IN PGROWBUFFER GrowBuf,
  79. IN DWORD BytesToReserve
  80. )
  81. {
  82. DWORD end;
  83. PBYTE result;
  84. end = GrowBuf->End;
  85. result = GrowBuffer (GrowBuf, BytesToReserve);
  86. GrowBuf->End = end;
  87. return result;
  88. }
  89. VOID
  90. FreeGrowBuffer (
  91. IN PGROWBUFFER GrowBuf
  92. )
  93. /*++
  94. Routine Description:
  95. FreeGrowBuffer frees a buffer allocated by GrowBuffer.
  96. Arguments:
  97. GrowBuf - A pointer to the same structure passed to GrowBuffer
  98. Return Value:
  99. none
  100. --*/
  101. {
  102. MYASSERT(GrowBuf);
  103. if (GrowBuf->Buf) {
  104. MemFree (g_hHeap, 0, GrowBuf->Buf);
  105. ZeroMemory (GrowBuf, sizeof (GROWBUFFER));
  106. }
  107. }
  108. /*++
  109. Routine Descriptions:
  110. MultiSzAppend
  111. This function is a general-purpose function to append a string
  112. to a grow buffer.
  113. MultiSzAppendVal
  114. This function adds a key=decimal_val string, where key is a
  115. specified string, and decimal_val is a specified DWORD.
  116. MultiSzAppendString
  117. This function adds key=string to the grow buffer, where key
  118. is a specified string, and string is a specified string value.
  119. Arguments:
  120. GrowBuf - The buffer to append the string or key/value pair
  121. Key - The key part of the key=val pair
  122. Val - The val part of the key=val pair
  123. Return Value:
  124. TRUE if the function succeeded, or FALSE if a memory allocation
  125. failure occurred.
  126. --*/
  127. BOOL
  128. RealMultiSzAppendA (
  129. PGROWBUFFER GrowBuf,
  130. PCSTR String
  131. )
  132. {
  133. PSTR p;
  134. p = (PSTR) GrowBuffer (GrowBuf, SizeOfStringA (String) + sizeof(CHAR));
  135. if (!p) {
  136. return FALSE;
  137. }
  138. StringCopyA (p, String);
  139. GrowBuf->End -= sizeof (CHAR);
  140. GrowBuf->Buf[GrowBuf->End] = 0;
  141. return TRUE;
  142. }
  143. BOOL
  144. RealMultiSzAppendValA (
  145. PGROWBUFFER GrowBuf,
  146. PCSTR Key,
  147. DWORD Val
  148. )
  149. {
  150. CHAR KeyValPair[256];
  151. wsprintfA (KeyValPair, "%s=%u", Key, Val);
  152. return MultiSzAppendA (GrowBuf, KeyValPair);
  153. }
  154. BOOL
  155. RealMultiSzAppendStringA (
  156. PGROWBUFFER GrowBuf,
  157. PCSTR Key,
  158. PCSTR Val
  159. )
  160. {
  161. CHAR KeyValPair[1024];
  162. wsprintfA (KeyValPair, "%s=%s", Key, Val);
  163. return MultiSzAppendA (GrowBuf, KeyValPair);
  164. }
  165. BOOL
  166. RealMultiSzAppendW (
  167. PGROWBUFFER GrowBuf,
  168. PCWSTR String
  169. )
  170. {
  171. PWSTR p;
  172. p = (PWSTR) GrowBuffer (GrowBuf, SizeOfStringW (String) + sizeof(WCHAR));
  173. if (!p) {
  174. return FALSE;
  175. }
  176. StringCopyW (p, String);
  177. GrowBuf->End -= sizeof (WCHAR);
  178. *((PWCHAR) (GrowBuf->Buf + GrowBuf->End)) = 0;
  179. return TRUE;
  180. }
  181. BOOL
  182. RealMultiSzAppendValW (
  183. PGROWBUFFER GrowBuf,
  184. PCWSTR Key,
  185. DWORD Val
  186. )
  187. {
  188. WCHAR KeyValPair[256];
  189. wsprintfW (KeyValPair, L"%s=%u", Key, Val);
  190. return MultiSzAppendW (GrowBuf, KeyValPair);
  191. }
  192. BOOL
  193. RealMultiSzAppendStringW (
  194. PGROWBUFFER GrowBuf,
  195. PCWSTR Key,
  196. PCWSTR Val
  197. )
  198. {
  199. WCHAR KeyValPair[1024];
  200. wsprintfW (KeyValPair, L"%s=%s", Key, Val);
  201. return MultiSzAppendW (GrowBuf, KeyValPair);
  202. }
  203. BOOL
  204. RealGrowBufAppendDword (
  205. PGROWBUFFER GrowBuf,
  206. DWORD d
  207. )
  208. {
  209. PDWORD p;
  210. p = (PDWORD) GrowBuffer (GrowBuf, sizeof (DWORD));
  211. if (!p) {
  212. return FALSE;
  213. }
  214. *p = d;
  215. return TRUE;
  216. }
  217. /*++
  218. Routine Description:
  219. GrowBufAppendString copies the specified string to the end of the grow
  220. buffer. This is the equivalent of strcat. The grow buffer is
  221. automatically expanded as necessary.
  222. Arguments:
  223. GrowBuf - Specifies the destination grow buffer
  224. String - Specifies the string to append
  225. Return Value:
  226. Always TRUE.
  227. --*/
  228. BOOL
  229. RealGrowBufAppendStringA (
  230. IN OUT PGROWBUFFER GrowBuf,
  231. IN PCSTR String
  232. )
  233. {
  234. UINT OldEnd;
  235. PSTR p;
  236. UINT Bytes;
  237. if (String) {
  238. Bytes = SizeOfStringA (String);
  239. OldEnd = GrowBuf->End;
  240. if (OldEnd) {
  241. p = (PSTR) (GrowBuf->Buf + OldEnd - sizeof (CHAR));
  242. if (*p == 0) {
  243. OldEnd -= sizeof (CHAR);
  244. }
  245. }
  246. RealGrowBuffer (GrowBuf, Bytes);
  247. p = (PSTR) (GrowBuf->Buf + OldEnd);
  248. StringCopyA (p, String);
  249. GrowBuf->End = OldEnd + Bytes;
  250. }
  251. return TRUE;
  252. }
  253. BOOL
  254. RealGrowBufAppendStringW (
  255. IN OUT PGROWBUFFER GrowBuf,
  256. IN PCWSTR String
  257. )
  258. {
  259. UINT OldEnd;
  260. PWSTR p;
  261. UINT Bytes;
  262. if (String) {
  263. Bytes = SizeOfStringW (String);
  264. OldEnd = GrowBuf->End;
  265. if (OldEnd) {
  266. p = (PWSTR) (GrowBuf->Buf + OldEnd - sizeof (WCHAR));
  267. if (*p == 0) {
  268. OldEnd -= sizeof (WCHAR);
  269. }
  270. }
  271. RealGrowBuffer (GrowBuf, Bytes);
  272. p = (PWSTR) (GrowBuf->Buf + OldEnd);
  273. StringCopyW (p, String);
  274. GrowBuf->End = OldEnd + Bytes;
  275. }
  276. return TRUE;
  277. }
  278. /*++
  279. Routine Description:
  280. GrowBufAppendStringAB copies the specified string range to the
  281. end of the grow buffer. This concatenates the string to the
  282. existing buffer contents, and keeps the buffer terminated.
  283. Arguments:
  284. GrowBuf - Specifies the destination grow buffer
  285. Start - Specifies the start of string to append
  286. EndPlusOne - Specifies one logical character beyond the end of
  287. the string, and can point to a nul.
  288. Return Value:
  289. Always TRUE.
  290. --*/
  291. BOOL
  292. RealGrowBufAppendStringABA (
  293. IN OUT PGROWBUFFER GrowBuf,
  294. IN PCSTR Start,
  295. IN PCSTR EndPlusOne
  296. )
  297. {
  298. UINT OldEnd;
  299. PSTR p;
  300. UINT Bytes;
  301. if (Start && Start < EndPlusOne) {
  302. Bytes = (PBYTE) EndPlusOne - (PBYTE) Start;
  303. OldEnd = GrowBuf->End;
  304. if (OldEnd) {
  305. p = (PSTR) (GrowBuf->Buf + OldEnd - sizeof (CHAR));
  306. if (*p == 0) {
  307. OldEnd -= sizeof (CHAR);
  308. }
  309. }
  310. RealGrowBuffer (GrowBuf, Bytes + sizeof (CHAR));
  311. p = (PSTR) (GrowBuf->Buf + OldEnd);
  312. CopyMemory (p, Start, Bytes);
  313. p = (PSTR) ((PBYTE) p + Bytes);
  314. *p = 0;
  315. GrowBuf->End = OldEnd + Bytes + sizeof (CHAR);
  316. }
  317. return TRUE;
  318. }
  319. BOOL
  320. RealGrowBufAppendStringABW (
  321. IN OUT PGROWBUFFER GrowBuf,
  322. IN PCWSTR Start,
  323. IN PCWSTR EndPlusOne
  324. )
  325. {
  326. UINT OldEnd;
  327. PWSTR p;
  328. UINT Bytes;
  329. if (Start && Start < EndPlusOne) {
  330. Bytes = (PBYTE) EndPlusOne - (PBYTE) Start;
  331. OldEnd = GrowBuf->End;
  332. if (OldEnd > sizeof (WCHAR)) {
  333. p = (PWSTR) (GrowBuf->Buf + OldEnd - sizeof (WCHAR));
  334. if (*p == 0) {
  335. OldEnd -= sizeof (WCHAR);
  336. }
  337. }
  338. RealGrowBuffer (GrowBuf, Bytes + sizeof (WCHAR));
  339. p = (PWSTR) (GrowBuf->Buf + OldEnd);
  340. CopyMemory (p, Start, Bytes);
  341. p = (PWSTR) ((PBYTE) p + Bytes);
  342. *p = 0;
  343. GrowBuf->End = OldEnd + Bytes + sizeof (WCHAR);
  344. }
  345. return TRUE;
  346. }
  347. /*++
  348. Routine Description:
  349. GrowBufCopyString copies the specified string to the end of the grow buffer.
  350. Arguments:
  351. GrowBuf - Specifies the grow buffer to add to, receives the updated buffer
  352. String - Specifies the string to add to GrowBuf
  353. Return Value:
  354. --*/
  355. BOOL
  356. RealGrowBufCopyStringA (
  357. IN OUT PGROWBUFFER GrowBuf,
  358. IN PCSTR String
  359. )
  360. {
  361. PBYTE Buf;
  362. UINT Size;
  363. Size = SizeOfStringA (String);
  364. Buf = RealGrowBuffer (GrowBuf, Size);
  365. if (!Buf) {
  366. return FALSE;
  367. }
  368. CopyMemory (Buf, String, Size);
  369. return TRUE;
  370. }
  371. BOOL
  372. RealGrowBufCopyStringW (
  373. IN OUT PGROWBUFFER GrowBuf,
  374. IN PCWSTR String
  375. )
  376. {
  377. PBYTE Buf;
  378. UINT Size;
  379. Size = SizeOfStringW (String);
  380. Buf = RealGrowBuffer (GrowBuf, Size);
  381. if (!Buf) {
  382. return FALSE;
  383. }
  384. CopyMemory (Buf, String, Size);
  385. return TRUE;
  386. }