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.
 
 
 
 
 
 

373 lines
7.4 KiB

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
string.c
Abstract:
The string stack portion of the un-assembler
Author:
Stephane Plante
Environment:
Any
Revision History:
--*/
#include "pch.h"
NTSTATUS
StringStackAllocate(
OUT PSTRING_STACK *StringStack
)
/*++
Routine Description:
This routine allocates memory and returns a string stack object
Arguments:
String Stack - Where to store a pointer to the stack
Return Value:
NTSTATUS
--*/
{
PSTRING_STACK tempStack;
NTSTATUS status = STATUS_SUCCESS;
//
// Make sure that we have some place to store the stack pointer
//
ASSERT( StringStack != NULL );
//
// Allocate a block of memory for the stack
//
tempStack = MEMORY_ALLOCATE(
sizeof(STRING_STACK) + ( STRING_GROWTH_RATE - 1 )
);
if (tempStack == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto StringStackAllocateExit;
}
//
// Setup the control block of the stack
//
tempStack->Signature = (ULONG) STRING_SIGNATURE;
tempStack->StackSize = STRING_GROWTH_RATE;
tempStack->TopOfStack = 0;
//
// Zero out the current elements on the stack
//
MEMORY_ZERO( tempStack->Stack, STRING_GROWTH_RATE );
//
// Return the stack pointer
//
StringStackAllocateExit:
*StringStack = tempStack;
return status;
}
NTSTATUS
StringStackClear(
IN OUT PSTRING_STACK *StringStack
)
/*++
Routine Description:
This routine wipes out the contents of the stack and
restarts it as if it was new allocated. Saves some from
freeing and reallocating a stack
Arguments:
StringStack - Where to find a pointer to the stack
Return Value:
NTSTATUS
--*/
{
PSTRING_STACK localStack;
//
// Make sure that we point to something
//
ASSERT( StringStack != NULL && *StringStack != NULL );
ASSERT( (*StringStack)->Signature == STRING_SIGNATURE );
//
// Zero out the stack
//
localStack = *StringStack;
MEMORY_ZERO( localStack->Stack, localStack->StackSize );
//
// Reset the TOS to the root
//
localStack->TopOfStack = 0;
//
// Done
//
return STATUS_SUCCESS;
}
NTSTATUS
StringStackFree(
IN OUT PSTRING_STACK *StringStack
)
/*++
Routine Description:
This routine frees the string stack
Arguments:
StringStack - Where to find a pointer to the stack
Return Value:
NTSTATUS
--*/
{
//
// Make sure that we point to something
//
ASSERT( StringStack != NULL && *StringStack != NULL );
ASSERT( (*StringStack)->Signature == STRING_SIGNATURE );
//
// Free the stack
//
MEMORY_FREE( *StringStack );
//
// Point the stack to nowhere
//
*StringStack = NULL;
return STATUS_SUCCESS;
}
NTSTATUS
StringStackPop(
IN OUT PSTRING_STACK *StringStack,
IN ULONG NumBytes,
OUT PUCHAR *String
)
/*++
Routine Description:
This routine returns a pointer to the requested offset from the end
of the stack
Note: String points to memory that can be freed at any time. It is the
caller's responsibility to make a copy
Arguments:
StringStack - Where to find a pointer to the stack
NumBytes - Number of bytes to pop off
String - Pointer to the bytes.
Return Value:
NTSTATUS
--*/
{
PSTRING_STACK localStack;
//
// Make sure that we point to something
//
ASSERT( StringStack != NULL );
ASSERT( (*StringStack)->Signature == STRING_SIGNATURE );
ASSERT( String != NULL );
//
// Is there an item that we can remove from the stack?
//
localStack = *StringStack;
if ( localStack->TopOfStack == 0 ||
localStack->TopOfStack < NumBytes) {
return STATUS_FAIL_CHECK;
}
//
// Return a pointer to the requested bytes
//
localStack->TopOfStack -= NumBytes;
*String = &( localStack->Stack[ localStack->TopOfStack ] );
return STATUS_SUCCESS;
}
NTSTATUS
StringStackPush(
IN OUT PSTRING_STACK *StringStack,
IN ULONG StringLength,
IN PUCHAR String
)
/*++
Routine Description:
This routine obtains a pointer for an object on the top of the stack
and increments the top to point to something that can be then be used
again.
Arguments:
StringStack - Where to find a pointer to the stack
String - String to push onto stack
StringLength - How many bytes to push onto the stack
Return Value:
NTSTATUS
--*/
{
PSTRING_STACK localStack;
PSTRING_STACK tempStack;
ULONG newSize;
//
// Make sure that we point to something
//
ASSERT( StringStack != NULL );
ASSERT( String != NULL );
//
// Find the stack pointer and make sure that the signature is still
// valid
//
localStack = *StringStack;
ASSERT( localStack->Signature == STRING_SIGNATURE );
//
// Do we have enough space on the stack?
//
if ( localStack->TopOfStack + StringLength > localStack->StackSize ) {
//
// Figure out how many bytes by which to grow the stack and how
// large the total stack should be
//
newSize = sizeof(STRING_STACK) + localStack->StackSize +
STRING_GROWTH_RATE - 1;
//
// Grow the stack
//
tempStack = MEMORY_ALLOCATE( newSize );
if (tempStack == NULL) {
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// Empty the new stack and copy the old one to it
//
MEMORY_ZERO( tempStack->Stack, newSize - sizeof(STRING_STACK) + 1);
MEMORY_COPY( tempStack, localStack , newSize - STRING_GROWTH_RATE);
//
// Make sure that the new stack has the correct size
//
tempStack->StackSize += STRING_GROWTH_RATE;
//
// Free the old stack
//
StringStackFree( StringStack );
//
// Set the stack to point to the new one
//
*StringStack = localStack = tempStack;
}
//
// Grab a pointer to the part that we will return to the caller
//
MEMORY_COPY(
&(localStack->Stack[ localStack->TopOfStack] ),
String,
StringLength
);
//
// Find the new Top of Stack
//
localStack->TopOfStack += StringLength;
//
// Done
//
return STATUS_SUCCESS;
}
NTSTATUS
StringStackRoot(
IN OUT PSTRING_STACK *StringStack,
OUT PUCHAR *RootElement
)
/*++
Routine Description:
This routine returns the topmost stack location that is in current use
Arguments:
Stack - Where the stack is located
RootElement - Where to store the pointer to the root stack element
Return Value:
NTSTATUS
--*/
{
ASSERT( StringStack != NULL && *StringStack != NULL );
ASSERT( (*StringStack)->Signature == STRING_SIGNATURE );
//
// Grab the top stack location
//
*RootElement = (PUCHAR) (*StringStack)->Stack;
//
// Done
//
return STATUS_SUCCESS;
}