mirror of https://github.com/lianthony/NT4.0
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.
313 lines
6.3 KiB
313 lines
6.3 KiB
|
|
//
|
|
// Data block structure. Used to store a growing block of data.
|
|
//
|
|
//
|
|
// Structure used to amalgamate data
|
|
typedef struct _DATABLOCK {
|
|
//
|
|
// Current size of the data
|
|
//
|
|
LONG Size;
|
|
//
|
|
// The data itself
|
|
//
|
|
PUCHAR Data;
|
|
|
|
} DATABLOCK, *PDATABLOCK;
|
|
|
|
BOOL
|
|
InitDataBlock(
|
|
OUT PDATABLOCK DataBlock
|
|
);
|
|
|
|
VOID
|
|
TermDataBlock(
|
|
OUT PDATABLOCK DataBlock
|
|
);
|
|
|
|
LONG
|
|
AddToDataBlock(
|
|
IN OUT PDATABLOCK DataBlock,
|
|
IN PVOID Data,
|
|
IN DWORD DataSize
|
|
);
|
|
|
|
#define DataBlockIdToPointer(b,i) (((b)->Data)+i)
|
|
|
|
VOID
|
|
DataBlockIdsToPointers(
|
|
IN PDATABLOCK Block,
|
|
IN PVOID ArrayBase,
|
|
IN unsigned ArraySize,
|
|
IN unsigned ElementSize,
|
|
IN unsigned IdOffset
|
|
);
|
|
|
|
//
|
|
// String block structure. Used to store a growing list of strings.
|
|
// No attempt is made to sort, eliminate duplicates, etc.
|
|
// No provision is made for freeing space in the block.
|
|
//
|
|
|
|
typedef struct _STRINGBLOCK {
|
|
unsigned Size;
|
|
unsigned Used;
|
|
BOOL NeedToFree;
|
|
PWCHAR Data;
|
|
} STRINGBLOCK, *PSTRINGBLOCK;
|
|
|
|
#define STRBLK_SIZE_BYTES(s) ((s)->Size*sizeof(WCHAR))
|
|
#define STRBLK_USED_BYTES(s) ((s)->Used*sizeof(WCHAR))
|
|
|
|
#define StringBlockIdToPointer(Block,Id) (((Block)->Data)+Id)
|
|
|
|
PSTRINGBLOCK
|
|
CreateStringBlock(
|
|
VOID
|
|
);
|
|
|
|
BOOL
|
|
InitStringBlock(
|
|
IN OUT PSTRINGBLOCK Block
|
|
);
|
|
|
|
BOOL
|
|
ReinitStringBlock(
|
|
IN OUT PSTRINGBLOCK StringBlock,
|
|
IN PVOID Data
|
|
);
|
|
|
|
LONG
|
|
AddToStringBlock(
|
|
IN OUT PSTRINGBLOCK Block,
|
|
IN PCWSTR String
|
|
);
|
|
|
|
VOID
|
|
FreeStringBlock(
|
|
IN OUT PSTRINGBLOCK Block
|
|
);
|
|
|
|
VOID
|
|
StringBlockIdsToPointers(
|
|
IN PSTRINGBLOCK Block,
|
|
IN PVOID ArrayBase,
|
|
IN unsigned ArraySize,
|
|
IN unsigned ElementSize,
|
|
IN unsigned IdOffset
|
|
);
|
|
|
|
VOID
|
|
StringPointersToBlockIds(
|
|
IN PSTRINGBLOCK Block,
|
|
IN PVOID ArrayBase,
|
|
IN unsigned ArraySize,
|
|
IN unsigned ElementSize,
|
|
IN unsigned IdOffset
|
|
);
|
|
|
|
|
|
//
|
|
// Routines and macros to deal with a generic array.
|
|
//
|
|
typedef struct _MY_ARRAY {
|
|
//
|
|
// Total number of elements that could
|
|
// be stored in the buffer at its current size
|
|
//
|
|
unsigned Size;
|
|
|
|
//
|
|
// Current number of elements in the array buffer
|
|
//
|
|
unsigned Used;
|
|
|
|
//
|
|
// Element size in bytes
|
|
//
|
|
unsigned ElementSize;
|
|
|
|
//
|
|
// Amount to grow array in units
|
|
//
|
|
unsigned GrowthDelta;
|
|
|
|
//
|
|
// Boolean indicating whether this struct is static
|
|
// or needs to be freed
|
|
//
|
|
BOOL NeedsFreeing;
|
|
|
|
//
|
|
// The array itself
|
|
//
|
|
PVOID Data;
|
|
|
|
} MY_ARRAY, *PMY_ARRAY;
|
|
|
|
//
|
|
// Macro to create a new array.
|
|
//
|
|
// PMY_ARRAY
|
|
// NEW_ARRAY(
|
|
// IN ElementType,
|
|
// IN unsigned InitialElementCount,
|
|
// IN unsigned GrowthDelta
|
|
// );
|
|
//
|
|
#define NEW_ARRAY(type,initialsize,growthdelta) \
|
|
\
|
|
StartArray(NULL,initialsize,growthdelta,sizeof(type))
|
|
|
|
//
|
|
// Macro to initialize a static MY_ARRAY structure
|
|
//
|
|
// BOOL
|
|
// INIT_ARRAY(
|
|
// IN MY_ARRAY ArrayStruct,
|
|
// IN ElementType,
|
|
// IN unsigned InitialElementCount,
|
|
// IN unsigned GrowthDelta
|
|
// );
|
|
//
|
|
#define INIT_ARRAY(a,type,initialsize,growthdelta) \
|
|
\
|
|
(StartArray(&a,initialsize,growthdelta,sizeof(type)) != NULL)
|
|
|
|
//
|
|
// Macro to free an array.
|
|
//
|
|
// VOID
|
|
// FREE_ARRAY(
|
|
// IN OUT PMY_ARRAY Array
|
|
// );
|
|
//
|
|
#define FREE_ARRAY(a) FreeArray(a)
|
|
|
|
//
|
|
// Macro to determine how many elements are currently in the array
|
|
//
|
|
// unsigned
|
|
// ARRAY_SIZE(
|
|
// IN PMY_ARRAY Array
|
|
// );
|
|
//
|
|
#define ARRAY_USED(a) (a)->Used
|
|
#define ARRAY_SIZE(a) (a)->Size
|
|
|
|
//
|
|
// Macro to determine the size taken up in bytes by the array data
|
|
//
|
|
#define ARRAY_USED_BYTES(a) ((a)->Used*(a)->ElementSize)
|
|
#define ARRAY_SIZE_BYTES(a) ((a)->Size*(a)->ElementSize)
|
|
|
|
#define ARRAY_DATA(a) (a)->Data
|
|
#define ARRAY_ELEMENT_SIZE(a) (a)->ElementSize
|
|
|
|
//
|
|
// Macro to shrink down array data block to the min size
|
|
// it needs to be given current usage
|
|
//
|
|
#define TRIM_ARRAY(a) ResizeArray((a),-1)
|
|
|
|
//
|
|
// Macro to add an element to the end of an array, growing the array
|
|
// if necessary.
|
|
//
|
|
// BOOL
|
|
// ADD_TO_ARRAY(
|
|
// IN OUT PMY_ARRAY Array,
|
|
// IN NewElement
|
|
// );
|
|
//
|
|
#define ADD_TO_ARRAY(a,item) (((a)->Size == (a)->Used) \
|
|
\
|
|
? (GrowArray((a),0) && (CopyMemory((PUCHAR)((a)->Data)+((a)->Used*(a)->ElementSize),&item,(a)->ElementSize),++((a)->Used))) \
|
|
\
|
|
: (CopyMemory((PUCHAR)((a)->Data)+((a)->Used*(a)->ElementSize),&item,(a)->ElementSize),(a)->Used++))
|
|
|
|
//
|
|
// Macro to expand an array by a certain minimum delta.
|
|
// In other words, this macro guarantees that there is at least enough
|
|
// space in the array to store n more elements.
|
|
//
|
|
// BOOL
|
|
// EXPAND_ARRAY(
|
|
// IN OUT PMY_ARRAY Array,
|
|
// IN unsigned SlotsRequired
|
|
// );
|
|
//
|
|
#define EXPAND_ARRAY(a,n) (((a)->Used+(n) <= (a)->Size) ? TRUE : GrowArray((a),(n)))
|
|
|
|
//
|
|
// Macro to address individual array elements.
|
|
//
|
|
#define ARRAY_ELEMENT(a,n,type) (((type *)((a)->Data))[n])
|
|
|
|
|
|
|
|
//
|
|
// Routines -- do not use these, use the macros provided above.
|
|
//
|
|
PMY_ARRAY
|
|
StartArray(
|
|
OUT PMY_ARRAY ExistingStruct, OPTIONAL
|
|
IN unsigned InitialCount,
|
|
IN unsigned GrowthDelta,
|
|
IN unsigned ElementSize
|
|
);
|
|
|
|
BOOL
|
|
CopyDataIntoArray(
|
|
IN OUT PMY_ARRAY Array,
|
|
IN PVOID Data
|
|
);
|
|
|
|
BOOL
|
|
GrowArray(
|
|
IN PMY_ARRAY Array,
|
|
IN unsigned MinimumDelta OPTIONAL
|
|
);
|
|
|
|
VOID
|
|
FreeArray(
|
|
IN OUT PMY_ARRAY Array
|
|
);
|
|
|
|
BOOL
|
|
ResizeArray(
|
|
IN OUT PMY_ARRAY Array,
|
|
IN LONG ElementCount
|
|
);
|
|
|
|
|
|
|
|
//
|
|
// Define type of routine expected by qsort()
|
|
//
|
|
typedef
|
|
int
|
|
(_CRTAPI1 *PQSORTCB) (
|
|
const void *p1,
|
|
const void *p2
|
|
);
|
|
|
|
VOID
|
|
SortByStrings(
|
|
IN PSTRINGBLOCK StringBlock,
|
|
IN OUT PMY_ARRAY StructArray,
|
|
IN unsigned StructStringOffset,
|
|
IN PQSORTCB Compare
|
|
);
|
|
|
|
//
|
|
// Routine to use for Compare when dealing with
|
|
// an array of string pointers
|
|
//
|
|
int
|
|
_CRTAPI1
|
|
CompareStringsRoutine(
|
|
const void *p1,
|
|
const void *p2
|
|
);
|