mirror of
https://github.com/reactos/reactos.git
synced 2025-01-04 21:38:43 +00:00
- 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:
parent
35f4d34682
commit
3768902d9b
6 changed files with 152 additions and 52 deletions
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue