windows-nt/Source/XPSP1/NT/drivers/wdm/rt/clients/glitch/mapview.c

192 lines
4.2 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 2001 Microsoft Corporation. All Rights Reserved.
Module Name:
mapview.c
Abstract:
This code is used to map a read only copy of the glitch output buffer into
a user mode process. It currently supports mapping the output buffer to
only 1 user mode process at a time.
Author:
Joseph Ballantyne
Environment:
Kernel Mode
Revision History:
--*/
#ifdef UNDER_NT
#include "common.h"
#include <ntddk.h>
#include <rt.h>
#include "glitch.h"
#include "mapview.h"
// Note that there are PAGEABLE_CODE and PAGEABLE_DATA pragmas in common.h
// so all of this code is pageable. That is as it should be - as this code
// is all called while handling IOCTLS.
HANDLE SectionHandle=NULL;
HANDLE Process=NULL;
NTSTATUS
MapContiguousBufferToUserModeProcess (
PVOID Buffer,
PVOID *MappedBuffer
)
{
NTSTATUS Status;
PHYSICAL_ADDRESS Physical;
UNICODE_STRING SectionName;
OBJECT_ATTRIBUTES ObjectAttributes;
ULONG ViewSize;
LARGE_INTEGER ViewBase;
PVOID BaseAddress;
// We only map our buffer into 1 process at a time.
// Punt if we have already mapped or started to map it.
if (InterlockedCompareExchangePointer(&SectionHandle, 1, NULL)!=NULL) {
return STATUS_UNSUCCESSFUL;
}
// First get the physical address of the buffer we are going to
// map into read only user mode memory of the process calling us.
Physical=MmGetPhysicalAddress(Buffer);
// Now map this buffer into user mode memory and return a pointer
// to the mapped memory.
//
// Open a physical memory section to map in physical memory.
//
RtlInitUnicodeString(
&SectionName,
L"\\Device\\PhysicalMemory"
);
InitializeObjectAttributes(
&ObjectAttributes,
&SectionName,
OBJ_CASE_INSENSITIVE,
(HANDLE) NULL,
(PSECURITY_DESCRIPTOR) NULL
);
Status = ZwOpenSection(
&SectionHandle,
SECTION_ALL_ACCESS,
&ObjectAttributes
);
if (NT_SUCCESS(Status)) {
BaseAddress = NULL;
ViewSize = GlitchInfo->BufferSize+PROCPAGESIZE;
ViewBase.QuadPart = Physical.QuadPart;
Status =ZwMapViewOfSection(
SectionHandle,
NtCurrentProcess(),
&BaseAddress,
0,
ViewSize,
&ViewBase,
&ViewSize,
ViewUnmap,
0,
PAGE_READONLY
);
if (NT_SUCCESS(Status)) {
// Keep track of which process opened and mapped this section.
Process=IoGetCurrentProcess();
*MappedBuffer=BaseAddress;
}
else {
// If we fail to map the view. Then we clean up here.
// Close down our SectionHandle and setup so we can run this routine
// again later.
ZwClose(SectionHandle);
// Clear the SectionHandle so we can open it again.
InterlockedExchangePointer(&SectionHandle, NULL);
}
}
else {
// Clear the SectionHandle so we don't lock out all future mapping attempts.
InterlockedExchangePointer(&SectionHandle, NULL);
}
return Status;
}
NTSTATUS
UnMapContiguousBufferFromUserModeProcess (
PVOID MappedBuffer
)
{
HANDLE CurrentProcess;
NTSTATUS Status=STATUS_UNSUCCESSFUL;
// Only let this call through, if we have an open section handle,
// and the process calling us matches the process that opened the
// section handle.
CurrentProcess=IoGetCurrentProcess();
if (InterlockedCompareExchangePointer(&Process, NULL, CurrentProcess)==CurrentProcess) {
// I should NEVER be able to get here unless SectionHandle is valid
// and was a handle opened by the current process. I should also
// NEVER be able to get here unless MappedBuffer is valid as well.
ASSERT( SectionHandle!=NULL );
ASSERT( MappedBuffer!=NULL );
Status = ZwUnmapViewOfSection(NtCurrentProcess(), MappedBuffer);
ZwClose(SectionHandle);
// Clear the SectionHandle so we can open it again.
InterlockedExchangePointer(&SectionHandle, NULL);
}
return Status;
}
#endif