|
|
/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
spmemory.c
Abstract:
Memory allocation routines for text setup.
Author:
Ted Miller (tedm) 29-July-1993
Revision History:
--*/
#include "spprecmp.h"
#pragma hdrstop
PVOID SpMemAlloc( IN SIZE_T Size ) { return(SpMemAllocEx(Size,'pteS', PagedPool)); }
PVOID SpMemAllocNonPagedPool( IN SIZE_T Size ) { return(SpMemAllocEx(Size,'pteS', NonPagedPool)); }
PVOID SpMemAllocEx( IN SIZE_T Size, IN ULONG Tag, IN POOL_TYPE Type )
/*++
Routine Description:
This function is guaranteed to succeed.
Arguments:
Return Value:
--*/
{ PSIZE_T p;
//
// Add space for storing the size of the block.
//
#if defined(SETUP_TEST_USERMODE)
p = RtlAllocateHeap(RtlProcessHeap(), 0, Size + (2 * sizeof(SIZE_T))); #else
p = ExAllocatePoolWithTag(Type, Size + (2 * sizeof(SIZE_T)), Tag); #endif
if(!p) {
SpOutOfMemory(); }
//
// Store the size of the block, and return the address
// of the user portion of the block.
//
*p = Tag; *(p + 1) = Size;
return(p + 2); }
PVOID SpMemRealloc( IN PVOID Block, IN SIZE_T NewSize )
/*++
Routine Description:
This function is guaranteed to succeed.
Arguments:
Return Value:
--*/
{ PSIZE_T NewBlock; SIZE_T OldSize; ULONG OldTag;
//
// Get the size of the block being reallocated.
//
OldTag = (ULONG)((PSIZE_T)Block)[-2]; OldSize = ((PSIZE_T)Block)[-1];
//
// Allocate a new block of the new size.
//
NewBlock = SpMemAllocEx(NewSize, OldTag, PagedPool); ASSERT(NewBlock);
//
// Copy the old block to the new block.
//
if (NewSize < OldSize) { RtlCopyMemory(NewBlock, Block, NewSize); } else { RtlCopyMemory(NewBlock, Block, OldSize); }
//
// Free the old block.
//
SpMemFree(Block);
//
// Return the address of the new block.
//
return(NewBlock); }
VOID SpMemFree( IN PVOID Block )
/*++
Routine Description:
Arguments:
Return Value:
--*/
{ extern PWSTR CommonStrings[11]; unsigned long i;
if (Block == NULL) return;
for( i = 0; i < sizeof(CommonStrings)/sizeof(PWSTR); i++ ) { if( (PWSTR)Block == CommonStrings[i] ) { return; } }
//
// Free the block at its real address.
//
#if defined(SETUP_TEST_USERMODE)
RtlFreeHeap(RtlProcessHeap(), 0, (PULONG_PTR)Block - 2); #else
ExFreePool((PULONG_PTR)Block - 2); #endif
}
VOID SpOutOfMemory( VOID ) { KdPrintEx((DPFLTR_SETUP_ID, DPFLTR_ERROR_LEVEL, "SETUP: Out of memory\n"));
#if !defined(SETUP_TEST_USERMODE)
if(VideoInitialized) { if(KbdLayoutInitialized) {
ULONG ValidKeys[2] = { KEY_F3,0 };
//
// We run a high risk of getting into an infinite loop
// here because SpStartScreen will result in a call to
// SpMemAlloc(), which will fail and call SpOutOfMemory
// again. In order to get around this, we'll jettison
// some memory that we won't need anymore (since we're
// about to die). These should give us enough memory
// to display the messages below.
//
SpFreeBootVars(); SpFreeArcNames();
while(1) { SpStartScreen(SP_SCRN_OUT_OF_MEMORY,5,0,FALSE,TRUE,DEFAULT_ATTRIBUTE);
SpDisplayStatusOptions( DEFAULT_STATUS_ATTRIBUTE, SP_STAT_F3_EQUALS_EXIT, 0 );
if(SpWaitValidKey(ValidKeys,NULL,NULL) == KEY_F3) { SpDone(0,FALSE,TRUE); } } } else { //
// we haven't loaded the layout dll yet, so we can't prompt for a keypress to reboot
//
SpStartScreen(SP_SCRN_OUT_OF_MEMORY_RAW,5,0,FALSE,TRUE,DEFAULT_ATTRIBUTE);
SpDisplayStatusOptions(DEFAULT_STATUS_ATTRIBUTE, SP_STAT_KBD_HARD_REBOOT, 0);
while(TRUE); // Loop forever
} } else { SpDisplayRawMessage(SP_SCRN_OUT_OF_MEMORY_RAW, 2); while(TRUE); // loop forever
} #endif
}
|