Commit in reactos/ntoskrnl/mm on MAIN
mm.c+7-11.68 -> 1.69
mdl.c+112-341.59 -> 1.60
+119-35
2 modified files

- Checked in MmMapLockedPages patch from Anich Gregor.

reactos/ntoskrnl/mm
mm.c 1.68 -> 1.69
diff -u -r1.68 -r1.69
--- mm.c	15 Feb 2004 19:03:29 -0000	1.68
+++ mm.c	13 Mar 2004 19:14:15 -0000	1.69
@@ -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: mm.c,v 1.68 2004/02/15 19:03:29 hbirr Exp $
+/* $Id: mm.c,v 1.69 2004/03/13 19:14:15 dwelch Exp $
  *
  * COPYRIGHT:   See COPYING in the top directory
  * PROJECT:     ReactOS kernel 
@@ -35,6 +35,7 @@
 #include <internal/ntoskrnl.h>
 #include <internal/io.h>
 #include <internal/ps.h>
+#include <reactos/bugcodes.h>
 
 #define NDEBUG
 #include <internal/debug.h>
@@ -78,6 +79,11 @@
 				 NULL,
 				 NULL);
        break;
+
+     case MEMORY_AREA_MDL_MAPPING:
+       KEBUGCHECK(PROCESS_HAS_LOCKED_PAGES);
+       break;
+
      default:
        KEBUGCHECK(0);
      }

reactos/ntoskrnl/mm
mdl.c 1.59 -> 1.60
diff -u -r1.59 -r1.60
--- mdl.c	6 Mar 2004 22:21:20 -0000	1.59
+++ mdl.c	13 Mar 2004 19:14:16 -0000	1.60
@@ -1,4 +1,4 @@
-/* $Id: mdl.c,v 1.59 2004/03/06 22:21:20 dwelch Exp $
+/* $Id: mdl.c,v 1.60 2004/03/13 19:14:16 dwelch Exp $
  *
  * COPYRIGHT:    See COPYING in the top level directory
  * PROJECT:      ReactOS kernel
@@ -152,42 +152,78 @@
    KIRQL oldIrql;
    ULONG RegionSize;
    ULONG StartingOffset;
-   
+   PEPROCESS CurrentProcess, OldProcess;
+
    DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode);
 
-   if (Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL)
+   if ((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) && AccessMode != UserMode)
      {
        return(Mdl->MappedSystemVa);
      }
 
+   /* Calculate the number of pages required. */
+   RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
+
    if (AccessMode == UserMode)
      {
-       DPRINT1("MDL mapping to user-mode not yet handled.\n");
-       KEBUGCHECK(0);
+       MEMORY_AREA *Result;
+       LARGE_INTEGER BoundaryAddressMultiple;
+       NTSTATUS Status;
+
+       BoundaryAddressMultiple.QuadPart = 0;
+       Base = NULL;
+
+       CurrentProcess = OldProcess = PsGetCurrentProcess();
+       if (Mdl->Process != CurrentProcess)
+	 {
+           KeAttachProcess(Mdl->Process);
+           CurrentProcess = Mdl->Process;
+	 }
+
+       MmLockAddressSpace(&CurrentProcess->AddressSpace);
+       Status = MmCreateMemoryArea(CurrentProcess,
+     			      &CurrentProcess->AddressSpace,
+     			      MEMORY_AREA_MDL_MAPPING,
+     			      &Base,
+     			      RegionSize * PAGE_SIZE,
+     			      0, /* PAGE_READWRITE? */
+     			      &Result,
+     			      FALSE,
+     			      FALSE,
+     			      BoundaryAddressMultiple);
+       MmUnlockAddressSpace(&CurrentProcess->AddressSpace);
+       if (!NT_SUCCESS(Status))
+         {
+           KEBUGCHECK(0);
+           /* FIXME: handle this? */
+         }
      }
+   else
+     {
+       CurrentProcess = OldProcess = NULL;
 
-   /* Calculate the number of pages required. */
-   RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
+       /* Allocate that number of pages from the mdl mapping region. */
+       KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
 
-   /* Allocate that number of pages from the mdl mapping region. */
-   KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
+       StartingOffset = RtlFindClearBitsAndSet(&MiMdlMappingRegionAllocMap, RegionSize, MiMdlMappingRegionHint);
 
-   StartingOffset = RtlFindClearBitsAndSet(&MiMdlMappingRegionAllocMap, RegionSize, MiMdlMappingRegionHint);
-  
-   if (StartingOffset == 0xffffffff)
-   {
-      DPRINT1("Out of MDL mapping space\n");
-      KEBUGCHECK(0);
-   }
+       if (StartingOffset == 0xffffffff)
+         {
+           DPRINT1("Out of MDL mapping space\n");
+           KEBUGCHECK(0);
+         }
 
-   Base = (char*)MiMdlMappingRegionBase + StartingOffset * PAGE_SIZE;
+       Base = (char*)MiMdlMappingRegionBase + StartingOffset * PAGE_SIZE;
+
+       if (MiMdlMappingRegionHint == StartingOffset)
+         {
+            MiMdlMappingRegionHint +=RegionSize;
+         }
+
+       KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
+     }
 
