update for HEAD-2003091401
[reactos.git] / ntoskrnl / mm / virtual.c
index dece177..4661586 100644 (file)
@@ -62,9 +62,43 @@ NTSTATUS STDCALL
 NtLockVirtualMemory(HANDLE     ProcessHandle,
                    PVOID       BaseAddress,
                    ULONG       NumberOfBytesToLock,
-                   PULONG      NumberOfBytesLocked)
+                   PULONG      NumberOfBytesLocked)   // ULONG LockOption?
 {
-  UNIMPLEMENTED;
+    // AG [08-20-03] : I have *no* idea if this is correct, I just used the
+    // other functions as a template and made a few intelligent guesses...
+
+  NTSTATUS Status;
+  PMDL Mdl;
+  PEPROCESS Process;
+  
+  DPRINT("NtLockVirtualMemory(ProcessHandle %x, BaseAddress %x, "
+        "NumberOfBytesToLock %d), NumberOfBytesLocked %x\n",ProcessHandle,BaseAddress,
+        NumberOfBytesToLock, NumberOfBytesLocked);
+  
+  Status = ObReferenceObjectByHandle(ProcessHandle,
+                                    PROCESS_VM_WRITE,
+                                    NULL,
+                                    UserMode,
+                                    (PVOID*)(&Process),
+                                    NULL);
+  if (Status != STATUS_SUCCESS)
+    {
+      return(Status);
+    }
+  
+  Mdl = MmCreateMdl(NULL, 
+                   BaseAddress,
+                   NumberOfBytesToLock);
+  MmProbeAndLockPages(Mdl,
+                     UserMode,
+                     IoWriteAccess);
+  
+  ExFreePool(Mdl);  // Are we supposed to do this here?
+  
+  ObDereferenceObject(Process);
+  
+  *NumberOfBytesLocked = NumberOfBytesToLock;
+  return(STATUS_SUCCESS);
 }
 
 NTSTATUS STDCALL 
@@ -285,7 +319,44 @@ NtUnlockVirtualMemory(HANDLE       ProcessHandle,
                      ULONG     NumberOfBytesToUnlock,
                      PULONG NumberOfBytesUnlocked OPTIONAL)
 {
-  UNIMPLEMENTED;
+    // AG [08-20-03] : I have *no* idea if this is correct, I just used the
+    // other functions as a template and made a few intelligent guesses...
+
+  NTSTATUS Status;
+  PMDL Mdl;
+  PEPROCESS Process;
+  
+  DPRINT("NtUnlockVirtualMemory(ProcessHandle %x, BaseAddress %x, "
+        "NumberOfBytesToUnlock %d), NumberOfBytesUnlocked %x\n",ProcessHandle,BaseAddress,
+        NumberOfBytesToUnlock, NumberOfBytesUnlocked);
+  
+  Status = ObReferenceObjectByHandle(ProcessHandle,
+                                    PROCESS_VM_WRITE,
+                                    NULL,
+                                    UserMode,
+                                    (PVOID*)(&Process),
+                                    NULL);
+  if (Status != STATUS_SUCCESS)
+    {
+      return(Status);
+    }
+  
+  Mdl = MmCreateMdl(NULL, 
+                   BaseAddress,
+                   NumberOfBytesToUnlock);
+
+   ObDereferenceObject(Process);
+
+   if (Mdl->MappedSystemVa != NULL)
+     {
+       MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
+     }
+   MmUnlockPages(Mdl);
+   ExFreePool(Mdl);
+   
+   *NumberOfBytesUnlocked = NumberOfBytesToUnlock;
+   
+   return(STATUS_SUCCESS);
 }
 
 
@@ -333,7 +404,7 @@ NtWriteVirtualMemory(IN     HANDLE  ProcessHandle,
    ObDereferenceObject(Process);
 
    if (Mdl->MappedSystemVa != NULL)
-     {      
+     {
        MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
      }
    MmUnlockPages(Mdl);
@@ -344,20 +415,100 @@ NtWriteVirtualMemory(IN  HANDLE  ProcessHandle,
    return(STATUS_SUCCESS);
 }
 
-DWORD STDCALL
-MmSecureVirtualMemory (DWORD   Unknown0,
-                      DWORD    Unknown1,
-                      DWORD    Unknown2)
+/*
+ * @unimplemented
+ */
+PVOID STDCALL
+MmSecureVirtualMemory (PVOID  Address,
+                       SIZE_T Length,
+                       ULONG  Mode)
 {
+  /* Only works for user space */
+  if (MmHighestUserAddress < Address)
+    {
+      return NULL;
+    }
+
   UNIMPLEMENTED;
+
   return 0;
 }
 
 
+/*
+ * @unimplemented
+ */
 VOID STDCALL
-MmUnsecureVirtualMemory (DWORD Unknown0)
+MmUnsecureVirtualMemory(PVOID SecureMem)
 {
+  if (NULL == SecureMem)
+    {
+      return;
+    }
+
   UNIMPLEMENTED;
 }
 
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+ProbeForRead (IN PVOID Address,
+             IN ULONG Length,
+             IN ULONG Alignment)
+{
+  assert (Alignment ==1 || Alignment == 2 || Alignment == 4 || Alignment == 8);
+
+  if (Length == 0)
+    return;
+
+  if (((ULONG_PTR)Address & (Alignment - 1)) != 0)
+    {
+      ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT);
+    }
+  else if ((ULONG_PTR)Address + Length < (ULONG_PTR)Address ||
+          (ULONG_PTR)Address + Length > (ULONG_PTR)MmUserProbeAddress)
+    {
+      ExRaiseStatus (STATUS_ACCESS_VIOLATION);
+    }
+}
+
+
+/*
+ * @implemented
+ */
+VOID STDCALL
+ProbeForWrite (IN PVOID Address,
+              IN ULONG Length,
+              IN ULONG Alignment)
+{
+  PULONG Ptr;
+  ULONG x;
+  ULONG i;
+
+  assert (Alignment ==1 || Alignment == 2 || Alignment == 4 || Alignment == 8);
+
+  if (Length == 0)
+    return;
+
+  if (((ULONG_PTR)Address & (Alignment - 1)) != 0)
+    {
+      ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT);
+    }
+  else if ((ULONG_PTR)Address + Length < (ULONG_PTR)Address ||
+          (ULONG_PTR)Address + Length > (ULONG_PTR)MmUserProbeAddress)
+    {
+      ExRaiseStatus (STATUS_ACCESS_VIOLATION);
+    }
+
+  /* Check for accessible pages */
+  for (i = 0; i < Length; i += PAGE_SIZE)
+    {
+      Ptr = (PULONG)(((ULONG_PTR)Address & ~(PAGE_SIZE - 1)) + i);
+      x = *Ptr;
+      *Ptr = x;
+    }
+}
+
 /* EOF */