600 lines
13 KiB
C
600 lines
13 KiB
C
|
//
|
||
|
// 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 <ntddk.h>
|
||
|
#include <wchar.h>
|
||
|
|
||
|
#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
|
||
|
|