⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mapmemory.c

📁 通过VC源代码
💻 C
字号:

// mapMemory.c driver utilities for PCI bus adapters
/*****************************************************************************
*           Change Log
*  Date     | Change
*-----------+-----------------------------------------------------------------
  09-13-96     create log
*****************************************************************************/

/*****************************************************************************
*           To DO
*-----------------------------------------------------------------------------


*****************************************************************************/

  



#define BYTE UCHAR
/*++


Module Name:

    mapmem.c

Abstract:

    Windows NT device driver utility

Author:

    Edward Dekker

Environment:

    kernel mode only

Notes:

    --*/


#include "ntddk.h"
//#include "mapmem.h"       // include device extension for target driver here
 

#ifdef NEVER
// 
//  Example calling sequence for  MapSystemLogicalMemory
//
{
...
         extension->DMABufferSystemVirtualAddr = MmAllocateContiguousMemory( (ULONG) REQUESTED_SIZE, HighLimit);
 
...
         if (STATUS_SUCCESS != MapSystemLogicalMemory( DeviceObject,
                                         extension->DMABufferSystemVirtualAddr,
                                         (ULONG)REQUESTED_SIZE,
                                           &extension->DMABufferUserVirtualAddr,
                                           sizeof(extension->DMABufferUserVirtualAddr)                                                                                                                      
                                         ) )
         {
            KdPrint( ("MapMem: failed MapSystemLogicalMemory  shared memory\n") );
            ret = STATUS_UNSUCCESSFUL;                      
            break;
         }                                              


}
#endif

NTSTATUS MapSystemLogicalMemory(
    IN PDEVICE_OBJECT DeviceObject,
    IN PVOID          LogicalAddress,
    IN ULONG          LengthToMap,
    OUT PVOID         OutBuffer,
    IN ULONG          OutputBufferLength
    )
