240 lines
4.2 KiB
C
240 lines
4.2 KiB
C
|
/*++
|
||
|
|
||
|
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
|
||
|
}
|