ReactOS 0.4.16-dev-87-g3dfbe52
pagefile.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for pagefile.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MINIMUM_PAGEFILE_SIZE   (256ULL * PAGE_SIZE)
 
#define MM_PAGEFILE_COMMIT_RATIO   (1)
 
#define MM_PAGEFILE_COMMIT_GRACE   (256)
 
#define FILE_FROM_ENTRY(i)   ((i) & 0x0f)
 
#define OFFSET_FROM_ENTRY(i)   ((i) >> 11)
 
#define ENTRY_FROM_FILE_OFFSET(i, j)   ((i) | ((j) << 11) | 0x400)
 

Functions

 C_ASSERT (FILE_FROM_ENTRY(0xffffffff)< MAX_PAGING_FILES)
 
VOID NTAPI MmBuildMdlFromPages (PMDL Mdl, PPFN_NUMBER Pages)
 
BOOLEAN NTAPI MmIsFileObjectAPagingFile (PFILE_OBJECT FileObject)
 
VOID NTAPI MmShowOutOfSpaceMessagePagingFile (VOID)
 
NTSTATUS NTAPI MmWriteToSwapPage (SWAPENTRY SwapEntry, PFN_NUMBER Page)
 
NTSTATUS NTAPI MmReadFromSwapPage (SWAPENTRY SwapEntry, PFN_NUMBER Page)
 
NTSTATUS NTAPI MiReadPageFile (_In_ PFN_NUMBER Page, _In_ ULONG PageFileIndex, _In_ ULONG_PTR PageFileOffset)
 
VOID NTAPI MmInitPagingFile (VOID)
 
VOID NTAPI MmFreeSwapPage (SWAPENTRY Entry)
 
SWAPENTRY NTAPI MmAllocSwapPage (VOID)
 
NTSTATUS NTAPI NtCreatePagingFile (_In_ PUNICODE_STRING FileName, _In_ PLARGE_INTEGER MinimumSize, _In_ PLARGE_INTEGER MaximumSize, _In_ ULONG Reserved)
 

Variables

PMMPAGING_FILE MmPagingFile [MAX_PAGING_FILES]
 
KGUARDED_MUTEX MmPageFileCreationLock
 
ULONG MmNumberOfPagingFiles
 
PFN_COUNT MiFreeSwapPages
 
PFN_COUNT MiUsedSwapPages
 
BOOLEAN MmZeroPageFile
 
static PFN_COUNT MiReservedSwapPages
 
static BOOLEAN MmSwapSpaceMessage = FALSE
 
static BOOLEAN MmSystemPageFileLocated = FALSE
 

Macro Definition Documentation

◆ ENTRY_FROM_FILE_OFFSET

#define ENTRY_FROM_FILE_OFFSET (   i,
  j 
)    ((i) | ((j) << 11) | 0x400)

Definition at line 98 of file pagefile.c.

◆ FILE_FROM_ENTRY

#define FILE_FROM_ENTRY (   i)    ((i) & 0x0f)

Definition at line 96 of file pagefile.c.

◆ MINIMUM_PAGEFILE_SIZE

#define MINIMUM_PAGEFILE_SIZE   (256ULL * PAGE_SIZE)

Definition at line 18 of file pagefile.c.

◆ MM_PAGEFILE_COMMIT_GRACE

#define MM_PAGEFILE_COMMIT_GRACE   (256)

Definition at line 91 of file pagefile.c.

◆ MM_PAGEFILE_COMMIT_RATIO

#define MM_PAGEFILE_COMMIT_RATIO   (1)

Definition at line 83 of file pagefile.c.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file pagefile.c.

◆ OFFSET_FROM_ENTRY

#define OFFSET_FROM_ENTRY (   i)    ((i) >> 11)

Definition at line 97 of file pagefile.c.

Function Documentation

◆ C_ASSERT()

C_ASSERT ( )

◆ MiReadPageFile()

NTSTATUS NTAPI MiReadPageFile ( _In_ PFN_NUMBER  Page,
_In_ ULONG  PageFileIndex,
_In_ ULONG_PTR  PageFileOffset 
)

Definition at line 211 of file pagefile.c.

