Merge trunk head (r43756)
[reactos.git] / reactos / ntoskrnl / mm / section.c
index 803013d..e741a43 100644 (file)
@@ -125,7 +125,7 @@ MmGetFileNameForSection(IN PROS_SECTION_OBJECT Section,
     /* Allocate memory for our structure */
     ObjectNameInfo = ExAllocatePoolWithTag(PagedPool,
                                            1024,
-                                           TAG('M', 'm', ' ', ' '));
+                                           '  mM');
     if (!ObjectNameInfo) return STATUS_NO_MEMORY;
 
     /* Query the name */
@@ -136,7 +136,7 @@ MmGetFileNameForSection(IN PROS_SECTION_OBJECT Section,
     if (!NT_SUCCESS(Status))
     {
         /* Failed, free memory */
-        ExFreePoolWithTag(ObjectNameInfo, TAG('M', 'm', ' ', ' '));
+        ExFreePoolWithTag(ObjectNameInfo, '  mM');
         return Status;
     }
 
@@ -191,7 +191,7 @@ MmGetFileNameForAddress(IN PVOID Address,
                                 ModuleNameInformation->Name.Buffer);
 
          /* Free temp taged buffer from MmGetFileNameForSection() */
-         ExFreePoolWithTag(ModuleNameInformation, TAG('M', 'm', ' ', ' '));
+         ExFreePoolWithTag(ModuleNameInformation, '  mM');
          DPRINT("Found ModuleName %S by address %p\n",
                 ModuleName->Buffer,Address);
       }
@@ -574,6 +574,25 @@ BOOLEAN MiIsPageFromCache(PMEMORY_AREA MemoryArea,
    return FALSE;
 }
 
+NTSTATUS
+NTAPI
+MiCopyFromUserPage(PFN_TYPE DestPage, PVOID SourceAddress)
+{
+    PEPROCESS Process;
+    KIRQL Irql;
+    PVOID TempAddress;
+    
+    Process = PsGetCurrentProcess();
+    TempAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
+    if (TempAddress == NULL)
+    {
+        return(STATUS_NO_MEMORY);
+    }
+    memcpy(TempAddress, SourceAddress, PAGE_SIZE);
+    MiUnmapPageInHyperSpace(Process, TempAddress, Irql);
+    return(STATUS_SUCCESS);
+}
+
 NTSTATUS
 NTAPI
 MiReadPage(PMEMORY_AREA MemoryArea,
@@ -771,6 +790,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
    PMM_REGION Region;
    BOOLEAN HasSwapEntry;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+   KIRQL OldIrql;
     
    /*
     * There is a window between taking the page fault and locking the
@@ -781,7 +801,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
    {
       if (Locked)
       {
+         OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
          MmLockPage(MmGetPfnForProcess(Process, Address));
+         KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
       }
       return(STATUS_SUCCESS);
    }
@@ -908,7 +930,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       }
       if (Locked)
       {
+         OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
          MmLockPage(Page);
+         KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
       }
       MmUnlockSectionSegment(Segment);
       PageOp->Status = STATUS_SUCCESS;
@@ -978,7 +1002,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
        */
       if (Locked)
       {
+         OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
          MmLockPage(Page);
+         KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
       }
       PageOp->Status = STATUS_SUCCESS;
       MmspCompleteAndReleasePageOp(PageOp);
@@ -1013,7 +1039,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
        */
       if (Locked)
       {
-         MmLockPageUnsafe(Page);
+         OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+         MmLockPage(Page);
+         KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
       }
 
       /*
@@ -1056,7 +1084,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       MmInsertRmap(Page, Process, (PVOID)PAddress);
       if (Locked)
       {
+         OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
          MmLockPage(Page);
+         KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
       }
 
       /*
@@ -1156,7 +1186,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
 
       if (Locked)
       {
+         OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
          MmLockPage(Page);
+         KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
       }
       PageOp->Status = STATUS_SUCCESS;
       MmspCompleteAndReleasePageOp(PageOp);
@@ -1230,7 +1262,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       MmInsertRmap(Page, Process, (PVOID)PAddress);
       if (Locked)
       {
+         OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
          MmLockPage(Page);
+         KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
       }
       PageOp->Status = STATUS_SUCCESS;
       MmspCompleteAndReleasePageOp(PageOp);
@@ -1262,7 +1296,9 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
       MmInsertRmap(Page, Process, (PVOID)PAddress);
       if (Locked)
       {
+         OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
          MmLockPage(Page);
+         KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
       }
       PageOp->Status = STATUS_SUCCESS;
       MmspCompleteAndReleasePageOp(PageOp);
@@ -1289,6 +1325,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    PMM_REGION Region;
    ULONG Entry;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+   KIRQL OldIrql;
     
    DPRINT("MmAccessFaultSectionView(%x, %x, %x, %x)\n", AddressSpace, MemoryArea, Address, Locked);
 
@@ -1429,8 +1466,10 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
    }
    if (Locked)
    {
+      OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
       MmLockPage(NewPage);
       MmUnlockPage(OldPage);
+      KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
    }
 
    /*
@@ -1511,6 +1550,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    BOOLEAN DirectMapped;
    BOOLEAN IsImageSection;
    PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
+   KIRQL OldIrql;
     
    Address = (PVOID)PAGE_ROUND_DOWN(Address);
 
@@ -1599,7 +1639,9 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
    }
    else
    {
+      OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
       MmReferencePage(Page);
+      KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
    }
 
    MmDeleteAllRmaps(Page, (PVOID)&Context, MmPageOutDeleteMapping);
@@ -2098,7 +2140,7 @@ NTSTATUS NTAPI
 MmQuerySectionView(PMEMORY_AREA MemoryArea,
                    PVOID Address,
                    PMEMORY_BASIC_INFORMATION Info,
-                   PULONG ResultLength)
+                   PSIZE_T ResultLength)
 {
    PMM_REGION Region;
    PVOID RegionBaseAddress;
@@ -2328,6 +2370,8 @@ MmInitSectionImplementation(VOID)
    ObjectTypeInitializer.CloseProcedure = MmpCloseSection;
    ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS;
    ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &MmSectionObjectType);
+    
+   MmCreatePhysicalMemorySection();
 
    return(STATUS_SUCCESS);
 }
@@ -2375,10 +2419,9 @@ MmCreatePageFileSection(PROS_SECTION_OBJECT *SectionObject,
    /*
     * Initialize it
     */
+   RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
    Section->SectionPageProtection = SectionPageProtection;
    Section->AllocationAttributes = AllocationAttributes;
-   Section->Segment = NULL;
-   Section->FileObject = NULL;
    Section->MaximumSize = MaximumSize;
    Segment = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_SECTION_SEGMENT),
                                    TAG_MM_SECTION_SEGMENT);
