// // Template Driver // Copyright (c) Microsoft Corporation, 2000. // // Module: ResrvMap.c // Author: Daniel Mihai (DMihai) // Created: 10/18/2000 // // This module contains tests for Mm APIs for reserved mapping addresses // // MmAllocateMappingAddress // MmFreeMappingAddress // MmMapLockedPagesWithReservedMapping // MmUnmapReservedMapping // // --- History --- // // 10/18/2000 (DMihai): initial version. // #include #include #include "active.h" #include "tdriver.h" #include "ResrvMap.h" #if !RESRVMAP_ACTIVE // // Dummy stubs in case this module is disabled // VOID TdReservedMappingSetSize( IN PVOID Irp ) { DbgPrint( "Buggy: ReservedMapping module is disabled (check \\driver\\active.h header)\n"); } #else //#if !RESRVMAP_ACTIVE // // This is the real stuff // ////////////////////////////////////////////////////////// // // Global data // // // Size of the current reserved mapping address // SIZE_T CrtReservedSize; // // Current reserved mapping address // PVOID CrtReservedAddress; ///////////////////////////////////////////////////////////////////// // // Clean-up a possible currently reserved buffer // Called for IRP_MJ_CLEANUP // VOID TdReservedMappingCleanup( VOID ) { if( NULL != CrtReservedAddress ) { DbgPrint( "Buggy: TdReservedMappingCleanup: free reserved mapping address %p\n", CrtReservedAddress ); MmFreeMappingAddress( CrtReservedAddress, TD_POOL_TAG ); } else { ASSERT( 0 == CrtReservedSize ); } } ///////////////////////////////////////////////////////////////////// // // Set the current reserved size and address as asked by the user // VOID TdReservedMappingSetSize( IN PVOID Irp ) { PIO_STACK_LOCATION IrpStack; ULONG InputBufferLength; SIZE_T NewReservedSize; PVOID NewReservedAddress; IrpStack = IoGetCurrentIrpStackLocation ( (PIRP)Irp); InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; if( InputBufferLength != sizeof( SIZE_T ) ) { // // The user should send us the new size of the buffer // DbgPrint( "Buggy: TdReservedMappingSetSize: invalid buffer length %p\n", InputBufferLength ); DbgBreakPoint(); return; } // // This will be our new reserved mapping address size // NewReservedSize = *(PSIZE_T) ( (PIRP) Irp )->AssociatedIrp.SystemBuffer; if( NewReservedSize < PAGE_SIZE ) { NewReservedSize = PAGE_SIZE; } else { NewReservedSize = ROUND_TO_PAGES( NewReservedSize ); } //DbgPrint( "Buggy: TdReservedMappingSetSize: new reserved mapping address size %p\n", // NewReservedSize ); if( 0 != NewReservedSize ) { // // Try to reserve NewReservedSize bytes // NewReservedAddress = MmAllocateMappingAddress( NewReservedSize, TD_POOL_TAG ); if( NULL == NewReservedAddress ) { DbgPrint( "Buggy: TdReservedMappingSetSize: MmAllocateMappingAddress returned NULL, keeping old reserved address %p, size = %p\n", CrtReservedAddress, CrtReservedSize ); return; } } else { // // Just release the old reserved address and set the size to 0 // NewReservedAddress = NULL; } // // We have a new buffer, release the old one // TdReservedMappingCleanup(); CrtReservedSize = NewReservedSize; CrtReservedAddress = NewReservedAddress; /* DbgPrint( "Buggy: TdReservedMappingSetSize: new reserved address %p, size = %p\n", CrtReservedAddress, CrtReservedSize ); */ } //////////////////////////////////////////////////////////////////////// // // Simulate a "read" operation in a user-supplied buffer // VOID TdReservedMappingDoRead( IN PVOID Irp ) { PVOID UserBuffer; PVOID MappedAddress; PSIZE_T CrtPageAdddress; SIZE_T UserBufferSize; SIZE_T CrtPageIndex; SIZE_T CrtCycleSize; SIZE_T CrtCyclePages; PMDL Mdl; PIO_STACK_LOCATION IrpStack; ULONG InputBufferLength; PUSER_READ_BUFFER UserReadBufferStruct; BOOLEAN Locked; // // If we don't have a reserved address for mapping currently we cannot // execute the operation // if( NULL == CrtReservedAddress ) { ASSERT( 0 == CrtReservedSize ); DbgPrint( "Buggy: TdReservedMappingDoRead: no buffer available - rejecting request\n" ); return; } // // Make a copy of the user-supplied buffer address and size // IrpStack = IoGetCurrentIrpStackLocation ( (PIRP)Irp); InputBufferLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; if( InputBufferLength != sizeof( USER_READ_BUFFER ) ) { // // The user should have sent us a USER_READ_BUFFER // DbgPrint( "Buggy: TdReservedMappingDoRead: invalid user buffer length %p, expected %p\n", InputBufferLength, (SIZE_T)sizeof( USER_READ_BUFFER ) ); DbgBreakPoint(); return; } UserReadBufferStruct = (PUSER_READ_BUFFER) ( (PIRP) Irp )->AssociatedIrp.SystemBuffer ; UserBuffer = UserReadBufferStruct->UserBuffer; UserBufferSize = UserReadBufferStruct->UserBufferSize; // // Map CrtReservedSize bytes at most // CrtPageIndex = 1; while( UserBufferSize >= PAGE_SIZE ) { //DbgPrint( "Buggy: TdReservedMappingDoRead: %p bytes left to be read at adddress %p\n", // UserBufferSize, // UserBuffer ); if( UserBufferSize > CrtReservedSize ) { CrtCycleSize = CrtReservedSize; } else { CrtCycleSize = UserBufferSize; } //DbgPrint( "Buggy: TdReservedMappingDoRead: reading %p bytes this cycle\n", // CrtCycleSize ); // // Allocate an MDL // Mdl = IoAllocateMdl( UserBuffer, (ULONG)CrtCycleSize, FALSE, // not secondary buffer FALSE, // do not charge quota NULL); // no irp if( NULL != Mdl ) { // // Try to lock the pages // Locked = FALSE; try { MmProbeAndLockPages( Mdl, KernelMode, IoWriteAccess); //DbgPrint( // "Buggy: locked pages in MDL %p\n", // Mdl); Locked = TRUE; } except (EXCEPTION_EXECUTE_HANDLER) { DbgPrint( "Buggy: MmProbeAndLockPages( %p ) raised exception %X\n", Mdl, GetExceptionCode() ); DbgBreakPoint(); } if( TRUE == Locked ) { // // Map them to our reserved address // MappedAddress = MmMapLockedPagesWithReservedMapping( CrtReservedAddress, TD_POOL_TAG, Mdl, MmCached ); if( NULL == MappedAddress ) { DbgPrint( "Buggy: MmProbeAndLockPages( %p, MDL %p ) returned NULL. This API is almost guaranteed to succeed\n", CrtReservedAddress, Mdl ); DbgBreakPoint(); } else { // // Mapped successfully - execute the "read" // CrtCyclePages = CrtCycleSize / PAGE_SIZE; CrtPageAdddress = (PSIZE_T)MappedAddress; // // Stamp all the pages with their index, starting from 1 // while( CrtCyclePages > 0 ) { *CrtPageAdddress = CrtPageIndex; CrtPageIndex += 1; CrtCyclePages -= 1; CrtPageAdddress = (PSIZE_T)( (PCHAR)CrtPageAdddress + PAGE_SIZE ); } // // Unmap // MmUnmapReservedMapping( MappedAddress, TD_POOL_TAG, Mdl ); } // // Unlock // MmUnlockPages (Mdl); } // // Free MDL // IoFreeMdl (Mdl); } else { // // Bad luck - couldn't allocate the MDL // DbgPrint( "Buggy: TdReservedMappingDoRead: IoAllocateMdl( %p, %p ) returned NULL\n", UserBuffer, UserBufferSize ); } // // How many bytes left to be read and to what address? // UserBufferSize -= CrtCycleSize; UserBuffer = (PVOID)( (PCHAR)UserBuffer + CrtCycleSize ); } } #endif //#if !RESRVMAP_ACTIVE