543 lines
9.8 KiB
C
543 lines
9.8 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1996 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
growbuf.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Simple buffer management functions that allow variable blocks to
|
||
|
be added as an array. (Initially used to build a SID array, where
|
||
|
each SID can be a different size.)
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Jim Schmidt (jimschm) 05-Feb-1997
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
jimschm 11-Aug-1998 Added GrowBufAppendString
|
||
|
calinn 15-Jan-1998 modified MultiSzAppend
|
||
|
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "pch.h"
|
||
|
|
||
|
#define DEFAULT_GROW_SIZE 8192
|
||
|
|
||
|
PBYTE
|
||
|
RealGrowBuffer (
|
||
|
IN OUT PGROWBUFFER GrowBuf,
|
||
|
IN DWORD SpaceNeeded
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
GrowBuffer makes sure there is enough bytes in the buffer
|
||
|
to accomodate SpaceNeeded. It allocates an initial buffer
|
||
|
when no buffer is allocated, and it reallocates the buffer
|
||
|
in increments of GrowBuf->Size (or DEFAULT_GROW_SIZE) when
|
||
|
needed.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
GrowBuf - A pointer to a GROWBUFFER structure.
|
||
|
Initialize this structure to zero for
|
||
|
the first call to GrowBuffer.
|
||
|
|
||
|
SpaceNeeded - The number of free bytes needed in the buffer
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
A pointer to the SpaceNeeded bytes, or NULL if a memory allocation
|
||
|
error occurred.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
PBYTE NewBuffer;
|
||
|
DWORD TotalSpaceNeeded;
|
||
|
DWORD GrowTo;
|
||
|
|
||
|
MYASSERT(SpaceNeeded);
|
||
|
|
||
|
if (!GrowBuf->Buf) {
|
||
|
GrowBuf->Size = 0;
|
||
|
GrowBuf->End = 0;
|
||
|
}
|
||
|
|
||
|
if (!GrowBuf->GrowSize) {
|
||
|
GrowBuf->GrowSize = DEFAULT_GROW_SIZE;
|
||
|
}
|
||
|
|
||
|
TotalSpaceNeeded = GrowBuf->End + SpaceNeeded;
|
||
|
if (TotalSpaceNeeded > GrowBuf->Size) {
|
||
|
GrowTo = (TotalSpaceNeeded + GrowBuf->GrowSize) - (TotalSpaceNeeded % GrowBuf->GrowSize);
|
||
|
} else {
|
||
|
GrowTo = 0;
|
||
|
}
|
||
|
|
||
|
if (!GrowBuf->Buf) {
|
||
|
GrowBuf->Buf = (PBYTE) MemAlloc (g_hHeap, 0, GrowTo);
|
||
|
if (!GrowBuf->Buf) {
|
||
|
DEBUGMSG ((DBG_ERROR, "GrowBuffer: Initial alloc failed"));
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
GrowBuf->Size = GrowTo;
|
||
|
} else if (GrowTo) {
|
||
|
NewBuffer = MemReAlloc (g_hHeap, 0, GrowBuf->Buf, GrowTo);
|
||
|
if (!NewBuffer) {
|
||
|
DEBUGMSG ((DBG_ERROR, "GrowBuffer: Realloc failed"));
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
GrowBuf->Size = GrowTo;
|
||
|
GrowBuf->Buf = NewBuffer;
|
||
|
}
|
||
|
|
||
|
NewBuffer = GrowBuf->Buf + GrowBuf->End;
|
||
|
GrowBuf->End += SpaceNeeded;
|
||
|
|
||
|
return NewBuffer;
|
||
|
}
|
||
|
|
||
|
|
||
|
PBYTE
|
||
|
RealGrowBufferReserve (
|
||
|
IN PGROWBUFFER GrowBuf,
|
||
|
IN DWORD BytesToReserve
|
||
|
)
|
||
|
{
|
||
|
DWORD end;
|
||
|
PBYTE result;
|
||
|
|
||
|
end = GrowBuf->End;
|
||
|
result = GrowBuffer (GrowBuf, BytesToReserve);
|
||
|
GrowBuf->End = end;
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
FreeGrowBuffer (
|
||
|
IN PGROWBUFFER GrowBuf
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
FreeGrowBuffer frees a buffer allocated by GrowBuffer.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
GrowBuf - A pointer to the same structure passed to GrowBuffer
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
none
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
{
|
||
|
MYASSERT(GrowBuf);
|
||
|
|
||
|
if (GrowBuf->Buf) {
|
||
|
MemFree (g_hHeap, 0, GrowBuf->Buf);
|
||
|
ZeroMemory (GrowBuf, sizeof (GROWBUFFER));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Descriptions:
|
||
|
|
||
|
MultiSzAppend
|
||
|
This function is a general-purpose function to append a string
|
||
|
to a grow buffer.
|
||
|
|
||
|
MultiSzAppendVal
|
||
|
This function adds a key=decimal_val string, where key is a
|
||
|
specified string, and decimal_val is a specified DWORD.
|
||
|
|
||
|
MultiSzAppendString
|
||
|
This function adds key=string to the grow buffer, where key
|
||
|
is a specified string, and string is a specified string value.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
GrowBuf - The buffer to append the string or key/value pair
|
||
|
Key - The key part of the key=val pair
|
||
|
Val - The val part of the key=val pair
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE if the function succeeded, or FALSE if a memory allocation
|
||
|
failure occurred.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
RealMultiSzAppendA (
|
||
|
PGROWBUFFER GrowBuf,
|
||
|
PCSTR String
|
||
|
)
|
||
|
{
|
||
|
PSTR p;
|
||
|
|
||
|
p = (PSTR) GrowBuffer (GrowBuf, SizeOfStringA (String) + sizeof(CHAR));
|
||
|
if (!p) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
StringCopyA (p, String);
|
||
|
GrowBuf->End -= sizeof (CHAR);
|
||
|
GrowBuf->Buf[GrowBuf->End] = 0;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
RealMultiSzAppendValA (
|
||
|
PGROWBUFFER GrowBuf,
|
||
|
PCSTR Key,
|
||
|
DWORD Val
|
||
|
)
|
||
|
{
|
||
|
CHAR KeyValPair[256];
|
||
|
|
||
|
wsprintfA (KeyValPair, "%s=%u", Key, Val);
|
||
|
return MultiSzAppendA (GrowBuf, KeyValPair);
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
RealMultiSzAppendStringA (
|
||
|
PGROWBUFFER GrowBuf,
|
||
|
PCSTR Key,
|
||
|
PCSTR Val
|
||
|
)
|
||
|
{
|
||
|
CHAR KeyValPair[1024];
|
||
|
|
||
|
wsprintfA (KeyValPair, "%s=%s", Key, Val);
|
||
|
return MultiSzAppendA (GrowBuf, KeyValPair);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
RealMultiSzAppendW (
|
||
|
PGROWBUFFER GrowBuf,
|
||
|
PCWSTR String
|
||
|
)
|
||
|
{
|
||
|
PWSTR p;
|
||
|
|
||
|
p = (PWSTR) GrowBuffer (GrowBuf, SizeOfStringW (String) + sizeof(WCHAR));
|
||
|
if (!p) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
StringCopyW (p, String);
|
||
|
GrowBuf->End -= sizeof (WCHAR);
|
||
|
*((PWCHAR) (GrowBuf->Buf + GrowBuf->End)) = 0;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
RealMultiSzAppendValW (
|
||
|
PGROWBUFFER GrowBuf,
|
||
|
PCWSTR Key,
|
||
|
DWORD Val
|
||
|
)
|
||
|
{
|
||
|
WCHAR KeyValPair[256];
|
||
|
|
||
|
wsprintfW (KeyValPair, L"%s=%u", Key, Val);
|
||
|
return MultiSzAppendW (GrowBuf, KeyValPair);
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
RealMultiSzAppendStringW (
|
||
|
PGROWBUFFER GrowBuf,
|
||
|
PCWSTR Key,
|
||
|
PCWSTR Val
|
||
|
)
|
||
|
{
|
||
|
WCHAR KeyValPair[1024];
|
||
|
|
||
|
wsprintfW (KeyValPair, L"%s=%s", Key, Val);
|
||
|
return MultiSzAppendW (GrowBuf, KeyValPair);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
RealGrowBufAppendDword (
|
||
|
PGROWBUFFER GrowBuf,
|
||
|
DWORD d
|
||
|
)
|
||
|
{
|
||
|
PDWORD p;
|
||
|
|
||
|
p = (PDWORD) GrowBuffer (GrowBuf, sizeof (DWORD));
|
||
|
if (!p) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
*p = d;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
GrowBufAppendString copies the specified string to the end of the grow
|
||
|
buffer. This is the equivalent of strcat. The grow buffer is
|
||
|
automatically expanded as necessary.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
GrowBuf - Specifies the destination grow buffer
|
||
|
String - Specifies the string to append
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Always TRUE.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
RealGrowBufAppendStringA (
|
||
|
IN OUT PGROWBUFFER GrowBuf,
|
||
|
IN PCSTR String
|
||
|
)
|
||
|
|
||
|
{
|
||
|
UINT OldEnd;
|
||
|
PSTR p;
|
||
|
UINT Bytes;
|
||
|
|
||
|
if (String) {
|
||
|
Bytes = SizeOfStringA (String);
|
||
|
|
||
|
OldEnd = GrowBuf->End;
|
||
|
if (OldEnd) {
|
||
|
p = (PSTR) (GrowBuf->Buf + OldEnd - sizeof (CHAR));
|
||
|
if (*p == 0) {
|
||
|
OldEnd -= sizeof (CHAR);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
RealGrowBuffer (GrowBuf, Bytes);
|
||
|
|
||
|
p = (PSTR) (GrowBuf->Buf + OldEnd);
|
||
|
StringCopyA (p, String);
|
||
|
GrowBuf->End = OldEnd + Bytes;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
RealGrowBufAppendStringW (
|
||
|
IN OUT PGROWBUFFER GrowBuf,
|
||
|
IN PCWSTR String
|
||
|
)
|
||
|
{
|
||
|
UINT OldEnd;
|
||
|
PWSTR p;
|
||
|
UINT Bytes;
|
||
|
|
||
|
if (String) {
|
||
|
Bytes = SizeOfStringW (String);
|
||
|
|
||
|
OldEnd = GrowBuf->End;
|
||
|
if (OldEnd) {
|
||
|
p = (PWSTR) (GrowBuf->Buf + OldEnd - sizeof (WCHAR));
|
||
|
if (*p == 0) {
|
||
|
OldEnd -= sizeof (WCHAR);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
RealGrowBuffer (GrowBuf, Bytes);
|
||
|
|
||
|
p = (PWSTR) (GrowBuf->Buf + OldEnd);
|
||
|
StringCopyW (p, String);
|
||
|
GrowBuf->End = OldEnd + Bytes;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
GrowBufAppendStringAB copies the specified string range to the
|
||
|
end of the grow buffer. This concatenates the string to the
|
||
|
existing buffer contents, and keeps the buffer terminated.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
GrowBuf - Specifies the destination grow buffer
|
||
|
Start - Specifies the start of string to append
|
||
|
EndPlusOne - Specifies one logical character beyond the end of
|
||
|
the string, and can point to a nul.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
Always TRUE.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
RealGrowBufAppendStringABA (
|
||
|
IN OUT PGROWBUFFER GrowBuf,
|
||
|
IN PCSTR Start,
|
||
|
IN PCSTR EndPlusOne
|
||
|
)
|
||
|
|
||
|
{
|
||
|
UINT OldEnd;
|
||
|
PSTR p;
|
||
|
UINT Bytes;
|
||
|
|
||
|
if (Start && Start < EndPlusOne) {
|
||
|
Bytes = (PBYTE) EndPlusOne - (PBYTE) Start;
|
||
|
|
||
|
OldEnd = GrowBuf->End;
|
||
|
if (OldEnd) {
|
||
|
p = (PSTR) (GrowBuf->Buf + OldEnd - sizeof (CHAR));
|
||
|
if (*p == 0) {
|
||
|
OldEnd -= sizeof (CHAR);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
RealGrowBuffer (GrowBuf, Bytes + sizeof (CHAR));
|
||
|
|
||
|
p = (PSTR) (GrowBuf->Buf + OldEnd);
|
||
|
CopyMemory (p, Start, Bytes);
|
||
|
p = (PSTR) ((PBYTE) p + Bytes);
|
||
|
*p = 0;
|
||
|
|
||
|
GrowBuf->End = OldEnd + Bytes + sizeof (CHAR);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
RealGrowBufAppendStringABW (
|
||
|
IN OUT PGROWBUFFER GrowBuf,
|
||
|
IN PCWSTR Start,
|
||
|
IN PCWSTR EndPlusOne
|
||
|
)
|
||
|
{
|
||
|
UINT OldEnd;
|
||
|
PWSTR p;
|
||
|
UINT Bytes;
|
||
|
|
||
|
if (Start && Start < EndPlusOne) {
|
||
|
Bytes = (PBYTE) EndPlusOne - (PBYTE) Start;
|
||
|
|
||
|
OldEnd = GrowBuf->End;
|
||
|
if (OldEnd > sizeof (WCHAR)) {
|
||
|
p = (PWSTR) (GrowBuf->Buf + OldEnd - sizeof (WCHAR));
|
||
|
if (*p == 0) {
|
||
|
OldEnd -= sizeof (WCHAR);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
RealGrowBuffer (GrowBuf, Bytes + sizeof (WCHAR));
|
||
|
|
||
|
p = (PWSTR) (GrowBuf->Buf + OldEnd);
|
||
|
CopyMemory (p, Start, Bytes);
|
||
|
p = (PWSTR) ((PBYTE) p + Bytes);
|
||
|
*p = 0;
|
||
|
|
||
|
GrowBuf->End = OldEnd + Bytes + sizeof (WCHAR);
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
GrowBufCopyString copies the specified string to the end of the grow buffer.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
GrowBuf - Specifies the grow buffer to add to, receives the updated buffer
|
||
|
|
||
|
String - Specifies the string to add to GrowBuf
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
RealGrowBufCopyStringA (
|
||
|
IN OUT PGROWBUFFER GrowBuf,
|
||
|
IN PCSTR String
|
||
|
)
|
||
|
{
|
||
|
PBYTE Buf;
|
||
|
UINT Size;
|
||
|
|
||
|
Size = SizeOfStringA (String);
|
||
|
|
||
|
Buf = RealGrowBuffer (GrowBuf, Size);
|
||
|
if (!Buf) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
CopyMemory (Buf, String, Size);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
RealGrowBufCopyStringW (
|
||
|
IN OUT PGROWBUFFER GrowBuf,
|
||
|
IN PCWSTR String
|
||
|
)
|
||
|
{
|
||
|
PBYTE Buf;
|
||
|
UINT Size;
|
||
|
|
||
|
Size = SizeOfStringW (String);
|
||
|
|
||
|
Buf = RealGrowBuffer (GrowBuf, Size);
|
||
|
if (!Buf) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
CopyMemory (Buf, String, Size);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|