@@ -2427,6 +2470,7 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
    LARGE_INTEGER Offset;
    CHAR Buffer;
    FILE_STANDARD_INFORMATION FileInfo;
+   ULONG Length;
 
    /*
     * Create the section
@@ -2447,9 +2491,9 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
    /*
     * Initialize it
     */
+   RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
    Section->SectionPageProtection = SectionPageProtection;
    Section->AllocationAttributes = AllocationAttributes;
-   Section->Segment = NULL;
 
    /*
     * Check file access required
@@ -2489,7 +2533,8 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
                                    FileStandardInformation,
                                    sizeof(FILE_STANDARD_INFORMATION),
                                    &FileInfo,
-                                   &Iosb.Information);
+                                   &Length);
+   Iosb.Information = Length;
    if (!NT_SUCCESS(Status))
    {
       ObDereferenceObject(Section);
@@ -2754,7 +2799,11 @@ ExeFmtpReadFile(IN PVOID File,
     */
    Buffer = ExAllocatePoolWithTag(PagedPool,
                                   BufferSize,
-                                  TAG('M', 'm', 'X', 'r'));
+                                  'rXmM');
+   if (!Buffer)
+   {
+      KeBugCheck(MEMORY_MANAGEMENT);
+   }
 
    UsedSize = 0;
 
@@ -2805,7 +2854,7 @@ ExeFmtpReadFile(IN PVOID File,
    }
    else
    {
-      ExFreePoolWithTag(Buffer, TAG('M', 'm', 'X', 'r'));
+      ExFreePoolWithTag(Buffer, 'rXmM');
    }
 
    return Status;
@@ -3214,7 +3263,7 @@ ExeFmtpCreateImageSection(HANDLE FileHandle,
          break;
    }
 
