* 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
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;
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)
#endif
}
-NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page)
+NTSTATUS
+NTAPI
+MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page)
{
ULONG i, offset;
LARGE_INTEGER file_offset;
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;
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;
}
BOOLEAN
+NTAPI
MmReserveSwapPages(ULONG Nr)
{
KIRQL oldIrql;
}
VOID
+NTAPI
MmDereserveSwapPages(ULONG Nr)
{
KIRQL oldIrql;
}
VOID
+NTAPI
MmFreeSwapPage(SWAPENTRY Entry)
{
ULONG i;
i = FILE_FROM_ENTRY(Entry);
off = OFFSET_FROM_ENTRY(Entry);
-
+
if (i >= MAX_PAGING_FILES)
{
DPRINT1("Bad swap entry 0x%.8X\n", Entry);
KEBUGCHECK(0);
}
KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock);
-
+
PagingFileList[i]->AllocMap[off >> 5] &= (~(1 << (off % 32)));
-
+
PagingFileList[i]->FreePages++;
PagingFileList[i]->UsedPages--;
}
BOOLEAN
+NTAPI
MmIsAvailableSwapPage(VOID)
{
return(MiFreeSwapPages > 0);
}
SWAPENTRY
+NTAPI
MmAllocSwapPage(VOID)
{
KIRQL oldIrql;
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)));
for (i = 0; i < MmStats.NrTotalPages; i++)
{
MdlMap[0] = i;
- MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame,
+ MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame,
PAGE_READWRITE,
MdlMap,
1);
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,
FALSE,
&Event,
&Iosb);
- if(Irp == NULL)
+ if(Irp == NULL)
{
ObDereferenceObject(PageFile);
return(STATUS_NO_MEMORY);// tMk - is this correct return code ???
}
/* 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);
}
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;
}
}
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,
NULL,
SL_OPEN_PAGING_FILE | IO_NO_PARAMETER_CHECKING);
- RtlReleaseCapturedUnicodeString(&CapturedFileName,
- PreviousMode,
- FALSE);
+ ReleaseCapturedUnicodeString(&CapturedFileName,
+ PreviousMode);
if (!NT_SUCCESS(Status))
{
return(Status);
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;
}