Source code of Windows XP (NT5)
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.
|
|
/*++
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; }
|