[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / mm / section.c
index 1f0f99e..4943dab 100644 (file)
@@ -171,11 +171,6 @@ static GENERIC_MAPPING MmpSectionMapping =
     SECTION_ALL_ACCESS
 };
 
-static const INFORMATION_CLASS_INFO ExSectionInfoClass[] =
-{
-    ICI_SQ_SAME( sizeof(SECTION_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionBasicInformation */
-    ICI_SQ_SAME( sizeof(SECTION_IMAGE_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SectionImageInformation */
-};
 
 /* FUNCTIONS *****************************************************************/
 
@@ -1115,6 +1110,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
          * filesystems do because it is safe for us to use an offset with an
          * alignment less than the file system block size.
          */
+        KeEnterCriticalRegion();
         Status = CcRosGetVacb(SharedCacheMap,
                               FileOffset,
                               &BaseOffset,
@@ -1123,6 +1119,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
                               &Vacb);
         if (!NT_SUCCESS(Status))
         {
+            KeLeaveCriticalRegion();
             return(Status);
         }
         if (!UptoDate)
@@ -1135,6 +1132,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
             if (!NT_SUCCESS(Status))
             {
                 CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
+                KeLeaveCriticalRegion();
                 return Status;
             }
         }
@@ -1149,6 +1147,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
                                        FileOffset - BaseOffset).LowPart >> PAGE_SHIFT;
 
         CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, TRUE);
+        KeLeaveCriticalRegion();
     }
     else
     {
@@ -1168,6 +1167,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
         {
             return(Status);
         }
+        KeEnterCriticalRegion();
         Status = CcRosGetVacb(SharedCacheMap,
                               FileOffset,
                               &BaseOffset,
@@ -1176,6 +1176,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
                               &Vacb);
         if (!NT_SUCCESS(Status))
         {
+            KeLeaveCriticalRegion();
             return(Status);
         }
         if (!UptoDate)
@@ -1188,6 +1189,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
             if (!NT_SUCCESS(Status))
             {
                 CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
+                KeLeaveCriticalRegion();
                 return Status;
             }
         }
@@ -1217,6 +1219,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
                                   &Vacb);
             if (!NT_SUCCESS(Status))
             {
+                KeLeaveCriticalRegion();
                 return(Status);
             }
             if (!UptoDate)
@@ -1229,6 +1232,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
                 if (!NT_SUCCESS(Status))
                 {
                     CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
+                    KeLeaveCriticalRegion();
                     return Status;
                 }
             }
@@ -1244,6 +1248,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
         }
         MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
         CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE);
+        KeLeaveCriticalRegion();
     }
     return(STATUS_SUCCESS);
 }
@@ -2756,7 +2761,7 @@ MmCreatePhysicalMemorySection(VOID)
     SectionSize.QuadPart = 0xFFFFFFFF;
     InitializeObjectAttributes(&Obj,
                                &Name,
-                               OBJ_PERMANENT,
+                               OBJ_PERMANENT | OBJ_KERNEL_EXCLUSIVE,
                                NULL,
                                NULL);
     Status = MmCreateSection((PVOID)&PhysSection,
@@ -2998,7 +3003,7 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
         {
             ObDereferenceObject(Section);
             ObDereferenceObject(FileObject);
-            return STATUS_FILE_INVALID;
+            return STATUS_MAPPED_FILE_SIZE_ZERO;
         }
     }
 
@@ -3237,10 +3242,12 @@ ExeFmtpReadFile(IN PVOID File,
     BufferSize = PAGE_ROUND_UP(BufferSize);
 
     /* Flush data since we're about to perform a non-cached read */
+    KeEnterCriticalRegion();
     CcFlushCache(FileObject->SectionObjectPointer,
                  &FileOffset,
                  BufferSize,
                  &Iosb);
+    KeLeaveCriticalRegion();
 
     /*
      * It's ok to use paged pool, because this is a temporary buffer only used in
@@ -3782,6 +3789,14 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject,
     if (FileObject == NULL)
         return STATUS_INVALID_FILE_FOR_SECTION;
 
+#ifndef NEWCC
+    if (FileObject->SectionObjectPointer->SharedCacheMap == NULL)
+    {
+        DPRINT1("Denying section creation due to missing cache initialization\n");
+        return STATUS_INVALID_FILE_FOR_SECTION;
+    }
+#endif
+
     /*
      * Create the section
      */
@@ -4190,7 +4205,7 @@ MiRosUnmapViewOfSection(IN PEPROCESS Process,
              (MemoryArea->Type != MEMORY_AREA_CACHE)) ||
             MemoryArea->DeleteInProgress)
     {
-        if (MemoryArea) NT_ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3);
+        if (MemoryArea) ASSERT(MemoryArea->Type != MEMORY_AREA_OWNED_BY_ARM3);
         MmUnlockAddressSpace(AddressSpace);
         return STATUS_NOT_MAPPED_VIEW;
     }
