[NTOSKRNL]
[reactos.git] / reactos / ntoskrnl / mm / section.c
index 8f6ef47..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 *****************************************************************/
 
@@ -241,13 +236,13 @@ NTSTATUS NTAPI PeFmtCreateSection(IN CONST VOID * FileHeader,
     if(pidhDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
         DIE(("No MZ signature found, e_magic is %hX\n", pidhDosHeader->e_magic));
 
+    /* NT HEADER */
+    nStatus = STATUS_INVALID_IMAGE_PROTECT;
+
     /* not a Windows executable */
     if(pidhDosHeader->e_lfanew <= 0)
         DIE(("Not a Windows executable, e_lfanew is %d\n", pidhDosHeader->e_lfanew));
 
-    /* NT HEADER */
-    nStatus = STATUS_INVALID_IMAGE_FORMAT;
-
     if(!Intsafe_AddULong32(&cbFileHeaderOffsetSize, pidhDosHeader->e_lfanew, RTL_SIZEOF_THROUGH_FIELD(IMAGE_NT_HEADERS32, FileHeader)))
         DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
 
@@ -286,7 +281,7 @@ l_ReadHeaderFromFile:
             NTSTATUS ReturnedStatus = nStatus;
 
             /* If it attempted to read past the end of the file, it means e_lfanew is invalid */
-            if (ReturnedStatus == STATUS_END_OF_FILE) nStatus = STATUS_ROS_EXEFMT_UNKNOWN_FORMAT;
+            if (ReturnedStatus == STATUS_END_OF_FILE) nStatus = STATUS_INVALID_IMAGE_PROTECT;
 
             DIE(("ReadFile failed, status %08X\n", ReturnedStatus));
         }
@@ -336,11 +331,11 @@ l_ReadHeaderFromFile:
         if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
             DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
 
-        nStatus = STATUS_INVALID_IMAGE_FORMAT;
-
         if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
             DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
 
+        nStatus = STATUS_INVALID_IMAGE_FORMAT;
+
         if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, cbOptHeaderOffsetSize, pinhNtHeader->FileHeader.SizeOfOptionalHeader))
             DIE(("The NT header is too large, SizeOfOptionalHeader is %X\n", pinhNtHeader->FileHeader.SizeOfOptionalHeader));
 
@@ -363,7 +358,9 @@ l_ReadHeaderFromFile:
     switch(piohOptHeader->Magic)
     {
     case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
+#ifdef _WIN64
     case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
+#endif // _WIN64
         break;
 
     default:
@@ -1113,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,
@@ -1121,6 +1119,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
                               &Vacb);
         if (!NT_SUCCESS(Status))
         {
+            KeLeaveCriticalRegion();
             return(Status);
         }
         if (!UptoDate)
@@ -1133,6 +1132,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
             if (!NT_SUCCESS(Status))
             {
                 CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
+                KeLeaveCriticalRegion();
                 return Status;
             }
         }
@@ -1147,6 +1147,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
                                        FileOffset - BaseOffset).LowPart >> PAGE_SHIFT;
 
         CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, TRUE);
+        KeLeaveCriticalRegion();
     }
     else
     {
@@ -1166,6 +1167,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
         {
             return(Status);
         }
+        KeEnterCriticalRegion();
         Status = CcRosGetVacb(SharedCacheMap,
                               FileOffset,
                               &BaseOffset,
@@ -1174,6 +1176,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
                               &Vacb);
         if (!NT_SUCCESS(Status))
         {
+            KeLeaveCriticalRegion();
             return(Status);
         }
         if (!UptoDate)
@@ -1186,6 +1189,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
             if (!NT_SUCCESS(Status))
             {
                 CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
+                KeLeaveCriticalRegion();
                 return Status;
             }
         }
@@ -1215,6 +1219,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
                                   &Vacb);
             if (!NT_SUCCESS(Status))
             {
+                KeLeaveCriticalRegion();
                 return(Status);
             }
             if (!UptoDate)
@@ -1227,6 +1232,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
                 if (!NT_SUCCESS(Status))
                 {
                     CcRosReleaseVacb(SharedCacheMap, Vacb, FALSE, FALSE, FALSE);
+                    KeLeaveCriticalRegion();
                     return Status;
                 }
             }
@@ -1242,6 +1248,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
         }
         MiUnmapPageInHyperSpace(Process, PageAddr, Irql);
         CcRosReleaseVacb(SharedCacheMap, Vacb, TRUE, FALSE, FALSE);
+        KeLeaveCriticalRegion();
     }
     return(STATUS_SUCCESS);
 }
@@ -1323,12 +1330,12 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
     }
 
     PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
-    Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
+    Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
                       + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
 
     Segment = MemoryArea->Data.SectionData.Segment;
     Section = MemoryArea->Data.SectionData.Section;
-    Region = MmFindRegion(MemoryArea->StartingAddress,
+    Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
                           &MemoryArea->Data.SectionData.RegionListHead,
                           Address, NULL);
     ASSERT(Region != NULL);