/*++

Routine Description:

    Given a system logical address, maps this address into a user mode process's
    address space

    Assume logical address passed to this routine points to a contiguous buffer 
    large enough to contain the buffer requested.
    
    This routine must be called at DISPATCH level from the context of the Application thread.  

Arguments:

    DeviceObject       - pointer to a device object
    LogicalAddress     - system logical address
    LengthToMap        - length to map
    OutBuffer          - pointer to the Output buffer
    OutputBufferLength - output buffer length



Return Value:

    STATUS_SUCCESS if sucessful, otherwise
    STATUS_UNSUCCESSFUL,
    STATUS_INSUFFICIENT_RESOURCES,
    (other STATUS_* as returned by kernel APIs)

--*/
{
    PHYSICAL_ADDRESS   physicalAddress;
    ULONG              length;
    UNICODE_STRING     physicalMemoryUnicodeString;
    OBJECT_ATTRIBUTES  objectAttributes;
    HANDLE             physicalMemoryHandle  = NULL;
    PVOID              PhysicalMemorySection = NULL;
    ULONG              inIoSpace, inIoSpace2;
    NTSTATUS           ntStatus;
    PHYSICAL_ADDRESS   physicalAddressBase;
    PHYSICAL_ADDRESS   physicalAddressEnd;
    PHYSICAL_ADDRESS   viewBase;
    PHYSICAL_ADDRESS   mappedLength;
    PVOID              virtualAddress;



    if ( OutputBufferLength < sizeof (PVOID) ) 
    {
       KdPrint (("MapMem: Insufficient input or output buffer\n"));
       ntStatus = STATUS_INSUFFICIENT_RESOURCES;
       goto done;
    }

    physicalAddress = MmGetPhysicalAddress(LogicalAddress);
    KdPrint( ("MapMem: MapSystemLogicalMemory()  physicalAddress = %x %x\n", 
            physicalAddress.HighPart, physicalAddress.LowPart ));

    //
    // Get a pointer to physical memory...
    //
    // - Create the name
    // - Initialize the data to find the object
    // - Open a handle to the object and check the status
    // - Get a pointer to the object
    // - Free the handle
    //

    RtlInitUnicodeString (&physicalMemoryUnicodeString,  L"\\Device\\PhysicalMemory");

    InitializeObjectAttributes (&objectAttributes,
                                &physicalMemoryUnicodeString,
                                OBJ_CASE_INSENSITIVE,
                                (HANDLE) NULL,
                                (PSECURITY_DESCRIPTOR) NULL);

    ntStatus = ZwOpenSection (&physicalMemoryHandle,
                              SECTION_ALL_ACCESS,
                              &objectAttributes);

    if (!NT_SUCCESS(ntStatus))
    {
        KdPrint (("MapMem: ZwOpenSection failed\n"));
        goto done;
    }

    ntStatus = ObReferenceObjectByHandle (physicalMemoryHandle,
                                          SECTION_ALL_ACCESS,
                                          (POBJECT_TYPE) NULL,
                                          KernelMode,
                                          &PhysicalMemorySection,
                                          (POBJECT_HANDLE_INFORMATION) NULL);

    if (!NT_SUCCESS(ntStatus))
    {
        KdPrint (("MapMem: ObReferenceObjectByHandle failed\n"));
        goto close_handle;
    }


    //
    // Initialize the physical addresses that will be translated
    //

    physicalAddressBase = physicalAddress;
    physicalAddressEnd = RtlLargeIntegerAdd (physicalAddress, RtlConvertUlongToLargeInteger( LengthToMap ) );

    //
    // Calculate the length of the memory to be mapped
    //

    mappedLength = RtlLargeIntegerSubtract (physicalAddressEnd, physicalAddressBase);


    //
    // If the mappedlength is zero, somthing very weird happened in the HAL
    // since the Length was checked against zero.
    //

    if (mappedLength.LowPart == 0)
    {
        KdPrint (("MapMem: mappedLength.LowPart == 0\n"));
        ntStatus = STATUS_UNSUCCESSFUL;
        goto close_handle;
    }

    length = mappedLength.LowPart;

    //
    // initialize view base that will receive the physical mapped
    // address after the MapViewOfSection call.
    //

    viewBase = physicalAddressBase;

    //
    // Let ZwMapViewOfSection pick an address
    //

    virtualAddress = NULL;

    //
    // Map the section
    //

    ntStatus = ZwMapViewOfSection (physicalMemoryHandle,
                                   (HANDLE) -1,
                                   &virtualAddress,
                                   0L,
                                   length,
                                   &viewBase,
                                   &length,
                                   ViewShare,
                                   0,
                                   PAGE_READWRITE | PAGE_NOCACHE);

    if (!NT_SUCCESS(ntStatus))
    {
        KdPrint (("MapMem: ZwMapViewOfSection failed\n"));

        goto close_handle;
    }

    //
    // Mapping the section above rounded the physical address down to the
    // nearest 64 K boundary. Now return a virtual address that sits where
    // we wnat by adding in the offset from the beginning of the section.
    //


    (ULONG) virtualAddress += (ULONG)physicalAddressBase.LowPart -
                              (ULONG)viewBase.LowPart;



    *((PVOID *) OutBuffer) = virtualAddress;          


    KdPrint( ("MapMem: MapSystemLogicalMemory() returning virtualAddress = %x\n", virtualAddress));




    ntStatus = STATUS_SUCCESS;

close_handle:
    ZwClose (physicalMemoryHandle);

done:
    return ntStatus;
}


NTSTATUS MapBoardMemory(
    IN PDEVICE_OBJECT DeviceObject,
    PHYSICAL_ADDRESS   physicalAddress,   
    IN ULONG          LengthToMap,
    OUT PVOID         OutBuffer,
    IN ULONG          OutputBufferLength
    )