-   if (MiMdlMappingRegionHint == StartingOffset)
-   {
-       MiMdlMappingRegionHint +=RegionSize; 
-   }
 
-   KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
 
    /* Set the virtual mappings for the MDL pages. */
    MdlPages = (PULONG)(Mdl + 1);
@@ -198,7 +234,7 @@
 	PHYSICAL_ADDRESS dummyJunkNeeded;
 	dummyJunkNeeded.QuadPart = MdlPages[i];
 #endif
-       Status = MmCreateVirtualMapping(NULL,
+       Status = MmCreateVirtualMapping(CurrentProcess,
 				       (PVOID)((ULONG)Base+(i*PAGE_SIZE)),
 				       PAGE_READWRITE,
 #if defined(__GNUC__)
@@ -214,6 +250,11 @@
 	 }
      }
 
+   if (AccessMode == UserMode && CurrentProcess != OldProcess)
+     {
+       KeDetachProcess();
+     }
+
    /* Mark the MDL has having being mapped. */
    Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
    Mdl->MappedSystemVa = (char*)Base + Mdl->ByteOffset;
@@ -223,7 +264,7 @@
 /*
  * @implemented
  */
-VOID STDCALL 
+VOID STDCALL
 MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
 /*
  * FUNCTION: Releases a mapping set up by a preceding call to MmMapLockedPages
@@ -236,6 +277,7 @@
   ULONG i;
   ULONG RegionSize;
   ULONG Base;
+  PEPROCESS CurrentProcess, OldProcess;
 
   DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", BaseAddress, Mdl);
 
@@ -243,11 +285,26 @@
    * In this case, the MDL has the same system address as the base address
    * so there is no need to free it
    */
-  if (Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL)
+  if ((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) &&
+      ((ULONG_PTR)BaseAddress >= KERNEL_BASE))
     {
       return;
     }
 
+  if ((ULONG_PTR)BaseAddress >= KERNEL_BASE)
+    {
+      CurrentProcess = OldProcess = NULL;
+    }
+  else
+    {
+      CurrentProcess = OldProcess = PsGetCurrentProcess();
+      if (Mdl->Process != CurrentProcess)
+	    {
+          KeAttachProcess(Mdl->Process);
+          CurrentProcess = Mdl->Process;
+        }
+    }
+
   /* Calculate the number of pages we mapped. */
   RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
 #if defined(__GNUC__)
@@ -263,23 +320,44 @@
   /* Unmap all the pages. */
   for (i = 0; i < RegionSize; i++)
     {
-      MmDeleteVirtualMapping(NULL, 
+      MmDeleteVirtualMapping(NULL,
 			     (char*)BaseAddress + (i * PAGE_SIZE),
 			     FALSE,
 			     NULL,
 			     NULL);
     }
 
-  KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
-  /* Deallocate all the pages used. */
-  Base = (ULONG)((char*)BaseAddress - (char*)MiMdlMappingRegionBase) / PAGE_SIZE;
-  
-  RtlClearBits(&MiMdlMappingRegionAllocMap, Base, RegionSize);
+  if ((DWORD)BaseAddress >= KERNEL_BASE)
+    {
+      KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
+      /* Deallocate all the pages used. */
+      Base = (ULONG)((char*)BaseAddress - (char*)MiMdlMappingRegionBase) / PAGE_SIZE;
+
+      RtlClearBits(&MiMdlMappingRegionAllocMap, Base, RegionSize);
+
+      MiMdlMappingRegionHint = min (MiMdlMappingRegionHint, Base);
 
-  MiMdlMappingRegionHint = min (MiMdlMappingRegionHint, Base);
+      KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
+    }
+  else
+    {
+      MEMORY_AREA *Marea;
+
+      Marea = MmOpenMemoryAreaByAddress( &CurrentProcess->AddressSpace, BaseAddress );
+      if (Marea == NULL)
+        {
+          DPRINT1( "Couldn't open memory area when unmapping user-space pages!\n" );
+          KEBUGCHECK(0);
+        }
+
+      MmFreeMemoryArea( &CurrentProcess->AddressSpace, Marea->BaseAddress, 0, NULL, NULL );
+
+      if (CurrentProcess != OldProcess)
+        {
+          KeDetachProcess();
+        }
+    }
 
-  KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
-  
   /* Reset the MDL state. */
   Mdl->MdlFlags = Mdl->MdlFlags & ~MDL_MAPPED_TO_SYSTEM_VA;
   Mdl->MappedSystemVa = NULL;
CVSspam 0.2.8