@@ -1700,12 +1707,12 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
      * Find the offset of the page
      */
     PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
-    Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
+    Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea)
                       + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
 
     Segment = MemoryArea->Data.SectionData.Segment;
     Section = MemoryArea->Data.SectionData.Section;
-    Region = MmFindRegion(MemoryArea->StartingAddress,
+    Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
                           &MemoryArea->Data.SectionData.RegionListHead,
                           Address, NULL);
     ASSERT(Region != NULL);
@@ -1895,7 +1902,7 @@ MmPageOutSectionView(PMMSUPPORT AddressSpace,
     Context.SectionEntry = Entry;
     Context.CallingProcess = Process;
 
-    Context.Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+    Context.Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)
                               + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
 
     DirectMapped = FALSE;
@@ -2294,7 +2301,7 @@ MmWritePageSectionView(PMMSUPPORT AddressSpace,
 
     Address = (PVOID)PAGE_ROUND_DOWN(Address);
 
-    Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+    Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)
                       + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
 
     /*
@@ -2478,7 +2485,7 @@ MmAlterViewAttributes(PMMSUPPORT AddressSpace,
                 ULONG_PTR Entry;
                 PFN_NUMBER Page;
 
-                Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+                Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)
                                   + MemoryArea->Data.SectionData.ViewOffset.QuadPart;
                 Entry = MmGetPageEntrySectionSegment(Segment, &Offset);
                 /*
@@ -2520,11 +2527,11 @@ MmProtectSectionView(PMMSUPPORT AddressSpace,
     NTSTATUS Status;
     ULONG_PTR MaxLength;
 
-    MaxLength = (ULONG_PTR)MemoryArea->EndingAddress - (ULONG_PTR)BaseAddress;
+    MaxLength = MA_GetEndingAddress(MemoryArea) - (ULONG_PTR)BaseAddress;
     if (Length > MaxLength)
         Length = (ULONG)MaxLength;
 
-    Region = MmFindRegion(MemoryArea->StartingAddress,
+    Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
                           &MemoryArea->Data.SectionData.RegionListHead,
                           BaseAddress, NULL);
     ASSERT(Region != NULL);
@@ -2536,7 +2543,7 @@ MmProtectSectionView(PMMSUPPORT AddressSpace,
     }
 
     *OldProtect = Region->Protect;
-    Status = MmAlterRegion(AddressSpace, MemoryArea->StartingAddress,
+    Status = MmAlterRegion(AddressSpace, (PVOID)MA_GetStartingAddress(MemoryArea),
                            &MemoryArea->Data.SectionData.RegionListHead,
                            BaseAddress, Length, Region->Type, Protect,
                            MmAlterViewAttributes);
@@ -2555,7 +2562,7 @@ MmQuerySectionView(PMEMORY_AREA MemoryArea,
     PROS_SECTION_OBJECT Section;
     PMM_SECTION_SEGMENT Segment;
 
-    Region = MmFindRegion((PVOID)MemoryArea->StartingAddress,
+    Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea),
                           &MemoryArea->Data.SectionData.RegionListHead,
                           Address, &RegionBaseAddress);
     if (Region == NULL)
@@ -2567,12 +2574,12 @@ MmQuerySectionView(PMEMORY_AREA MemoryArea,
     if (Section->AllocationAttributes & SEC_IMAGE)
     {
         Segment = MemoryArea->Data.SectionData.Segment;
-        Info->AllocationBase = (PUCHAR)MemoryArea->StartingAddress - Segment->Image.VirtualAddress;
+        Info->AllocationBase = (PUCHAR)MA_GetStartingAddress(MemoryArea) - Segment->Image.VirtualAddress;
         Info->Type = MEM_IMAGE;
     }
     else
     {
-        Info->AllocationBase = MemoryArea->StartingAddress;
+        Info->AllocationBase = (PVOID)MA_GetStartingAddress(MemoryArea);
         Info->Type = MEM_MAPPED;
     }
     Info->BaseAddress = RegionBaseAddress;
@@ -2754,7 +2761,7 @@ MmCreatePhysicalMemorySection(VOID)
     SectionSize.QuadPart = 0xFFFFFFFF;
     InitializeObjectAttributes(&Obj,
                                &Name,
-                               OBJ_PERMANENT,
+                               OBJ_PERMANENT | OBJ_KERNEL_EXCLUSIVE,
                                NULL,
                                NULL);
     Status = MmCreateSection((PVOID)&PhysSection,
@@ -2996,7 +3003,7 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject,
         {
             ObDereferenceObject(Section);
             ObDereferenceObject(FileObject);
-            return STATUS_FILE_INVALID;
+            return STATUS_MAPPED_FILE_SIZE_ZERO;
         }
     }
 
@@ -3234,6 +3241,14 @@ ExeFmtpReadFile(IN PVOID File,
     BufferSize = Length + OffsetAdjustment;
     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
      * the loading of executables. The assumption is that MmCreateSection is
@@ -3245,7 +3260,7 @@ ExeFmtpReadFile(IN PVOID File,
                                    'rXmM');
     if (!Buffer)
     {
-        KeBugCheck(MEMORY_MANAGEMENT);
+        return STATUS_INSUFFICIENT_RESOURCES;
     }
 
     UsedSize = 0;
@@ -3610,7 +3625,7 @@ MmspPageAlignSegments
 }
 
 NTSTATUS
-ExeFmtpCreateImageSection(HANDLE FileHandle,
+ExeFmtpCreateImageSection(PFILE_OBJECT FileObject,
                           PMM_IMAGE_SECTION_OBJECT ImageSectionObject)
 {
     LARGE_INTEGER Offset;
@@ -3628,8 +3643,7 @@ ExeFmtpCreateImageSection(HANDLE FileHandle,
      */
     Offset.QuadPart = 0;
 