215{
216 LARGE_INTEGER file_offset;
220 UCHAR MdlBase[sizeof(MDL) + sizeof(PFN_NUMBER)];
221 PMDL Mdl = (PMDL)MdlBase;
222 PMMPAGING_FILE PagingFile;
223
224 DPRINT("MiReadSwapFile\n");
225
226 if (PageFileOffset == 0)
227 {
228 KeBugCheck(MEMORY_MANAGEMENT);
229 return(STATUS_UNSUCCESSFUL);
230 }
231
232 /* Normalize offset. */
233 PageFileOffset--;
234
235 ASSERT(PageFileIndex < MAX_PAGING_FILES);
236
237 PagingFile = MmPagingFile[PageFileIndex];
238
239 if (PagingFile->FileObject == NULL || PagingFile->FileObject->DeviceObject == NULL)
240 {
241 DPRINT1("Bad paging file %u\n", PageFileIndex);
242 KeBugCheck(MEMORY_MANAGEMENT);
243 }
244
248
249 file_offset.QuadPart = PageFileOffset * PAGE_SIZE;
250
252 Status = IoPageRead(PagingFile->FileObject,
253 Mdl,
254 &file_offset,
255 &Event,
256 &Iosb);
257 if (Status == STATUS_PENDING)
258 {
260 Status = Iosb.Status;
261 }
262 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
263 {
264 MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
265 }
266 return(Status);
267}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define MAX_PAGING_FILES
Definition: pagefile.c:23
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1430
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
return Iosb
Definition: create.c:4402
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Status
Definition: gdiplustypes.h:25
NTSTATUS NTAPI IoPageRead(IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
Definition: iofunc.c:1201
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:837
#define ASSERT(a)
Definition: mode.c:44
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
PMMPAGING_FILE MmPagingFile[MAX_PAGING_FILES]
Definition: pagefile.c:57
VOID NTAPI MmBuildMdlFromPages(PMDL Mdl, PPFN_NUMBER Pages)
Definition: pagefile.c:111
#define STATUS_PENDING
Definition: ntstatus.h:82
ULONG PFN_NUMBER
Definition: ke.h:9
#define DPRINT
Definition: sndvol32.h:73
PFILE_OBJECT FileObject
Definition: mm.h:506
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
LONGLONG QuadPart
Definition: typedefs.h:114
PVOID PMDL
Definition: usb.h:39
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
@ Executive
Definition: ketypes.h:415
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
MDL
Definition: mmtypes.h:117
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define MDL_IO_PAGE_READ
Definition: mmtypes.h:24
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by MiResolvePageFileFault(), and MmReadFromSwapPage().

◆ MmAllocSwapPage()

SWAPENTRY NTAPI MmAllocSwapPage ( VOID  )

Definition at line 322 of file pagefile.c.

323{
324 ULONG i;
325 ULONG off;
327
329
330 if (MiFreeSwapPages == 0)
331 {
333 return(0);
334 }
335
336 for (i = 0; i < MAX_PAGING_FILES; i++)
337 {
338 if (MmPagingFile[i] != NULL &&
339 MmPagingFile[i]->FreeSpace >= 1)
340 {
342 if (off == 0xFFFFFFFF)
343 {
344 KeBugCheck(MEMORY_MANAGEMENT);
346 return(STATUS_UNSUCCESSFUL);
347 }
351
353
354 entry = ENTRY_FROM_FILE_OFFSET(i, off + 1);
355 return(entry);
356 }
357 }
358
360 KeBugCheck(MEMORY_MANAGEMENT);
361 return(0);
362}
#define RtlFindClearBitsAndSet
Definition: dbgbitmap.h:333
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
uint32_t entry
Definition: isohybrid.c:63
FORCEINLINE VOID UpdateTotalCommittedPages(LONG Delta)
Definition: mm.h:871
ULONG_PTR SWAPENTRY
Definition: mm.h:57
KGUARDED_MUTEX MmPageFileCreationLock
Definition: pagefile.c:60
PFN_COUNT MiFreeSwapPages
Definition: pagefile.c:66
#define ENTRY_FROM_FILE_OFFSET(i, j)
Definition: pagefile.c:98
PFN_COUNT MiUsedSwapPages
Definition: pagefile.c:69
uint32_t ULONG
Definition: typedefs.h:59

Referenced by MmPageOutPhysicalAddress().

◆ MmBuildMdlFromPages()

VOID NTAPI MmBuildMdlFromPages ( PMDL  Mdl,
PPFN_NUMBER  Pages 
)

Definition at line 111 of file pagefile.c.

112{
113 memcpy(Mdl + 1, Pages, sizeof(PFN_NUMBER) * (PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGE_SIZE));
114}
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38

Referenced by MiReadFilePage(), MiReadPageFile(), MiWritePage(), and MmWriteToSwapPage().

◆ MmFreeSwapPage()

VOID NTAPI MmFreeSwapPage ( SWAPENTRY  Entry)

Definition at line 291 of file pagefile.c.

292{
293 ULONG i;
294 ULONG_PTR off;
295 PMMPAGING_FILE PagingFile;
296
298 off = OFFSET_FROM_ENTRY(Entry) - 1;
299
301
302 PagingFile = MmPagingFile[i];
303 if (PagingFile == NULL)
304 {
305 KeBugCheck(MEMORY_MANAGEMENT);
306 }
307
308 RtlClearBit(PagingFile->Bitmap, off >> 5);
309
310 PagingFile->FreeSpace++;
311 PagingFile->CurrentUsage--;
312
316
318}
#define RtlClearBit
Definition: dbgbitmap.h:330
#define FILE_FROM_ENTRY(i)
Definition: pagefile.c:96
#define OFFSET_FROM_ENTRY(i)
Definition: pagefile.c:97
base of all file and directory entries
Definition: entries.h:83
PRTL_BITMAP Bitmap
Definition: mm.h:508
PFN_NUMBER CurrentUsage
Definition: mm.h:505
PFN_NUMBER FreeSpace
Definition: mm.h:504
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by MiFreeSegmentPage(), MmFreeCacheSectionPage(), MmFreeSectionPage(), MmPageOutPhysicalAddress(), MmpFreePageFileSegment(), and MmUnsharePageEntrySectionSegment().

◆ MmInitPagingFile()

VOID NTAPI MmInitPagingFile ( VOID  )

Definition at line 272 of file pagefile.c.

273{
274 ULONG i;
275
277
278 MiFreeSwapPages = 0;
279 MiUsedSwapPages = 0;
281
282 for (i = 0; i < MAX_PAGING_FILES; i++)
283 {
285 }
287}
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
ULONG MmNumberOfPagingFiles
Definition: pagefile.c:63
static PFN_COUNT MiReservedSwapPages
Definition: pagefile.c:76

Referenced by MmInitSystem().

◆ MmIsFileObjectAPagingFile()

BOOLEAN NTAPI MmIsFileObjectAPagingFile ( PFILE_OBJECT  FileObject)

Definition at line 119 of file pagefile.c.

120{
121 ULONG i;
122
123 /* Loop through all the paging files */
124 for (i = 0; i < MmNumberOfPagingFiles; i++)
125 {
126 /* Check if this is one of them */
127 if (MmPagingFile[i]->FileObject == FileObject) return TRUE;
128 }
129
130 /* Nothing found */
131 return FALSE;
132}
#define TRUE
Definition: types.h:120
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550

Referenced by FsRtlIsPagingFile(), and IoPageRead().

◆ MmReadFromSwapPage()

NTSTATUS NTAPI MmReadFromSwapPage ( SWAPENTRY  SwapEntry,
PFN_NUMBER  Page 
)

Definition at line 204 of file pagefile.c.

205{
206 return MiReadPageFile(Page, FILE_FROM_ENTRY(SwapEntry), OFFSET_FROM_ENTRY(SwapEntry));
207}
NTSTATUS NTAPI MiReadPageFile(_In_ PFN_NUMBER Page, _In_ ULONG PageFileIndex, _In_ ULONG_PTR PageFileOffset)
Definition: pagefile.c:211

Referenced by MiSwapInPage(), and MmNotPresentFaultSectionView().

◆ MmShowOutOfSpaceMessagePagingFile()

VOID NTAPI MmShowOutOfSpaceMessagePagingFile ( VOID  )

Definition at line 136 of file pagefile.c.

137{
139 {
140 DPRINT1("MM: Out of swap space.\n");
142 }
143}
static BOOLEAN MmSwapSpaceMessage
Definition: pagefile.c:103

◆ MmWriteToSwapPage()

NTSTATUS NTAPI MmWriteToSwapPage ( SWAPENTRY  SwapEntry,
PFN_NUMBER  Page 
)

Definition at line 147 of file pagefile.c.

148{
149 ULONG i;
151 LARGE_INTEGER file_offset;
155 UCHAR MdlBase[sizeof(MDL) + sizeof(PFN_NUMBER)];
156 PMDL Mdl = (PMDL)MdlBase;
157
158 DPRINT("MmWriteToSwapPage\n");
159
160 if (SwapEntry == 0)
161 {
162 KeBugCheck(MEMORY_MANAGEMENT);
163 return(STATUS_UNSUCCESSFUL);
164 }
165
166 i = FILE_FROM_ENTRY(SwapEntry);
167 offset = OFFSET_FROM_ENTRY(SwapEntry) - 1;
168
169 if (MmPagingFile[i]->FileObject == NULL ||
170 MmPagingFile[i]->FileObject->DeviceObject == NULL)
171 {
172 DPRINT1("Bad paging file 0x%.8X\n", SwapEntry);
173 KeBugCheck(MEMORY_MANAGEMENT);
174 }
175
178 Mdl->MdlFlags |= MDL_PAGES_LOCKED;
179
180 file_offset.QuadPart = offset * PAGE_SIZE;
181
184 Mdl,
185 &file_offset,
186 &Event,
187 &Iosb);
188 if (Status == STATUS_PENDING)
189 {
191 Status = Iosb.Status;
192 }
193
194 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
195 {
196 MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
197 }
198 return(Status);
199}
GLintptr offset
Definition: glext.h:5920
NTSTATUS NTAPI IoSynchronousPageWrite(IN PFILE_OBJECT FileObject, IN PMDL Mdl, IN PLARGE_INTEGER Offset, IN PKEVENT Event, IN PIO_STATUS_BLOCK StatusBlock)
Definition: iofunc.c:1146

