- Implemented NtQueryVirtualMemory for unallocated regions.

- Fixed some minor bugs in NtQueryVirtualMemory and its related query functions.

svn path=/trunk/; revision=10065
This commit is contained in:
Hartmut Birr 2004-07-10 17:01:03 +00:00
parent 35f4d34682
commit 3768902d9b
6 changed files with 152 additions and 52 deletions

View file

@ -203,6 +203,8 @@ NTSTATUS MmCreateMemoryArea(struct _EPROCESS* Process,
PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL);
MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
PVOID Address);
ULONG MmFindGapAtAddress(PMADDRESS_SPACE AddressSpace,
PVOID Address);
NTSTATUS MmInitMemoryAreas(VOID);
VOID MiInitializeNonPagedPool(VOID);
NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: anonmem.c,v 1.28 2004/06/06 08:36:31 hbirr Exp $
/* $Id: anonmem.c,v 1.29 2004/07/10 17:01:03 hbirr Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/anonmem.c
@ -887,8 +887,9 @@ MmQueryAnonMem(PMEMORY_AREA MemoryArea,
Region = MmFindRegion(MemoryArea->BaseAddress,
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
Address, &RegionBase);
Info->AllocationBase = RegionBase;
Info->AllocationProtect = Region->Protect; /* FIXME */
Info->BaseAddress = RegionBase;
Info->AllocationBase = MemoryArea->BaseAddress;
Info->AllocationProtect = MemoryArea->Attributes;
Info->RegionSize = (char*)RegionBase + Region->Length - (char*)Info->BaseAddress;
Info->State = Region->Type;
Info->Protect = Region->Protect;

View file