-    /* FIXME: use FileObject instead of FileHandle */
-    Status = ExeFmtpReadFile (FileHandle,
+    Status = ExeFmtpReadFile (FileObject,
                               &Offset,
                               PAGE_SIZE * 2,
                               &FileHeader,
@@ -3653,10 +3667,9 @@ ExeFmtpCreateImageSection(HANDLE FileHandle,
         RtlZeroMemory(ImageSectionObject, sizeof(*ImageSectionObject));
         Flags = 0;
 
-        /* FIXME: use FileObject instead of FileHandle */
         Status = ExeFmtpLoaders[i](FileHeader,
                                    FileHeaderSize,
-                                   FileHandle,
+                                   FileObject,
                                    ImageSectionObject,
                                    &Flags,
                                    ExeFmtpReadFile,
@@ -3776,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
      */
@@ -3965,7 +3986,6 @@ MmMapViewOfSegment(PMMSUPPORT AddressSpace,
                                 ViewSize,
                                 Protect,
                                 &MArea,
-                                FALSE,
                                 AllocationType,
                                 Granularity);
     if (!NT_SUCCESS(Status))
@@ -3980,6 +4000,11 @@ MmMapViewOfSegment(PMMSUPPORT AddressSpace,
     MArea->Data.SectionData.Segment = Segment;
     MArea->Data.SectionData.Section = Section;
     MArea->Data.SectionData.ViewOffset.QuadPart = ViewOffset;
+    if (Section->AllocationAttributes & SEC_IMAGE)
+    {
+        MArea->VadNode.u.VadFlags.VadType = VadImageMap;
+    }
+
     MmInitializeRegion(&MArea->Data.SectionData.RegionListHead,
                        ViewSize, 0, Protect);
 
@@ -4008,7 +4033,7 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
 
     Address = (PVOID)PAGE_ROUND_DOWN(Address);
 
-    Offset.QuadPart = ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress) +
+    Offset.QuadPart = ((ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)) +
                       MemoryArea->Data.SectionData.ViewOffset.QuadPart;
 
     Section = MemoryArea->Data.SectionData.Section;
@@ -4180,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;
     }
@@ -4206,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)
@@ -4222,20 +4244,27 @@ 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);
-                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));
             }
         }
     }
     else
     {
         Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
-        NT_ASSERT(NT_SUCCESS(Status));
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("MmUnmapViewOfSegment failed for %p (Process %p) with %lx\n",
+                    BaseAddress, Process, Status);
+            ASSERT(NT_SUCCESS(Status));
+        }
     }
 
     MmUnlockAddressSpace(AddressSpace);
@@ -4271,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;
@@ -4284,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,
@@ -4306,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;
@@ -4371,11 +4430,10 @@ NtQuerySection(IN HANDLE SectionHandle,
 
             break;
         }
-        }
-
-        ObDereferenceObject(Section);
     }
 
+    ObDereferenceObject(Section);
+
     return(Status);
 }
 
@@ -4468,6 +4526,8 @@ MmMapViewOfSection(IN PVOID SectionObject,
         return STATUS_INVALID_PAGE_PROTECTION;
     }
 
+    /* FIXME: We should keep this, but it would break code checking equality */
+    Protect &= ~PAGE_NOCACHE;
 
     Section = (PROS_SECTION_OBJECT)SectionObject;
     AddressSpace = &Process->Vm;
@@ -4498,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;
@@ -4513,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;
         }
@@ -4548,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);
             }
         }
 
@@ -4597,13 +4651,6 @@ MmMapViewOfSection(IN PVOID SectionObject,
             return STATUS_SECTION_PROTECTION;
         }
 
-        if (ViewSize == NULL)
-        {
-            /* Following this pointer would lead to us to the dark side */
-            /* What to do? Bugcheck? Return status? Do the mambo? */
-            KeBugCheck(MEMORY_MANAGEMENT);
-        }
-
         if (SectionOffset == NULL)
         {
             ViewOffset = 0;
@@ -4648,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;