/*++

Routine Description:

    Given a physical address, maps this address into a user mode process's
    address space

    Assume that the physical address passed to this routine points to a contiguous buffer 
    large enough to contain the buffer requested.

Arguments:

    DeviceObject       - pointer to a device object
    PhysicalAddress    - Physical  address of board memory
    LengthToMap        - length to map
    OutBuffer          - pointer to the Output buffer
    OutputBufferLength - output buffer length

Return Value:

    STATUS_SUCCESS if sucessful, otherwise
    STATUS_UNSUCCESSFUL,
    STATUS_INSUFFICIENT_RESOURCES,
    (other STATUS_* as returned by kernel APIs)

--*/
{
    PHYSICAL_ADDRESS   physicalAddressBase;
    ULONG              length;
    UNICODE_STRING     physicalMemoryUnicodeString;
    OBJECT_ATTRIBUTES  objectAttributes;
    HANDLE             physicalMemoryHandle  = NULL;
    PVOID              PhysicalMemorySection = NULL;
    ULONG              inIoSpace, inIoSpace2;
    NTSTATUS           ntStatus;
    PHYSICAL_ADDRESS   physicalAddressEnd;
    PHYSICAL_ADDRESS   viewBase;
    PHYSICAL_ADDRESS   mappedLength;
    PVOID              virtualAddress;



    if ( OutputBufferLength < sizeof (PVOID) ) 
    {
       KdPrint (("MapMem: Insufficient input or output buffer\n"));
       ntStatus = STATUS_INSUFFICIENT_RESOURCES;
       goto done;
    }

    KdPrint( ("MapMem: MapBoardMemory()  physicalAddress = %x %x\n", 
              physicalAddress.HighPart, physicalAddress.LowPart ));

    //
    // Get a pointer to physical memory...
    //
    // - Create the name
    // - Initialize the data to find the object
    // - Open a handle to the object and check the status
    // - Get a pointer to the object
    // - Free the handle
    //

    RtlInitUnicodeString (&physicalMemoryUnicodeString,  L"\\Device\\PhysicalMemory");

    InitializeObjectAttributes (&objectAttributes,
                                &physicalMemoryUnicodeString,
                                OBJ_CASE_INSENSITIVE,
                                (HANDLE) NULL,
                                (PSECURITY_DESCRIPTOR) NULL);

    ntStatus = ZwOpenSection (&physicalMemoryHandle,
                              SECTION_ALL_ACCESS,
                              &objectAttributes);

    if (!NT_SUCCESS(ntStatus))
    {
        KdPrint (("MapMem: ZwOpenSection failed\n"));
        goto done;
    }

    ntStatus = ObReferenceObjectByHandle (physicalMemoryHandle,
                                          SECTION_ALL_ACCESS,
                                          (POBJECT_TYPE) NULL,
                                          KernelMode,
                                          &PhysicalMemorySection,
                                          (POBJECT_HANDLE_INFORMATION) NULL);

    if (!NT_SUCCESS(ntStatus))
    {
        KdPrint (("MapMem: ObReferenceObjectByHandle failed\n"));
        goto close_handle;
    }


    //
    // Initialize the physical addresses that will be translated
    //

    physicalAddressBase = physicalAddress;
    physicalAddressEnd = RtlLargeIntegerAdd (physicalAddress, RtlConvertUlongToLargeInteger( LengthToMap ) );

    //
    // Calculate the length of the memory to be mapped
    //

    mappedLength = RtlLargeIntegerSubtract (physicalAddressEnd, physicalAddressBase);


    //
    // If the mappedlength is zero, somthing very weird happened in the HAL
    // since the Length was checked against zero.
    //

    if (mappedLength.LowPart == 0)
    {
        KdPrint (("MapMem: mappedLength.LowPart == 0\n"));
        ntStatus = STATUS_UNSUCCESSFUL;
        goto close_handle;
    }

    length = mappedLength.LowPart;

    //
    // initialize view base that will receive the physical mapped
    // address after the MapViewOfSection call.
    //

    viewBase = physicalAddressBase;

    //
    // Let ZwMapViewOfSection pick an address
    //

    virtualAddress = NULL;

    //
    // Map the section
    //

    ntStatus = ZwMapViewOfSection (physicalMemoryHandle,
                                   (HANDLE) -1,
                                   &virtualAddress,
                                   0L,
                                   length,
                                   &viewBase,
                                   &length,
                                   ViewShare,
                                   0,
                                   PAGE_READWRITE | PAGE_NOCACHE);

    if (!NT_SUCCESS(ntStatus))
    {
        KdPrint (("MapMem: ZwMapViewOfSection failed\n"));

        goto close_handle;
    }

    //
    // Mapping the section above rounded the physical address down to the
    // nearest 64 K boundary. Now return a virtual address that sits where
    // we wnat by adding in the offset from the beginning of the section.
    //


    (ULONG) virtualAddress += (ULONG)physicalAddressBase.LowPart -
                              (ULONG)viewBase.LowPart;



    *((PVOID *) OutBuffer) = virtualAddress;          


    KdPrint( ("MapMem: MapBoardMemory() returning virtualAddress = %x\n", virtualAddress));




    ntStatus = STATUS_SUCCESS;

close_handle:
    ZwClose (physicalMemoryHandle);

done:
    return ntStatus;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -