// // Template Driver // Copyright (c) Microsoft Corporation, 1999. // // Module: SectMap.c // Author: Daniel Mihai (DMihai) // Created: 6/19/1999 2:39pm // // This module contains tests for MmMapViewOfSection & MmMapViewInSystemSpace. // // --- History --- // // 6/19/1999 (DMihai): initial version. // #include #include #include "active.h" #include "ContMem.h" #if !SECTMAP_ACTIVE void TdSectionMapTestProcessSpace( PVOID NotUsed ) { DbgPrint ("Buggy: sectmap test is disabled \n"); } void TdSectionMapTestSystemSpace( PVOID NotUsed ) { DbgPrint ("Buggy: sectmap test is disabled \n"); } #else NTKERNELAPI NTSTATUS MmCreateSection ( OUT PVOID *SectionObject, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL, IN PFILE_OBJECT File OPTIONAL ); NTKERNELAPI NTSTATUS MmMapViewOfSection( IN PVOID SectionToMap, IN PEPROCESS Process, IN OUT PVOID *CapturedBase, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset, IN OUT PSIZE_T CapturedViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect ); NTKERNELAPI NTSTATUS MmUnmapViewOfSection( IN PEPROCESS Process, IN PVOID BaseAddress ); ///////////////////////////////////////////////////////////////////////// // // macros // #define SECTMAP_TEST_FILE_SIZE (4 * 1024 * 1024) #ifndef SEC_COMMIT #define SEC_COMMIT 0x8000000 #endif ///////////////////////////////////////////////////////////////////////// // // test variations // void TdSectionMapTestProcessSpace( PVOID NotUsed ) { NTSTATUS Status; ULONG uCrtThreadId; ULONG uPagesNo; PULONG puCrtUlong; PEPROCESS pEProcess; PVOID pSectionObject; PVOID pViewBase; PVOID pAfterLastValidPage; HANDLE hFile; SIZE_T sizeView; LARGE_INTEGER liMaxSize; LARGE_INTEGER CurrentTime; LARGE_INTEGER liSectionOffset; UNICODE_STRING ustrFileName; OBJECT_ATTRIBUTES ObjAttrib; IO_STATUS_BLOCK IoStatusBlock; WCHAR strFileName[ 64 ] = L"\\DosDevices\\c:\\maptest"; WCHAR strThreadId[ 16 ]; uCrtThreadId = PtrToUlong( PsGetCurrentThreadId() ); // // generate the file name // swprintf( strThreadId, L"%u", uCrtThreadId ); wcscat( strFileName, strThreadId ); /* DbgPrint( "buggy: TdSectionMapTestProcessSpace: thread %u, using file %ws\n", uCrtThreadId, strFileName ); */ // // make it a UNICODE_STRING // RtlInitUnicodeString( &ustrFileName, strFileName ); InitializeObjectAttributes( &ObjAttrib, &ustrFileName, OBJ_CASE_INSENSITIVE, 0, 0 ); // // open the file // liMaxSize.QuadPart = SECTMAP_TEST_FILE_SIZE; Status = ZwCreateFile( &hFile, GENERIC_READ | GENERIC_WRITE, &ObjAttrib, &IoStatusBlock, &liMaxSize, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN_IF, FILE_WRITE_THROUGH | FILE_NO_INTERMEDIATE_BUFFERING | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); if( ! NT_SUCCESS( Status ) ) { DbgPrint( "buggy: TdSectionMapTestProcessSpace: thread %u, ZwCreateFile failed %X\n", uCrtThreadId, (ULONG)Status ); DbgBreakPoint(); return; } /* DbgPrint( "buggy: TdSectionMapTestProcessSpace: thread %u, file opened\n", uCrtThreadId ); */ ASSERT( IoStatusBlock.Information == FILE_CREATED || IoStatusBlock.Information == FILE_OPENED ); ASSERT( hFile != (HANDLE)-1 ); ASSERT( liMaxSize.QuadPart == SECTMAP_TEST_FILE_SIZE ); // // create the section // Status = MmCreateSection( &pSectionObject, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE, 0, &liMaxSize, PAGE_READWRITE, SEC_COMMIT, hFile, NULL ); ZwClose(hFile); if( ! NT_SUCCESS( Status ) ) { DbgPrint( "buggy: TdSectionMapTestProcessSpace: thread %u, MmCreateSection failed %X\n", uCrtThreadId, (ULONG)Status ); DbgBreakPoint(); return; } /* DbgPrint( "buggy: TdSectionMapTestProcessSpace: thread %u, section %p created\n", uCrtThreadId, pSectionObject ); */ // // map the section // sizeView = (SIZE_T)liMaxSize.LowPart; liSectionOffset.QuadPart = 0; pEProcess = PsGetCurrentProcess(); /* DbgPrint( "buggy: TdSectionMapTestProcessSpace: thread %u, mapping section %p in process %p\n", uCrtThreadId, pSectionObject, pEProcess ); */ pViewBase = NULL; Status = MmMapViewOfSection( pSectionObject, pEProcess, &pViewBase, 0, 0, &liSectionOffset, &sizeView, ViewUnmap, 0, // allocation type PAGE_READWRITE ); if( ! NT_SUCCESS( Status ) ) { // // dereference the section object // ObDereferenceObject( pSectionObject ); DbgPrint( "buggy: TdSectionMapTestProcessSpace: thread %u, MmMapViewOfSection failed %X\n", uCrtThreadId, (ULONG)Status ); DbgBreakPoint(); return; } /* DbgPrint( "buggy: TdSectionMapTestProcessSpace: thread %u, section mapped, pViewBase = %p\n", uCrtThreadId, pViewBase ); */ // DbgBreakPoint(); ASSERT( liSectionOffset.QuadPart == 0 ); ASSERT( sizeView == SECTMAP_TEST_FILE_SIZE ); ASSERT( pViewBase != NULL ); // // touch some of the pages // uPagesNo = (ULONG)sizeView / PAGE_SIZE; pAfterLastValidPage = (PVOID)( (ULONG_PTR)pViewBase + uPagesNo * PAGE_SIZE ); KeQuerySystemTime (&CurrentTime); puCrtUlong = (PULONG)( (ULONG_PTR)pViewBase + (CurrentTime.LowPart % 5) * PAGE_SIZE ); while( (ULONG_PTR)puCrtUlong < (ULONG_PTR)pAfterLastValidPage ) { /* DbgPrint( "buggy: TdSectionMapTestProcessSpace: thread %u, touching page %p\n", uCrtThreadId, puCrtUlong ); */ *puCrtUlong = CurrentTime.LowPart; KeQuerySystemTime (&CurrentTime); puCrtUlong = (PULONG)( (ULONG_PTR)puCrtUlong + (CurrentTime.LowPart % 5 + 1) * PAGE_SIZE ); } // // clean-up // // // un-map the section // /* DbgPrint( "buggy: TdSectionMapTestProcessSpace: thread %u, MmUnmapViewOfSection process %p, pViewBase = %p\n", uCrtThreadId, pEProcess, pViewBase ); */ Status = MmUnmapViewOfSection( pEProcess, pViewBase ); if( ! NT_SUCCESS( Status ) ) { DbgPrint( "buggy: TdSectionMapTestProcessSpace: thread %u, MmUnmapViewOfSection failed %X\n", uCrtThreadId, (ULONG)Status ); DbgBreakPoint(); } // // dereference the section object // /* DbgPrint( "buggy: TdSectionMapTestProcessSpace: thread %u, dereference section at %p\n", uCrtThreadId, pSectionObject ); */ ObDereferenceObject( pSectionObject ); } ///////////////////////////////////////////////////////////////////////// void TdSectionMapTestSystemSpace( PVOID NotUsed ) { NTSTATUS Status; ULONG uCrtThreadId; ULONG uPagesNo; PULONG puCrtUlong; PVOID pSectionObject; PVOID pViewBase; PVOID pAfterLastValidPage; HANDLE hFile; SIZE_T sizeView; LARGE_INTEGER liMaxSize; LARGE_INTEGER CurrentTime; LARGE_INTEGER liSectionOffset; UNICODE_STRING ustrFileName; OBJECT_ATTRIBUTES ObjAttrib; IO_STATUS_BLOCK IoStatusBlock; WCHAR strFileName[ 64 ] = L"\\DosDevices\\c:\\maptest"; WCHAR strThreadId[ 16 ]; uCrtThreadId = PtrToUlong( PsGetCurrentThreadId() ); // // generate the file name // swprintf( strThreadId, L"%u", uCrtThreadId ); wcscat( strFileName, strThreadId ); /* DbgPrint( "buggy: TdSectionMapTestSystemSpace: thread %u, using file %ws\n", uCrtThreadId, strFileName ); */ // // make it a UNICODE_STRING // RtlInitUnicodeString( &ustrFileName, strFileName ); InitializeObjectAttributes( &ObjAttrib, &ustrFileName, OBJ_CASE_INSENSITIVE, 0, 0 ); // // open the file // liMaxSize.QuadPart = SECTMAP_TEST_FILE_SIZE; Status = ZwCreateFile( &hFile, GENERIC_READ | GENERIC_WRITE, &ObjAttrib, &IoStatusBlock, &liMaxSize, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN_IF, FILE_WRITE_THROUGH | FILE_NO_INTERMEDIATE_BUFFERING | FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); if( ! NT_SUCCESS( Status ) ) { DbgPrint( "buggy: TdSectionMapTestSystemSpace: thread %u, ZwCreateFile failed %X\n", uCrtThreadId, (ULONG)Status ); DbgBreakPoint(); return; } /* DbgPrint( "buggy: TdSectionMapTestSystemSpace: thread %u, file opened\n", uCrtThreadId ); */ ASSERT( IoStatusBlock.Information == FILE_CREATED || IoStatusBlock.Information == FILE_OPENED ); ASSERT( hFile != (HANDLE)-1 ); ASSERT( liMaxSize.QuadPart == SECTMAP_TEST_FILE_SIZE ); // // create the section // Status = MmCreateSection( &pSectionObject, STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE, 0, &liMaxSize, PAGE_READWRITE, SEC_COMMIT, hFile, NULL ); ZwClose(hFile); if( ! NT_SUCCESS( Status ) ) { DbgPrint( "buggy: TdSectionMapTestSystemSpace: thread %u, MmCreateSection failed %X\n", uCrtThreadId, (ULONG)Status ); DbgBreakPoint(); return; } /* DbgPrint( "buggy: TdSectionMapTestSystemSpace: thread %u, section %p created\n", uCrtThreadId, pSectionObject ); */ // // map the section // sizeView = (SIZE_T)liMaxSize.LowPart; liSectionOffset.QuadPart = 0; /* DbgPrint( "buggy: TdSectionMapTestSystemSpace: thread %u, mapping section %p system space\n", uCrtThreadId, pSectionObject ); */ pViewBase = NULL; Status = MmMapViewInSystemSpace( pSectionObject, &pViewBase, &sizeView ); if( ! NT_SUCCESS( Status ) ) { // // dereference the section object // ObDereferenceObject( pSectionObject ); DbgPrint( "buggy: TdSectionMapTestSystemSpace: thread %u, MmMapViewInSystemSpace failed %X\n", uCrtThreadId, (ULONG)Status ); DbgBreakPoint(); return; } /* DbgPrint( "buggy: TdSectionMapTestSystemSpace: thread %u, section mapped, pViewBase = %p\n", uCrtThreadId, pViewBase ); */ // DbgBreakPoint(); ASSERT( liSectionOffset.QuadPart == 0 ); ASSERT( sizeView == SECTMAP_TEST_FILE_SIZE ); ASSERT( pViewBase != NULL ); // // touch some of the pages // uPagesNo = (ULONG)sizeView / PAGE_SIZE; pAfterLastValidPage = (PVOID)( (ULONG_PTR)pViewBase + uPagesNo * PAGE_SIZE ); KeQuerySystemTime (&CurrentTime); puCrtUlong = (PULONG)( (ULONG_PTR)pViewBase + (CurrentTime.LowPart % 5) * PAGE_SIZE ); while( (ULONG_PTR)puCrtUlong < (ULONG_PTR)pAfterLastValidPage ) { /* DbgPrint( "buggy: TdSectionMapTestSystemSpace: thread %u, touching page %p\n", uCrtThreadId, puCrtUlong ); */ *puCrtUlong = CurrentTime.LowPart; KeQuerySystemTime (&CurrentTime); puCrtUlong = (PULONG)( (ULONG_PTR)puCrtUlong + (CurrentTime.LowPart % 5 + 1) * PAGE_SIZE ); } // // clean-up // // // un-map the section // /* DbgPrint( "buggy: TdSectionMapTestSystemSpace: thread %u, MmUnmapViewInSystemSpace pViewBase = %p\n", uCrtThreadId, pViewBase ); */ Status = MmUnmapViewInSystemSpace( pViewBase ); if( ! NT_SUCCESS( Status ) ) { DbgPrint( "buggy: TdSectionMapTestSystemSpace: thread %u, MmUnmapViewInSystemSpace failed %X\n", uCrtThreadId, (ULONG)Status ); DbgBreakPoint(); } // // dereference the section object // /* DbgPrint( "buggy: TdSectionMapTestSystemSpace: thread %u, dereference section at %p\n", uCrtThreadId, pSectionObject ); */ ObDereferenceObject( pSectionObject ); } #endif // #if !SECTMAP_ACTIVE