Revert part of r20493. Created bug 1229 to keep track of the issue.
[reactos.git] / reactos / ntoskrnl / mm / pagefile.c
index ff38500..5cccff8 100644 (file)
@@ -16,8 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id$
- *
+/*
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/mm/pagefile.c
  * PURPOSE:         Paging file functions
 #define NDEBUG
 #include <internal/debug.h>
 
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, MmInitPagingFile)
+#endif
+
+
 /* TYPES *********************************************************************/
 
 typedef struct _PAGINGFILE
@@ -78,7 +82,7 @@ ULONG MiFreeSwapPages;
 ULONG MiUsedSwapPages;
 
 /*
- * Number of pages that have been reserved for swapping but not yet allocated 
+ * Number of pages that have been reserved for swapping but not yet allocated
  */
 static ULONG MiReservedSwapPages;
 
@@ -122,19 +126,20 @@ STDCALL
 MmIsFileAPagingFile(PFILE_OBJECT FileObject)
 {
     ULONG i;
-    
+
     /* Loop through all the paging files */
     for (i = 0; i < MiPagingFileCount; i++)
     {
         /* Check if this is one of them */
         if (PagingFileList[i]->FileObject == FileObject) return TRUE;
     }
-    
+
     /* Nothing found */
     return FALSE;
 }
 
 VOID
+NTAPI
 MmShowOutOfSpaceMessagePagingFile(VOID)
 {
    if (!MmSwapSpaceMessage)
@@ -201,7 +206,9 @@ MmGetOffsetPageFile(PRETRIEVAL_POINTERS_BUFFER RetrievalPointers, LARGE_INTEGER
 #endif
 }
 
-NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page)
+NTSTATUS
+NTAPI
+MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page)
 {
    ULONG i, offset;
    LARGE_INTEGER file_offset;
@@ -251,11 +258,13 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page)
       KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
       Status = Iosb.Status;
    }
-   MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);            
+   MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
    return(Status);
 }
 
-NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page)
+NTSTATUS
+NTAPI
+MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page)
 {
    ULONG i, offset;
    LARGE_INTEGER file_offset;
@@ -305,11 +314,13 @@ NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page)
       KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
       Status = Iosb.Status;
    }
-   MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);            
+   MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
    return(Status);
 }
 
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
 MmInitPagingFile(VOID)
 {
    ULONG i;
@@ -344,6 +355,7 @@ MmInitPagingFile(VOID)
 }
 
 BOOLEAN
+NTAPI
 MmReserveSwapPages(ULONG Nr)
 {
    KIRQL oldIrql;
@@ -363,6 +375,7 @@ MmReserveSwapPages(ULONG Nr)
 }
 
 VOID
+NTAPI
 MmDereserveSwapPages(ULONG Nr)
 {
    KIRQL oldIrql;
@@ -400,6 +413,7 @@ MiAllocPageFromPagingFile(PPAGINGFILE PagingFile)
 }
 
 VOID
+NTAPI
 MmFreeSwapPage(SWAPENTRY Entry)
 {
    ULONG i;
@@ -408,7 +422,7 @@ MmFreeSwapPage(SWAPENTRY Entry)
 
    i = FILE_FROM_ENTRY(Entry);
    off = OFFSET_FROM_ENTRY(Entry);
-   
+
    if (i >= MAX_PAGING_FILES)
    {
        DPRINT1("Bad swap entry 0x%.8X\n", Entry);
@@ -421,9 +435,9 @@ MmFreeSwapPage(SWAPENTRY Entry)
       KEBUGCHECK(0);
    }
    KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock);
-   
+
    PagingFileList[i]->AllocMap[off >> 5] &= (~(1 << (off % 32)));
-   
+
    PagingFileList[i]->FreePages++;
    PagingFileList[i]->UsedPages--;
 
@@ -435,12 +449,14 @@ MmFreeSwapPage(SWAPENTRY Entry)
 }
 
 BOOLEAN
+NTAPI
 MmIsAvailableSwapPage(VOID)
 {
    return(MiFreeSwapPages > 0);
 }
 
 SWAPENTRY
