/* PRIVATE FUNCTIONS **********************************************************/
-static
-int
+LONG
MiGetExceptionInfo(EXCEPTION_POINTERS *ExceptionInfo, BOOLEAN * HaveBadAddress, ULONG_PTR * BadAddress)
{
PEXCEPTION_RECORD ExceptionRecord;
PMDL Mdl = (PMDL)MdlBuffer;
SIZE_T TotalSize, CurrentSize, RemainingSize;
volatile BOOLEAN FailedInProbe = FALSE, FailedInMapping = FALSE, FailedInMoving;
- BOOLEAN PagesLocked;
+ volatile BOOLEAN PagesLocked;
PVOID CurrentAddress = SourceAddress, CurrentTargetAddress = TargetAddress;
- PVOID MdlAddress;
+ volatile PVOID MdlAddress;
KAPC_STATE ApcState;
BOOLEAN HaveBadAddress;
ULONG_PTR BadAddress;
NTSTATUS Status;
PEPROCESS Process;
MEMORY_AREA* MemoryArea;
- PMM_AVL_TABLE AddressSpace;
+ PMMSUPPORT AddressSpace;
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
return(Status);
}
- AddressSpace = &Process->VadRoot;
+ AddressSpace = &Process->Vm;
MmLockAddressSpace(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
default:
{
+ DPRINT1("Unsupported or unimplemented class: %lx\n", VirtualMemoryInformationClass);
Status = STATUS_INVALID_INFO_CLASS;
*ResultLength = 0;
break;
OUT PULONG OldAccessProtection OPTIONAL)
{
PMEMORY_AREA MemoryArea;
- PMM_AVL_TABLE AddressSpace;
+ PMMSUPPORT AddressSpace;
ULONG OldAccessProtection_;
NTSTATUS Status;
PAGE_ROUND_DOWN(*BaseAddress);
*BaseAddress = (PVOID)PAGE_ROUND_DOWN(*BaseAddress);
- AddressSpace = &Process->VadRoot;
+ AddressSpace = &Process->Vm;
MmLockAddressSpace(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, *BaseAddress);
return Status;
}
+PVOID
+NTAPI
+MiMapLockedPagesInUserSpace(IN PMDL Mdl,
+ IN PVOID BaseVa,
+ IN MEMORY_CACHING_TYPE CacheType,
+ IN PVOID BaseAddress)
+{
+ PVOID Base;
+ PPFN_NUMBER MdlPages;
+ ULONG PageCount;
+ PEPROCESS CurrentProcess;
+ NTSTATUS Status;
+ ULONG Protect;
+ MEMORY_AREA *Result;
+ LARGE_INTEGER BoundaryAddressMultiple;
+
+ /* Calculate the number of pages required. */
+ MdlPages = (PPFN_NUMBER)(Mdl + 1);
+ PageCount = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
+
+ /* Set default page protection */
+ Protect = PAGE_READWRITE;
+ if (CacheType == MmNonCached) Protect |= PAGE_NOCACHE;
+
+ BoundaryAddressMultiple.QuadPart = 0;
+ Base = BaseAddress;
+
+ CurrentProcess = PsGetCurrentProcess();
+
+ MmLockAddressSpace(&CurrentProcess->Vm);
+ Status = MmCreateMemoryArea(&CurrentProcess->Vm,
+ MEMORY_AREA_MDL_MAPPING,
+ &Base,
+ PageCount * PAGE_SIZE,
+ Protect,
+ &Result,
+ (Base != NULL),
+ 0,
+ BoundaryAddressMultiple);
+ MmUnlockAddressSpace(&CurrentProcess->Vm);
+ if (!NT_SUCCESS(Status))
+ {
+ if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL)
+ {
+ return NULL;
+ }
+
+ /* Throw exception */
+ ExRaiseStatus(STATUS_ACCESS_VIOLATION);
+ ASSERT(0);
+ }
+
+ /* Set the virtual mappings for the MDL pages. */
+ if (Mdl->MdlFlags & MDL_IO_SPACE)
+ {
+ /* Map the pages */
+ Status = MmCreateVirtualMappingUnsafe(CurrentProcess,
+ Base,
+ Protect,
+ MdlPages,
+ PageCount);
+ }
+ else
+ {
+ /* Map the pages */
+ Status = MmCreateVirtualMapping(CurrentProcess,
+ Base,
+ Protect,
+ MdlPages,
+ PageCount);
+ }
+
+ /* Check if the mapping suceeded */
+ if (!NT_SUCCESS(Status))
+ {
+ /* If it can fail, return NULL */
+ if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL) return NULL;
+
+ /* Throw exception */
+ ExRaiseStatus(STATUS_ACCESS_VIOLATION);
+ }
+
+ /* Return the base */
+ Base = (PVOID)((ULONG_PTR)Base + Mdl->ByteOffset);
+ return Base;
+}
+
+VOID
+NTAPI
+MiUnmapLockedPagesInUserSpace(IN PVOID BaseAddress,
+ IN PMDL Mdl)
+{
+ PMEMORY_AREA MemoryArea;
+
+ /* Sanity check */
+ ASSERT(Mdl->Process == PsGetCurrentProcess());
+
+ /* Find the memory area */
+ MemoryArea = MmLocateMemoryAreaByAddress(&Mdl->Process->Vm,
+ BaseAddress);
+ ASSERT(MemoryArea);
+
+ /* Free it */
+ MmFreeMemoryArea(&Mdl->Process->Vm,
+ MemoryArea,
+ NULL,
+ NULL);
+}
+
/* PUBLIC FUNCTIONS ***********************************************************/
/*
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PEPROCESS Process;
NTSTATUS Status = STATUS_SUCCESS;
- ULONG BytesWritten = 0;
+ SIZE_T BytesWritten = 0;
PAGED_CODE();
/* Check if we came from user mode */
{
PEPROCESS Process;
ULONG OldAccessProtection;
+ ULONG Protection;
PVOID BaseAddress = NULL;
SIZE_T NumberOfBytesToProtect = 0;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
+ PAGED_CODE();
+
+ /* Check for valid protection flags */
+ Protection = NewAccessProtection & ~(PAGE_GUARD|PAGE_NOCACHE);
+ if (Protection != PAGE_NOACCESS &&
+ Protection != PAGE_READONLY &&
+ Protection != PAGE_READWRITE &&
+ Protection != PAGE_WRITECOPY &&
+ Protection != PAGE_EXECUTE &&
+ Protection != PAGE_EXECUTE_READ &&
+ Protection != PAGE_EXECUTE_READWRITE &&
+ Protection != PAGE_EXECUTE_WRITECOPY)
+ {
+ return STATUS_INVALID_PAGE_PROTECTION;
+ }
/* Check if we came from user mode */
if (PreviousMode != KernelMode)
WCHAR ModuleFileNameBuffer[MAX_PATH] = {0};
UNICODE_STRING ModuleFileName;
PMEMORY_SECTION_NAME SectionName = NULL;
+ PEPROCESS Process;
union
{
MEMORY_BASIC_INFORMATION BasicInfo;
PreviousMode = ExGetPreviousMode();
- if (PreviousMode != KernelMode && UnsafeResultLength != NULL)
+ if (PreviousMode != KernelMode)
{
_SEH2_TRY
{
- ProbeForWriteSize_t(UnsafeResultLength);
+ ProbeForWrite(VirtualMemoryInformation,
+ Length,
+ sizeof(ULONG_PTR));
+
+ if (UnsafeResultLength) ProbeForWriteSize_t(UnsafeResultLength);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* FIXME: Move this inside MiQueryVirtualMemory */
if (VirtualMemoryInformationClass == MemorySectionName)
{
+ Status = ObReferenceObjectByHandle(ProcessHandle,
+ PROCESS_QUERY_INFORMATION,
+ NULL,
+ PreviousMode,
+ (PVOID*)(&Process),
+ NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NtQueryVirtualMemory() = %x\n",Status);
+ return(Status);
+ }
+
RtlInitEmptyUnicodeString(&ModuleFileName, ModuleFileNameBuffer, sizeof(ModuleFileNameBuffer));
Status = MmGetFileNameForAddress(Address, &ModuleFileName);
}
}
}
+ ObDereferenceObject(Process);
return Status;
}
else
return STATUS_SUCCESS;
}
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+NtGetWriteWatch(IN HANDLE ProcessHandle,
+ IN ULONG Flags,
+ IN PVOID BaseAddress,
+ IN ULONG RegionSize,
+ IN PVOID *UserAddressArray,
+ OUT PULONG EntriesInUserAddressArray,
+ OUT PULONG Granularity)
+{
+ if (!EntriesInUserAddressArray || !Granularity)
+ {
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ if (!*EntriesInUserAddressArray || !RegionSize)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (!UserAddressArray)
+ {
+ return STATUS_ACCESS_VIOLATION;
+ }
+
+ /* HACK: Set granularity to PAGE_SIZE */
+ *Granularity = PAGE_SIZE;
+
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+NtResetWriteWatch(IN HANDLE ProcessHandle,
+ IN PVOID BaseAddress,
+ IN ULONG RegionSize)
+{
+ if (!RegionSize)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ UNIMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
/* EOF */