这段内存操作代码,高手能否解释一下!谢谢!技术探讨20分。
NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID pPhysAddress,
ULONG PhysMemSizeInBytes,
PVOID *ppPhysMemLin,
HANDLE *pPhysicalMemoryHandle)
{
UNICODE_STRING PhysicalMemoryUnicodeString;
PVOID PhysicalMemorySection = NULL;
OBJECT_ATTRIBUTES ObjectAttributes;
PHYSICAL_ADDRESS ViewBase;
NTSTATUS ntStatus;
PHYSICAL_ADDRESS pStartPhysAddress;
PHYSICAL_ADDRESS pEndPhysAddress;
PHYSICAL_ADDRESS MappingLength;
BOOLEAN Result1, Result2;
ULONG IsIOSpace;
unsigned char *pbPhysMemLin = NULL;
OutputDebugString ("Entering MapPhysicalMemoryToLinearSpace");
RtlInitUnicodeString (&PhysicalMemoryUnicodeString,
L"\\Device\\PhysicalMemory");
InitializeObjectAttributes (&ObjectAttributes,
&PhysicalMemoryUnicodeString,
OBJ_CASE_INSENSITIVE,
(HANDLE) NULL,
(PSECURITY_DESCRIPTOR) NULL);
*pPhysicalMemoryHandle = NULL;
ntStatus = ZwOpenSection (pPhysicalMemoryHandle,
SECTION_ALL_ACCESS,
&ObjectAttributes);
if (NT_SUCCESS(ntStatus))
{
ntStatus = ObReferenceObjectByHandle (*pPhysicalMemoryHandle,
SECTION_ALL_ACCESS,
(POBJECT_TYPE) NULL,
KernelMode,
&PhysicalMemorySection,
(POBJECT_HANDLE_INFORMATION) NULL);
if (NT_SUCCESS(ntStatus))
{
pStartPhysAddress.QuadPart = (ULONGLONG)pPhysAddress;
pEndPhysAddress = RtlLargeIntegerAdd (pStartPhysAddress,
RtlConvertUlongToLargeInteger(PhysMemSizeInBytes));
IsIOSpace = 0;
Result1 = HalTranslateBusAddress (1, 0, pStartPhysAddress, &IsIOSpace, &pStartPhysAddress);
IsIOSpace = 0;
Result2 = HalTranslateBusAddress (1, 0, pEndPhysAddress, &IsIOSpace, &pEndPhysAddress);
if (Result1 && Result2)
{
MappingLength = RtlLargeIntegerSubtract (pEndPhysAddress, pStartPhysAddress);
if (MappingLength.LowPart)
{
// Let ZwMapViewOfSection pick a linear address
PhysMemSizeInBytes = MappingLength.LowPart;
ViewBase = pStartPhysAddress;
ntStatus = ZwMapViewOfSection (*pPhysicalMemoryHandle,
(HANDLE) -1,
&pbPhysMemLin,
0L,
PhysMemSizeInBytes,
&ViewBase,
&PhysMemSizeInBytes,
ViewShare,
0,
PAGE_READWRITE | PAGE_NOCACHE);
if (!NT_SUCCESS(ntStatus))
OutputDebugString ("ERROR: ZwMapViewOfSection failed");
else
{
pbPhysMemLin += (ULONG)pStartPhysAddress.LowPart - (ULONG)ViewBase.LowPart;
*ppPhysMemLin = pbPhysMemLin;
}
}
else
OutputDebugString ("ERROR: RtlLargeIntegerSubtract failed");
}
else
OutputDebugString ("ERROR: MappingLength = 0");
}
else
OutputDebugString ("ERROR: ObReferenceObjectByHandle failed");
}
else
OutputDebugString ("ERROR: ZwOpenSection failed");
if (!NT_SUCCESS(ntStatus))
ZwClose(*pPhysicalMemoryHandle);
OutputDebugString ("Leaving MapPhysicalMemoryToLinearSpace");
return ntStatus;
}
NTSTATUS UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PVOID pPhysMemLin)
{
NTSTATUS ntStatus;
OutputDebugString ("Entering UnmapPhysicalMemory");
ntStatus = ZwUnmapViewOfSection((HANDLE)-1, pPhysMemLin);
if (!NT_SUCCESS(ntStatus))
OutputDebugString ("ERROR: UnmapViewOfSection failed");
ZwClose(PhysicalMemoryHandle);
OutputDebugString ("Leaving UnmapPhysicalMemory");
return ntStatus;
}