ReactOS  0.4.14-dev-41-g31d7680
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 */
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  {
207  }
208 
209  /* Now loop the existing descriptors */
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! */
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) ||
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 
252  FileName,
254  NULL,
255  NULL);
259  &IoStatusBlock,
262  if (!NT_SUCCESS(Status)) return Status;
263 
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);
274  return Status;
275  }
276 
278  Size->QuadPart = StandardInfo.AllocationSize.QuadPart;
279  return STATUS_SUCCESS;
280 }
281 
282 NTSTATUS
283 NTAPI
285 {
291 
292  /* Open the page file */
294  FileName,
296  NULL,
297  NULL);
299  DELETE,
301  &IoStatusBlock,
304  if (NT_SUCCESS(Status))
305  {
306  /* Delete it */
307  Disposition.DeleteFile = TRUE;
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 */
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
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);
354  DPRINT("SMSS:PFILE: Querying volume `%wZ' for free space\n", &VolumeName);
355 
356  /* Open the volume */
358  &VolumeName,
360  NULL,
361  NULL);
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 */
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);
389  return Status;
390  }
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 
415 NTAPI
417 {
418  WCHAR UpLetter;
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 */
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 {
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;
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);
510 
511  /* Update how much free space we have now that we extracted a dump */
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 */
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 */
571  &Descriptor->ActualMinSize,
572  &Descriptor->ActualMaxSize,
573  0);
574  if (NT_SUCCESS(Status))
575  {
576  /* We're done, update flags and increase the count */
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  {
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);
603  }
604 
605  /* Return the status */
606  return Status;
607 }
608 
609 NTSTATUS
610 NTAPI
612  IN PLARGE_INTEGER FuzzFactor,
613  IN PLARGE_INTEGER MinimumSize)
614 {
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 */
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;
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 */
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;
689 }
690 
691 NTSTATUS
692 NTAPI
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);
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 */
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 */
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 {
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 */
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 */
803  Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = '?';
807 
808  /* Insert it into the descriptor list */
811 
812  /* Go ahead and create it now, with the minimal size possible */
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;
831  LARGE_INTEGER FreeSpace, FinalFreeSpace;
832  WCHAR Buffer[32];
833 
834  /* We should be starting with an empty list */
836 
837  /* Query the device map so we can get the drive letters */
840  &ProcessInformation.Query,
841  sizeof(ProcessInformation.Query),
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 */
864  &VolumePath,
866  NULL,
867  NULL);
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 */
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);
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);
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));
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 */
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 */
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);
957  continue;
958  }
959 
960  /* Done querying volume information, close the handle */
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 */
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);
991 
992  /* Something is really messed up if we found no disks at all */
994 }
995 
996 NTSTATUS
997 NTAPI
999 {
1000  NTSTATUS Status;
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 */
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 */
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 */
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);
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);
1046  }
1047  }
1048  else
1049  {
1050  /* This is a manually entered descriptor. Validate its size first */
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;
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;
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;
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");
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
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LIST_ENTRY SmpVolumeDescriptorList
Definition: pagefile.c:67
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
#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
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
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)
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
HANDLE FileHandle
Definition: stats.c:38
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
#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
PWCHAR Drive
Definition: chkdsk.c:73
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
LARGE_INTEGER AvailableAllocationUnits
Definition: from_kernel.h:264
unsigned char BOOLEAN
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:4084
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
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
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:3951
__wchar_t WCHAR
Definition: xmlstorage.h:180
UNICODE_STRING Token
Definition: pagefile.c:43
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN NTAPI SmpCheckForCrashDump(IN PUNICODE_STRING FileName)
Definition: crashdmp.c:20
uint64_t ULONGLONG
Definition: typedefs.h:65
const GLubyte * c
Definition: glext.h:8905
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: propsheet.cpp:54
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#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:1250
#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)
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#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
PSMP_VOLUME_DESCRIPTOR NTAPI SmpSearchVolumeDescriptor(IN WCHAR DriveLetter)
Definition: pagefile.c:416
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
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
#define DPRINT1
Definition: precomp.h:8
#define FileStandardInformation
Definition: propsheet.cpp:61
LARGE_INTEGER ActualMinSize
Definition: pagefile.c:46
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
LARGE_INTEGER FreeSpace
Definition: pagefile.c:63
NTSTATUS NTAPI NtCreatePagingFile(IN PUNICODE_STRING FileName, IN PLARGE_INTEGER MinimumSize, IN PLARGE_INTEGER MaximumSize, IN ULONG Reserved)
Definition: pagefile.c:349
_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
return STATUS_SUCCESS
Definition: btrfs.c:2966
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:3042
#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
struct _PROCESS_DEVICEMAP_INFORMATION::@3781::@3783 Query
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