@@ -4216,13 +4231,10 @@ MiRosUnmapViewOfSection(IN PEPROCESS Process,
          * and calculate the image base address */
         for (i = 0; i < NrSegments; i++)
         {
-            if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
+            if (Segment == &SectionSegments[i])
             {
-                if (Segment == &SectionSegments[i])
-                {
-                    ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
-                    break;
-                }
+                ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].Image.VirtualAddress;
+                break;
             }
         }
         if (i >= NrSegments)
@@ -4232,18 +4244,15 @@ MiRosUnmapViewOfSection(IN PEPROCESS Process,
 
         for (i = 0; i < NrSegments; i++)
         {
-            if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
-            {
-                PVOID SBaseAddress = (PVOID)
-                                     ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
+            PVOID SBaseAddress = (PVOID)
+                                 ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
 
-                Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
-                if (!NT_SUCCESS(Status))
-                {
-                    DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
-                            SBaseAddress, Process, Status);
-                    NT_ASSERT(NT_SUCCESS(Status));
-                }
+            Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
+            if (!NT_SUCCESS(Status))
+            {
+                DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
+                        SBaseAddress, Process, Status);
+                ASSERT(NT_SUCCESS(Status));
             }
         }
     }
@@ -4254,7 +4263,7 @@ MiRosUnmapViewOfSection(IN PEPROCESS Process,
         {
             DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
                     BaseAddress, Process, Status);
-            NT_ASSERT(NT_SUCCESS(Status));
+            ASSERT(NT_SUCCESS(Status));
         }
     }
 
