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.
 
 
 
 
 
 

284 lines
10 KiB

// Ruler
// 1 2 3 4 5 6 7 8
//345678901234567890123456789012345678901234567890123456789012345678901234567890
/********************************************************************/
/* */
/* The standard layout. */
/* */
/* The standard layout for 'cpp' files in this code is as */
/* follows: */
/* */
/* 1. Include files. */
/* 2. Constants local to the class. */
/* 3. Data structures local to the class. */
/* 4. Data initializations. */
/* 5. Static functions. */
/* 6. Class functions. */
/* */
/* The constructor is typically the first function, class */
/* member functions appear in alphabetical order with the */
/* destructor appearing at the end of the file. Any section */
/* or function this is not required is simply omitted. */
/* */
/********************************************************************/
#include "InterfacePCH.hpp"
#include "Common.hpp"
#include "RockallBackEnd.hpp"
#include "RockallFrontEnd.hpp"
/********************************************************************/
/* */
/* Static member initialization. */
/* */
/* Static member initialization sets the initial value for all */
/* static members. */
/* */
/********************************************************************/
#pragma init_seg(compiler)
ROCKALL_BACK_END ROCKALL_BACK_END::DefaultBaseClass;
/********************************************************************/
/* */
/* Class constructor. */
/* */
/* The may be a situation where the Rockall Back End needs a */
/* constructor but this is certainly not expected to be */
/* very common. */
/* */
/********************************************************************/
ROCKALL_BACK_END::ROCKALL_BACK_END( void )
{ /* void */ }
/********************************************************************/
/* */
/* Delete allocation area. */
/* */
/* All memory requests are eventually sent back to the external */
/* deallocator. This function can be overloaded so that memory */
/* can be provided from any source. The default is to send */
/* it back to the operating system. */
/* */
/********************************************************************/
void ROCKALL_BACK_END::DeleteArea( void *Memory,int Size,bool User )
{
REGISTER DWORD NewSize = ((Size == 0) ? Size : 0);
#ifdef DEBUGGING
#ifdef ENABLE_ALLOCATION_STATISTICS
//
// When we are debugging print out trace information.
//
DebugPrint( "Delete\t 0x%08x %d bytes\n",Memory,Size );
#endif
#endif
//
// The NT 'VirtualFree' call requires the 'Size'
// to be zero. This may not be true of all
// deallocators so we pass the value and then
// replace it with zero above.
//
if ( VirtualFree( Memory,NewSize,MEM_RELEASE ) == NULL )
{ Failure( "Delete fails in DeleteArea" ); }
}
/********************************************************************/
/* */
/* The natural allocation size. */
/* */
/* We would like to know a good default size for allocations. */
/* We really don't have a clue so we ask the operating system */
/* for the size of an allocation granual. */
/* */
/********************************************************************/
int ROCKALL_BACK_END::NaturalSize( void )
{
STATIC SBIT32 AllocationSize = 0;
//
// Ask the operation system for the allocation
// granularity.
//
if ( AllocationSize <= 0 )
{
AUTO SYSTEM_INFO SystemInformation;
GetSystemInfo( & SystemInformation );
AllocationSize = (SBIT32) SystemInformation.dwAllocationGranularity;
}
return ((int) AllocationSize);
}
/********************************************************************/
/* */
/* New allocation area. */
/* */
/* All memory requests are eventually sent to the new external */
/* allocator. This function can be overloaded so that memory */
/* can be provided from any source. The default is to get */
/* new memory from the operating system. */
/* */
/********************************************************************/
void *ROCKALL_BACK_END::NewArea( int AlignMask,int Size,bool User )
{
//
// When there is an alignment requirement greater
// than the natural alignment provided by the
// operating system we have to play various tricks
// to allocate a suitable block. If not then we
// just do a normal allocation call.
//
if ( AlignMask > NaturalSize() )
{
REGISTER SBIT32 NewSize = (AlignMask + Size);
//
// We need to allocate a block with an
// alignment requirement greater than
// the operating system default. So we
// allocate a much larger block and
// release the parts we don't need.
//
while ( True )
{
REGISTER VOID *Reserved =
(
VirtualAlloc
(
NULL,
((DWORD) NewSize),
MEM_RESERVE,
PAGE_READWRITE
)
);
//
// Lets ensure we were able to find a suitable
// memory block. If not then we exit.
//
if ( Reserved != NULL )
{
//
// We just want to return the parts of
// the block we don't need but 'NT' is
// not smart enough. So we free the
// entire block.
//
if ( VirtualFree( Reserved,0,MEM_RELEASE ) )
{
REGISTER LONG Address = ((LONG) Reserved);
REGISTER VOID *NewMemory;
//
// Compute the base address of the part
// of the block we really want to allocate.
//
Address = ((Address + AlignMask) & ~AlignMask);
//
// Finally, lets reallocate the part of
// the block we wanted but just released
// and hope that nobody else got it before
// us.
//
NewMemory =
(
VirtualAlloc
(
((LPVOID) Address),
((DWORD) Size),
(MEM_RESERVE | MEM_COMMIT),
PAGE_READWRITE
)
);
//
// If it all worked we can exit.
//
if ( NewMemory != NULL )
{
#ifdef DEBUGGING
#ifdef ENABLE_ALLOCATION_STATISTICS
//
// When we are debugging output
// out trace information.
//
DebugPrint
(
"New\t\t 0x%08x %d bytes\n",
NewMemory,
Size
);
#endif
#endif
return ((void*) NewMemory);
}
}
else
{ return ((void*) AllocationFailure); }
}
else
{ return ((void*) AllocationFailure); }
}
}
else
{
REGISTER VOID *NewMemory;
//
// We can allocate directly from the operating
// system as the default alignment requirement
// is enough for this case.
//
NewMemory =
(
VirtualAlloc
(
NULL,
((DWORD) Size),
MEM_COMMIT,
PAGE_READWRITE
)
);
#ifdef DEBUGGING
#ifdef ENABLE_ALLOCATION_STATISTICS
if ( NewMemory != NULL )
{
//
// When we are debugging output out trace
// information.
//
DebugPrint( "New\t\t 0x%08x %d bytes\n",NewMemory,Size );
}
#endif
#endif
return ((void*) NewMemory);
}
}
/********************************************************************/
/* */
/* Class destructor. */
/* */
/* The may be a situation where the Rockall Back End needs a */
/* destructor but this is certainly not expected to be */
/* very common. */
/* */
/********************************************************************/
ROCKALL_BACK_END::~ROCKALL_BACK_END( void )
{ /* void */ }