Problem w/ ZwMapViewOfSection

A

Andrea De Nardis

Hi all,
I have a big problem in using ZwMapViewOfSection in WinXP. I have to map
a dynamically allocated memory w/ MmAllocatePoolWithTag (NonPagedPool,
0x20000) in a process space. I have allocated 128KB of non-pageable memory
so there always is a 1-1 correspondence between the virtual and the physical
address for each process. I read in "Developing Windows NT device Drivers"
(by Dekker and Newcommer) that ZwMapViewOfSection works well only for
64KB-aligned physical address, so I did it in my code. It perfectly works in
Win2K and WinNT4.0, too, but when I try to run the same driver in WinXP the
function returns STATUS_CONFLICTING_ADDRESSES ((NTSTATUS)0xC0000018L)!!!
Have you any idea of what is goin on???
Please help me if you can!!!
thanx in advance.
Best Regards,
andrea

PS: here is the complete code: Fpu2001MapMemory is a routine called as a
DeviceIoControl so it si run at PASSIVE_LEVEL and within the context of the
calling thread process.

NTSTATUS
Fpu2001MapMemory (
PFPU2001_DEVICE_EXT FdoData,
PUCHAR *pPt
)
{
ULONG length;
UNICODE_STRING physicalMemoryUnicodeString = {0};
OBJECT_ATTRIBUTES objectAttributes;
HANDLE physicalMemoryHandle = NULL;
PVOID PhysicalMemorySection = NULL;
NTSTATUS ntStatus;
PHYSICAL_ADDRESS physicalAddress;
PHYSICAL_ADDRESS viewBase;
PHYSICAL_ADDRESS mappedLength;
PVOID virtualAddress;

PAGED_CODE ();

ASSERT_VALID_EXT (FdoData);

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

physicalAddress = MmGetPhysicalAddress (FdoData->Hardware.VirtualAddress);

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

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

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

ASSERT (NT_SUCCESS (ntStatus));
if (!NT_SUCCESS(ntStatus))
{
goto done;
}

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

ASSERT (NT_SUCCESS (ntStatus));
if (!NT_SUCCESS(ntStatus))
{
goto close_handle;
}


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

mappedLength.HighPart = 0;
mappedLength.LowPart = FdoData->Hardware.MemorySize;
if (mappedLength.LowPart == 0)
{
ntStatus = STATUS_UNSUCCESSFUL;
goto close_handle;
}
viewBase = physicalAddress;
//arrotondamento al blocco di 64KB + vicino
if (viewBase.LowPart % 0x10000)
viewBase.LowPart /= 0x10000 +1;
else
viewBase.LowPart /= 0x10000;
viewBase.LowPart *= 0x10000;
length = mappedLength.LowPart;
length += (physicalAddress.LowPart - viewBase.LowPart) ;
//
// 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);
ASSERT (NT_SUCCESS (ntStatus));

if (!NT_SUCCESS(ntStatus))
{
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.
//

((LONG) virtualAddress) += (ULONG) physicalAddress.LowPart - (LONG)
viewBase.LowPart;

*pPt = (PUCHAR) virtualAddress;
*pPt += FPU2001_REGISTER_SPACE;

ntStatus = STATUS_SUCCESS;

close_handle:

if (NULL != physicalMemoryHandle)
ZwClose (physicalMemoryHandle);
done:
return ntStatus;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top