@ -346,6 +346,53 @@ PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, BOOL TopDown)
return MmFindGapBottomUp(AddressSpace, Length);
}
ULONG MmFindGapAtAddress(PMADDRESS_SPACE AddressSpace, PVOID Address)
{
PLIST_ENTRY current_entry, ListHead;
PMEMORY_AREA current;
Address = (PVOID)PAGE_ROUND_DOWN(Address);
if (AddressSpace->LowestAddress < KERNEL_BASE)
{
if (Address >= (PVOID)KERNEL_BASE)
{
return 0;
}
}
else
{
if ((ULONG_PTR)Address < AddressSpace->LowestAddress)
{
return 0;
}
}
ListHead = &AddressSpace->MAreaListHead;
current_entry = ListHead->Flink;
while (current_entry != ListHead)
{
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
if (current->BaseAddress <= Address && Address < current->BaseAddress + current->Length)
{
return 0;
}
else if (current->BaseAddress > Address)
{
return (ULONG_PTR)current->BaseAddress - (ULONG_PTR)Address;
}
current_entry = current_entry->Flink;
}
if (AddressSpace->LowestAddress < KERNEL_BASE)
{
return KERNEL_BASE - (ULONG_PTR)Address;
}
else
{
return 0 - (ULONG_PTR)Address;
}
}
NTSTATUS INIT_FUNCTION
MmInitMemoryAreas(VOID)

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: section.c,v 1.152 2004/06/20 10:21:48 navaraf Exp $
/* $Id: section.c,v 1.153 2004/07/10 17:01:02 hbirr Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/section.c
@ -2035,7 +2035,7 @@ MmQuerySectionView(PMEMORY_AREA MemoryArea,
}
}
KeReleaseSpinLock(&Section->ViewListLock, oldIrql);
Info->BaseAddress = MemoryArea->BaseAddress;
Info->BaseAddress = RegionBaseAddress;
Info->AllocationProtect = MemoryArea->Attributes;
Info->Type = MEM_IMAGE;
}
@ -2043,10 +2043,10 @@ MmQuerySectionView(PMEMORY_AREA MemoryArea,
{
Info->BaseAddress = RegionBaseAddress;
Info->AllocationBase = MemoryArea->BaseAddress;
Info->AllocationProtect = Region->Protect;
Info->AllocationProtect = MemoryArea->Attributes;
Info->Type = MEM_MAPPED;
}
Info->RegionSize = MemoryArea->Length;
Info->RegionSize = PAGE_ROUND_UP(MemoryArea->Length);
Info->State = MEM_COMMIT;
Info->Protect = Region->Protect;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: virtual.c,v 1.77 2004/07/09 20:14:49 navaraf Exp $
/* $Id: virtual.c,v 1.78 2004/07/10 17:01:02 hbirr Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/virtual.c
@ -132,6 +132,12 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle,
MEMORY_AREA* MemoryArea;
ULONG ResultLength = 0;
PMADDRESS_SPACE AddressSpace;
KPROCESSOR_MODE PrevMode;
union
{
MEMORY_BASIC_INFORMATION BasicInfo;
}
VirtualMemoryInfo;
DPRINT("NtQueryVirtualMemory(ProcessHandle %x, Address %x, "
"VirtualMemoryInformationClass %d, VirtualMemoryInformation %x, "
@ -139,20 +145,33 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle,
VirtualMemoryInformationClass,VirtualMemoryInformation,
Length,ResultLength);
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
NULL,
UserMode,
(PVOID*)(&Process),
NULL);
PrevMode = ExGetPreviousMode();
if (!NT_SUCCESS(Status))
if (PrevMode == UserMode && Address >= (PVOID)KERNEL_BASE)
{
DPRINT("NtQueryVirtualMemory() = %x\n",Status);
return(Status);
return STATUS_INVALID_PARAMETER;
}
AddressSpace = &Process->AddressSpace;
if (Address < (PVOID)KERNEL_BASE)
{
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
NULL,
UserMode,
(PVOID*)(&Process),
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("NtQueryVirtualMemory() = %x\n",Status);
return(Status);
}
AddressSpace = &Process->AddressSpace;
}
else
{
AddressSpace = MmGetKernelAddressSpace();
}
MmLockAddressSpace(AddressSpace);
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
Address);
@ -160,47 +179,65 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle,
{
case MemoryBasicInformation:
{
PMEMORY_BASIC_INFORMATION Info =
(PMEMORY_BASIC_INFORMATION)VirtualMemoryInformation;
PMEMORY_BASIC_INFORMATION Info = &VirtualMemoryInfo.BasicInfo;
if (Length != sizeof(MEMORY_BASIC_INFORMATION))
{
MmUnlockAddressSpace(AddressSpace);
ObDereferenceObject(Process);
return(STATUS_INFO_LENGTH_MISMATCH);
}
if (MemoryArea == NULL)
{
Info->Type = 0;
Info->State = MEM_FREE;
Info->Protect = PAGE_NOACCESS;
Info->AllocationProtect = 0;
Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address);
Info->AllocationBase = 0;
Info->AllocationProtect = 0;
/* TODO: Find the next memory area and set RegionSize! */
/* Since programs might depend on RegionSize for
* iteration, we for now just make up a value.
*/
Info->RegionSize = (Address > (PVOID)0x80000000) ? 0 : 0x10000;
Info->Protect = PAGE_NOACCESS;
Info->Type = 0;
Info->AllocationBase = NULL;
Info->RegionSize = MmFindGapAtAddress(AddressSpace, Info->BaseAddress);
Status = STATUS_SUCCESS;
ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
}
else if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY)
{
Status = MmQueryAnonMem(MemoryArea, Address, Info,
&ResultLength);
}
else if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW)
{
Status = MmQuerySectionView(MemoryArea, Address, Info,
&ResultLength);
}
else
{
Status = STATUS_UNSUCCESSFUL;
ResultLength = 0;
}
}
else
{
switch(MemoryArea->Type)
{
case MEMORY_AREA_VIRTUAL_MEMORY:
Status = MmQueryAnonMem(MemoryArea, Address, Info,
&ResultLength);
break;
case MEMORY_AREA_SECTION_VIEW:
Status = MmQuerySectionView(MemoryArea, Address, Info,
&ResultLength);
break;
case MEMORY_AREA_NO_ACCESS:
Info->Type = 0;
Info->State = MEM_FREE;
Info->Protect = MemoryArea->Attributes;
Info->AllocationProtect = MemoryArea->Attributes;
Info->BaseAddress = MemoryArea->BaseAddress;
Info->AllocationBase = MemoryArea->BaseAddress;
Info->RegionSize = MemoryArea->Length;
Status = STATUS_SUCCESS;
ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
break;
case MEMORY_AREA_SHARED_DATA:
Info->Type = 0;
Info->State = MEM_COMMIT;
Info->Protect = MemoryArea->Attributes;
Info->AllocationProtect = MemoryArea->Attributes;
Info->BaseAddress = MemoryArea->BaseAddress;
Info->AllocationBase = MemoryArea->BaseAddress;
Info->RegionSize = MemoryArea->Length;
Status = STATUS_SUCCESS;
ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
break;
default:
Status = STATUS_UNSUCCESSFUL;
ResultLength = 0;
}
}
break;
}
@ -213,7 +250,20 @@ NtQueryVirtualMemory (IN HANDLE ProcessHandle,
}
MmUnlockAddressSpace(AddressSpace);
ObDereferenceObject(Process);
if (Address < (PVOID)KERNEL_BASE)
{
ObDereferenceObject(Process);
}
if (NT_SUCCESS(Status) && ResultLength > 0)
{
Status = MmCopyToCaller(VirtualMemoryInformation, &VirtualMemoryInfo, ResultLength);
if (!NT_SUCCESS(Status))
{
ResultLength = 0;
}
}
if (UnsafeResultLength != NULL)
{
MmCopyToCaller(UnsafeResultLength, &ResultLength, sizeof(ULONG));

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.73 2004/03/24 22:00:39 ea Exp $
/* $Id: create.c,v 1.74 2004/07/10 17:01:03 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -481,7 +481,7 @@ PsCreateTeb(HANDLE ProcessHandle,
while (TRUE)
{
Status = NtQueryVirtualMemory(ProcessHandle,
Status = ZwQueryVirtualMemory(ProcessHandle,
TebBase,
MemoryBasicInformation,
&Info,
@ -489,14 +489,14 @@ PsCreateTeb(HANDLE ProcessHandle,
&ResultLength);
if (!NT_SUCCESS(Status))
{
CPRINT("NtQueryVirtualMemory (Status %x)\n", Status);
CPRINT("ZwQueryVirtualMemory (Status %x)\n", Status);
KEBUGCHECK(0);
}
/* FIXME: Race between this and the above check */
if (Info.State == MEM_FREE)
{
/* The TEB must reside in user space */
Status = NtAllocateVirtualMemory(ProcessHandle,
Status = ZwAllocateVirtualMemory(ProcessHandle,
&TebBase,
0,
&TebSize,