/* PRIVATE FUNCTIONS **********************************************************/
-_SEH_DEFINE_LOCALS(MiGetExceptionInfo)
+static
+int
+MiGetExceptionInfo(EXCEPTION_POINTERS *ExceptionInfo, BOOLEAN * HaveBadAddress, ULONG_PTR * BadAddress)
{
- volatile BOOLEAN HaveBadAddress;
- volatile ULONG_PTR BadAddress;
-};
-
-_SEH_FILTER(MiGetExceptionInfo)
-{
- _SEH_ACCESS_LOCALS(MiGetExceptionInfo);
- EXCEPTION_POINTERS *ExceptionInfo = _SEH_GetExceptionPointers();
PEXCEPTION_RECORD ExceptionRecord;
PAGED_CODE();
-
+
/* Assume default */
- _SEH_VAR(HaveBadAddress) = FALSE;
-
+ *HaveBadAddress = FALSE;
+
/* Get the exception record */
ExceptionRecord = ExceptionInfo->ExceptionRecord;
-
+
/* Look at the exception code */
if ((ExceptionRecord->ExceptionCode == STATUS_ACCESS_VIOLATION) ||
(ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION) ||
if (ExceptionRecord->NumberParameters > 1)
{
/* Return the address */
- _SEH_VAR(HaveBadAddress) = TRUE;
- _SEH_VAR(BadAddress) = ExceptionRecord->ExceptionInformation[1];
+ *HaveBadAddress = TRUE;
+ *BadAddress = ExceptionRecord->ExceptionInformation[1];
}
}
-
+
/* Continue executing the next handler */
return EXCEPTION_EXECUTE_HANDLER;
}
IN PVOID SourceAddress,
IN PEPROCESS TargetProcess,
OUT PVOID TargetAddress,
- IN ULONG BufferSize,
+ IN SIZE_T BufferSize,
IN KPROCESSOR_MODE PreviousMode,
- OUT PULONG ReturnSize)
+ OUT PSIZE_T ReturnSize)
{
- PFN_NUMBER MdlBuffer[(sizeof(MDL) / sizeof(PFN_NUMBER)) + (MI_MAPPED_COPY_PAGES >> PAGE_SHIFT) + 1];
+ PFN_NUMBER MdlBuffer[(sizeof(MDL) / sizeof(PFN_NUMBER)) + MI_MAPPED_COPY_PAGES + 1];
PMDL Mdl = (PMDL)MdlBuffer;
- ULONG TotalSize, CurrentSize, RemainingSize;
- BOOLEAN FailedInProbe = FALSE, FailedInMapping = FALSE, FailedInMoving;
- BOOLEAN PagesLocked;
+ SIZE_T TotalSize, CurrentSize, RemainingSize;
+ volatile BOOLEAN FailedInProbe = FALSE, FailedInMapping = FALSE, FailedInMoving;
+ volatile BOOLEAN PagesLocked;
PVOID CurrentAddress = SourceAddress, CurrentTargetAddress = TargetAddress;
- PVOID MdlAddress;
+ volatile PVOID MdlAddress;
KAPC_STATE ApcState;
- _SEH_DECLARE_LOCALS(MiGetExceptionInfo);
+ BOOLEAN HaveBadAddress;
+ ULONG_PTR BadAddress;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
-
+
/* Calculate the maximum amount of data to move */
- TotalSize = MI_MAPPED_COPY_PAGES - 2;
- if (TotalSize <= (MI_MAPPED_COPY_PAGES - 2)) TotalSize = BufferSize;
- CurrentSize = BufferSize;
- RemainingSize = TotalSize;
-
+ TotalSize = (MI_MAPPED_COPY_PAGES - 2) * PAGE_SIZE;
+ if (BufferSize <= TotalSize) TotalSize = BufferSize;
+ CurrentSize = TotalSize;
+ RemainingSize = BufferSize;
+
/* Loop as long as there is still data */
while (RemainingSize > 0)
{
/* Check if this transfer will finish everything off */
if (RemainingSize < CurrentSize) CurrentSize = RemainingSize;
-
+
/* Attach to the source address space */
KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
-
+
/* Reset state for this pass */
MdlAddress = NULL;
PagesLocked = FALSE;
FailedInMoving = FALSE;
ASSERT(FailedInProbe == FALSE);
-
+
/* Protect user-mode copy */
- _SEH_TRY
+ _SEH2_TRY
{
/* If this is our first time, probe the buffer */
if ((CurrentAddress == SourceAddress) && (PreviousMode != KernelMode))
{
/* Catch a failure here */
FailedInProbe = TRUE;
-
+
/* Do the probe */
ProbeForRead(SourceAddress, BufferSize, sizeof(CHAR));
-
+
/* Passed */
FailedInProbe = FALSE;
}
-
+
/* Initialize and probe and lock the MDL */
- MmInitializeMdl (Mdl, CurrentAddress, CurrentSize);
+ MmInitializeMdl (Mdl, CurrentAddress, CurrentSize);
MmProbeAndLockPages (Mdl, PreviousMode, IoReadAccess);
PagesLocked = TRUE;
-
+
/* Now map the pages */
MdlAddress = MmMapLockedPagesSpecifyCache(Mdl,
KernelMode,
FailedInMapping = TRUE;
ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
}
-
+
/* Now let go of the source and grab to the target process */
KeUnstackDetachProcess(&ApcState);
KeStackAttachProcess(&TargetProcess->Pcb, &ApcState);
-
+
/* Check if this is our first time through */
if ((CurrentAddress == SourceAddress) && (PreviousMode != KernelMode))
{
/* Catch a failure here */
FailedInProbe = TRUE;
-
+
/* Do the probe */
ProbeForWrite(TargetAddress, BufferSize, sizeof(CHAR));
-
+
/* Passed */
FailedInProbe = FALSE;
}
-
+
/* Now do the actual move */
FailedInMoving = TRUE;
RtlCopyMemory(CurrentTargetAddress, MdlAddress, CurrentSize);
}
- _SEH_EXCEPT(MiGetExceptionInfo)
+ _SEH2_EXCEPT(MiGetExceptionInfo(_SEH2_GetExceptionInformation(), &HaveBadAddress, &BadAddress))
{
/* Detach from whoever we may be attached to */
KeUnstackDetachProcess(&ApcState);
-
+
/* Check if we had mapped the pages */
if (MdlAddress) MmUnmapLockedPages(MdlAddress, Mdl);
-
+
/* Check if we had locked the pages */
if (PagesLocked) MmUnlockPages(Mdl);
-
+
/* Check if we failed during the probe or mapping */
if ((FailedInProbe) || (FailedInMapping))
{
/* Exit */
- Status = _SEH_GetExceptionCode();
- _SEH_YIELD();
+ Status = _SEH2_GetExceptionCode();
+ _SEH2_YIELD(return Status);
}
-
+
/* Otherwise, we failed probably during the move */
*ReturnSize = BufferSize - RemainingSize;
if (FailedInMoving)
{
/* Check if we know exactly where we stopped copying */
- if (_SEH_VAR(HaveBadAddress))
+ if (HaveBadAddress)
{
/* Return the exact number of bytes copied */
- *ReturnSize = _SEH_VAR(BadAddress) - (ULONG_PTR)SourceAddress;
+ *ReturnSize = BadAddress - (ULONG_PTR)SourceAddress;
}
}
-
+
/* Return partial copy */
Status = STATUS_PARTIAL_COPY;
}
- _SEH_END;
-
+ _SEH2_END;
+
/* Check for SEH status */
if (Status != STATUS_SUCCESS) return Status;
-
+
/* Detach from target */
KeUnstackDetachProcess(&ApcState);
-
+
/* Unmap and unlock */
MmUnmapLockedPages(MdlAddress, Mdl);
MmUnlockPages(Mdl);
-
+
/* Update location and size */
RemainingSize -= CurrentSize;
CurrentAddress = (PVOID)((ULONG_PTR)CurrentAddress + CurrentSize);
CurrentTargetAddress = (PVOID)((ULONG_PTR)CurrentTargetAddress + CurrentSize);
}
-
+
/* All bytes read */
*ReturnSize = BufferSize;
return STATUS_SUCCESS;
IN PVOID SourceAddress,
IN PEPROCESS TargetProcess,
OUT PVOID TargetAddress,
- IN ULONG BufferSize,
+ IN SIZE_T BufferSize,
IN KPROCESSOR_MODE PreviousMode,
- OUT PULONG ReturnSize)
+ OUT PSIZE_T ReturnSize)
{
UCHAR StackBuffer[MI_POOL_COPY_BYTES];
- ULONG TotalSize, CurrentSize, RemainingSize;
- BOOLEAN FailedInProbe = FALSE, FailedInMoving, HavePoolAddress = FALSE;
+ SIZE_T TotalSize, CurrentSize, RemainingSize;
+ volatile BOOLEAN FailedInProbe = FALSE, FailedInMoving, HavePoolAddress = FALSE;
PVOID CurrentAddress = SourceAddress, CurrentTargetAddress = TargetAddress;
PVOID PoolAddress;
KAPC_STATE ApcState;
- _SEH_DECLARE_LOCALS(MiGetExceptionInfo);
+ BOOLEAN HaveBadAddress;
+ ULONG_PTR BadAddress;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
-
+
/* Calculate the maximum amount of data to move */
TotalSize = MI_MAX_TRANSFER_SIZE;
- if (TotalSize <= MI_MAX_TRANSFER_SIZE) TotalSize = BufferSize;
- CurrentSize = BufferSize;
- RemainingSize = TotalSize;
-
+ if (BufferSize <= MI_MAX_TRANSFER_SIZE) TotalSize = BufferSize;
+ CurrentSize = TotalSize;
+ RemainingSize = BufferSize;
+
/* Check if we can use the stack */
if (BufferSize <= MI_POOL_COPY_BYTES)
{
if (!PoolAddress) ASSERT(FALSE);
HavePoolAddress = TRUE;
}
-
+
/* Loop as long as there is still data */
while (RemainingSize > 0)
{
/* Check if this transfer will finish everything off */
if (RemainingSize < CurrentSize) CurrentSize = RemainingSize;
-
+
/* Attach to the source address space */
KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
-
+
/* Reset state for this pass */
FailedInMoving = FALSE;
ASSERT(FailedInProbe == FALSE);
-
+
/* Protect user-mode copy */
- _SEH_TRY
+ _SEH2_TRY
{
/* If this is our first time, probe the buffer */
if ((CurrentAddress == SourceAddress) && (PreviousMode != KernelMode))
{
/* Catch a failure here */
FailedInProbe = TRUE;
-
+
/* Do the probe */
ProbeForRead(SourceAddress, BufferSize, sizeof(CHAR));
-
+
/* Passed */
FailedInProbe = FALSE;
}
-
+
/* Do the copy */
RtlCopyMemory(PoolAddress, CurrentAddress, CurrentSize);
-
+
/* Now let go of the source and grab to the target process */
KeUnstackDetachProcess(&ApcState);
KeStackAttachProcess(&TargetProcess->Pcb, &ApcState);
-
+
/* Check if this is our first time through */
if ((CurrentAddress == SourceAddress) && (PreviousMode != KernelMode))
{
/* Catch a failure here */
FailedInProbe = TRUE;
-
+
/* Do the probe */
ProbeForWrite(TargetAddress, BufferSize, sizeof(CHAR));
-
+
/* Passed */
FailedInProbe = FALSE;
}
-
+
/* Now do the actual move */
FailedInMoving = TRUE;
RtlCopyMemory(CurrentTargetAddress, PoolAddress, CurrentSize);
}
- _SEH_EXCEPT(MiGetExceptionInfo)
+ _SEH2_EXCEPT(MiGetExceptionInfo(_SEH2_GetExceptionInformation(), &HaveBadAddress, &BadAddress))
{
/* Detach from whoever we may be attached to */
KeUnstackDetachProcess(&ApcState);
-
+
/* Check if we had allocated pool */
if (HavePoolAddress) ExFreePool(PoolAddress);
-
+
/* Check if we failed during the probe */
if (FailedInProbe)
{
/* Exit */
- Status = _SEH_GetExceptionCode();
- _SEH_YIELD();
+ Status = _SEH2_GetExceptionCode();
+ _SEH2_YIELD(return Status);
}
-
+
/* Otherwise, we failed probably during the move */
*ReturnSize = BufferSize - RemainingSize;
if (FailedInMoving)
{
/* Check if we know exactly where we stopped copying */
- if (_SEH_VAR(HaveBadAddress))
+ if (HaveBadAddress)
{
/* Return the exact number of bytes copied */
- *ReturnSize = _SEH_VAR(BadAddress) - (ULONG_PTR)SourceAddress;
+ *ReturnSize = BadAddress - (ULONG_PTR)SourceAddress;
}
}
-
+
/* Return partial copy */
Status = STATUS_PARTIAL_COPY;
}
- _SEH_END;
-
+ _SEH2_END;
+
/* Check for SEH status */
if (Status != STATUS_SUCCESS) return Status;
-
+
/* Detach from target */
KeUnstackDetachProcess(&ApcState);
-
+
/* Update location and size */
RemainingSize -= CurrentSize;
CurrentAddress = (PVOID)((ULONG_PTR)CurrentAddress + CurrentSize);
CurrentTargetAddress = (PVOID)((ULONG_PTR)CurrentTargetAddress + CurrentSize);
}
-
+
/* Check if we had allocated pool */
if (HavePoolAddress) ExFreePool(PoolAddress);
-
+
/* All bytes read */
*ReturnSize = BufferSize;
return STATUS_SUCCESS;
IN PVOID SourceAddress,
IN PEPROCESS TargetProcess,
OUT PVOID TargetAddress,
- IN ULONG BufferSize,
+ IN SIZE_T BufferSize,
IN KPROCESSOR_MODE PreviousMode,
- OUT PULONG ReturnSize)
+ OUT PSIZE_T ReturnSize)
{
NTSTATUS Status;
PEPROCESS Process = SourceProcess;
/* Don't accept zero-sized buffers */
if (!BufferSize) return STATUS_SUCCESS;
-
+
/* If we are copying from ourselves, lock the target instead */
if (SourceProcess == PsGetCurrentProcess()) Process = TargetProcess;
-
+
/* Acquire rundown protection */
if (!ExAcquireRundownProtection(&Process->RundownProtect))
{
/* Fail */
return STATUS_PROCESS_IS_TERMINATING;
}
-
+
/* See if we should use the pool copy */
if (BufferSize > MI_POOL_COPY_BYTES)
{
PreviousMode,
ReturnSize);
}
-
+
/* Release the lock */
ExReleaseRundownProtection(&Process->RundownProtect);
return Status;
IN PVOID Address,
IN MEMORY_INFORMATION_CLASS VirtualMemoryInformationClass,
OUT PVOID VirtualMemoryInformation,
- IN ULONG Length,
- OUT PULONG ResultLength)
+ IN SIZE_T Length,
+ OUT PSIZE_T ResultLength)
{
NTSTATUS Status;
PEPROCESS Process;
MEMORY_AREA* MemoryArea;
- PMADDRESS_SPACE AddressSpace;
+ PMM_AVL_TABLE AddressSpace;
- if (Address < MmSystemRangeStart)
- {
- Status = ObReferenceObjectByHandle(ProcessHandle,
- PROCESS_QUERY_INFORMATION,
- NULL,
- UserMode,
- (PVOID*)(&Process),
- NULL);
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_QUERY_INFORMATION,
+ NULL,
+ UserMode,
+ (PVOID*)(&Process),
+ NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NtQueryVirtualMemory() = %x\n",Status);
- return(Status);
- }
- AddressSpace = (PMADDRESS_SPACE)&Process->VadRoot;
- }
- else
+ if (!NT_SUCCESS(Status))
{
- AddressSpace = MmGetKernelAddressSpace();
+ DPRINT("NtQueryVirtualMemory() = %x\n",Status);
+ return(Status);
}
+
+ AddressSpace = &Process->VadRoot;
+
MmLockAddressSpace(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
switch(VirtualMemoryInformationClass)
}
MmUnlockAddressSpace(AddressSpace);
- if (Address < MmSystemRangeStart)
- {
- ASSERT(Process);
- ObDereferenceObject(Process);
- }
+ ObDereferenceObject(Process);
return Status;
}
-NTSTATUS STDCALL
+NTSTATUS NTAPI
MiProtectVirtualMemory(IN PEPROCESS Process,
IN OUT PVOID *BaseAddress,
- IN OUT PULONG NumberOfBytesToProtect,
+ IN OUT PSIZE_T NumberOfBytesToProtect,
IN ULONG NewAccessProtection,
OUT PULONG OldAccessProtection OPTIONAL)
{
PMEMORY_AREA MemoryArea;
- PMADDRESS_SPACE AddressSpace;
+ PMM_AVL_TABLE AddressSpace;
ULONG OldAccessProtection_;
NTSTATUS Status;
-
+
*NumberOfBytesToProtect =
PAGE_ROUND_UP((ULONG_PTR)(*BaseAddress) + (*NumberOfBytesToProtect)) -
PAGE_ROUND_DOWN(*BaseAddress);
*BaseAddress = (PVOID)PAGE_ROUND_DOWN(*BaseAddress);
-
- AddressSpace = (PMADDRESS_SPACE)&(Process)->VadRoot;
-
+
+ AddressSpace = &Process->VadRoot;
+
MmLockAddressSpace(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, *BaseAddress);
if (MemoryArea == NULL)
MmUnlockAddressSpace(AddressSpace);
return STATUS_UNSUCCESSFUL;
}
-
+
if (OldAccessProtection == NULL)
OldAccessProtection = &OldAccessProtection_;
-
+
if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY)
{
Status = MmProtectAnonMem(AddressSpace, MemoryArea, *BaseAddress,
/* FIXME: Should we return failure or success in this case? */
Status = STATUS_CONFLICTING_ADDRESSES;
}
-
+
MmUnlockAddressSpace(AddressSpace);
-
+
return Status;
}
NtReadVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
- IN ULONG NumberOfBytesToRead,
- OUT PULONG NumberOfBytesRead OPTIONAL)
+ IN SIZE_T NumberOfBytesToRead,
+ OUT PSIZE_T NumberOfBytesRead OPTIONAL)
{
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PEPROCESS Process;
NTSTATUS Status = STATUS_SUCCESS;
- ULONG BytesRead = 0;
- PAGED_CODE();
+ SIZE_T BytesRead = 0;
+ PAGED_CODE();
/* Check if we came from user mode */
if (PreviousMode != KernelMode)
{
/* Validate the read addresses */
if ((((ULONG_PTR)BaseAddress + NumberOfBytesToRead) < (ULONG_PTR)BaseAddress) ||
- (((ULONG_PTR)Buffer + NumberOfBytesToRead) < (ULONG_PTR)Buffer) ||
+ (((ULONG_PTR)Buffer + NumberOfBytesToRead) < (ULONG_PTR)Buffer) ||
(((ULONG_PTR)BaseAddress + NumberOfBytesToRead) > MmUserProbeAddress) ||
(((ULONG_PTR)Buffer + NumberOfBytesToRead) > MmUserProbeAddress))
{
/* Don't allow to write into kernel space */
return STATUS_ACCESS_VIOLATION;
}
-
+
/* Enter SEH for probe */
- _SEH_TRY
+ _SEH2_TRY
{
/* Probe the output value */
- if (NumberOfBytesRead) ProbeForWriteUlong(NumberOfBytesRead);
+ if (NumberOfBytesRead) ProbeForWriteSize_t(NumberOfBytesRead);
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Get exception code */
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
-
+ _SEH2_END;
+
/* Return if we failed */
if (!NT_SUCCESS(Status)) return Status;
}
-
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_VM_READ,
NumberOfBytesToRead,
PreviousMode,
&BytesRead);
-
- /* Derefernece the process */
+
+ /* Dereference the process */
ObDereferenceObject(Process);
}
-
+
/* Check if the caller sent this parameter */
if (NumberOfBytesRead)
{
/* Enter SEH to guard write */
- _SEH_TRY
+ _SEH2_TRY
{
/* Return the number of bytes read */
*NumberOfBytesRead = BytesRead;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Handle exception */
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
}
/* Return status */
NtWriteVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
- IN ULONG NumberOfBytesToWrite,
- OUT PULONG NumberOfBytesWritten OPTIONAL)
+ IN SIZE_T NumberOfBytesToWrite,
+ OUT PSIZE_T NumberOfBytesWritten OPTIONAL)
{
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PEPROCESS Process;
NTSTATUS Status = STATUS_SUCCESS;
- ULONG BytesWritten = 0;
- PAGED_CODE();
+ SIZE_T BytesWritten = 0;
+ PAGED_CODE();
/* Check if we came from user mode */
if (PreviousMode != KernelMode)
{
/* Validate the read addresses */
if ((((ULONG_PTR)BaseAddress + NumberOfBytesToWrite) < (ULONG_PTR)BaseAddress) ||
- (((ULONG_PTR)Buffer + NumberOfBytesToWrite) < (ULONG_PTR)Buffer) ||
+ (((ULONG_PTR)Buffer + NumberOfBytesToWrite) < (ULONG_PTR)Buffer) ||
(((ULONG_PTR)BaseAddress + NumberOfBytesToWrite) > MmUserProbeAddress) ||
(((ULONG_PTR)Buffer + NumberOfBytesToWrite) > MmUserProbeAddress))
{
/* Don't allow to write into kernel space */
return STATUS_ACCESS_VIOLATION;
}
-
+
/* Enter SEH for probe */
- _SEH_TRY
+ _SEH2_TRY
{
/* Probe the output value */
- if (NumberOfBytesWritten) ProbeForWriteUlong(NumberOfBytesWritten);
+ if (NumberOfBytesWritten) ProbeForWriteSize_t(NumberOfBytesWritten);
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Get exception code */
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
-
+ _SEH2_END;
+
/* Return if we failed */
if (!NT_SUCCESS(Status)) return Status;
}
-
+
/* Reference the process */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_VM_WRITE,
NumberOfBytesToWrite,
PreviousMode,
&BytesWritten);
-
- /* Derefernece the process */
+
+ /* Dereference the process */
ObDereferenceObject(Process);
}
-
+
/* Check if the caller sent this parameter */
if (NumberOfBytesWritten)
{
/* Enter SEH to guard write */
- _SEH_TRY
+ _SEH2_TRY
{
/* Return the number of bytes read */
*NumberOfBytesWritten = BytesWritten;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Handle exception */
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
}
-
+
/* Return status */
return Status;
}
NTAPI
NtProtectVirtualMemory(IN HANDLE ProcessHandle,
IN OUT PVOID *UnsafeBaseAddress,
- IN OUT ULONG *UnsafeNumberOfBytesToProtect,
+ IN OUT SIZE_T *UnsafeNumberOfBytesToProtect,
IN ULONG NewAccessProtection,
OUT PULONG UnsafeOldAccessProtection)
{
PEPROCESS Process;
ULONG OldAccessProtection;
PVOID BaseAddress = NULL;
- ULONG NumberOfBytesToProtect = 0;
+ SIZE_T NumberOfBytesToProtect = 0;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
if (PreviousMode != KernelMode)
{
/* Enter SEH for probing */
- _SEH_TRY
+ _SEH2_TRY
{
/* Validate all outputs */
ProbeForWritePointer(UnsafeBaseAddress);
- ProbeForWriteUlong(UnsafeNumberOfBytesToProtect);
+ ProbeForWriteSize_t(UnsafeNumberOfBytesToProtect);
ProbeForWriteUlong(UnsafeOldAccessProtection);
-
+
/* Capture them */
BaseAddress = *UnsafeBaseAddress;
NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Get exception code */
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
-
+ _SEH2_END;
+
/* Return on exception */
if (!NT_SUCCESS(Status)) return Status;
}
BaseAddress = *UnsafeBaseAddress;
NumberOfBytesToProtect = *UnsafeNumberOfBytesToProtect;
}
-
+
/* Catch illegal base address */
if (BaseAddress > (PVOID)MmUserProbeAddress) return STATUS_INVALID_PARAMETER_2;
-
+
/* Catch illegal region size */
if ((MmUserProbeAddress - (ULONG_PTR)BaseAddress) < NumberOfBytesToProtect)
{
/* Release reference */
ObDereferenceObject(Process);
-
+
/* Enter SEH to return data */
- _SEH_TRY
+ _SEH2_TRY
{
/* Return data to user */
*UnsafeOldAccessProtection = OldAccessProtection;
*UnsafeBaseAddress = BaseAddress;
*UnsafeNumberOfBytesToProtect = NumberOfBytesToProtect;
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Catch exception */
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
/* Return status */
return Status;
}
-NTSTATUS STDCALL
+NTSTATUS NTAPI
NtQueryVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID Address,
IN MEMORY_INFORMATION_CLASS VirtualMemoryInformationClass,
OUT PVOID VirtualMemoryInformation,
- IN ULONG Length,
- OUT PULONG UnsafeResultLength)
+ IN SIZE_T Length,
+ OUT PSIZE_T UnsafeResultLength)
{
NTSTATUS Status = STATUS_SUCCESS;
- ULONG ResultLength = 0;
+ SIZE_T ResultLength = 0;
KPROCESSOR_MODE PreviousMode;
+ WCHAR ModuleFileNameBuffer[MAX_PATH] = {0};
+ UNICODE_STRING ModuleFileName;
+ PMEMORY_SECTION_NAME SectionName = NULL;
union
{
MEMORY_BASIC_INFORMATION BasicInfo;
}
VirtualMemoryInfo;
-
+
DPRINT("NtQueryVirtualMemory(ProcessHandle %x, Address %x, "
"VirtualMemoryInformationClass %d, VirtualMemoryInformation %x, "
"Length %lu ResultLength %x)\n",ProcessHandle,Address,
VirtualMemoryInformationClass,VirtualMemoryInformation,
Length,ResultLength);
-
+
PreviousMode = ExGetPreviousMode();
-
+
if (PreviousMode != KernelMode && UnsafeResultLength != NULL)
{
- _SEH_TRY
+ _SEH2_TRY
{
- ProbeForWriteUlong(UnsafeResultLength);
+ ProbeForWriteSize_t(UnsafeResultLength);
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
-
+ _SEH2_END;
+
if (!NT_SUCCESS(Status))
{
return Status;
}
}
-
+
if (Address >= MmSystemRangeStart)
{
DPRINT1("Invalid parameter\n");
return STATUS_INVALID_PARAMETER;
}
-
- Status = MiQueryVirtualMemory(ProcessHandle,
- Address,
- VirtualMemoryInformationClass,
- &VirtualMemoryInfo,
- Length,
- &ResultLength );
-
+
+ /* FIXME: Move this inside MiQueryVirtualMemory */
+ if (VirtualMemoryInformationClass == MemorySectionName)
+ {
+ RtlInitEmptyUnicodeString(&ModuleFileName, ModuleFileNameBuffer, sizeof(ModuleFileNameBuffer));
+ Status = MmGetFileNameForAddress(Address, &ModuleFileName);
+
+ if (NT_SUCCESS(Status))
+ {
+ SectionName = VirtualMemoryInformation;
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ RtlInitUnicodeString(&SectionName->SectionFileName, SectionName->NameBuffer);
+ SectionName->SectionFileName.MaximumLength = Length;
+ RtlCopyUnicodeString(&SectionName->SectionFileName, &ModuleFileName);
+
+ if (UnsafeResultLength != NULL)
+ {
+ *UnsafeResultLength = ModuleFileName.Length;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ RtlInitUnicodeString(&SectionName->SectionFileName, SectionName->NameBuffer);
+ SectionName->SectionFileName.MaximumLength = Length;
+ RtlCopyUnicodeString(&SectionName->SectionFileName, &ModuleFileName);
+
+ if (UnsafeResultLength != NULL)
+ {
+ *UnsafeResultLength = ModuleFileName.Length;
+ }
+ }
+ }
+ return Status;
+ }
+ else
+ {
+ Status = MiQueryVirtualMemory(ProcessHandle,
+ Address,
+ VirtualMemoryInformationClass,
+ &VirtualMemoryInfo,
+ Length,
+ &ResultLength);
+ }
+
if (NT_SUCCESS(Status))
{
if (PreviousMode != KernelMode)
{
- _SEH_TRY
+ _SEH2_TRY
{
if (ResultLength > 0)
{
*UnsafeResultLength = ResultLength;
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
}
else
{
&VirtualMemoryInfo,
ResultLength);
}
-
+
if (UnsafeResultLength != NULL)
{
*UnsafeResultLength = ResultLength;
}
}
}
-
+
return(Status);
}
NTAPI
NtLockVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
- IN ULONG NumberOfBytesToLock,
- OUT PULONG NumberOfBytesLocked OPTIONAL)
+ IN SIZE_T NumberOfBytesToLock,
+ OUT PSIZE_T NumberOfBytesLocked OPTIONAL)
{
UNIMPLEMENTED;
if (NumberOfBytesLocked) *NumberOfBytesLocked = 0;
NTAPI
NtUnlockVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
- IN ULONG NumberOfBytesToUnlock,
- OUT PULONG NumberOfBytesUnlocked OPTIONAL)
+ IN SIZE_T NumberOfBytesToUnlock,
+ OUT PSIZE_T NumberOfBytesUnlocked OPTIONAL)
{
UNIMPLEMENTED;
if (NumberOfBytesUnlocked) *NumberOfBytesUnlocked = 0;