+NTAPI
 MmAllocSwapPage(VOID)
 {
    KIRQL oldIrql;
@@ -532,7 +548,7 @@ MmDumpToPagingFile(ULONG BugCode,
    Headers->Type = MmCoreDumpType;
    if (TrapFrame != NULL)
    {
-      if (!(TrapFrame->Eflags & (1 << 17)))
+      if (!(TrapFrame->EFlags & (1 << 17)))
       {
          memcpy(&Headers->TrapFrame, TrapFrame,
                 sizeof(KTRAP_FRAME) - (4 * sizeof(DWORD)));
@@ -602,7 +618,7 @@ MmDumpToPagingFile(ULONG BugCode,
       for (i = 0; i < MmStats.NrTotalPages; i++)
       {
          MdlMap[0] = i;
-         MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame, 
+         MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame,
                                         PAGE_READWRITE,
                                          MdlMap,
                                         1);
@@ -648,10 +664,10 @@ MmInitializeCrashDump(HANDLE PageFileHandle, ULONG PageFileNum)
    PIRP Irp;
    KEVENT Event;
    IO_STATUS_BLOCK Iosb;
-   UNICODE_STRING DiskDumpName;
+   UNICODE_STRING DiskDumpName = RTL_CONSTANT_STRING(L"DiskDump");
    ANSI_STRING ProcName;
    PIO_STACK_LOCATION StackPtr;
-   PMODULE_OBJECT ModuleObject;
+   PLDR_DATA_TABLE_ENTRY ModuleObject;
 
    Status = ZwFsControlFile(PageFileHandle,
                             0,
@@ -695,7 +711,7 @@ MmInitializeCrashDump(HANDLE PageFileHandle, ULONG PageFileNum)
                                        FALSE,
                                        &Event,
                                        &Iosb);
-   if(Irp == NULL) 
+   if(Irp == NULL)
    {
       ObDereferenceObject(PageFile);
       return(STATUS_NO_MEMORY);// tMk - is this correct return code ???
@@ -724,14 +740,13 @@ MmInitializeCrashDump(HANDLE PageFileHandle, ULONG PageFileNum)
    }
 
    /* Load the diskdump driver. */
-   RtlRosInitUnicodeStringFromLiteral(&DiskDumpName, L"DiskDump");
    ModuleObject = LdrGetModuleObject(&DiskDumpName);
    if (ModuleObject == NULL)
    {
       return(STATUS_OBJECT_NAME_NOT_FOUND);
    }
    RtlInitAnsiString(&ProcName, "DiskDumpFunctions");
-   Status = LdrGetProcedureAddress(ModuleObject->Base,
+   Status = LdrGetProcedureAddress(ModuleObject->DllBase,
                                    &ProcName,
                                    0,
                                    (PVOID*)&MmCoreDumpFunctions);
@@ -792,40 +807,22 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
    }
 
    PreviousMode = ExGetPreviousMode();
-   
-   Status = RtlCaptureUnicodeString(&CapturedFileName,
-                                    PreviousMode,
-                                    PagedPool,
-                                    FALSE,
-                                    FileName);
-   if (!NT_SUCCESS(Status))
-   {
-      return(Status);
-   }
-   if (PreviousMode == UserMode)
+
+   if (PreviousMode != KernelMode)
    {
       _SEH_TRY
       {
-         ProbeForRead(InitialSize,
-                      sizeof(LARGE_INTEGER),
-                      sizeof(ULONG));
-         SafeInitialSize = *InitialSize;
-         ProbeForRead(MaximumSize,
-                      sizeof(LARGE_INTEGER),
-                      sizeof(ULONG));
-         SafeMaximumSize = *MaximumSize;
+         SafeInitialSize = ProbeForReadLargeInteger(InitialSize);
+         SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
       }
       _SEH_HANDLE
       {
          Status = _SEH_GetExceptionCode();
       }
       _SEH_END;
-    
+
       if (!NT_SUCCESS(Status))
       {
-         RtlReleaseCapturedUnicodeString(&CapturedFileName,
-                                         PreviousMode,
-                                         FALSE);
          return Status;
       }
    }
@@ -835,6 +832,29 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
       SafeMaximumSize = *MaximumSize;
    }
 
+   /* Pagefiles can't be larger than 4GB and ofcourse the minimum should be
+      smaller than the maximum */
+   if (0 != SafeInitialSize.u.HighPart)
+   {
+      return STATUS_INVALID_PARAMETER_2;
+   }
+   if (0 != SafeMaximumSize.u.HighPart)
+   {
+      return STATUS_INVALID_PARAMETER_3;
+   }
+   if (SafeMaximumSize.u.LowPart < SafeInitialSize.u.LowPart)
+   {
+      return STATUS_INVALID_PARAMETER_MIX;
+   }
+
+   Status = ProbeAndCaptureUnicodeString(&CapturedFileName,
+                                         PreviousMode,
+                                         FileName);
+   if (!NT_SUCCESS(Status))
+   {
+      return(Status);
+   }
+
    InitializeObjectAttributes(&ObjectAttributes,
                               &CapturedFileName,
                               0,
@@ -856,9 +876,8 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
                          NULL,
                          SL_OPEN_PAGING_FILE | IO_NO_PARAMETER_CHECKING);
 
-   RtlReleaseCapturedUnicodeString(&CapturedFileName,
-                                   PreviousMode,
-                                   FALSE);
+   ReleaseCapturedUnicodeString(&CapturedFileName,
+                                PreviousMode);
    if (!NT_SUCCESS(Status))
    {
       return(Status);
@@ -875,9 +894,17 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
       return Status;
    }
 
-   BytesPerAllocationUnit = FsSizeInformation.SectorsPerAllocationUnit * FsSizeInformation.BytesPerSector;
+   BytesPerAllocationUnit = FsSizeInformation.SectorsPerAllocationUnit *
+                            FsSizeInformation.BytesPerSector;
+   /* FIXME: If we have 2048 BytesPerAllocationUnit (FAT16 < 128MB) there is
+    * a problem if the paging file is fragmented. Suppose the first cluster
+    * of the paging file is cluster 3042 but cluster 3043 is NOT part of the
+    * paging file but of another file. We can't write a complete page (4096
+    * bytes) to the physical location of cluster 3042 then. */
    if (BytesPerAllocationUnit % PAGE_SIZE)
    {
+      DPRINT1("BytesPerAllocationUnit %d is not a multiple of PAGE_SIZE %d\n",
+              BytesPerAllocationUnit, PAGE_SIZE);
       ZwClose(FileHandle);
       return STATUS_UNSUCCESSFUL;
    }