@@ -4291,12 +4300,14 @@ MiRosUnmapViewOfSection(IN PEPROCESS Process,
  *
  * @implemented
  */
-NTSTATUS NTAPI
-NtQuerySection(IN HANDLE SectionHandle,
-               IN SECTION_INFORMATION_CLASS SectionInformationClass,
-               OUT PVOID SectionInformation,
-               IN SIZE_T SectionInformationLength,
-               OUT PSIZE_T ResultLength  OPTIONAL)
+NTSTATUS
+NTAPI
+NtQuerySection(
+    _In_ HANDLE SectionHandle,
+    _In_ SECTION_INFORMATION_CLASS SectionInformationClass,
+    _Out_ PVOID SectionInformation,
+    _In_ SIZE_T SectionInformationLength,
+    _Out_opt_ PSIZE_T ResultLength)
 {
     PROS_SECTION_OBJECT Section;
     KPROCESSOR_MODE PreviousMode;
@@ -4304,20 +4315,44 @@ NtQuerySection(IN HANDLE SectionHandle,
     PAGED_CODE();
 
     PreviousMode = ExGetPreviousMode();
+    if (PreviousMode != KernelMode)
+    {
+        _SEH2_TRY
+        {
+            ProbeForWrite(SectionInformation,
+                          SectionInformationLength,
+                          __alignof(ULONG));
+            if (ResultLength != NULL)
+            {
+                ProbeForWrite(ResultLength,
+                              sizeof(*ResultLength),
+                              __alignof(SIZE_T));
+            }
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            return _SEH2_GetExceptionCode();
+        }
+        _SEH2_END;
+    }
 
-    Status = DefaultQueryInfoBufferCheck(SectionInformationClass,
-                                         ExSectionInfoClass,
-                                         sizeof(ExSectionInfoClass) / sizeof(ExSectionInfoClass[0]),
-                                         SectionInformation,
-                                         (ULONG)SectionInformationLength,
-                                         NULL,
-                                         ResultLength,
-                                         PreviousMode);
-
-    if(!NT_SUCCESS(Status))
+    if (SectionInformationClass == SectionBasicInformation)
     {
-        DPRINT1("NtQuerySection() failed, Status: 0x%x\n", Status);
-        return Status;
+        if (SectionInformationLength < sizeof(SECTION_BASIC_INFORMATION))
+        {
+            return STATUS_INFO_LENGTH_MISMATCH;
+        }
+    }
+    else if (SectionInformationClass == SectionImageInformation)
+    {
+        if (SectionInformationLength < sizeof(SECTION_IMAGE_INFORMATION))
+        {
+            return STATUS_INFO_LENGTH_MISMATCH;
+        }
+    }
+    else
+    {
+        return STATUS_INVALID_INFO_CLASS;
     }
 
     Status = ObReferenceObjectByHandle(SectionHandle,
@@ -4326,10 +4361,14 @@ NtQuerySection(IN HANDLE SectionHandle,
                                        PreviousMode,
                                        (PVOID*)(PVOID)&Section,
                                        NULL);
-    if (NT_SUCCESS(Status))
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to reference section: 0x%lx\n", Status);
+        return Status;
+    }
+
+    switch (SectionInformationClass)
     {
-        switch (SectionInformationClass)
-        {
         case SectionBasicInformation:
         {
             PSECTION_BASIC_INFORMATION Sbi = (PSECTION_BASIC_INFORMATION)SectionInformation;
@@ -4391,11 +4430,10 @@ NtQuerySection(IN HANDLE SectionHandle,
 
             break;
         }
-        }
-
-        ObDereferenceObject(Section);
     }
 
+    ObDereferenceObject(Section);
+
     return(Status);
 }
 
@@ -4520,13 +4558,10 @@ MmMapViewOfSection(IN PVOID SectionObject,
         ImageSize = 0;
         for (i = 0; i < NrSegments; i++)
         {
-            if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
-            {
-                ULONG_PTR MaxExtent;
-                MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress +
-                                        SectionSegments[i].Length.QuadPart);
-                ImageSize = max(ImageSize, MaxExtent);
-            }
+            ULONG_PTR MaxExtent;
+            MaxExtent = (ULONG_PTR)(SectionSegments[i].Image.VirtualAddress +
+                                    SectionSegments[i].Length.QuadPart);
+            ImageSize = max(ImageSize, MaxExtent);
         }
 
         ImageSectionObject->ImageInformation.ImageFileSize = (ULONG)ImageSize;
@@ -4535,14 +4570,14 @@ MmMapViewOfSection(IN PVOID SectionObject,
         if (((ImageBase + ImageSize) > (ULONG_PTR)MmHighestUserAddress) ||
                 ((ImageBase + ImageSize) < ImageSize))
         {
-            NT_ASSERT(*BaseAddress == NULL);
+            ASSERT(*BaseAddress == NULL);
             ImageBase = ALIGN_DOWN_BY((ULONG_PTR)MmHighestUserAddress - ImageSize,
                                       MM_VIRTMEM_GRANULARITY);
             NotAtBase = TRUE;
         }
         else if (ImageBase != ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY))
         {
-            NT_ASSERT(*BaseAddress == NULL);
+            ASSERT(*BaseAddress == NULL);
             ImageBase = ALIGN_DOWN_BY(ImageBase, MM_VIRTMEM_GRANULARITY);
             NotAtBase = TRUE;
         }
@@ -4570,25 +4605,22 @@ MmMapViewOfSection(IN PVOID SectionObject,
 
         for (i = 0; i < NrSegments; i++)
         {
-            if (!(SectionSegments[i].Image.Characteristics & IMAGE_SCN_TYPE_NOLOAD))
+            PVOID SBaseAddress = (PVOID)
+                                 ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
+            MmLockSectionSegment(&SectionSegments[i]);
+            Status = MmMapViewOfSegment(AddressSpace,
+                                        Section,
+                                        &SectionSegments[i],
+                                        &SBaseAddress,
+                                        SectionSegments[i].Length.LowPart,
+                                        SectionSegments[i].Protection,
+                                        0,
+                                        0);
+            MmUnlockSectionSegment(&SectionSegments[i]);
+            if (!NT_SUCCESS(Status))
             {
-                PVOID SBaseAddress = (PVOID)
-                                     ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].Image.VirtualAddress);
-                MmLockSectionSegment(&SectionSegments[i]);
-                Status = MmMapViewOfSegment(AddressSpace,
-                                            Section,
-                                            &SectionSegments[i],
-                                            &SBaseAddress,
-                                            SectionSegments[i].Length.LowPart,
-                                            SectionSegments[i].Protection,
-                                            0,
-                                            0);
-                MmUnlockSectionSegment(&SectionSegments[i]);
-                if (!NT_SUCCESS(Status))
-                {
-                    MmUnlockAddressSpace(AddressSpace);
-                    return(Status);
-                }
+                MmUnlockAddressSpace(AddressSpace);
+                return(Status);
             }
         }
 
@@ -4663,7 +4695,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
     }
 
     MmUnlockAddressSpace(AddressSpace);
-    NT_ASSERT(*BaseAddress == ALIGN_DOWN_POINTER_BY(*BaseAddress, MM_VIRTMEM_GRANULARITY));
+    ASSERT(*BaseAddress == ALIGN_DOWN_POINTER_BY(*BaseAddress, MM_VIRTMEM_GRANULARITY));
 
     if (NotAtBase)
         Status = STATUS_IMAGE_NOT_AT_BASE;