| Platform SDK: Memory |
The following sample program illustrates the Address Windowing Extensions for Windows 2000.
#include <windows.h>
#include <stdio.h>
#define MEMORY_REQUESTED 1024*1024 // request a megabyte
BOOL
LoggedSetLockPagesPrivilege ( HANDLE hProcess,
BOOL bEnable);
void _cdecl main()
{
BOOL bResult; // generic boolean value
ULONG_PTR NumberOfPages, // number of pages we will request
NumberOfPagesInitial; // initial number of pages requested
ULONG_PTR *aPFNs; // page info; holds opaque data
PVOID lpMemReserved; // AWE window
SYSTEM_INFO sSysInfo; // useful system information
int PFNArraySize; // memory to request for PFN array
GetSystemInfo(&sSysInfo); // populate the system information structure
printf ("This computer has a page size of %d.\n", sSysInfo.dwPageSize);
// Calculate the number of pages of memory we'll request.
NumberOfPages = MEMORY_REQUESTED/sSysInfo.dwPageSize;
printf ("Requesting %d pages of memory.\n", NumberOfPages);
// Calculate the size of the user PFN array.
PFNArraySize = NumberOfPages * sizeof (ULONG_PTR);
printf ("Requesting a PFN array of %d bytes.\n", PFNArraySize);
aPFNs = (ULONG_PTR *) HeapAlloc (GetProcessHeap (), 0, PFNArraySize);
if (aPFNs == NULL) {
printf ("Failed to allocate on heap.\n");
return;
}
// Enable the privilege.
if( ! LoggedSetLockPagesPrivilege( GetCurrentProcess(), TRUE ) ) {
return;
}
// Allocate the physical memory we want.
NumberOfPagesInitial = NumberOfPages;
bResult = AllocateUserPhysicalPages( GetCurrentProcess(),
&NumberOfPages,
aPFNs );
if( bResult != TRUE )
{
printf("Cannot allocate physical pages, error %u.\n", GetLastError() );
return;
}
if( NumberOfPagesInitial != NumberOfPages )
{
printf("Allocated only %p pages.\n", NumberOfPages );
return;
}
// Reserve the virtual memory.
lpMemReserved = VirtualAlloc( NULL,
MEMORY_REQUESTED,
MEM_RESERVE | MEM_PHYSICAL,
PAGE_READWRITE );
if( lpMemReserved == NULL )
{
printf("Cannot reserve memory.\n");
return;
}
// Map the physical memory into our window.
bResult = MapUserPhysicalPages( lpMemReserved,
NumberOfPages,
aPFNs );
if( bResult != TRUE )
{
printf("MapUserPhysicalPages failed to map, error %u.\n", GetLastError() );
return;
}
// unmap
bResult = MapUserPhysicalPages( lpMemReserved,
NumberOfPages,
NULL );
if( bResult != TRUE )
{
printf("MapUserPhysicalPages failed to unmap, error %u.\n", GetLastError() );
return;
}
// Free the physical pages.
bResult = FreeUserPhysicalPages( GetCurrentProcess(),
&NumberOfPages,
aPFNs );
if( bResult != TRUE )
{
printf("Cannot free physical pages, error %u.\n", GetLastError() );
return;
}
// Free virtual memory.
bResult = VirtualFree( lpMemReserved,
0,
MEM_RELEASE );
}
/*****************************************************************
LoggedSetLockPagesPrivilege: a function to obtain, if possible, or
release the privilege of locking physical pages.
Inputs:
HANDLE hProcess: Handle for the process for which we seek the
privilege
BOOL bEnable: Shall we enable (TRUE) or disable?
Return value: TRUE indicates success, FALSE failure.
*****************************************************************/
BOOL
LoggedSetLockPagesPrivilege ( HANDLE hProcess,
BOOL bEnable)
{
struct {
DWORD Count;
LUID_AND_ATTRIBUTES Privilege [1];
} Info;
HANDLE Token;
BOOL Result;
// Open the token.
Result = OpenProcessToken ( hProcess,
TOKEN_ADJUST_PRIVILEGES,
& Token);
if( Result != TRUE ) {
printf( "Cannot open process token.\n" );
return FALSE;
}
// Enable or disable?
Info.Count = 1;
if( bEnable )
{
Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
}
else
{
Info.Privilege[0].Attributes = 0;
}
// Get the LUID.
Result = LookupPrivilegeValue ( NULL,
SE_LOCK_MEMORY_NAME,
&(Info.Privilege[0].Luid));
if( Result != TRUE )
{
printf( "Cannot get privilege value for %s.\n", SE_LOCK_MEMORY_NAME );
return FALSE;
}
// Adjust the privilege.
Result = AdjustTokenPrivileges ( Token, FALSE,
(PTOKEN_PRIVILEGES) &Info,
NULL, NULL, NULL);
// Check the result.
if( Result != TRUE )
{
printf ("Cannot adjust token privileges, error %u.\n", GetLastError() );
return FALSE;
}
else
{
if( GetLastError() != ERROR_SUCCESS )
{
printf ("Cannot enable SE_LOCK_MEMORY privilege, please check the local policy.\n");
return FALSE;
}
}
CloseHandle( Token );
return TRUE;
}