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

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
growlist.c
Abstract:
Simple buffer management functions that maintenence of a list of binary
objects.
Author:
08-Aug-1997 jimschm Created
Revision History:
marcw 2-Sep-1999 Moved over from Win9xUpg project.
--*/
#include "pch.h"
#include "commonp.h"
#define INSERT_LAST 0xffffffff
PBYTE
pGlAdd (
IN OUT PGROWLIST GrowList,
IN UINT InsertBefore,
IN PBYTE DataToAdd, OPTIONAL
IN UINT SizeOfData,
IN UINT NulBytesToAdd
)
/*++
Routine Description:
pGlAdd allocates memory for a binary block by using a pool, and then expands
an array of pointers, maintaining a quick-access list.
Arguments:
GrowList - Specifies the list to add the entry to
InsertBefore - Specifies the index of the array element to insert
before, or INSERT_LIST to append.
DataToAdd - Specifies the binary block of data to add.
SizeOfData - Specifies the size of data.
NulBytesToAdd - Specifies the number of nul bytes to add to the buffer
Return Value:
A pointer to the binary block if data was copied into the list, 1 if a list
item was created but no data was set for the item, or NULL if an error
occurred.
--*/
{
PBYTE *Item;
PBYTE *InsertAt;
PBYTE Data;
UINT OldEnd;
UINT Size;
UINT TotalSize;
TotalSize = SizeOfData + NulBytesToAdd;
MYASSERT (TotalSize || !DataToAdd);
//
// Expand list array
//
OldEnd = GrowList->ListArray.End;
Item = (PBYTE *) GbGrow (&GrowList->ListArray, sizeof (PBYTE));
if (!Item) {
DEBUGMSG ((DBG_WARNING, "GrowList: Could not allocate array item"));
return NULL;
}
//
// Copy data
//
if (DataToAdd || NulBytesToAdd) {
Data = FAST_MALLOC (TotalSize);
if (!Data) {
GrowList->ListArray.End = OldEnd;
DEBUGMSG ((DBG_WARNING, "GrowList: Could not allocate data block"));
return NULL;
}
if (DataToAdd) {
CopyMemory (Data, DataToAdd, SizeOfData);
}
if (NulBytesToAdd) {
ZeroMemory (Data + SizeOfData, NulBytesToAdd);
}
} else {
Data = NULL;
}
//
// Adjust array
//
Size = GlGetSize (GrowList);
if (InsertBefore >= Size) {
//
// Append mode
//
*Item = Data;
} else {
//
// Insert mode
//
InsertAt = (PBYTE *) (GrowList->ListArray.Buf) + InsertBefore;
MoveMemory (&InsertAt[1], InsertAt, (Size - InsertBefore) * sizeof (PBYTE));
*InsertAt = Data;
}
return Data ? Data : (PBYTE) 1;
}
VOID
GlFree (
IN PGROWLIST GrowList
)
/*++
Routine Description:
GlFree frees the resources allocated by a GROWLIST.
Arguments:
GrowList - Specifies the list to clean up
Return Value:
none
--*/
{
if (!GrowList) {
return;
}
GlReset (GrowList);
GbFree (&GrowList->ListArray);
ZeroMemory (GrowList, sizeof (GROWLIST));
}
VOID
GlReset (
IN OUT PGROWLIST GrowList
)
/*++
Routine Description:
GlReset empties the grow list but does not destroy the index buffer or pool.
It is used to efficiently reuse a list.
Arguments:
GrowList - Specifies the list to clean up
Return Value:
none
--*/
{
UINT u;
UINT count;
PBYTE *dataPtr;
if (!GrowList) {
MYASSERT (FALSE);
return;
}
count = GlGetSize (GrowList);
dataPtr = (PBYTE *) (GrowList->ListArray.Buf);
for (u = 0 ; u < count ; u++) {
FAST_FREE (dataPtr[u]);
}
GrowList->ListArray.End = 0;
}
PBYTE
GlGetItem (
IN PGROWLIST GrowList,
IN UINT Index
)
/*++
Routine Description:
GlGetItem returns a pointer to the block of data for item specified by
Index.
Arguments:
GrowList - Specifies the list to access
Index - Specifies zero-based index of item in list to access
Return Value:
A pointer to the item's data, or NULL if the Index does not
represent an actual item.
--*/
{
PBYTE *ItemPtr;
UINT Size;
Size = GlGetSize (GrowList);
if (Index >= Size) {
return NULL;
}
ItemPtr = (PBYTE *) (GrowList->ListArray.Buf);
MYASSERT(ItemPtr);
return ItemPtr[Index];
}
UINT
GlGetSize (
IN PGROWLIST GrowList
)
/*++
Routine Description:
GlGetSize calculates the number of items in the list.
Arguments:
GrowList - Specifies the list to calculate the size of
Return Value:
The number of items in the list, or zero if the list is empty.
--*/
{
return GrowList->ListArray.End / sizeof (PBYTE);
}
PBYTE
RealGlAppend (
IN OUT PGROWLIST GrowList,
IN PBYTE DataToAppend, OPTIONAL
IN UINT SizeOfData
)
/*++
Routine Description:
GlAppend appends a black of data as a new list item.
Arguments:
GrowList - Specifies the list to modify
DataToAppend - Specifies a block of data to be copied
SizeOfData - Specifies the number of bytes in DataToAppend
Return Value:
A pointer to the binary block if data was copied into the list, 1 if a list
item was created but no data was set for the item, or NULL if an error
occurred.
--*/
{
return pGlAdd (GrowList, INSERT_LAST, DataToAppend, SizeOfData, 0);
}
PBYTE
RealGlAppendAddNul (
IN OUT PGROWLIST GrowList,
IN PBYTE DataToAppend, OPTIONAL
IN UINT SizeOfData
)
/*++
Routine Description:
GlAppend appends a black of data as a new list item and appends two zero
bytes (used for string termination).
Arguments:
GrowList - Specifies the list to modify
DataToAppend - Specifies a block of data to be copied
SizeOfData - Specifies the number of bytes in DataToAppend
Return Value:
A pointer to the binary block if data was copied into the list, 1 if a list
item was created but no data was set for the item, or NULL if an error
occurred.
--*/
{
return pGlAdd (GrowList, INSERT_LAST, DataToAppend, SizeOfData, 2);
}
PBYTE
RealGlInsert (
IN OUT PGROWLIST GrowList,
IN UINT Index,
IN PBYTE DataToInsert, OPTIONAL
IN UINT SizeOfData
)
/*++
Routine Description:
GlAppend inserts a black of data as a new list item, before the specified
Index.
Arguments:
GrowList - Specifies the list to modify
Index - Specifies the zero-based index of item to insert ahead of.
DataToInsert - Specifies a block of data to be copied
SizeOfData - Specifies the number of bytes in DataToInsert
Return Value:
A pointer to the binary block if data was copied into the list, 1 if a list
item was created but no data was set for the item, or NULL if an error
occurred.
--*/
{
UINT Size;
Size = GlGetSize (GrowList);
if (Index > Size) {
return NULL;
}
return pGlAdd (GrowList, Index, DataToInsert, SizeOfData, 0);
}
PBYTE
RealGlInsertAddNul (
IN OUT PGROWLIST GrowList,
IN UINT Index,
IN PBYTE DataToInsert, OPTIONAL
IN UINT SizeOfData
)
/*++
Routine Description:
GlAppend inserts a block of data as a new list item, before the specified
Index. Two zero bytes are appended to the block of data (used for string
termination).
Arguments:
GrowList - Specifies the list to modify
Index - Specifies the zero-based index of item to insert ahead of.
DataToInsert - Specifies a block of data to be copied
SizeOfData - Specifies the number of bytes in DataToInsert
Return Value:
A pointer to the binary block if data was copied into the list, 1 if a list
item was created but no data was set for the item, or NULL if an error
occurred.
--*/
{
UINT Size;
Size = GlGetSize (GrowList);
if (Index > Size) {
return NULL;
}
return pGlAdd (GrowList, Index, DataToInsert, SizeOfData, 2);
}
BOOL
GlDeleteItem (
IN OUT PGROWLIST GrowList,
IN UINT Index
)
/*++
Routine Description:
GlDeleteItem removes an item from the list.
Arguments:
GrowList - Specifies the list to modify
Index - Specifies the zero-based index of the item to remove.
Return Value:
TRUE if the data block was removed from the list, or FALSE if
Index is invalid.
--*/
{
UINT Size;
PBYTE *DeleteAt;
Size = GlGetSize (GrowList);
if (Size <= Index) {
return FALSE;
}
DeleteAt = (PBYTE *) (GrowList->ListArray.Buf) + Index;
if (*DeleteAt) {
FAST_FREE (*DeleteAt);
}
Size--;
if (Size > Index) {
MoveMemory (DeleteAt, &DeleteAt[1], (Size - Index) * sizeof (PBYTE));
}
GrowList->ListArray.End = Size * sizeof (PBYTE);
return TRUE;
}
BOOL
GlResetItem (
IN OUT PGROWLIST GrowList,
IN UINT Index
)
/*++
Routine Description:
GlResetItem sets the list pointer of the specified item to NULL, freeing the
memory associated with the item's data.
Arguments:
GrowList - Specifies the list to modify
Index - Specifies the zero-based index of the item to reset.
Return Value:
TRUE if the data block was freed and the list element was nulled,
or FALSE if Index is invalid.
--*/
{
UINT Size;
PBYTE *ResetAt;
Size = GlGetSize (GrowList);
if (Size <= Index) {
return FALSE;
}
ResetAt = (PBYTE *) (GrowList->ListArray.Buf) + Index;
if (*ResetAt) {
FAST_FREE (*ResetAt);
}
*ResetAt = NULL;
return TRUE;
}
PBYTE
RealGlSetItem (
IN OUT PGROWLIST GrowList,
IN UINT Index,
IN PCBYTE DataToCopy,
IN UINT DataSize
)
/*++
Routine Description:
GlSetItem replaces the data associated with a list item.
Arguments:
GrowList - Specifies the list to modify
Index - Specifies the zero-based index of the item to remove.
DataToCopy - Specifies data to associate with the list item
DataSize - Specifies the size of Data
Return Value:
A pointer to the binary block if data was copied into the list, 1 if a list
item was created but no data was set for the item, or NULL if an error
occurred.
--*/
{
UINT Size;
PBYTE *ReplaceAt;
PBYTE Data;
MYASSERT (DataSize || !DataToCopy);
Size = GlGetSize (GrowList);
if (Size <= Index) {
return NULL;
}
//
// Copy data
//
if (DataToCopy) {
Data = FAST_MALLOC (DataSize);
if (!Data) {
DEBUGMSG ((DBG_WARNING, "GrowList: Could not allocate data block (2)"));
return NULL;
}
CopyMemory (Data, DataToCopy, DataSize);
} else {
Data = NULL;
}
//
// Update list pointer
//
ReplaceAt = (PBYTE *) (GrowList->ListArray.Buf) + Index;
if (*ReplaceAt) {
FAST_FREE (*ReplaceAt);
}
*ReplaceAt = Data;
return Data ? Data : (PBYTE) 1;
}