ReactOS  0.4.10-dev-479-g13a3cf0
pagefile.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Windows-Compatible Session Manager
3  * LICENSE: BSD 2-Clause License
4  * FILE: base/system/smss/pagefile.c
5  * PURPOSE: Main SMSS Code
6  * PROGRAMMERS: Alex Ionescu
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "smss.h"
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* GLOBALS ********************************************************************/
17 
18 //
19 // Constants
20 //
21 #define STANDARD_PAGING_FILE_NAME L"\\??\\?:\\pagefile.sys"
22 #define STANDARD_DRIVE_LETTER_OFFSET 4
23 #define MEGABYTE 0x100000UL
24 #define MAXIMUM_PAGEFILE_SIZE (4095 * MEGABYTE)
25 /* This should be 32 MB, but we need more than that for 2nd stage setup */
26 #define MINIMUM_TO_KEEP_FREE (64 * MEGABYTE)
27 #define FUZZ_FACTOR (16 * MEGABYTE)
28 
29 //
30 // Structure and flags describing each pagefile
31 //
32 #define SMP_PAGEFILE_CREATED 0x01
33 #define SMP_PAGEFILE_DEFAULT 0x02
34 #define SMP_PAGEFILE_SYSTEM_MANAGED 0x04
35 #define SMP_PAGEFILE_WAS_TOO_BIG 0x08
36 #define SMP_PAGEFILE_ON_ANY_DRIVE 0x10
37 #define SMP_PAGEFILE_EMERGENCY 0x20
38 #define SMP_PAGEFILE_DUMP_PROCESSED 0x40
40 {
50 
51 //
52 // Structure and flags describing each volume
53 //
54 #define SMP_VOLUME_INSERTED 0x01
55 #define SMP_VOLUME_PAGEFILE_CREATED 0x04
56 #define SMP_VOLUME_IS_BOOT 0x08
57 typedef struct _SMP_VOLUME_DESCRIPTOR
58 {
66 
70 
71 /* FUNCTIONS ******************************************************************/
72 
73 VOID
74 NTAPI
76 {
77  /* Initialize the two lists */
78  InitializeListHead(&SmpPagingFileDescriptorList);
79  InitializeListHead(&SmpVolumeDescriptorList);
80 }
81 
83 NTAPI
85 {
87  ULONG MinSize = 0, MaxSize = 0;
88  BOOLEAN SystemManaged = FALSE, ZeroSize = TRUE;
89  PSMP_PAGEFILE_DESCRIPTOR Descriptor, ListDescriptor;
90  ULONG i;
91  WCHAR c;
92  PLIST_ENTRY NextEntry;
93  UNICODE_STRING PageFileName, Arguments, SecondArgument;
94 
95  /* Make sure we don't have too many */
96  if (SmpNumberOfPagingFiles >= 16)
97  {
98  DPRINT1("SMSS:PFILE: Too many paging files specified - %lu\n",
101  }
102 
103  /* Parse the specified and get the name and arguments out of it */
104  DPRINT("SMSS:PFILE: Paging file specifier `%wZ'\n", PageFileToken);
105  Status = SmpParseCommandLine(PageFileToken,
106  NULL,
107  &PageFileName,
108  NULL,
109  &Arguments);
110  if (!NT_SUCCESS(Status))
111  {
112  /* Fail */
113  DPRINT1("SMSS:PFILE: SmpParseCommandLine( %wZ ) failed - Status == %lx\n",
114  PageFileToken, Status);
115  return Status;
116  }
117 
118  /* Set the variable to let everyone know we have a pagefile token */
120 
121  /* Parse the arguments, if any */
122  if (Arguments.Buffer)
123  {
124  /* Parse the pagefile size */
125  for (i = 0; i < Arguments.Length / sizeof(WCHAR); i++)
126  {
127  /* Check if it's zero */
128  c = Arguments.Buffer[i];
129  if ((c != L' ') && (c != L'\t') && (c != L'0'))
130  {
131  /* It isn't, break out */
132  ZeroSize = FALSE;
133  break;
134  }
135  }
136  }
137 
138  /* Was a pagefile not specified, or was it specified with no size? */
139  if (!(Arguments.Buffer) || (ZeroSize))
140  {
141  /* In this case, the system will manage its size */
142  SystemManaged = TRUE;
143  }
144  else
145  {
146  /* We do have a size, so convert the arguments into a number */
147  Status = RtlUnicodeStringToInteger(&Arguments, 0, &MinSize);
148  if (!NT_SUCCESS(Status))
149  {
150  /* Fail */
151  RtlFreeUnicodeString(&PageFileName);
152  RtlFreeUnicodeString(&Arguments);
153  return Status;
154  }
155 
156  /* Now advance to the next argument */
157  for (i = 0; i < Arguments.Length / sizeof(WCHAR); i++)
158  {
159  /* Found a space -- second argument must start here */
160  if (Arguments.Buffer[i] == L' ')
161  {
162  /* Use the rest of the arguments as a maximum size */
163  SecondArgument.Buffer = &Arguments.Buffer[i];
164  SecondArgument.Length = (USHORT)(Arguments.Length -
165  i * sizeof(WCHAR));
166  SecondArgument.MaximumLength = (USHORT)(Arguments.MaximumLength -
167  i * sizeof(WCHAR));
168  Status = RtlUnicodeStringToInteger(&SecondArgument, 0, &MaxSize);
169  if (!NT_SUCCESS(Status))
170  {
171  /* Fail */
172  RtlFreeUnicodeString(&PageFileName);
173  RtlFreeUnicodeString(&Arguments);
174  return Status;
175  }
176 
177  break;
178  }
179  }
180  }
181 
182  /* We are done parsing arguments */
183  RtlFreeUnicodeString(&Arguments);
184 
185  /* Now we can allocate our descriptor */
186  Descriptor = RtlAllocateHeap(RtlGetProcessHeap(),
188  sizeof(SMP_PAGEFILE_DESCRIPTOR));
189  if (!Descriptor)
190  {
191  /* Fail if we couldn't */
192  RtlFreeUnicodeString(&PageFileName);
193  return STATUS_NO_MEMORY;
194  }
195 
196  /* Capture all our data into the descriptor */
197  Descriptor->Token = *PageFileToken;
198  Descriptor->Name = PageFileName;
199  Descriptor->MinSize.QuadPart = MinSize * MEGABYTE;
200  Descriptor->MaxSize.QuadPart = MaxSize * MEGABYTE;
201  if (SystemManaged) Descriptor->Flags |= SMP_PAGEFILE_SYSTEM_MANAGED;
204  if (Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == '?')
205  {
206  Descriptor->Flags |= SMP_PAGEFILE_ON_ANY_DRIVE;
207  }
208 
209  /* Now loop the existing descriptors */
210  NextEntry = SmpPagingFileDescriptorList.Flink;
211  do
212  {
213  /* Are there none, or have we looped back to the beginning? */
214  if (NextEntry == &SmpPagingFileDescriptorList)
215  {
216  /* This means no duplicates exist, so insert our descriptor! */
217  InsertTailList(&SmpPagingFileDescriptorList, &Descriptor->Entry);
219  DPRINT("SMSS:PFILE: Created descriptor for `%wZ' (`%wZ')\n",
220  PageFileToken, &Descriptor->Name);
221  return STATUS_SUCCESS;
222  }
223 
224  /* Keep going until we find a duplicate, unless we are in "any" mode */
225  ListDescriptor = CONTAINING_RECORD(NextEntry, SMP_PAGEFILE_DESCRIPTOR, Entry);
226  NextEntry = NextEntry->Flink;
227  } while (!(ListDescriptor->Flags & SMP_PAGEFILE_ON_ANY_DRIVE) ||
228  !(Descriptor->Flags & SMP_PAGEFILE_ON_ANY_DRIVE));
229 
230  /* We found a duplicate, so skip this descriptor/pagefile and fail */
231  DPRINT1("SMSS:PFILE: Skipping duplicate specifier `%wZ'\n", PageFileToken);
232  RtlFreeUnicodeString(&PageFileName);
233  RtlFreeHeap(RtlGetProcessHeap(), 0, Descriptor);
235 }
236 
237 NTSTATUS
238 NTAPI
241 {
246  FILE_STANDARD_INFORMATION StandardInfo;
247 
248  DPRINT("SMSS:PFILE: Trying to get size for `%wZ'\n", FileName);
249  Size->QuadPart = 0;
250 
251  InitializeObjectAttributes(&ObjectAttributes,
252  FileName,
254  NULL,
255  NULL);
256  Status = NtOpenFile(&FileHandle,
258  &ObjectAttributes,
259  &IoStatusBlock,
262  if (!NT_SUCCESS(Status)) return Status;
263 
264  Status = NtQueryInformationFile(FileHandle,
265  &IoStatusBlock,
266  &StandardInfo,
267  sizeof(StandardInfo),
269  if (!NT_SUCCESS(Status))
270  {
271  DPRINT1("SMSS:PFILE: Failed query for size potential pagefile `%wZ' with status %X\n",
272  FileName, Status);
273  NtClose(FileHandle);
274  return Status;
275  }
276 
277  NtClose(FileHandle);
278  Size->QuadPart = StandardInfo.AllocationSize.QuadPart;
279  return STATUS_SUCCESS;
280 }
281 
282 NTSTATUS
283 NTAPI
285 {
291 
292  /* Open the page file */
293  InitializeObjectAttributes(&ObjectAttributes,
294  FileName,
296  NULL,
297  NULL);
298  Status = NtOpenFile(&FileHandle,
299  DELETE,
300  &ObjectAttributes,
301  &IoStatusBlock,
304  if (NT_SUCCESS(Status))
305  {
306  /* Delete it */
307  Disposition.DeleteFile = TRUE;
308  Status = NtSetInformationFile(FileHandle,
309  &IoStatusBlock,
310  &Disposition,
311  sizeof(Disposition),
313  if (!NT_SUCCESS(Status))
314  {
315  DPRINT1("SMSS:PFILE: Failed to delete page file `%wZ' (status %X)\n",
316  FileName, Status);
317  }
318  else
319  {
320  DPRINT("SMSS:PFILE: Deleted stale paging file - %wZ\n", FileName);
321  }
322 
323  /* Close the handle */
324  NtClose(FileHandle);
325  }
326  else
327  {
328  DPRINT1("SMSS:PFILE: Failed to open for deletion page file `%wZ' (status %X)\n",
329  FileName, Status);
330  }
331 
332  /* All done */
333  return Status;
334 }
335 
336 NTSTATUS
337 NTAPI
338 SmpGetVolumeFreeSpace(IN PSMP_VOLUME_DESCRIPTOR Volume)
339 {
341  LARGE_INTEGER FreeSpace, FinalFreeSpace;
342  FILE_FS_SIZE_INFORMATION SizeInfo;
347  WCHAR PathString[32];
348  ASSERT(Volume->Flags & SMP_VOLUME_IS_BOOT); // ASSERT says "BootVolume == 1"
349 
350  /* Build the standard path */
351  wcscpy(PathString, L"\\??\\A:\\");
352  RtlInitUnicodeString(&VolumeName, PathString);
353  VolumeName.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = Volume->DriveLetter;
354  DPRINT("SMSS:PFILE: Querying volume `%wZ' for free space\n", &VolumeName);
355 
356  /* Open the volume */
357  InitializeObjectAttributes(&ObjectAttributes,
358  &VolumeName,
360  NULL,
361  NULL);
362  Status = NtOpenFile(&VolumeHandle,
364  &ObjectAttributes,
365  &IoStatusBlock,
368  if (!NT_SUCCESS(Status))
369  {
370  DPRINT1("SMSS:PFILE: Open volume `%wZ' failed with status %X\n", &VolumeName, Status);
371  return Status;
372  }
373 
374  /* Now get size information on the volume */
375  Status = NtQueryVolumeInformationFile(VolumeHandle,
376  &IoStatusBlock,
377  &SizeInfo,
378  sizeof(SizeInfo),
380  if (!NT_SUCCESS(Status))
381  {
382  /* We failed */
383  DPRINT1("SMSS:PFILE: Query volume `%wZ' (handle %p) for size failed"
384  " with status %X\n",
385  &VolumeName,
386  VolumeHandle,
387  Status);
388  NtClose(VolumeHandle);
389  return Status;
390  }
391  NtClose(VolumeHandle);
392 
393  /* Compute how much free space we have */
394  FreeSpace.QuadPart = SizeInfo.AvailableAllocationUnits.QuadPart *
395  SizeInfo.SectorsPerAllocationUnit;
396  FinalFreeSpace.QuadPart = FreeSpace.QuadPart * SizeInfo.BytesPerSector;
397 
398  /* Check if there's less than 32MB free so we don't starve the disk */
399  if (FinalFreeSpace.QuadPart <= MINIMUM_TO_KEEP_FREE)
400  {
401  /* In this case, act as if there's no free space */
402  Volume->FreeSpace.QuadPart = 0;
403  }
404  else
405  {
406  /* Trim off 32MB to give the disk a bit of breathing room */
407  Volume->FreeSpace.QuadPart = FinalFreeSpace.QuadPart -
409  }
410 
411  return STATUS_SUCCESS;
412 }
413 
414 PSMP_VOLUME_DESCRIPTOR
415 NTAPI
417 {
418  WCHAR UpLetter;
419  PSMP_VOLUME_DESCRIPTOR Volume = NULL;
420  PLIST_ENTRY NextEntry;
421 
422  /* Use upper case to reduce differences */
423  UpLetter = RtlUpcaseUnicodeChar(DriveLetter);
424 
425  /* Loop each volume */
426  NextEntry = SmpVolumeDescriptorList.Flink;
427  while (NextEntry != &SmpVolumeDescriptorList)
428  {
429  /* Grab the entry */
430  Volume = CONTAINING_RECORD(NextEntry, SMP_VOLUME_DESCRIPTOR, Entry);
431 
432  /* Make sure it's a valid entry with an uppcase drive letter */
433  ASSERT(Volume->Flags & SMP_VOLUME_INSERTED); // Volume->Initialized in ASSERT
434  ASSERT(Volume->DriveLetter >= L'A' && Volume->DriveLetter <= L'Z');
435 
436  /* Break if it matches, if not, keep going */
437  if (Volume->DriveLetter == UpLetter) break;
438  NextEntry = NextEntry->Flink;
439  }
440 
441  /* Return the volume if one was found */
442  if (NextEntry == &SmpVolumeDescriptorList) Volume = NULL;
443  return Volume;
444 }
445 
446 NTSTATUS
447 NTAPI
449  IN PLARGE_INTEGER MinSize,
450  IN PLARGE_INTEGER MaxSize,
451  IN ULONG Priority)
452 {
454 
455  /* Tell the kernel to create the pagefile */
456  Status = NtCreatePagingFile(Name, MinSize, MaxSize, Priority);
457  if (NT_SUCCESS(Status))
458  {
459  DPRINT("SMSS:PFILE: NtCreatePagingFile (%wZ, %I64X, %I64X) succeeded.\n",
460  Name,
461  MinSize->QuadPart,
462  MaxSize->QuadPart);
463  }
464  else
465  {
466  DPRINT1("SMSS:PFILE: NtCreatePagingFile (%wZ, %I64X, %I64X) failed with %X\n",
467  Name,
468  MinSize->QuadPart,
469  MaxSize->QuadPart,
470  Status);
471  }
472 
473  /* Return the status */
474  return Status;
475 }
476 
477 NTSTATUS
478 NTAPI
480  IN PLARGE_INTEGER FuzzFactor,
481  IN PLARGE_INTEGER MinimumSize)
482 {
483  PSMP_VOLUME_DESCRIPTOR Volume;
484  BOOLEAN ShouldDelete;
486  LARGE_INTEGER PageFileSize;
487  ASSERT(Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] != L'?');
488 
489  /* Try to find the volume descriptor for this drive letter */
490  ShouldDelete = FALSE;
491  Volume = SmpSearchVolumeDescriptor(Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET]);
492  if (!Volume)
493  {
494  /* Couldn't find it, fail */
495  DPRINT1("SMSS:PFILE: No volume descriptor for `%wZ'\n",
496  &Descriptor->Name);
498  }
499 
500  /* Check if this is the boot volume */
501  if (Volume->Flags & SMP_VOLUME_IS_BOOT)
502  {
503  /* Check if we haven't yet processed a crash dump on this volume */
504  if (!(Descriptor->Flags & SMP_PAGEFILE_DUMP_PROCESSED))
505  {
506  /* Try to find a crash dump and extract it */
507  DPRINT("SMSS:PFILE: Checking for crash dump in `%wZ' on boot volume\n",
508  &Descriptor->Name);
509  SmpCheckForCrashDump(&Descriptor->Name);
510 
511  /* Update how much free space we have now that we extracted a dump */
512  Status = SmpGetVolumeFreeSpace(Volume);
513  if (!NT_SUCCESS(Status))
514  {
515  DPRINT1("SMSS:PFILE: Failed to query free space for boot volume `%wC'\n",
516  Volume->DriveLetter);
517  }
518  else
519  {
520  DPRINT("Queried free space for boot volume `%wC: %I64x'\n",
521  Volume->DriveLetter, Volume->FreeSpace.QuadPart);
522  }
523 
524  /* Don't process crashdump on this volume anymore */
525  Descriptor->Flags |= SMP_PAGEFILE_DUMP_PROCESSED;
526  }
527  }
528  else
529  {
530  /* Crashdumps can only be on the boot volume */
531  DPRINT("SMSS:PFILE: Skipping crash dump checking for `%wZ' on non boot"
532  "volume `%wC'\n",
533  &Descriptor->Name,
534  Volume->DriveLetter);
535  }
536 
537  /* Update the size after dump extraction */
538  Descriptor->ActualMinSize = Descriptor->MinSize;
539  Descriptor->ActualMaxSize = Descriptor->MaxSize;
540 
541  /* Check how big we can make the pagefile */
542  Status = SmpGetPagingFileSize(&Descriptor->Name, &PageFileSize);
543  if (NT_SUCCESS(Status) && PageFileSize.QuadPart > 0) ShouldDelete = TRUE;
544  DPRINT("SMSS:PFILE: Detected size %I64X for future paging file `%wZ'\n",
545  PageFileSize,
546  &Descriptor->Name);
547  DPRINT("SMSS:PFILE: Free space on volume `%wC' is %I64X\n",
548  Volume->DriveLetter,
549  Volume->FreeSpace.QuadPart);
550 
551  /* Now update our size and make sure none of these are too big */
552  PageFileSize.QuadPart += Volume->FreeSpace.QuadPart;
553  if (Descriptor->ActualMinSize.QuadPart > PageFileSize.QuadPart)
554  {
555  Descriptor->ActualMinSize = PageFileSize;
556  }
557  if (Descriptor->ActualMaxSize.QuadPart > PageFileSize.QuadPart)
558  {
559  Descriptor->ActualMaxSize = PageFileSize;
560  }
561  DPRINT("SMSS:PFILE: min %I64X, max %I64X, real min %I64X\n",
562  Descriptor->ActualMinSize.QuadPart,
563  Descriptor->ActualMaxSize.QuadPart,
564  MinimumSize->QuadPart);
565 
566  /* Keep going until we've created a pagefile of the right size */
567  while (Descriptor->ActualMinSize.QuadPart >= MinimumSize->QuadPart)
568  {
569  /* Call NT to do it */
570  Status = SmpCreatePagingFile(&Descriptor->Name,
571  &Descriptor->ActualMinSize,
572  &Descriptor->ActualMaxSize,
573  0);
574  if (NT_SUCCESS(Status))
575  {
576  /* We're done, update flags and increase the count */
577  Descriptor->Flags |= SMP_PAGEFILE_CREATED;
579  Volume->PageFileCount++;
580  break;
581  }
582 
583  /* We failed, try a slightly smaller pagefile */
584  Descriptor->ActualMinSize.QuadPart -= FuzzFactor->QuadPart;
585  }
586 
587  /* Check if we weren't able to create it */
588  if (Descriptor->ActualMinSize.QuadPart < MinimumSize->QuadPart)
589  {
590  /* Delete the current page file and fail */
591  if (ShouldDelete)
592  {
593  SmpDeletePagingFile(&Descriptor->Name);
594 
595  /* FIXFIX: Windows Vista does this, and it seems like we should too, so try to see if this fixes KVM */
596  Volume->FreeSpace.QuadPart = PageFileSize.QuadPart;
597  }
598  DPRINT1("SMSS:PFILE: Failing for min %I64X, max %I64X, real min %I64X\n",
599  Descriptor->ActualMinSize.QuadPart,
600  Descriptor->ActualMaxSize.QuadPart,
601  MinimumSize->QuadPart);
602  Status = STATUS_DISK_FULL;
603  }
604 
605  /* Return the status */
606  return Status;
607 }
608 
609 NTSTATUS
610 NTAPI
611 SmpCreatePagingFileOnAnyDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor,
612  IN PLARGE_INTEGER FuzzFactor,
613  IN PLARGE_INTEGER MinimumSize)
614 {
615  PSMP_VOLUME_DESCRIPTOR Volume;
617  PLIST_ENTRY NextEntry;
618  ASSERT(Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == L'?');
619 
620  /* Loop the volume list */
621  NextEntry = SmpVolumeDescriptorList.Flink;
622  while (NextEntry != &SmpVolumeDescriptorList)
623  {
624  /* Get the volume */
625  Volume = CONTAINING_RECORD(NextEntry, SMP_VOLUME_DESCRIPTOR, Entry);
626 
627  /* Make sure it's inserted and on a valid drive letter */
628  ASSERT(Volume->Flags & SMP_VOLUME_INSERTED); // Volume->Initialized in ASSERT
629  ASSERT(Volume->DriveLetter >= L'A' && Volume->DriveLetter <= L'Z');
630 
631  /* Write the drive letter to try creating it on this volume */
632  Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = Volume->DriveLetter;
633  Status = SmpCreatePagingFileOnFixedDrive(Descriptor,
634  FuzzFactor,
635  MinimumSize);
636  if (NT_SUCCESS(Status)) break;
637 
638  /* It didn't work, make it an any pagefile again and keep going */
639  Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = L'?';
640  NextEntry = NextEntry->Flink;
641  }
642 
643  /* Return disk full or success */
644  return Status;
645 }
646 
647 VOID
648 NTAPI
650 {
651  /* The default descriptor uses 128MB as a pagefile size */
652  Descriptor->Flags |= SMP_PAGEFILE_DEFAULT;
653  Descriptor->MinSize.QuadPart = 128 * MEGABYTE;
654  Descriptor->MaxSize.QuadPart = 128 * MEGABYTE;
655 }
656 
657 VOID
658 NTAPI
660 {
662  LONGLONG MinimumSize, MaximumSize, Ram;
663  SYSTEM_BASIC_INFORMATION BasicInfo;
664 
665  /* Query the page size of the system, and the amount of RAM */
667  &BasicInfo,
668  sizeof(BasicInfo),
669  NULL);
670  if (!NT_SUCCESS(Status))
671  {
672  /* If we failed, use defaults since we have no idea otherwise */
673  DPRINT1("SMSS:PFILE: NtQuerySystemInformation failed with %x\n", Status);
675  return;
676  }
677 
678  /* Chekc how much RAM we have and set three times this amount as maximum */
679  Ram = BasicInfo.NumberOfPhysicalPages * BasicInfo.PageSize;
680  MaximumSize = 3 * Ram;
681 
682  /* If we have more than 1GB, use that as minimum, otherwise, use 1.5X RAM */
683  MinimumSize = (Ram >= 1024 * MEGABYTE) ? Ram : MaximumSize / 2;
684 
685  /* Write the new sizes in the descriptor and mark it as system managed */
686  Descriptor->MinSize.QuadPart = MinimumSize;
687  Descriptor->MaxSize.QuadPart = MaximumSize;
688  Descriptor->Flags |= SMP_PAGEFILE_SYSTEM_MANAGED;
689 }
690 
691 NTSTATUS
692 NTAPI
693 SmpValidatePagingFileSizes(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
694 {
696  ULONGLONG MinSize, MaxSize;
697  BOOLEAN WasTooBig = FALSE;
698 
699  /* Capture the min and max */
700  MinSize = Descriptor->MinSize.QuadPart;
701  MaxSize = Descriptor->MaxSize.QuadPart;
702  DPRINT("SMSS:PFILE: Validating sizes for `%wZ' %I64X %I64X\n",
703  &Descriptor->Name, MinSize, MaxSize);
704 
705  /* Don't let minimum be bigger than maximum */
706  if (MinSize > MaxSize) MaxSize = MinSize;
707 
708  /* On PAE we can have bigger pagefiles... */
709  if (SharedUserData->ProcessorFeatures[PF_PAE_ENABLED])
710  {
711  /* But we don't support that yet */
712  DPRINT1("ReactOS does not support PAE yet... assuming sizes OK\n");
713  }
714  else
715  {
716  /* Check if the minimum is more then 4095 MB */
717  if (MinSize > MAXIMUM_PAGEFILE_SIZE)
718  {
719  /* Trim it, this isn't allowed */
720  WasTooBig = TRUE;
721  MinSize = MAXIMUM_PAGEFILE_SIZE;
722  }
723 
724  /* Check if the maximum is more then 4095 MB */
725  if (MaxSize > MAXIMUM_PAGEFILE_SIZE)
726  {
727  /* Trim it, this isn't allowed */
728  WasTooBig = TRUE;
729  MaxSize = MAXIMUM_PAGEFILE_SIZE;
730  }
731  }
732 
733  /* Did we trim? */
734  if (WasTooBig)
735  {
736  /* Notify debugger output and write a flag in the descriptor */
737  DPRINT("SMSS:PFILE: Trimmed size of `%wZ' to maximum allowed\n",
738  &Descriptor->Name);
739  Descriptor->Flags |= SMP_PAGEFILE_WAS_TOO_BIG;
740  }
741 
742  /* Now write the (possibly trimmed) sizes back */
743  Descriptor->MinSize.QuadPart = MinSize;
744  Descriptor->MaxSize.QuadPart = MaxSize;
745  return Status;
746 }
747 
748 NTSTATUS
749 NTAPI
751  IN BOOLEAN DecreaseSize)
752 {
753  LARGE_INTEGER FuzzFactor, Size;
754 
755  /* Make sure there's at least 1 paging file and that we are system-managed */
757  ASSERT(!IsListEmpty(&SmpPagingFileDescriptorList));
758  ASSERT(Descriptor->Flags & SMP_PAGEFILE_SYSTEM_MANAGED); // Descriptor->SystemManaged == 1 in ASSERT.
759 
760  /* Keep decreasing the pagefile by this amount if we run out of space */
761  FuzzFactor.QuadPart = FUZZ_FACTOR;
762 
763  /* Create the descriptor for it (mainly the right sizes) and validate */
765  SmpValidatePagingFileSizes(Descriptor);
766 
767  /* Use either the minimum size in the descriptor, or 16MB in minimal mode */
768  Size.QuadPart = DecreaseSize ? 16 * MEGABYTE : Descriptor->MinSize.QuadPart;
769 
770  /* Check if this should be a fixed pagefile or an any pagefile*/
771  if (Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == '?')
772  {
773  /* Find a disk for it */
774  return SmpCreatePagingFileOnAnyDrive(Descriptor, &FuzzFactor, &Size);
775  }
776 
777  /* Use the disk that was given */
778  return SmpCreatePagingFileOnFixedDrive(Descriptor, &FuzzFactor, &Size);
779 }
780 
781 NTSTATUS
782 NTAPI
784 {
785  PSMP_PAGEFILE_DESCRIPTOR Descriptor;
786  WCHAR Buffer[32];
787 
788  /* Allocate a descriptor */
789  Descriptor = RtlAllocateHeap(RtlGetProcessHeap(),
791  sizeof(SMP_PAGEFILE_DESCRIPTOR));
792  if (!Descriptor) return STATUS_NO_MEMORY;
793 
794  /* Initialize it */
795  RtlInitUnicodeString(&Descriptor->Token, NULL);
796 
797  /* Copy the default pagefile name */
798  ASSERT(sizeof(Buffer) >= sizeof(STANDARD_PAGING_FILE_NAME));
800 
801  /* Fill the rest of the descriptor out */
802  RtlInitUnicodeString(&Descriptor->Name, Buffer);
803  Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = '?';
804  Descriptor->Flags |= SMP_PAGEFILE_SYSTEM_MANAGED |
807 
808  /* Insert it into the descriptor list */
809  InsertHeadList(&SmpPagingFileDescriptorList, &Descriptor->Entry);
811 
812  /* Go ahead and create it now, with the minimal size possible */
813  return SmpCreateSystemManagedPagingFile(Descriptor, TRUE);
814 }
815 
816 NTSTATUS
817 NTAPI
819 {
821  UNICODE_STRING VolumePath;
822  BOOLEAN BootVolumeFound = FALSE;
823  WCHAR StartChar, Drive, DriveDiff;
827  PROCESS_DEVICEMAP_INFORMATION ProcessInformation;
829  FILE_FS_SIZE_INFORMATION SizeInfo;
830  PSMP_VOLUME_DESCRIPTOR Volume;
831  LARGE_INTEGER FreeSpace, FinalFreeSpace;
832  WCHAR Buffer[32];
833 
834  /* We should be starting with an empty list */
835  ASSERT(IsListEmpty(&SmpVolumeDescriptorList));
836 
837  /* Query the device map so we can get the drive letters */
840  &ProcessInformation,
841  sizeof(ProcessInformation),
842  NULL);
843  if (!NT_SUCCESS(Status))
844  {
845  DPRINT1("SMSS:PFILE: Query(ProcessDeviceMap) failed with status %X\n",
846  Status);
847  return Status;
848  }
849 
850  /* Build the volume string, starting with A: (we'll edit this in place) */
851  wcscpy(Buffer, L"\\??\\A:\\");
852  RtlInitUnicodeString(&VolumePath, Buffer);
853 
854  /* Start with the C drive except on weird Japanese NECs... */
855  StartChar = SharedUserData->AlternativeArchitecture ? L'A' : L'C';
856  for (Drive = StartChar, DriveDiff = StartChar - L'A'; Drive <= L'Z'; Drive++, DriveDiff++)
857  {
858  /* Skip the disk if it's not in the drive map */
859  if (!((1 << DriveDiff) & ProcessInformation.Query.DriveMap)) continue;
860 
861  /* Write the drive letter and try to open the volume */
863  InitializeObjectAttributes(&ObjectAttributes,
864  &VolumePath,
866  NULL,
867  NULL);
868  Status = NtOpenFile(&VolumeHandle,
870  &ObjectAttributes,
871  &IoStatusBlock,
874  if (!NT_SUCCESS(Status))
875  {
876  /* Skip the volume if we failed */
877  DPRINT1("SMSS:PFILE: Open volume `%wZ' failed with status %X\n",
878  &VolumePath, Status);
879  continue;
880  }
881 
882  /* Now query device information on the volume */
883  Status = NtQueryVolumeInformationFile(VolumeHandle,
884  &IoStatusBlock,
885  &DeviceInfo,
886  sizeof(DeviceInfo),
888  if (!NT_SUCCESS(Status))
889  {
890  /* Move to the next volume if we failed */
891  DPRINT1("SMSS:PFILE: Query volume `%wZ' (handle %p) for device info"
892  " failed with status %X\n",
893  &VolumePath,
894  VolumeHandle,
895  Status);
896  NtClose(VolumeHandle);
897  continue;
898  }
899 
900  /* Check if this is a fixed disk */
901  if (DeviceInfo.Characteristics & (FILE_FLOPPY_DISKETTE |
905  {
906  /* It isn't, so skip it */
907  DPRINT1("SMSS:PFILE: Volume `%wZ' (%X) cannot store a paging file\n",
908  &VolumePath,
909  DeviceInfo.Characteristics);
910  NtClose(VolumeHandle);
911  continue;
912  }
913 
914  /* We found a fixed volume, allocate a descriptor for it */
915  Volume = RtlAllocateHeap(RtlGetProcessHeap(),
917  sizeof(SMP_VOLUME_DESCRIPTOR));
918  if (!Volume)
919  {
920  /* Failed to allocate memory, try the next disk */
921  DPRINT1("SMSS:PFILE: Failed to allocate a volume descriptor (%u bytes)\n",
922  sizeof(SMP_VOLUME_DESCRIPTOR));
923  NtClose(VolumeHandle);
924  continue;
925  }
926 
927  /* Save the drive letter and device information */
928  Volume->DriveLetter = Drive;
929  Volume->DeviceInfo = DeviceInfo;
930 
931  /* Check if this is the boot volume */
932  if (RtlUpcaseUnicodeChar(Drive) ==
933  RtlUpcaseUnicodeChar(SharedUserData->NtSystemRoot[0]))
934  {
935  /* Save it */
936  ASSERT(BootVolumeFound == FALSE);
937  Volume->Flags |= SMP_VOLUME_IS_BOOT;
938  BootVolumeFound = TRUE;
939  }
940 
941  /* Now get size information on the volume */
942  Status = NtQueryVolumeInformationFile(VolumeHandle,
943  &IoStatusBlock,
944  &SizeInfo,
945  sizeof(SizeInfo),
947  if (!NT_SUCCESS(Status))
948  {
949  /* We failed -- keep going */
950  DPRINT1("SMSS:PFILE: Query volume `%wZ' (handle %p) for size failed"
951  " with status %X\n",
952  &VolumePath,
953  VolumeHandle,
954  Status);
955  RtlFreeHeap(RtlGetProcessHeap(), 0, Volume);
956  NtClose(VolumeHandle);
957  continue;
958  }
959 
960  /* Done querying volume information, close the handle */
961  NtClose(VolumeHandle);
962 
963  /* Compute how much free space we have */
964  FreeSpace.QuadPart = SizeInfo.AvailableAllocationUnits.QuadPart *
965  SizeInfo.SectorsPerAllocationUnit;
966  FinalFreeSpace.QuadPart = FreeSpace.QuadPart * SizeInfo.BytesPerSector;
967 
968  /* Check if there's less than 32MB free so we don't starve the disk */
969  if (FinalFreeSpace.QuadPart <= MINIMUM_TO_KEEP_FREE)
970  {
971  /* In this case, act as if there's no free space */
972  Volume->FreeSpace.QuadPart = 0;
973  }
974  else
975  {
976  /* Trim off 32MB to give the disk a bit of breathing room */
977  Volume->FreeSpace.QuadPart = FinalFreeSpace.QuadPart -
979  }
980 
981  /* All done, add this volume to our descriptor list */
982  InsertTailList(&SmpVolumeDescriptorList, &Volume->Entry);
983  Volume->Flags |= SMP_VOLUME_INSERTED;
984  DPRINT("SMSS:PFILE: Created volume descriptor for`%wZ'\n", &VolumePath);
985  }
986 
987  /* We must've found at least the boot volume */
988  ASSERT(BootVolumeFound == TRUE);
989  ASSERT(!IsListEmpty(&SmpVolumeDescriptorList));
990  if (!IsListEmpty(&SmpVolumeDescriptorList)) return STATUS_SUCCESS;
991 
992  /* Something is really messed up if we found no disks at all */
994 }
995 
996 NTSTATUS
997 NTAPI
999 {
1000  NTSTATUS Status;
1001  PSMP_PAGEFILE_DESCRIPTOR Descriptor;
1002  LARGE_INTEGER Size, FuzzFactor;
1003  BOOLEAN Created = FALSE;
1004  PLIST_ENTRY NextEntry;
1005 
1006  /* Check if no paging files were requested */
1008  {
1009  /* The list should be empty -- nothing to do */
1010  ASSERT(IsListEmpty(&SmpPagingFileDescriptorList));
1011  DPRINT1("SMSS:PFILE: No paging file was requested\n");
1012  return STATUS_SUCCESS;
1013  }
1014 
1015  /* Initialize the volume descriptors so we can know what's available */
1016  Status = SmpCreateVolumeDescriptors();
1017  if (!NT_SUCCESS(Status))
1018  {
1019  /* We can't make decisions without this, so fail */
1020  DPRINT1("SMSS:PFILE: Failed to create volume descriptors (status %X)\n",
1021  Status);
1022  return Status;
1023  }
1024 
1025  /* If we fail creating pagefiles, try to reduce by this much each time */
1026  FuzzFactor.QuadPart = FUZZ_FACTOR;
1027 
1028  /* Loop the descriptor list */
1029  NextEntry = SmpPagingFileDescriptorList.Flink;
1030  while (NextEntry != &SmpPagingFileDescriptorList)
1031  {
1032  /* Check what kind of descriptor this is */
1033  Descriptor = CONTAINING_RECORD(NextEntry, SMP_PAGEFILE_DESCRIPTOR, Entry);
1034  if (Descriptor->Flags & SMP_PAGEFILE_SYSTEM_MANAGED)
1035  {
1036  /* This is a system-managed descriptor. Create the correct file */
1037  DPRINT("SMSS:PFILE: Creating a system managed paging file (`%wZ')\n",
1038  &Descriptor->Name);
1039  Status = SmpCreateSystemManagedPagingFile(Descriptor, FALSE);
1040  if (!NT_SUCCESS(Status))
1041  {
1042  /* We failed -- try again, with size minimization this time */
1043  DPRINT("SMSS:PFILE: Trying lower sizes for (`%wZ')\n",
1044  &Descriptor->Name);
1045  Status = SmpCreateSystemManagedPagingFile(Descriptor, TRUE);
1046  }
1047  }
1048  else
1049  {
1050  /* This is a manually entered descriptor. Validate its size first */
1051  SmpValidatePagingFileSizes(Descriptor);
1052 
1053  /* Check if this is an ANY pagefile or a FIXED pagefile */
1054  DPRINT("SMSS:PFILE: Creating a normal paging file (`%wZ')\n",
1055  &Descriptor->Name);
1056  if (Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == L'?')
1057  {
1058  /* It's an any pagefile, try to create it wherever possible */
1059  Size = Descriptor->MinSize;
1060  Status = SmpCreatePagingFileOnAnyDrive(Descriptor,
1061  &FuzzFactor,
1062  &Size);
1063  if (!NT_SUCCESS(Status))
1064  {
1065  /* We failed to create it. Try again with a smaller size */
1066  DPRINT("SMSS:PFILE: Trying lower sizes for (`%wZ')\n",
1067  &Descriptor->Name);
1068  Size.QuadPart = 16 * MEGABYTE;
1069  Status = SmpCreatePagingFileOnAnyDrive(Descriptor,
1070  &FuzzFactor,
1071  &Size);
1072  }
1073  }
1074  else
1075  {
1076  /* It's a fixed pagefile: override the minimum and use ours */
1077  Size.QuadPart = 16 * MEGABYTE;
1078  Status = SmpCreatePagingFileOnFixedDrive(Descriptor,
1079  &FuzzFactor,
1080  &Size);
1081  }
1082  }
1083 
1084  /* Go to the next descriptor */
1085  if (NT_SUCCESS(Status)) Created = TRUE;
1086  NextEntry = NextEntry->Flink;
1087  }
1088 
1089  /* Check if none of the code in our loops above was able to create it */
1090  if (!Created)
1091  {
1092  /* Build an emergency pagefile ourselves */
1093  DPRINT1("SMSS:PFILE: Creating emergency paging file.\n");
1094  Status = SmpCreateEmergencyPagingFile();
1095  }
1096 
1097  /* All done */
1098  return Status;
1099 }
NTSTATUS NTAPI SmpDeletePagingFile(IN PUNICODE_STRING FileName)
Definition: pagefile.c:284
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
#define MAXIMUM_PAGEFILE_SIZE
Definition: pagefile.c:24
NTSTATUS NTAPI SmpCreateEmergencyPagingFile(VOID)
Definition: pagefile.c:783
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STANDARD_PAGING_FILE_NAME
Definition: pagefile.c:21
ULONG SmpNumberOfPagingFiles
Definition: pagefile.c:69
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
__wchar_t WCHAR
Definition: xmlstorage.h:180
LIST_ENTRY SmpVolumeDescriptorList
Definition: pagefile.c:67
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
return STATUS_SUCCESS
Definition: btrfs.c:2690
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
NTSTATUS NTAPI SmpParseCommandLine(IN PUNICODE_STRING CommandLine, OUT PULONG Flags, OUT PUNICODE_STRING FileName, OUT PUNICODE_STRING Directory, OUT PUNICODE_STRING Arguments)
Definition: smutil.c:233
#define SMP_VOLUME_INSERTED
Definition: pagefile.c:54
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
NTSTATUS NTAPI NtQueryInformationProcess(IN HANDLE ProcessHandle, IN PROCESSINFOCLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: query.c:59
_In_ KPRIORITY Priority
Definition: kefuncs.h:516
NTSTATUS NTAPI SmpGetVolumeFreeSpace(IN PSMP_VOLUME_DESCRIPTOR Volume)
Definition: pagefile.c:338
NTSTATUS NTAPI SmpCreatePagingFileOnFixedDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize)
Definition: pagefile.c:479
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define InsertTailList(ListHead, Entry)
#define WCHAR
Definition: msvc.h:43
NTSYSAPI WCHAR NTAPI RtlUpcaseUnicodeChar(WCHAR Source)
#define SMP_VOLUME_IS_BOOT
Definition: pagefile.c:56
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define FILE_SHARE_READ
Definition: compat.h:125
#define STATUS_TOO_MANY_PAGING_FILES
Definition: ntstatus.h:373
#define MEGABYTE
Definition: pagefile.c:23
VOID NTAPI SmpPagingFileInitialize(VOID)
Definition: pagefile.c:75
VOID NTAPI SmpMakeSystemManagedPagingFileDescriptor(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
Definition: pagefile.c:659
NTSTATUS NTAPI SmpCreateSystemManagedPagingFile(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN BOOLEAN DecreaseSize)
Definition: pagefile.c:750
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define SMP_PAGEFILE_WAS_TOO_BIG
Definition: pagefile.c:35
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
struct _SMP_PAGEFILE_DESCRIPTOR * PSMP_PAGEFILE_DESCRIPTOR
#define FALSE
Definition: types.h:117
PWCHAR Drive
Definition: chkdsk.c:70
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
LARGE_INTEGER AvailableAllocationUnits
Definition: from_kernel.h:264
NTSTATUS NTAPI NtCreatePagingFile(IN PUNICODE_STRING FileName, IN PLARGE_INTEGER InitialSize, IN PLARGE_INTEGER MaximumSize, IN ULONG Reserved)
Definition: pagefile.c:364
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI SmpCreatePagingFileOnAnyDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize)
Definition: pagefile.c:611
NTSTATUS NTAPI NtQueryVolumeInformationFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FsInformation, IN ULONG Length, IN FS_INFORMATION_CLASS FsInformationClass)
Definition: iofunc.c:3833
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
struct _SMP_PAGEFILE_DESCRIPTOR SMP_PAGEFILE_DESCRIPTOR
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define SMP_VOLUME_PAGEFILE_CREATED
Definition: pagefile.c:55
#define NtCurrentProcess()
Definition: nt_native.h:1657
UINTN Size
Definition: acefiex.h:555
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
int64_t LONGLONG
Definition: typedefs.h:66
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3508
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
UNICODE_STRING Token
Definition: pagefile.c:43
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
BOOLEAN NTAPI SmpCheckForCrashDump(IN PUNICODE_STRING FileName)
Definition: crashdmp.c:20
uint64_t ULONGLONG
Definition: typedefs.h:65
struct _DeviceInfo DeviceInfo
struct _SMP_VOLUME_DESCRIPTOR * PSMP_VOLUME_DESCRIPTOR
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2284
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
LARGE_INTEGER AllocationSize
Definition: nt_native.h:947
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3393
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
_In_ PUNICODE_STRING Name
Definition: mrx.h:218
#define SharedUserData
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1087
#define FILE_REMOTE_DEVICE
Definition: nt_native.h:811
#define SMP_PAGEFILE_SYSTEM_MANAGED
Definition: pagefile.c:34
NTSTATUS NTAPI SmpCreatePagingFiles(VOID)
Definition: pagefile.c:998
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
Definition: typedefs.h:117
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
#define SYNCHRONIZE
Definition: nt_native.h:61
LARGE_INTEGER MinSize
Definition: pagefile.c:44
#define SMP_PAGEFILE_ON_ANY_DRIVE
Definition: pagefile.c:36
Status
Definition: gdiplustypes.h:24
#define STANDARD_DRIVE_LETTER_OFFSET
Definition: pagefile.c:22
FILE_FS_DEVICE_INFORMATION DeviceInfo
Definition: pagefile.c:64
static HANDLE FileHandle
Definition: cabinet.c:48
PSMP_VOLUME_DESCRIPTOR NTAPI SmpSearchVolumeDescriptor(IN WCHAR DriveLetter)
Definition: pagefile.c:416
DWORD *typedef HANDLE
Definition: winlogon.h:60
unsigned short USHORT
Definition: pedump.c:61
#define PF_PAE_ENABLED
struct _SMP_VOLUME_DESCRIPTOR SMP_VOLUME_DESCRIPTOR
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define SystemBasicInformation
Definition: xboxvmp.h:35
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
NTSTATUS NTAPI SmpGetPagingFileSize(IN PUNICODE_STRING FileName, OUT PLARGE_INTEGER Size)
Definition: pagefile.c:239
VOID NTAPI SmpMakeDefaultPagingFileDescriptor(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
Definition: pagefile.c:649
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:360
#define STATUS_UNEXPECTED_IO_ERROR
Definition: ntstatus.h:455
struct _PROCESS_DEVICEMAP_INFORMATION::@3714::@3716 Query
#define DPRINT1
Definition: precomp.h:8
LARGE_INTEGER ActualMinSize
Definition: pagefile.c:46
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
LARGE_INTEGER FreeSpace
Definition: pagefile.c:63
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
#define OUT
Definition: typedefs.h:39
NTSTATUS NTAPI SmpCreatePagingFile(IN PUNICODE_STRING Name, IN PLARGE_INTEGER MinSize, IN PLARGE_INTEGER MaxSize, IN ULONG Priority)
Definition: pagefile.c:448
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
LIST_ENTRY SmpPagingFileDescriptorList
Definition: pagefile.c:67
#define c
Definition: ke_i.h:80
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define SMP_PAGEFILE_CREATED
Definition: pagefile.c:32
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
LIST_ENTRY Entry
Definition: pagefile.c:59
#define SMP_PAGEFILE_EMERGENCY
Definition: pagefile.c:37
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
NTSTATUS NTAPI SmpValidatePagingFileSizes(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
Definition: pagefile.c:693
LARGE_INTEGER MaxSize
Definition: pagefile.c:45
NTSTATUS NTAPI SmpCreatePagingFileDescriptor(IN PUNICODE_STRING PageFileToken)
Definition: pagefile.c:84
#define SMP_PAGEFILE_DEFAULT
Definition: pagefile.c:33
LARGE_INTEGER ActualMaxSize
Definition: pagefile.c:47
base of all file and directory entries
Definition: entries.h:82
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:2854
#define SMP_PAGEFILE_DUMP_PROCESSED
Definition: pagefile.c:38
#define FILE_READ_ONLY_DEVICE
Definition: nt_native.h:808
#define FUZZ_FACTOR
Definition: pagefile.c:27
UNICODE_STRING Name
Definition: pagefile.c:42
#define DELETE
Definition: nt_native.h:57
LONGLONG QuadPart
Definition: typedefs.h:112
#define MINIMUM_TO_KEEP_FREE
Definition: pagefile.c:26
NTSTATUS NTAPI SmpCreateVolumeDescriptors(VOID)
Definition: pagefile.c:818
BOOLEAN SmpRegistrySpecifierPresent
Definition: pagefile.c:68
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966