📄 mapmemory.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 + -