Referenced by MmPageOutPhysicalAddress().

◆ NtCreatePagingFile()

NTSTATUS NTAPI NtCreatePagingFile ( _In_ PUNICODE_STRING  FileName,
_In_ PLARGE_INTEGER  MinimumSize,
_In_ PLARGE_INTEGER  MaximumSize,
_In_ ULONG  Reserved 
)

Definition at line 366 of file pagefile.c.

371{
377 PMMPAGING_FILE PagingFile;
378 SIZE_T AllocMapSize;
379 ULONG Count;
381 UNICODE_STRING PageFileName;
382 LARGE_INTEGER SafeMinimumSize, SafeMaximumSize, AllocationSize;
383 FILE_FS_DEVICE_INFORMATION FsDeviceInfo;
385 PACL Dacl;
388
389 PAGED_CODE();
390
391 DPRINT("NtCreatePagingFile(FileName: '%wZ', MinimumSize: %I64d, MaximumSize: %I64d)\n",
392 FileName, MinimumSize->QuadPart, MaximumSize->QuadPart);
393
395 {
397 }
398
400
402 {
404 {
406 }
407
409 {
410 SafeMinimumSize = ProbeForReadLargeInteger(MinimumSize);
411 SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
412 PageFileName = ProbeForReadUnicodeString(FileName);
413 }
415 {
416 /* Return the exception code */
418 }
419 _SEH2_END;
420 }
421 else
422 {
423 SafeMinimumSize = *MinimumSize;
424 SafeMaximumSize = *MaximumSize;
425 PageFileName = *FileName;
426 }
427
428 /*
429 * Pagefiles cannot be larger than the platform-specific memory addressable
430 * limits, and of course the minimum should be smaller than the maximum.
431 */
432 if (SafeMinimumSize.QuadPart < MINIMUM_PAGEFILE_SIZE ||
433 SafeMinimumSize.QuadPart > MAXIMUM_PAGEFILE_SIZE)
434 {
436 }
437 if (SafeMaximumSize.QuadPart < SafeMinimumSize.QuadPart ||
438 SafeMaximumSize.QuadPart > MAXIMUM_PAGEFILE_SIZE)
439 {
441 }
442
443 /* Validate the name length */
444 if ((PageFileName.Length == 0) ||
445 (PageFileName.Length > MAXIMUM_FILENAME_LENGTH))
446 {
448 }
449
450 /* Allocate a buffer to keep the name copy. Note that it is kept only
451 * for information purposes, so it gets allocated in the paged pool,
452 * even if it will be stored in the PagingFile structure, that is
453 * allocated from non-paged pool (see below). */
454 PageFileName.MaximumLength = PageFileName.Length;
456 if (Buffer == NULL)
457 {
459 }
460
461 /* Copy the name */
463 {
465 {
466 ProbeForRead(PageFileName.Buffer, PageFileName.Length, sizeof(WCHAR));
467 RtlCopyMemory(Buffer, PageFileName.Buffer, PageFileName.Length);
468 }
470 {
472
473 /* Return the exception code */
475 }
476 _SEH2_END;
477 }
478 else
479 {
480 RtlCopyMemory(Buffer, PageFileName.Buffer, PageFileName.Length);
481 }
482
483 /* Replace caller's buffer with ours */
484 PageFileName.Buffer = Buffer;
485
486 /* Create the security descriptor for the page file */
488 if (!NT_SUCCESS(Status))
489 {
491 return Status;
492 }
493
494 /* Create the DACL: we will only allow two SIDs */
495 Count = sizeof(ACL) + (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
496 (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid));
498 if (Dacl == NULL)
499 {
502 }
503
504 /* Initialize the DACL */
506 if (!NT_SUCCESS(Status))
507 goto EarlyQuit;
508
509 /* Grant full access to admins */
511 if (!NT_SUCCESS(Status))
512 goto EarlyQuit;
513
514 /* Grant full access to SYSTEM */
516 if (!NT_SUCCESS(Status))
517 goto EarlyQuit;
518
519 /* Attach the DACL to the security descriptor */
521 if (!NT_SUCCESS(Status))
522 goto EarlyQuit;
523
525 &PageFileName,
527 NULL,
529
530 /* Make sure we can at least store a complete page:
531 * If we have 2048 BytesPerAllocationUnit (FAT16 < 128MB) there is
532 * a problem if the paging file is fragmented. Suppose the first cluster
533 * of the paging file is cluster 3042 but cluster 3043 is NOT part of the
534 * paging file but of another file. We can't write a complete page (4096
535 * bytes) to the physical location of cluster 3042 then. */
536 AllocationSize.QuadPart = SafeMinimumSize.QuadPart + PAGE_SIZE;
537
538 /* First, attempt to replace the page file, if existing */
542 &IoStatus,
548 NULL,
549 0,
551 NULL,
553 /* If we failed, relax a bit constraints, someone may be already holding the
554 * the file, so share write, don't attempt to replace and don't delete on close
555 * (basically, don't do anything conflicting).
556 * This can happen if the caller attempts to extend a page file.
557 */
558 if (!NT_SUCCESS(Status))
559 {
560 ULONG i;
561
565 &IoStatus,
569 FILE_OPEN,
571 NULL,
572 0,
574 NULL,
576 if (!NT_SUCCESS(Status))
577 goto EarlyQuit;
578
579 /* We opened it! Check we are that "someone" ;-)
580 * First, get the opened file object.
581 */
586 (PVOID*)&FileObject,
587 NULL);
588 if (!NT_SUCCESS(Status))
589 {
591 goto EarlyQuit;
592 }
593
594 /* Find if it matches a previous page file */
595 PagingFile = NULL;
596
598
599 for (i = 0; i < MmNumberOfPagingFiles; ++i)
600 {
601 if (MmPagingFile[i]->FileObject->SectionObjectPointer == FileObject->SectionObjectPointer)
602 {
603 /* Same object pointer: this is the matching page file */
604 PagingFile = MmPagingFile[i];
605 break;
606 }
607 }
608
609 /* If we didn't find the page file, fail */
610 if (PagingFile == NULL)
611 {
616 goto EarlyQuit;
617 }
618
619 /* Don't allow page file shrinking */
620 if (PagingFile->MinimumSize > (SafeMinimumSize.QuadPart >> PAGE_SHIFT))
621 {
626 goto EarlyQuit;
627 }
628
629 if ((SafeMaximumSize.QuadPart >> PAGE_SHIFT) < PagingFile->MaximumSize)
630 {
635 goto EarlyQuit;
636 }
637
638 /* FIXME: implement parameters checking and page file extension */
640
645 goto EarlyQuit;
646 }
647
648 if (!NT_SUCCESS(Status))
649 {
650EarlyQuit:
651 DPRINT1("Failed creating page file: %lx\n", Status);
654 return Status;
655 }
656
657 /* Set the security descriptor */
658 if (NT_SUCCESS(IoStatus.Status))
659 {
661 if (!NT_SUCCESS(Status))
662 {
666 return Status;
667 }
668 }
669
670 /* DACL is no longer needed, free it */
672
673 /* FIXME: To enable once page file management is moved to ARM3 */
674#if 0
675 /* Check we won't overflow commit limit with the page file */
677 {
681 }
682#endif
683
684 /* Set its end of file to minimal size */
685 Status = ZwSetInformationFile(FileHandle,
686 &IoStatus,
687 &SafeMinimumSize,
688 sizeof(LARGE_INTEGER),
690 if (!NT_SUCCESS(Status) || !NT_SUCCESS(IoStatus.Status))
691 {
694 return Status;
695 }
696
701 (PVOID*)&FileObject,
702 NULL);
703 if (!NT_SUCCESS(Status))
704 {
707 return Status;
708 }
709
710 /* Only allow page file on a few device types */
716 {
720 return Status;
721 }
722
723 /* Deny page file creation on a floppy disk */
724 FsDeviceInfo.Characteristics = 0;
726 sizeof(FsDeviceInfo), &FsDeviceInfo, &Count);
728 {
733 }
734
735 /*
736 * Missing validation steps TODO:
737 * (see https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/mm/modwrite/create.htm )
738 *
739 * - Verify that no file system driver or any filter driver has done file
740 * I/O while opening the file.
741 * Verify that nothing of the paging file is yet in memory. Specifically,
742 * the file object must either have no SectionObjectPointer or the latter
743 * must have neither a DataSectionObject nor an ImageSectionObject.
744 * Otherwise, we should fail, returning STATUS_INCOMPATIBLE_FILE_MAP.
745 *
746 * - Inform all the applicable drivers to prepare for the possibility of
747 * paging I/O. Much of the point to paging I/O is to resolve page faults.
748 * Especially important is that drivers that handle paging I/O do not
749 * cause more page faults. All the code and data that each driver might
750 * ever use for access to the paging file must be locked into physical
751 * memory. This can’t be left until paging I/O actually occurs.
752 * It must be done in advance.
753 */
754
755 PagingFile = ExAllocatePoolZero(NonPagedPool, sizeof(*PagingFile), TAG_MM);
756 if (PagingFile == NULL)
757 {
762 }
763
764 PagingFile->FileHandle = FileHandle;
765 PagingFile->FileObject = FileObject;
766 PagingFile->Size = (SafeMinimumSize.QuadPart >> PAGE_SHIFT);
767 PagingFile->MinimumSize = PagingFile->Size;
768 PagingFile->MaximumSize = (SafeMaximumSize.QuadPart >> PAGE_SHIFT);
769 /* First page is never used: it's the header
770 * TODO: write it
771 */
772 PagingFile->FreeSpace = PagingFile->Size - 1;
773 PagingFile->CurrentUsage = 0;
774 PagingFile->PageFileName = PageFileName;
775 ASSERT(PagingFile->Size == PagingFile->FreeSpace + PagingFile->CurrentUsage + 1);
776
777 AllocMapSize = sizeof(RTL_BITMAP) + (((PagingFile->MaximumSize + 31) / 32) * sizeof(ULONG));
779 AllocMapSize,
780 TAG_MM);
781 if (PagingFile->Bitmap == NULL)
782 {
783 ExFreePoolWithTag(PagingFile, TAG_MM);
788 }
789
790 RtlInitializeBitMap(PagingFile->Bitmap,
791 (PULONG)(PagingFile->Bitmap + 1),
792 (ULONG)(PagingFile->MaximumSize));
793 RtlClearAllBits(PagingFile->Bitmap);
794
795 /* Insert the new paging file information into the list */
797 /* Ensure the corresponding slot is empty yet */
803
805
807 {
809 }
810
811 return STATUS_SUCCESS;
812}
SIZE_T MmTotalCommitLimitMaximum
Definition: mminit.c:360
#define PAGED_CODE()
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
#define MAXIMUM_PAGEFILE_SIZE
Definition: pagefile.c:76
#define UNIMPLEMENTED
Definition: debug.h:118
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define RtlInitializeBitMap
Definition: dbgbitmap.h:326
#define RtlClearAllBits
Definition: dbgbitmap.h:329
#define RTL_BITMAP
Definition: dbgbitmap.h:323
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define DEVICE_TYPE
Definition: guid.c:10
#define FILE_SHARE_READ
Definition: compat.h:136
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define MAXIMUM_FILENAME_LENGTH
Definition: env_spec_w32.h:41
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define DO_SYSTEM_BOOT_PARTITION
Definition: env_spec_w32.h:400
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
#define ExGetPreviousMode
Definition: ex.h:140
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:323
struct _FileName FileName
Definition: fatprocs.h:897
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
@ FileEndOfFileInformation
Definition: from_kernel.h:81
#define FILE_NO_COMPRESSION
Definition: from_kernel.h:43
#define FILE_OPEN
Definition: from_kernel.h:54
@ FileFsDeviceInformation
Definition: from_kernel.h:222
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
NTSTATUS NTAPI IoQueryVolumeInformation(IN PFILE_OBJECT FileObject, IN FS_INFORMATION_CLASS FsInformationClass, IN ULONG Length, OUT PVOID FsInformation, OUT PULONG ReturnedLength)
Definition: iofunc.c:1294
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
DeviceType
Definition: mmdrv.h:42
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
FORCEINLINE PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
struct _ACL ACL
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:362
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1605
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
int Count
Definition: noreturn.cpp:7
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define WRITE_DAC
Definition: nt_native.h:59
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
BOOLEAN NTAPI IoInitializeCrashDump(IN HANDLE PageFileHandle)
Definition: iomgr.c:649
PSID SeLocalSystemSid
Definition: sid.c:38
PSID SeAliasAdminsSid
Definition: sid.c:41
const LUID SeCreatePagefilePrivilege
Definition: priv.c:34
PDEVICE_OBJECT NTAPI IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
Definition: device.c:1539
NTSTATUS NTAPI IoCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options)
Definition: file.c:3010
static BOOLEAN MmSystemPageFileLocated
Definition: pagefile.c:105
#define MINIMUM_PAGEFILE_SIZE
Definition: pagefile.c:18
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
#define STATUS_FLOPPY_VOLUME
Definition: ntstatus.h:592
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:477
#define STATUS_TOO_MANY_PAGING_FILES
Definition: ntstatus.h:387
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define FILE_DEVICE_DISK_FILE_SYSTEM
Definition: winioctl.h:53
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:65
#define FILE_DEVICE_DFS_FILE_SYSTEM
Definition: winioctl.h:98
#define FILE_DEVICE_DFS_VOLUME
Definition: winioctl.h:99
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define ProbeForReadUnicodeString(Ptr)
Definition: probe.h:77
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
Definition: rtltypes.h:993
PFN_NUMBER MinimumSize
Definition: mm.h:503
UNICODE_STRING PageFileName
Definition: mm.h:507
PFN_NUMBER Size
Definition: mm.h:501
PFN_NUMBER MaximumSize
Definition: mm.h:502
HANDLE FileHandle
Definition: mm.h:509
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TAG_DACL
Definition: tag.h:167
#define TAG_MM
Definition: tag.h:113
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:541
* PFILE_OBJECT
Definition: iotypes.h:1998
@ CreateFileTypeNone
Definition: iotypes.h:535
#define IO_OPEN_PAGING_FILE
Definition: iotypes.h:7351
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define ACL_REVISION
Definition: setypes.h:39
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by SmpCreatePagingFile().

