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.

693 lines
14 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. #include "migutilp.h"
  17. #define DEFAULT_GROW_SIZE 8192
  18. PBYTE
  19. RealGrowBuffer (
  20. IN OUT PGROWBUFFER GrowBuf,
  21. IN DWORD SpaceNeeded
  22. )
  23. /*++
  24. Routine Description:
  25. GrowBuffer makes sure there is enough bytes in the buffer
  26. to accomodate SpaceNeeded. It allocates an initial buffer
  27. when no buffer is allocated, and it reallocates the buffer
  28. in increments of GrowBuf->Size (or DEFAULT_GROW_SIZE) when
  29. needed.
  30. Arguments:
  31. GrowBuf - A pointer to a GROWBUFFER structure.
  32. Initialize this structure to zero for
  33. the first call to GrowBuffer.
  34. SpaceNeeded - The number of free bytes needed in the buffer
  35. Return Value:
  36. A pointer to the SpaceNeeded bytes, or NULL if a memory allocation
  37. error occurred.
  38. --*/
  39. {
  40. PBYTE NewBuffer;
  41. DWORD TotalSpaceNeeded;
  42. DWORD GrowTo;
  43. MYASSERT(SpaceNeeded);
  44. MYASSERT(GrowBuf);
  45. if (!GrowBuf->Buf) {
  46. GrowBuf->Size = 0;
  47. GrowBuf->End = 0;
  48. }
  49. if (!GrowBuf->GrowSize) {
  50. GrowBuf->GrowSize = DEFAULT_GROW_SIZE;
  51. }
  52. TotalSpaceNeeded = GrowBuf->End + SpaceNeeded;
  53. if (TotalSpaceNeeded > GrowBuf->Size) {
  54. GrowTo = (TotalSpaceNeeded + GrowBuf->GrowSize) - (TotalSpaceNeeded % GrowBuf->GrowSize);
  55. } else {
  56. GrowTo = 0;
  57. }
  58. if (!GrowBuf->Buf) {
  59. GrowBuf->Buf = (PBYTE) MemAlloc (g_hHeap, 0, GrowTo);
  60. if (!GrowBuf->Buf) {
  61. DEBUGMSG ((DBG_ERROR, "GrowBuffer: Initial alloc failed"));
  62. return NULL;
  63. }
  64. GrowBuf->Size = GrowTo;
  65. } else if (GrowTo) {
  66. NewBuffer = MemReAlloc (g_hHeap, 0, GrowBuf->Buf, GrowTo);
  67. if (!NewBuffer) {
  68. DEBUGMSG ((DBG_ERROR, "GrowBuffer: Realloc failed"));
  69. return NULL;
  70. }
  71. GrowBuf->Size = GrowTo;
  72. GrowBuf->Buf = NewBuffer;
  73. }
  74. NewBuffer = GrowBuf->Buf + GrowBuf->End;
  75. GrowBuf->End += SpaceNeeded;
  76. return NewBuffer;
  77. }
  78. PBYTE
  79. RealGrowBufferReserve (
  80. IN PGROWBUFFER GrowBuf,
  81. IN DWORD BytesToReserve
  82. )
  83. {
  84. DWORD end;
  85. PBYTE result;
  86. MYASSERT(GrowBuf);
  87. MYASSERT(BytesToReserve);
  88. end = GrowBuf->End;
  89. result = GrowBuffer (GrowBuf, BytesToReserve);
  90. GrowBuf->End = end;
  91. return result;
  92. }
  93. VOID
  94. FreeGrowBuffer (
  95. IN PGROWBUFFER GrowBuf
  96. )
  97. /*++
  98. Routine Description:
  99. FreeGrowBuffer frees a buffer allocated by GrowBuffer.
  100. Arguments:
  101. GrowBuf - A pointer to the same structure passed to GrowBuffer
  102. Return Value:
  103. none
  104. --*/
  105. {
  106. MYASSERT(GrowBuf);
  107. if (GrowBuf->Buf) {
  108. MemFree (g_hHeap, 0, GrowBuf->Buf);
  109. ZeroMemory (GrowBuf, sizeof (GROWBUFFER));
  110. }
  111. }
  112. /*++
  113. Routine Descriptions:
  114. MultiSzAppend
  115. This function is a general-purpose function to append a string
  116. to a grow buffer.
  117. MultiSzAppendVal
  118. This function adds a key=decimal_val string, where key is a
  119. specified string, and decimal_val is a specified DWORD.
  120. MultiSzAppendString
  121. This function adds key=string to the grow buffer, where key
  122. is a specified string, and string is a specified string value.
  123. Arguments:
  124. GrowBuf - The buffer to append the string or key/value pair
  125. Key - The key part of the key=val pair
  126. Val - The val part of the key=val pair
  127. Return Value:
  128. TRUE if the function succeeded, or FALSE if a memory allocation
  129. failure occurred.
  130. --*/
  131. BOOL
  132. RealMultiSzAppendA (
  133. PGROWBUFFER GrowBuf,
  134. PCSTR String
  135. )
  136. {
  137. PSTR p;
  138. if(!GrowBuf || !String){
  139. MYASSERT(GrowBuf);
  140. MYASSERT(String);
  141. return FALSE;
  142. }
  143. p = (PSTR) GrowBuffer (GrowBuf, SizeOfStringA (String) + sizeof(CHAR));
  144. if (!p) {
  145. return FALSE;
  146. }
  147. StringCopyA (p, String);
  148. GrowBuf->End -= sizeof (CHAR);
  149. GrowBuf->Buf[GrowBuf->End] = 0;
  150. return TRUE;
  151. }
  152. BOOL
  153. RealMultiSzAppendValA (
  154. PGROWBUFFER GrowBuf,
  155. PCSTR Key,
  156. DWORD Val
  157. )
  158. {
  159. CHAR KeyValPair[256];
  160. MYASSERT(GrowBuf);
  161. MYASSERT(Key);
  162. /*
  163. //BUGBUG: Decided to leave it as it was, because we know callers.
  164. if(!GrowBuf || !Key){
  165. MYASSERT(GrowBuf);
  166. MYASSERT(Key);
  167. return FALSE;
  168. }
  169. if(_snprintf(KeyValPair, ARRAYSIZE(KeyValPair), "%s=%u", Key, Val) < 0){
  170. DEBUGMSG((DBG_ERROR, "RealMultiSzAppendValA: Key was truncated, function fails."));
  171. //KeyValPair[ARRAYSIZE(KeyValPair) - 1] = '\0';
  172. return FALSE;//Continue with truncated string or return FALSE;
  173. }
  174. */
  175. wsprintfA (KeyValPair, "%s=%u", Key, Val);
  176. return MultiSzAppendA (GrowBuf, KeyValPair);
  177. }
  178. BOOL
  179. RealMultiSzAppendStringA (
  180. PGROWBUFFER GrowBuf,
  181. PCSTR Key,
  182. PCSTR Val
  183. )
  184. {
  185. CHAR KeyValPair[1024];
  186. MYASSERT(GrowBuf);
  187. MYASSERT(Key);
  188. MYASSERT(Val);
  189. /*
  190. //BUGBUG: Decided to leave it as it was, because we know callers.
  191. if(!GrowBuf || !Key || !Val){
  192. MYASSERT(GrowBuf);
  193. MYASSERT(Key);
  194. MYASSERT(Val);
  195. return FALSE;
  196. }
  197. if(_snprintf(KeyValPair, ARRAYSIZE(KeyValPair), "%s=%s", Key, Val) < 0){
  198. DEBUGMSG((DBG_ERROR, "RealMultiSzAppendStringA: Key was truncated, function fails."));
  199. //KeyValPair[ARRAYSIZE(KeyValPair) - 1] = '\0';
  200. return FALSE;//BUGBUG: Continue with truncated string or return FALSE;
  201. }
  202. */
  203. wsprintfA (KeyValPair, "%s=%s", Key, Val);
  204. return MultiSzAppendA (GrowBuf, KeyValPair);
  205. }
  206. BOOL
  207. RealMultiSzAppendW (
  208. PGROWBUFFER GrowBuf,
  209. PCWSTR String
  210. )
  211. {
  212. PWSTR p;
  213. if(!GrowBuf || !String){
  214. MYASSERT(GrowBuf);
  215. MYASSERT(String);
  216. return FALSE;
  217. }
  218. p = (PWSTR) GrowBuffer (GrowBuf, SizeOfStringW (String) + sizeof(WCHAR));
  219. if (!p) {
  220. return FALSE;
  221. }
  222. StringCopyW (p, String);
  223. GrowBuf->End -= sizeof (WCHAR);
  224. *((PWCHAR) (GrowBuf->Buf + GrowBuf->End)) = 0;
  225. return TRUE;
  226. }
  227. BOOL
  228. RealMultiSzAppendValW (
  229. PGROWBUFFER GrowBuf,
  230. PCWSTR Key,
  231. DWORD Val
  232. )
  233. {
  234. WCHAR KeyValPair[256];
  235. MYASSERT(GrowBuf);
  236. MYASSERT(Key);
  237. /*
  238. //BUGBUG: Decided to leave it as it was, because we know callers.
  239. if(!GrowBuf || !Key){
  240. MYASSERT(GrowBuf);
  241. MYASSERT(Key);
  242. return FALSE;
  243. }
  244. if(_snwprintf(KeyValPair, ARRAYSIZE(KeyValPair), L"%s=%u", Key, Val) < 0){
  245. DEBUGMSG((DBG_ERROR, "RealMultiSzAppendValW: Key was truncated, function fails."));
  246. //KeyValPair[ARRAYSIZE(KeyValPair) - 1] = '\0';
  247. return FALSE;//BUGBUG: Continue with truncated string or return FALSE;
  248. }
  249. */
  250. wsprintfW (KeyValPair, L"%s=%u", Key, Val);
  251. return MultiSzAppendW (GrowBuf, KeyValPair);
  252. }
  253. BOOL
  254. RealMultiSzAppendStringW (
  255. PGROWBUFFER GrowBuf,
  256. PCWSTR Key,
  257. PCWSTR Val
  258. )
  259. {
  260. WCHAR KeyValPair[1024];
  261. MYASSERT(GrowBuf);
  262. MYASSERT(Key);
  263. MYASSERT(Val);
  264. /*
  265. //BUGBUG: Decided to leave it as it was, because we know callers.
  266. if(!GrowBuf || !Key || !Val){
  267. MYASSERT(GrowBuf);
  268. MYASSERT(Key);
  269. MYASSERT(Val);
  270. return FALSE;
  271. }
  272. if(_snwprintf(KeyValPair, ARRAYSIZE(KeyValPair), L"%s=%s", Key, Val) < 0){
  273. DEBUGMSG((DBG_ERROR, "RealMultiSzAppendStringW: Key was truncated, function fails."));
  274. //KeyValPair[ARRAYSIZE(KeyValPair) - 1] = '\0';
  275. return FALSE;//BUGBUG: Continue with truncated string or return FALSE;
  276. }
  277. */
  278. wsprintfW (KeyValPair, L"%s=%s", Key, Val);
  279. return MultiSzAppendW (GrowBuf, KeyValPair);
  280. }
  281. BOOL
  282. RealGrowBufAppendDword (
  283. PGROWBUFFER GrowBuf,
  284. DWORD d
  285. )
  286. {
  287. PDWORD p;
  288. if(!GrowBuf){
  289. MYASSERT(GrowBuf);
  290. return FALSE;
  291. }
  292. p = (PDWORD) GrowBuffer (GrowBuf, sizeof (DWORD));
  293. if (!p) {
  294. return FALSE;
  295. }
  296. *p = d;
  297. return TRUE;
  298. }
  299. BOOL
  300. RealGrowBufAppendUintPtr (
  301. PGROWBUFFER GrowBuf,
  302. UINT_PTR d
  303. )
  304. {
  305. PUINT_PTR p;
  306. if(!GrowBuf){
  307. MYASSERT(GrowBuf);
  308. return FALSE;
  309. }
  310. p = (PUINT_PTR) GrowBuffer (GrowBuf, sizeof (UINT_PTR));
  311. if (!p) {
  312. return FALSE;
  313. }
  314. *p = d;
  315. return TRUE;
  316. }
  317. /*++
  318. Routine Description:
  319. GrowBufAppendString copies the specified string to the end of the grow
  320. buffer. This is the equivalent of strcat. The grow buffer is
  321. automatically expanded as necessary.
  322. Arguments:
  323. GrowBuf - Specifies the destination grow buffer
  324. String - Specifies the string to append
  325. Return Value:
  326. Always TRUE.
  327. --*/
  328. BOOL
  329. RealGrowBufAppendStringA (
  330. IN OUT PGROWBUFFER GrowBuf,
  331. IN PCSTR String
  332. )
  333. {
  334. UINT OldEnd;
  335. PSTR p;
  336. UINT Bytes;
  337. if(!GrowBuf){
  338. MYASSERT(GrowBuf);
  339. return FALSE;
  340. }
  341. if (String) {
  342. Bytes = SizeOfStringA (String);
  343. OldEnd = GrowBuf->End;
  344. if (OldEnd) {
  345. p = (PSTR) (GrowBuf->Buf + OldEnd - sizeof (CHAR));
  346. if (*p == 0) {
  347. OldEnd -= sizeof (CHAR);
  348. }
  349. }
  350. RealGrowBuffer (GrowBuf, Bytes);
  351. p = (PSTR) (GrowBuf->Buf + OldEnd);
  352. StringCopyA (p, String);
  353. GrowBuf->End = OldEnd + Bytes;
  354. }
  355. return TRUE;
  356. }
  357. BOOL
  358. RealGrowBufAppendStringW (
  359. IN OUT PGROWBUFFER GrowBuf,
  360. IN PCWSTR String
  361. )
  362. {
  363. UINT OldEnd;
  364. PWSTR p;
  365. UINT Bytes;
  366. if(!GrowBuf){
  367. MYASSERT(GrowBuf);
  368. return FALSE;
  369. }
  370. if (String) {
  371. Bytes = SizeOfStringW (String);
  372. OldEnd = GrowBuf->End;
  373. if (OldEnd) {
  374. p = (PWSTR) (GrowBuf->Buf + OldEnd - sizeof (WCHAR));
  375. if (*p == 0) {
  376. OldEnd -= sizeof (WCHAR);
  377. }
  378. }
  379. RealGrowBuffer (GrowBuf, Bytes);
  380. p = (PWSTR) (GrowBuf->Buf + OldEnd);
  381. StringCopyW (p, String);
  382. GrowBuf->End = OldEnd + Bytes;
  383. }
  384. return TRUE;
  385. }
  386. /*++
  387. Routine Description:
  388. GrowBufAppendStringAB copies the specified string range to the
  389. end of the grow buffer. This concatenates the string to the
  390. existing buffer contents, and keeps the buffer terminated.
  391. Arguments:
  392. GrowBuf - Specifies the destination grow buffer
  393. Start - Specifies the start of string to append
  394. EndPlusOne - Specifies one logical character beyond the end of
  395. the string, and can point to a nul.
  396. Return Value:
  397. Always TRUE.
  398. --*/
  399. BOOL
  400. RealGrowBufAppendStringABA (
  401. IN OUT PGROWBUFFER GrowBuf,
  402. IN PCSTR Start,
  403. IN PCSTR EndPlusOne
  404. )
  405. {
  406. UINT OldEnd;
  407. PSTR p;
  408. UINT Bytes;
  409. if(!GrowBuf){
  410. MYASSERT(GrowBuf);
  411. return FALSE;
  412. }
  413. if (Start && Start < EndPlusOne) {
  414. Bytes = (UINT) (UINT_PTR) ((PBYTE) EndPlusOne - (PBYTE) Start);
  415. OldEnd = GrowBuf->End;
  416. if (OldEnd) {
  417. p = (PSTR) (GrowBuf->Buf + OldEnd - sizeof (CHAR));
  418. if (*p == 0) {
  419. OldEnd -= sizeof (CHAR);
  420. }
  421. }
  422. RealGrowBuffer (GrowBuf, Bytes + sizeof (CHAR));
  423. p = (PSTR) (GrowBuf->Buf + OldEnd);
  424. CopyMemory (p, Start, Bytes);
  425. p = (PSTR) ((PBYTE) p + Bytes);
  426. *p = 0;
  427. GrowBuf->End = OldEnd + Bytes + sizeof (CHAR);
  428. }
  429. return TRUE;
  430. }
  431. BOOL
  432. RealGrowBufAppendStringABW (
  433. IN OUT PGROWBUFFER GrowBuf,
  434. IN PCWSTR Start,
  435. IN PCWSTR EndPlusOne
  436. )
  437. {
  438. UINT OldEnd;
  439. PWSTR p;
  440. UINT Bytes;
  441. if(!GrowBuf){
  442. MYASSERT(GrowBuf);
  443. return FALSE;
  444. }
  445. if (Start && Start < EndPlusOne) {
  446. Bytes = (UINT) (UINT_PTR) ((PBYTE) EndPlusOne - (PBYTE) Start);
  447. OldEnd = GrowBuf->End;
  448. if (OldEnd > sizeof (WCHAR)) {
  449. p = (PWSTR) (GrowBuf->Buf + OldEnd - sizeof (WCHAR));
  450. if (*p == 0) {
  451. OldEnd -= sizeof (WCHAR);
  452. }
  453. }
  454. RealGrowBuffer (GrowBuf, Bytes + sizeof (WCHAR));
  455. p = (PWSTR) (GrowBuf->Buf + OldEnd);
  456. CopyMemory (p, Start, Bytes);
  457. p = (PWSTR) ((PBYTE) p + Bytes);
  458. *p = 0;
  459. GrowBuf->End = OldEnd + Bytes + sizeof (WCHAR);
  460. }
  461. return TRUE;
  462. }
  463. /*++
  464. Routine Description:
  465. GrowBufCopyString copies the specified string to the end of the grow buffer.
  466. Arguments:
  467. GrowBuf - Specifies the grow buffer to add to, receives the updated buffer
  468. String - Specifies the string to add to GrowBuf
  469. Return Value:
  470. --*/
  471. BOOL
  472. RealGrowBufCopyStringA (
  473. IN OUT PGROWBUFFER GrowBuf,
  474. IN PCSTR String
  475. )
  476. {
  477. PBYTE Buf;
  478. UINT Size;
  479. if(!GrowBuf || !String){
  480. MYASSERT(GrowBuf);
  481. MYASSERT(String);
  482. return FALSE;
  483. }
  484. Size = SizeOfStringA (String);
  485. Buf = RealGrowBuffer (GrowBuf, Size);
  486. if (!Buf) {
  487. return FALSE;
  488. }
  489. CopyMemory (Buf, String, Size);
  490. return TRUE;
  491. }
  492. BOOL
  493. RealGrowBufCopyStringW (
  494. IN OUT PGROWBUFFER GrowBuf,
  495. IN PCWSTR String
  496. )
  497. {
  498. PBYTE Buf;
  499. UINT Size;
  500. if(!GrowBuf || !String){
  501. MYASSERT(GrowBuf);
  502. MYASSERT(String);
  503. return FALSE;
  504. }
  505. Size = SizeOfStringW (String);
  506. Buf = RealGrowBuffer (GrowBuf, Size);
  507. if (!Buf) {
  508. return FALSE;
  509. }
  510. CopyMemory (Buf, String, Size);
  511. return TRUE;
  512. }