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; }