ReactOS  r75400
pagefile.c
Go to the documentation of this file.
1 /*
2  * ReactOS kernel
3  * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 /*
20  * PROJECT: ReactOS kernel
21  * FILE: ntoskrnl/mm/pagefile.c
22  * PURPOSE: Paging file functions
23  * PROGRAMMER: David Welch (welch@mcmail.com)
24  * UPDATE HISTORY:
25  * Created 22/05/98
26  */
27 
28 /* INCLUDES *****************************************************************/
29 
30 #include <ntoskrnl.h>
31 #define NDEBUG
32 #include <debug.h>
33 
34 #if defined (ALLOC_PRAGMA)
35 #pragma alloc_text(INIT, MmInitPagingFile)
36 #endif
37 
38 PVOID
39 NTAPI
41  IN PANSI_STRING ExportName);
42 
43 /* TYPES *********************************************************************/
44 
45 typedef struct _PAGINGFILE
46 {
57 }
59 
61 {
64 }
66 
67 /* GLOBALS *******************************************************************/
68 
69 #define PAIRS_PER_RUN (1024)
70 
71 #define MAX_PAGING_FILES (16)
72 
73 /* List of paging files, both used and free */
74 static PPAGINGFILE PagingFileList[MAX_PAGING_FILES];
75 
76 /* Lock for examining the list of paging files */
78 
79 /* Number of paging files */
81 
82 /* Number of pages that are available for swapping */
84 
85 /* Number of pages that have been allocated for swapping */
87 
89 
90 /*
91  * Number of pages that have been reserved for swapping but not yet allocated
92  */
94 
95 /*
96  * Ratio between reserved and available swap pages, e.g. setting this to five
97  * forces one swap page to be available for every five swap pages that are
98  * reserved. Setting this to zero turns off commit checking altogether.
99  */
100 #define MM_PAGEFILE_COMMIT_RATIO (1)
101 
102 /*
103  * Number of pages that can be used for potentially swapable memory without
104  * pagefile space being reserved. The intention is that this allows smss
105  * to start up and create page files while ordinarily having a commit
106  * ratio of one.
107  */
108 #define MM_PAGEFILE_COMMIT_GRACE (256)
109 
110 /*
111  * Translate between a swap entry and a file and offset pair.
112  */
113 #define FILE_FROM_ENTRY(i) ((i) & 0x0f)
114 #define OFFSET_FROM_ENTRY(i) ((i) >> 11)
115 #define ENTRY_FROM_FILE_OFFSET(i, j) ((i) | ((j) << 11) | 0x400)
116 
117 /* Make sure there can be only 16 paging files */
119 
121 
122 /* FUNCTIONS *****************************************************************/
123 
124 VOID
125 NTAPI
127 {
128  memcpy(Mdl + 1, Pages, sizeof(PFN_NUMBER) * (PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGE_SIZE));
129 
130  /* FIXME: this flag should be set by the caller perhaps? */
131  Mdl->MdlFlags |= MDL_IO_PAGE_READ;
132 }
133 
134 
135 BOOLEAN
136 NTAPI
138 {
139  ULONG i;
140 
141  /* Loop through all the paging files */
142  for (i = 0; i < MmNumberOfPagingFiles; i++)
143  {
144  /* Check if this is one of them */
145  if (PagingFileList[i]->FileObject == FileObject) return TRUE;
146  }
147 
148  /* Nothing found */
149  return FALSE;
150 }
151 
152 VOID
153 NTAPI
155 {
156  if (!MmSwapSpaceMessage)
157  {
158  DPRINT1("MM: Out of swap space.\n");
159  MmSwapSpaceMessage = TRUE;
160  }
161 }
162 
163 static LARGE_INTEGER
165 {
166  /* Simple binary search */
167  ULONG first, last, mid;
168  first = 0;
169  last = RetrievalPointers->ExtentCount - 1;
170  while (first <= last)
171  {
172  mid = (last - first) / 2 + first;
173  if (Offset.QuadPart < RetrievalPointers->Extents[mid].NextVcn.QuadPart)
174  {
175  if (mid == 0)
176  {
177  Offset.QuadPart += RetrievalPointers->Extents[0].Lcn.QuadPart - RetrievalPointers->StartingVcn.QuadPart;
178  return Offset;
179  }
180  else
181  {
182  if (Offset.QuadPart >= RetrievalPointers->Extents[mid-1].NextVcn.QuadPart)
183  {
184  Offset.QuadPart += RetrievalPointers->Extents[mid].Lcn.QuadPart - RetrievalPointers->Extents[mid-1].NextVcn.QuadPart;
185  return Offset;
186  }
187  last = mid - 1;
188  }
189  }
190  else
191  {
192  if (mid == RetrievalPointers->ExtentCount - 1)
193  {
194  break;
195  }
196  if (Offset.QuadPart < RetrievalPointers->Extents[mid+1].NextVcn.QuadPart)
197  {
198  Offset.QuadPart += RetrievalPointers->Extents[mid+1].Lcn.QuadPart - RetrievalPointers->Extents[mid].NextVcn.QuadPart;
199  return Offset;
200  }
201  first = mid + 1;
202  }
203  }
204  KeBugCheck(MEMORY_MANAGEMENT);
205 #if defined(__GNUC__)
206 
207  return (LARGE_INTEGER)0LL;
208 #else
209 
210  {
211  const LARGE_INTEGER dummy =
212  {
213  0
214  };
215  return dummy;
216  }
217 #endif
218 }
219 
220 NTSTATUS
221 NTAPI
223 {
224  ULONG i;
226  LARGE_INTEGER file_offset;
229  KEVENT Event;
230  UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
231  PMDL Mdl = (PMDL)MdlBase;
232 
233  DPRINT("MmWriteToSwapPage\n");
234 
235  if (SwapEntry == 0)
236  {
237  KeBugCheck(MEMORY_MANAGEMENT);
238  return(STATUS_UNSUCCESSFUL);
239  }
240 
241  i = FILE_FROM_ENTRY(SwapEntry);
242  offset = OFFSET_FROM_ENTRY(SwapEntry) - 1;
243 
244  if (PagingFileList[i]->FileObject == NULL ||
245  PagingFileList[i]->FileObject->DeviceObject == NULL)
246  {
247  DPRINT1("Bad paging file 0x%.8X\n", SwapEntry);
248  KeBugCheck(MEMORY_MANAGEMENT);
249  }
250 
252  MmBuildMdlFromPages(Mdl, &Page);
253  Mdl->MdlFlags |= MDL_PAGES_LOCKED;
254 
255  file_offset.QuadPart = offset * PAGE_SIZE;
256  file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
257 
259  Status = IoSynchronousPageWrite(PagingFileList[i]->FileObject,
260  Mdl,
261  &file_offset,
262  &Event,
263  &Iosb);
264  if (Status == STATUS_PENDING)
265  {
267  Status = Iosb.Status;
268  }
269 
270  if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
271  {
272  MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
273  }
274  return(Status);
275 }
276 
277 
278 NTSTATUS
279 NTAPI
281 {
282  return MiReadPageFile(Page, FILE_FROM_ENTRY(SwapEntry), OFFSET_FROM_ENTRY(SwapEntry) - 1);
283 }
284 
285 NTSTATUS
286 NTAPI
288  _In_ PFN_NUMBER Page,
289  _In_ ULONG PageFileIndex,
290  _In_ ULONG_PTR PageFileOffset)
291 {
292  LARGE_INTEGER file_offset;
295  KEVENT Event;
296  UCHAR MdlBase[sizeof(MDL) + sizeof(ULONG)];
297  PMDL Mdl = (PMDL)MdlBase;
298  PPAGINGFILE PagingFile;
299 
300  DPRINT("MiReadSwapFile\n");
301 
302  if (PageFileOffset == 0)
303  {
304  KeBugCheck(MEMORY_MANAGEMENT);
305  return(STATUS_UNSUCCESSFUL);
306  }
307 
308  ASSERT(PageFileIndex < MAX_PAGING_FILES);
309 
310  PagingFile = PagingFileList[PageFileIndex];
311 
312  if (PagingFile->FileObject == NULL || PagingFile->FileObject->DeviceObject == NULL)
313  {
314  DPRINT1("Bad paging file %u\n", PageFileIndex);
315  KeBugCheck(MEMORY_MANAGEMENT);
316  }
317 
319  MmBuildMdlFromPages(Mdl, &Page);
320  Mdl->MdlFlags |= MDL_PAGES_LOCKED;
321 
322  file_offset.QuadPart = PageFileOffset * PAGE_SIZE;
323  file_offset = MmGetOffsetPageFile(PagingFile->RetrievalPointers, file_offset);
324 
326  Status = IoPageRead(PagingFile->FileObject,
327  Mdl,
328  &file_offset,
329  &Event,
330  &Iosb);
331  if (Status == STATUS_PENDING)
332  {
334  Status = Iosb.Status;
335  }
336  if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
337  {
338  MmUnmapLockedPages (Mdl->MappedSystemVa, Mdl);
339  }
340  return(Status);
341 }
342 
343 VOID
345 NTAPI
347 {
348  ULONG i;
349 
351 
352  MiFreeSwapPages = 0;
353  MiUsedSwapPages = 0;
355 
356  for (i = 0; i < MAX_PAGING_FILES; i++)
357  {
358  PagingFileList[i] = NULL;
359  }
361 }
362 
363 static ULONG
364 MiAllocPageFromPagingFile(PPAGINGFILE PagingFile)
365 {
366  KIRQL oldIrql;
367  ULONG i, j;
368 
369  KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql);
370 
371  for (i = 0; i < PagingFile->AllocMapSize; i++)
372  {
373  for (j = 0; j < 32; j++)
374  {
375  if (!(PagingFile->AllocMap[i] & (1 << j)))
376  {
377  PagingFile->AllocMap[i] |= (1 << j);
378  PagingFile->UsedPages++;
379  PagingFile->FreePages--;
380  KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
381  return((i * 32) + j);
382  }
383  }
384  }
385 
386  KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
387  return(0xFFFFFFFF);
388 }
389 
390 VOID
391 NTAPI
393 {
394  ULONG i;
395  ULONG_PTR off;
396  KIRQL oldIrql;
397 
398  i = FILE_FROM_ENTRY(Entry);
399  off = OFFSET_FROM_ENTRY(Entry) - 1;
400 
402  if (PagingFileList[i] == NULL)
403  {
404  KeBugCheck(MEMORY_MANAGEMENT);
405  }
406  KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock);
407 
408  PagingFileList[i]->AllocMap[off >> 5] &= (~(1 << (off % 32)));
409 
410  PagingFileList[i]->FreePages++;
411  PagingFileList[i]->UsedPages--;
412 
413  MiFreeSwapPages++;
414  MiUsedSwapPages--;
415 
416  KeReleaseSpinLockFromDpcLevel(&PagingFileList[i]->AllocMapLock);
418 }
419 
420 SWAPENTRY
421 NTAPI
423 {
424  KIRQL oldIrql;
425  ULONG i;
426  ULONG off;
428 
430 
431  if (MiFreeSwapPages == 0)
432  {
434  return(0);
435  }
436 
437  for (i = 0; i < MAX_PAGING_FILES; i++)
438  {
439  if (PagingFileList[i] != NULL &&
440  PagingFileList[i]->FreePages >= 1)
441  {
442  off = MiAllocPageFromPagingFile(PagingFileList[i]);
443  if (off == 0xFFFFFFFF)
444  {
445  KeBugCheck(MEMORY_MANAGEMENT);
447  return(STATUS_UNSUCCESSFUL);
448  }
449  MiUsedSwapPages++;
450  MiFreeSwapPages--;
452 
453  entry = ENTRY_FROM_FILE_OFFSET(i, off + 1);
454  return(entry);
455  }
456  }
457 
459  KeBugCheck(MEMORY_MANAGEMENT);
460  return(0);
461 }
462 
463 static PRETRIEVEL_DESCRIPTOR_LIST FASTCALL
465 {
466  ULONG Size;
467  PRETRIEVEL_DESCRIPTOR_LIST RetDescList;
468 
469  Size = sizeof(RETRIEVEL_DESCRIPTOR_LIST) + Pairs * 2 * sizeof(LARGE_INTEGER);
470  RetDescList = ExAllocatePool(NonPagedPool, Size);
471  if (RetDescList)
472  {
473  RtlZeroMemory(RetDescList, Size);
474  }
475 
476  return RetDescList;
477 }
478 
481  IN PLARGE_INTEGER InitialSize,
483  IN ULONG Reserved)
484 {
490  PPAGINGFILE PagingFile;
491  KIRQL oldIrql;
492  ULONG AllocMapSize;
493  FILE_FS_SIZE_INFORMATION FsSizeInformation;
494  PRETRIEVEL_DESCRIPTOR_LIST RetDescList;
495  PRETRIEVEL_DESCRIPTOR_LIST CurrentRetDescList;
496  ULONG i;
497  ULONG BytesPerAllocationUnit;
498  LARGE_INTEGER Vcn;
499  ULONG ExtentCount;
500  LARGE_INTEGER MaxVcn;
501  ULONG Count;
502  ULONG Size;
504  UNICODE_STRING CapturedFileName;
505  LARGE_INTEGER SafeInitialSize, SafeMaximumSize;
506 
507  DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n",
508  FileName, InitialSize->QuadPart);
509 
511  {
513  }
514 
515  PreviousMode = ExGetPreviousMode();
516 
517  if (PreviousMode != KernelMode)
518  {
519  _SEH2_TRY
520  {
521  SafeInitialSize = ProbeForReadLargeInteger(InitialSize);
522  SafeMaximumSize = ProbeForReadLargeInteger(MaximumSize);
523  }
525  {
526  /* Return the exception code */
528  }
529  _SEH2_END;
530  }
531  else
532  {
533  SafeInitialSize = *InitialSize;
534  SafeMaximumSize = *MaximumSize;
535  }
536 
537  /* Pagefiles can't be larger than 4GB and ofcourse the minimum should be
538  smaller than the maximum */
539  if (0 != SafeInitialSize.u.HighPart)
540  {
542  }
543  if (0 != SafeMaximumSize.u.HighPart)
544  {
546  }
547  if (SafeMaximumSize.u.LowPart < SafeInitialSize.u.LowPart)
548  {
550  }
551 
552  Status = ProbeAndCaptureUnicodeString(&CapturedFileName,
553  PreviousMode,
554  FileName);
555  if (!NT_SUCCESS(Status))
556  {
557  return(Status);
558  }
559 
560  InitializeObjectAttributes(&ObjectAttributes,
561  &CapturedFileName,
563  NULL,
564  NULL);
565 
566  Status = IoCreateFile(&FileHandle,
568  &ObjectAttributes,
569  &IoStatus,
570  NULL,
571  0,
572  0,
573  FILE_OPEN_IF,
575  NULL,
576  0,
578  NULL,
580 
581  ReleaseCapturedUnicodeString(&CapturedFileName,
582  PreviousMode);
583  if (!NT_SUCCESS(Status))
584  {
585  return(Status);
586  }
587 
588  Status = ZwQueryVolumeInformationFile(FileHandle,
589  &IoStatus,
590  &FsSizeInformation,
591  sizeof(FILE_FS_SIZE_INFORMATION),
593  if (!NT_SUCCESS(Status))
594  {
595  ZwClose(FileHandle);
596  return Status;
597  }
598 
599  BytesPerAllocationUnit = FsSizeInformation.SectorsPerAllocationUnit *
600  FsSizeInformation.BytesPerSector;
601  /* FIXME: If we have 2048 BytesPerAllocationUnit (FAT16 < 128MB) there is
602  * a problem if the paging file is fragmented. Suppose the first cluster
603  * of the paging file is cluster 3042 but cluster 3043 is NOT part of the
604  * paging file but of another file. We can't write a complete page (4096
605  * bytes) to the physical location of cluster 3042 then. */
606  if (BytesPerAllocationUnit % PAGE_SIZE)
607  {
608  DPRINT1("BytesPerAllocationUnit %lu is not a multiple of PAGE_SIZE %d\n",
609  BytesPerAllocationUnit, PAGE_SIZE);
610  ZwClose(FileHandle);
611  return STATUS_UNSUCCESSFUL;
612  }
613 
614  Status = ZwSetInformationFile(FileHandle,
615  &IoStatus,
616  &SafeInitialSize,
617  sizeof(LARGE_INTEGER),
619  if (!NT_SUCCESS(Status))
620  {
621  ZwClose(FileHandle);
622  return(Status);
623  }
624 
625  Status = ObReferenceObjectByHandle(FileHandle,
628  KernelMode,
629  (PVOID*)&FileObject,
630  NULL);
631  if (!NT_SUCCESS(Status))
632  {
633  ZwClose(FileHandle);
634  return(Status);
635  }
636 
637  CurrentRetDescList = RetDescList = MmAllocRetrievelDescriptorList(PAIRS_PER_RUN);
638 
639  if (CurrentRetDescList == NULL)
640  {
641  ObDereferenceObject(FileObject);
642  ZwClose(FileHandle);
643  return(STATUS_NO_MEMORY);
644  }
645 
646 #if defined(__GNUC__)
647  Vcn.QuadPart = 0LL;
648 #else
649 
650  Vcn.QuadPart = 0;
651 #endif
652 
653  ExtentCount = 0;
654  MaxVcn.QuadPart = (SafeInitialSize.QuadPart + BytesPerAllocationUnit - 1) / BytesPerAllocationUnit;
655  while(1)
656  {
657  Status = ZwFsControlFile(FileHandle,
658  0,
659  NULL,
660  NULL,
661  &IoStatus,
663  &Vcn,
664  sizeof(LARGE_INTEGER),
665  &CurrentRetDescList->RetrievalPointers,
666  sizeof(RETRIEVAL_POINTERS_BUFFER) + PAIRS_PER_RUN * 2 * sizeof(LARGE_INTEGER));
667  if (!NT_SUCCESS(Status))
668  {
669  while (RetDescList)
670  {
671  CurrentRetDescList = RetDescList;
672  RetDescList = RetDescList->Next;
673  ExFreePool(CurrentRetDescList);
674  }
675  ObDereferenceObject(FileObject);
676  ZwClose(FileHandle);
677  return(Status);
678  }
679  ExtentCount += CurrentRetDescList->RetrievalPointers.ExtentCount;
680  if (CurrentRetDescList->RetrievalPointers.Extents[CurrentRetDescList->RetrievalPointers.ExtentCount-1].NextVcn.QuadPart < MaxVcn.QuadPart)
681  {
682  CurrentRetDescList->Next = MmAllocRetrievelDescriptorList(PAIRS_PER_RUN);
683  if (CurrentRetDescList->Next == NULL)
684  {
685  while (RetDescList)
686  {
687  CurrentRetDescList = RetDescList;
688  RetDescList = RetDescList->Next;
689  ExFreePool(CurrentRetDescList);
690  }
691  ObDereferenceObject(FileObject);
692  ZwClose(FileHandle);
693  return(STATUS_NO_MEMORY);
694  }
695  Vcn = CurrentRetDescList->RetrievalPointers.Extents[CurrentRetDescList->RetrievalPointers.ExtentCount-1].NextVcn;
696  CurrentRetDescList = CurrentRetDescList->Next;
697  }
698  else
699  {
700  break;
701  }
702  }
703 
704  PagingFile = ExAllocatePool(NonPagedPool, sizeof(*PagingFile));
705  if (PagingFile == NULL)
706  {
707  while (RetDescList)
708  {
709  CurrentRetDescList = RetDescList;
710  RetDescList = RetDescList->Next;
711  ExFreePool(CurrentRetDescList);
712  }
713  ObDereferenceObject(FileObject);
714  ZwClose(FileHandle);
715  return(STATUS_NO_MEMORY);
716  }
717 
718  RtlZeroMemory(PagingFile, sizeof(*PagingFile));
719 
720  PagingFile->FileObject = FileObject;
721  PagingFile->MaximumSize.QuadPart = SafeMaximumSize.QuadPart;
722  PagingFile->CurrentSize.QuadPart = SafeInitialSize.QuadPart;
723  PagingFile->FreePages = (ULONG)(SafeInitialSize.QuadPart / PAGE_SIZE);
724  PagingFile->UsedPages = 0;
725  KeInitializeSpinLock(&PagingFile->AllocMapLock);
726 
727  AllocMapSize = (PagingFile->FreePages / 32) + 1;
728  PagingFile->AllocMap = ExAllocatePool(NonPagedPool,
729  AllocMapSize * sizeof(ULONG));
730  PagingFile->AllocMapSize = AllocMapSize;
731 
732  if (PagingFile->AllocMap == NULL)
733  {
734  while (RetDescList)
735  {
736  CurrentRetDescList = RetDescList;
737  RetDescList = RetDescList->Next;
738  ExFreePool(CurrentRetDescList);
739  }
740  ExFreePool(PagingFile);
741  ObDereferenceObject(FileObject);
742  ZwClose(FileHandle);
743  return(STATUS_NO_MEMORY);
744  }
745  DPRINT("ExtentCount: %lu\n", ExtentCount);
746  Size = sizeof(RETRIEVAL_POINTERS_BUFFER) + ExtentCount * 2 * sizeof(LARGE_INTEGER);
747  PagingFile->RetrievalPointers = ExAllocatePool(NonPagedPool, Size);
748  if (PagingFile->RetrievalPointers == NULL)
749  {
750  while (RetDescList)
751  {
752  CurrentRetDescList = RetDescList;
753  RetDescList = RetDescList->Next;
754  ExFreePool(CurrentRetDescList);
755  }
756  ExFreePool(PagingFile->AllocMap);
757  ExFreePool(PagingFile);
758  ObDereferenceObject(FileObject);
759  ZwClose(FileHandle);
760  return(STATUS_NO_MEMORY);
761  }
762 
763  RtlZeroMemory(PagingFile->AllocMap, AllocMapSize * sizeof(ULONG));
764  RtlZeroMemory(PagingFile->RetrievalPointers, Size);
765 
766  Count = 0;
767  PagingFile->RetrievalPointers->ExtentCount = ExtentCount;
768  PagingFile->RetrievalPointers->StartingVcn = RetDescList->RetrievalPointers.StartingVcn;
769  CurrentRetDescList = RetDescList;
770  while (CurrentRetDescList)
771  {
772  memcpy(&PagingFile->RetrievalPointers->Extents[Count],
773  CurrentRetDescList->RetrievalPointers.Extents,
774  CurrentRetDescList->RetrievalPointers.ExtentCount * 2 * sizeof(LARGE_INTEGER));
775  Count += CurrentRetDescList->RetrievalPointers.ExtentCount;
776  RetDescList = CurrentRetDescList;
777  CurrentRetDescList = CurrentRetDescList->Next;
778  ExFreePool(RetDescList);
779  }
780 
781  if (PagingFile->RetrievalPointers->ExtentCount != ExtentCount ||
782  PagingFile->RetrievalPointers->Extents[ExtentCount - 1].NextVcn.QuadPart != MaxVcn.QuadPart)
783  {
784  ExFreePool(PagingFile->RetrievalPointers);
785  ExFreePool(PagingFile->AllocMap);
786  ExFreePool(PagingFile);
787  ObDereferenceObject(FileObject);
788  ZwClose(FileHandle);
789  return(STATUS_UNSUCCESSFUL);
790  }
791 
792  /*
793  * Change the entries from lcn's to volume offset's.
794  */
795  PagingFile->RetrievalPointers->StartingVcn.QuadPart *= BytesPerAllocationUnit;
796  for (i = 0; i < ExtentCount; i++)
797  {
798  PagingFile->RetrievalPointers->Extents[i].Lcn.QuadPart *= BytesPerAllocationUnit;
799  PagingFile->RetrievalPointers->Extents[i].NextVcn.QuadPart *= BytesPerAllocationUnit;
800  }
801 
803  for (i = 0; i < MAX_PAGING_FILES; i++)
804  {
805  if (PagingFileList[i] == NULL)
806  {
807  PagingFileList[i] = PagingFile;
808  break;
809  }
810  }
811  MiFreeSwapPages = MiFreeSwapPages + PagingFile->FreePages;
814 
815  ZwClose(FileHandle);
816 
817  MmSwapSpaceMessage = FALSE;
818 
819  return(STATUS_SUCCESS);
820 }
821 
822 /* EOF */
static __inline NTSTATUS ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest, IN KPROCESSOR_MODE CurrentMode, IN const UNICODE_STRING *UnsafeSrc)
Definition: probe.h:142
#define MDL_IO_PAGE_READ
Definition: mmtypes.h:24
DWORD *typedef PVOID
Definition: winlogon.h:52
#define STATUS_SUCCESS
Definition: contextmenu.cpp:55
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
VOID INIT_FUNCTION NTAPI MmInitPagingFile(VOID)
Definition: pagefile.c:346
#define IN
Definition: typedefs.h:39
static PFN_COUNT MiReservedSwapPages
Definition: pagefile.c:93
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
#define TRUE
Definition: types.h:120
#define LL
Definition: tui.h:72
static LARGE_INTEGER MmGetOffsetPageFile(PRETRIEVAL_POINTERS_BUFFER RetrievalPointers, LARGE_INTEGER Offset)
Definition: pagefile.c:164
struct _RETRIEVEL_DESCRIPTOR_LIST * PRETRIEVEL_DESCRIPTOR_LIST
#define FILE_OPEN_IF
Definition: from_kernel.h:56
KSPIN_LOCK AllocMapLock
Definition: pagefile.c:54
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
ULONG PFN_COUNT
Definition: mmtypes.h:102
POINT last
Definition: font.c:45
#define SL_OPEN_PAGING_FILE
Definition: iotypes.h:1768
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
PFILE_OBJECT FileObject
Definition: pagefile.c:48
VOID NTAPI MmBuildMdlFromPages(PMDL Mdl, PPFN_NUMBER Pages)
Definition: pagefile.c:126
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
PFN_NUMBER UsedPages
Definition: pagefile.c:52
struct _PAGINGFILE PAGINGFILE
SWAPENTRY NTAPI MmAllocSwapPage(VOID)
Definition: pagefile.c:422
const GLint * first
Definition: glext.h:5794
uint8_t entry
Definition: isohybrid.c:63
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2737
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:267
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:1074
#define STATUS_INVALID_PARAMETER_MIX
Definition: ntstatus.h:271
PVOID PMDL
Definition: usb.h:39
VOID NTAPI MmShowOutOfSpaceMessagePagingFile(VOID)
Definition: pagefile.c:154
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FASTCALL
Definition: nt_native.h:50
NTSTATUS NTAPI MiReadPageFile(_In_ PFN_NUMBER Page, _In_ ULONG PageFileIndex, _In_ ULONG_PTR PageFileOffset)
Definition: pagefile.c:287
#define PAGE_ROUND_UP(x)
Definition: scsiport_int.h:13
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
#define STATUS_TOO_MANY_PAGING_FILES
Definition: ntstatus.h:373
uint32_t ULONG_PTR
Definition: typedefs.h:64
ACPI_EFI_EVENT Event
Definition: acefiex.h:607
_Must_inspect_result_ _Out_ PIO_STATUS_BLOCK Iosb
Definition: fltkernel.h:1761
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG * PPFN_NUMBER
Definition: ke.h:8
GLenum GLclampf GLint i
Definition: glfuncs.h:14
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:388
ULONG PFN_NUMBER
Definition: ke.h:8
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:463
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define FALSE
Definition: types.h:117
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:508
#define _SEH2_END
Definition: pseh2_64.h:7
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:811
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
LARGE_INTEGER StartingVcn
Definition: winioctl.h:527
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
static BOOLEAN MmSwapSpaceMessage
Definition: pagefile.c:120
NTSYSAPI NTSTATUS NTAPI ZwFsControlFile(IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, OUT PVOID OutputBuffer, IN ULONG OutputBufferSize)
NTSTATUS NTAPI NtCreatePagingFile(IN PUNICODE_STRING FileName, IN PLARGE_INTEGER InitialSize, IN PLARGE_INTEGER MaximumSize, IN ULONG Reserved)
Definition: pagefile.c:480
smooth NULL
Definition: ftsmooth.c:513
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:462
PFN_NUMBER FreePages
Definition: pagefile.c:51
_In_ PFILE_OBJECT FileObject
Definition: classpnp.h:1229
BOOLEAN MmZeroPageFile
Definition: pagefile.c:88
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
struct _PAGINGFILE * PPAGINGFILE
UINTN Size
Definition: acefiex.h:550
static __inline VOID ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString, IN KPROCESSOR_MODE CurrentMode)
Definition: probe.h:228
unsigned char BOOLEAN
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
PRETRIEVAL_POINTERS_BUFFER RetrievalPointers
Definition: pagefile.c:56
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define FILE_FROM_ENTRY(i)
Definition: pagefile.c:113
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define STATUS_PENDING
Definition: ntstatus.h:82
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
PVOID NTAPI MiFindExportedRoutineByName(IN PVOID DllBase, IN PANSI_STRING ExportName)
Definition: sysldr.c:490
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
BOOLEAN NTAPI MmIsFileObjectAPagingFile(PFILE_OBJECT FileObject)
Definition: pagefile.c:137
#define ENTRY_FROM_FILE_OFFSET(i, j)
Definition: pagefile.c:115
#define ProbeForReadLargeInteger(Ptr)
Definition: probe.h:75
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
* PFILE_OBJECT
Definition: iotypes.h:1949
ULONG MmNumberOfPagingFiles
Definition: pagefile.c:80
ULONG AllocMapSize
Definition: pagefile.c:55
NTSYSAPI NTSTATUS NTAPI ZwQueryVolumeInformationFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FsInformation, IN ULONG Length, IN FS_INFORMATION_CLASS FsInformationClass)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS NTAPI MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
Definition: pagefile.c:222
MDL
Definition: mmtypes.h:117
struct _RETRIEVEL_DESCRIPTOR_LIST RETRIEVEL_DESCRIPTOR_LIST
static PRETRIEVEL_DESCRIPTOR_LIST FASTCALL MmAllocRetrievelDescriptorList(ULONG Pairs)
Definition: pagefile.c:464
#define FSCTL_GET_RETRIEVAL_POINTERS
Definition: winioctl.h:95
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
LARGE_INTEGER CurrentSize
Definition: pagefile.c:50
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:118
struct _LARGE_INTEGER::@2028 u
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define MAX_PAGING_FILES
Definition: pagefile.c:71
ULONG PVOID Reserved
Definition: ntimage.h:533
static ULONG MiAllocPageFromPagingFile(PPAGINGFILE PagingFile)
Definition: pagefile.c:364
Status
Definition: gdiplustypes.h:24
_In_ PLARGE_INTEGER _In_ ULONG _In_ BOOLEAN _In_ ULONG _Out_ PVOID _Out_ PIO_STATUS_BLOCK IoStatus
Definition: npfs.h:636
#define _In_
Definition: no_sal2.h:204
static HANDLE FileHandle
Definition: cabinet.c:47
#define NT_SUCCESS(StatCode)
Definition: cmd.c:149
DWORD *typedef HANDLE
Definition: winlogon.h:52
struct RETRIEVAL_POINTERS_BUFFER RETRIEVAL_POINTERS_BUFFER
LONG NTSTATUS
Definition: DriverTester.h:11
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
unsigned char dummy
Definition: maze.c:118
ULONG_PTR SWAPENTRY
Definition: mm.h:45
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define _SEH2_TRY
Definition: pseh2_64.h:5
#define PAIRS_PER_RUN
Definition: pagefile.c:69
unsigned int * PULONG
Definition: retypes.h:1
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:1027
static KSPIN_LOCK PagingFileListLock
Definition: pagefile.c:77
LIST_ENTRY PagingFileListEntry
Definition: pagefile.c:47
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:360
#define DPRINT1
Definition: precomp.h:8
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:2614
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
NTSTATUS NTAPI MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_NUMBER Page)
Definition: pagefile.c:280
struct _RETRIEVEL_DESCRIPTOR_LIST * Next
Definition: pagefile.c:62
unsigned int ULONG
Definition: retypes.h:1
#define OFFSET_FROM_ENTRY(i)
Definition: pagefile.c:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
LARGE_INTEGER MaximumSize
Definition: pagefile.c:49
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
PULONG AllocMap
Definition: pagefile.c:53
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
PFN_COUNT MiUsedSwapPages
Definition: pagefile.c:86
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
static PPAGINGFILE PagingFileList[MAX_PAGING_FILES]
Definition: pagefile.c:74
base of all file and directory entries
Definition: entries.h:82
C_ASSERT(FILE_FROM_ENTRY(0xffffffff)< MAX_PAGING_FILES)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
struct RETRIEVAL_POINTERS_BUFFER::@3013 Extents[1]
PFN_COUNT MiFreeSwapPages
Definition: pagefile.c:83
LONGLONG QuadPart
Definition: typedefs.h:113
GLintptr offset
Definition: glext.h:5920
#define INIT_FUNCTION
Definition: ntoskrnl.h:11
RETRIEVAL_POINTERS_BUFFER RetrievalPointers
Definition: pagefile.c:63
VOID NTAPI MmFreeSwapPage(SWAPENTRY Entry)
Definition: pagefile.c:392
off
Definition: i386-dis.c:3909