Variable Documentation

◆ MiFreeSwapPages

PFN_COUNT MiFreeSwapPages

◆ MiReservedSwapPages

PFN_COUNT MiReservedSwapPages
static

Definition at line 76 of file pagefile.c.

Referenced by MmInitPagingFile().

◆ MiUsedSwapPages

PFN_COUNT MiUsedSwapPages

Definition at line 69 of file pagefile.c.

Referenced by MmAllocSwapPage(), MmFreeSwapPage(), MmInitPagingFile(), and QSI_DEF().

◆ MmNumberOfPagingFiles

ULONG MmNumberOfPagingFiles

◆ MmPageFileCreationLock

KGUARDED_MUTEX MmPageFileCreationLock

Definition at line 60 of file pagefile.c.

Referenced by MmAllocSwapPage(), MmFreeSwapPage(), MmInitPagingFile(), and NtCreatePagingFile().

◆ MmPagingFile

◆ MmSwapSpaceMessage

BOOLEAN MmSwapSpaceMessage = FALSE
static

Definition at line 103 of file pagefile.c.

Referenced by MmShowOutOfSpaceMessagePagingFile(), and NtCreatePagingFile().

◆ MmSystemPageFileLocated

BOOLEAN MmSystemPageFileLocated = FALSE
static

Definition at line 105 of file pagefile.c.

Referenced by NtCreatePagingFile().

◆ MmZeroPageFile

BOOLEAN MmZeroPageFile

Definition at line 71 of file pagefile.c.