-   ExFreePoolWithTag(FileHeaderBuffer, TAG('M', 'm', 'X', 'r'));
+   ExFreePoolWithTag(FileHeaderBuffer, 'rXmM');
 
    /*
     * No loader handled the format
@@ -3373,6 +3422,7 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
    /*
     * Initialize it
     */
+   RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
    Section->SectionPageProtection = SectionPageProtection;
    Section->AllocationAttributes = AllocationAttributes;
 
@@ -3494,28 +3544,28 @@ NtCreateSection (OUT PHANDLE SectionHandle,
    LARGE_INTEGER SafeMaximumSize;
    PVOID SectionObject;
    KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+   NTSTATUS Status;
 
    PreviousMode = ExGetPreviousMode();
 
-   if(MaximumSize != NULL && PreviousMode != KernelMode)
+   if(PreviousMode != KernelMode)
    {
      _SEH2_TRY
      {
-       /* make a copy on the stack */
-       SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
-       MaximumSize = &SafeMaximumSize;
+       if (MaximumSize != NULL)
+       {
+          /* make a copy on the stack */
+          SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
+          MaximumSize = &SafeMaximumSize;
+       }
+       ProbeForWriteHandle(SectionHandle);
      }
      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
      {
-       Status = _SEH2_GetExceptionCode();
+         /* Return the exception code */
+         _SEH2_YIELD(return _SEH2_GetExceptionCode());
      }
      _SEH2_END;
-
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
    }
 
    Status = MmCreateSection(&SectionObject,
@@ -3564,7 +3614,7 @@ NtOpenSection(PHANDLE   SectionHandle,
 {
    HANDLE hSection;
    KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+   NTSTATUS Status;
 
    PreviousMode = ExGetPreviousMode();
 
@@ -3576,14 +3626,10 @@ NtOpenSection(PHANDLE   SectionHandle,
      }
      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
      {
-       Status = _SEH2_GetExceptionCode();
+        /* Return the exception code */
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
      }
      _SEH2_END;
-
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
    }
 
    Status = ObOpenObjectByName(ObjectAttributes,
@@ -3723,8 +3769,9 @@ NtMapViewOfSection(IN HANDLE SectionHandle,
    PEPROCESS Process;
    KPROCESSOR_MODE PreviousMode;
    PMMSUPPORT AddressSpace;
-   NTSTATUS Status = STATUS_SUCCESS;
+   NTSTATUS Status;
    ULONG tmpProtect;
+   ACCESS_MASK DesiredAccess;
 
    /*
     * Check the protection
@@ -3772,14 +3819,10 @@ NtMapViewOfSection(IN HANDLE SectionHandle,
      }
      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
      {
-       Status = _SEH2_GetExceptionCode();
+         /* Return the exception code */
+         _SEH2_YIELD(return _SEH2_GetExceptionCode());
      }
      _SEH2_END;
-
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
    }
    else
    {
@@ -3803,8 +3846,27 @@ NtMapViewOfSection(IN HANDLE SectionHandle,
 
    AddressSpace = &Process->Vm;
 
+   /* Convert NT Protection Attr to Access Mask */
+   if (Protect == PAGE_READONLY)
+   {
+      DesiredAccess = SECTION_MAP_READ;
+   }
+   else if (Protect == PAGE_READWRITE)
+   {
+      DesiredAccess = SECTION_MAP_WRITE;
+   }
+   else if (Protect == PAGE_WRITECOPY)
+   {
+      DesiredAccess = SECTION_QUERY;
+   }
+   /* FIXME: Handle other Protection Attributes. For now keep previous behavior */
+   else
+   {
+      DesiredAccess = SECTION_MAP_READ;
+   }
+
    Status = ObReferenceObjectByHandle(SectionHandle,
-                                      SECTION_MAP_READ,
+                                      DesiredAccess,
                                       MmSectionObjectType,
                                       PreviousMode,
                                       (PVOID*)(PVOID)&Section,
@@ -4232,12 +4294,13 @@ NTSTATUS NTAPI
 NtQuerySection(IN HANDLE SectionHandle,
                IN SECTION_INFORMATION_CLASS SectionInformationClass,
                OUT PVOID SectionInformation,
-               IN ULONG SectionInformationLength,
-               OUT PULONG ResultLength  OPTIONAL)
+               IN SIZE_T SectionInformationLength,
+               OUT PSIZE_T ResultLength  OPTIONAL)
 {
    PROS_SECTION_OBJECT Section;
    KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+   NTSTATUS Status;
+   PAGED_CODE();
 
    PreviousMode = ExGetPreviousMode();
 
@@ -4246,6 +4309,7 @@ NtQuerySection(IN HANDLE SectionHandle,
                                         sizeof(ExSectionInfoClass) / sizeof(ExSectionInfoClass[0]),
                                         SectionInformation,
                                         SectionInformationLength,
+                                        NULL,
                                         ResultLength,
                                         PreviousMode);
 
@@ -4365,7 +4429,7 @@ NtExtendSection(IN HANDLE SectionHandle,
    LARGE_INTEGER SafeNewMaximumSize;
    PROS_SECTION_OBJECT Section;
    KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+   NTSTATUS Status;
 
    PreviousMode = ExGetPreviousMode();
 
@@ -4379,14 +4443,10 @@ NtExtendSection(IN HANDLE SectionHandle,
      }
      _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
      {
-       Status = _SEH2_GetExceptionCode();
+        /* Return the exception code */
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
      }
      _SEH2_END;
-
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
    }
 
    Status = ObReferenceObjectByHandle(SectionHandle,
@@ -4402,7 +4462,7 @@ NtExtendSection(IN HANDLE SectionHandle,
 
    if (!(Section->AllocationAttributes & SEC_FILE))
    {
-      ObfDereferenceObject(Section);
+      ObDereferenceObject(Section);
       return STATUS_INVALID_PARAMETER;
    }
 
@@ -4753,7 +4813,7 @@ MmCanFileBeTruncated (IN PSECTION_OBJECT_POINTERS SectionObjectPointer,
          /* Something must gone wrong
           * how can we have a Section but no 
           * reference? */
-         DPRINT1("ERROR: DataSectionObject without reference!\n");
+         DPRINT("ERROR: DataSectionObject without reference!\n");
       }
    }
 
@@ -4815,7 +4875,7 @@ MmForceSectionClosed (
 NTSTATUS NTAPI
 MmMapViewInSystemSpace (IN PVOID SectionObject,
                         OUT PVOID * MappedBase,
-                        IN OUT PULONG ViewSize)
+                        IN OUT PSIZE_T ViewSize)
 {
    PROS_SECTION_OBJECT Section;
    PMMSUPPORT AddressSpace;
@@ -4903,22 +4963,6 @@ MmUnmapViewInSessionSpace (
        return STATUS_NOT_IMPLEMENTED;
 }
 
-/*
- * @unimplemented
- */
-NTSTATUS NTAPI
-MmSetBankedSection (ULONG Unknown0,
-                    ULONG Unknown1,
-                    ULONG Unknown2,
-                    ULONG Unknown3,
-                    ULONG Unknown4,
-                    ULONG Unknown5)
-{
-   UNIMPLEMENTED;
-   return (STATUS_NOT_IMPLEMENTED);
-}
-
-
 /**********************************************************************
  * NAME       EXPORTED
  *  MmCreateSection@
@@ -5032,46 +5076,6 @@ MmCreateSection (OUT PVOID  * Section,
                                   AllocationAttributes));
 }
 
-NTSTATUS
-NTAPI
-NtAllocateUserPhysicalPages(IN HANDLE ProcessHandle,
-                            IN OUT PULONG_PTR NumberOfPages,
-                            IN OUT PULONG_PTR UserPfnArray)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-NTAPI
-NtMapUserPhysicalPages(IN PVOID VirtualAddresses,
-                       IN ULONG_PTR NumberOfPages,
-                       IN OUT PULONG_PTR UserPfnArray)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-NTAPI
-NtMapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses,
-                              IN ULONG_PTR NumberOfPages,
-                              IN OUT PULONG_PTR UserPfnArray)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-NTAPI
-NtFreeUserPhysicalPages(IN HANDLE ProcessHandle,
-                        IN OUT PULONG_PTR NumberOfPages,
-                        IN OUT PULONG_PTR UserPfnArray)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
 NTSTATUS
 NTAPI
 NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage,