ReactOS 0.4.15-dev-7842-g558ab78
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 MAX_PAGING_FILES 16 // See also ntoskrnl/include/internal/mm.h
24#define MEGABYTE (1024 * 1024)
25
26/* Minimum pagefile size is 256 pages (1 MB) */
27// #define MINIMUM_PAGEFILE_SIZE (256ULL * PAGE_SIZE)
28
29/* Maximum pagefile sizes for different architectures */
30#define GIGABYTE (1024ULL * MEGABYTE)
31#define TERABYTE (1024ULL * GIGABYTE)
32
33// NOTE: No changes for NTDDI_WIN10
34#if (NTDDI_VERSION >= NTDDI_WINBLUE) // NTDDI_WIN81
35#define MAXIMUM_PAGEFILE_SIZE32 ((1ULL * 1024 * 1024 - 1) * PAGE_SIZE)
36 // PAGE_ROUND_DOWN(4ULL * GIGABYTE - 1)
37#else
38/* 4095 MB */
39#define MAXIMUM_PAGEFILE_SIZE32 (4095ULL * MEGABYTE)
40#endif
41
42// NOTE: No changes for NTDDI_WIN10
43#if (NTDDI_VERSION >= NTDDI_WINBLUE) // NTDDI_WIN81
44#define MAXIMUM_PAGEFILE_SIZE64 ((4ULL * 1024 * 1024 * 1024 - 1) * PAGE_SIZE)
45 // PAGE_ROUND_DOWN(16ULL * TERABYTE - 1)
46#else
47/* 16 TB */
48#define MAXIMUM_PAGEFILE_SIZE64 (16ULL * TERABYTE)
49#endif
50
51#if defined(_M_IX86)
52 #define MAXIMUM_PAGEFILE_SIZE MAXIMUM_PAGEFILE_SIZE32
53 /* PAE uses the same size as x64 */
54 #define MAXIMUM_PAGEFILE_SIZE_PAE MAXIMUM_PAGEFILE_SIZE64
55#elif defined (_M_AMD64) || defined(_M_ARM64)
56 #define MAXIMUM_PAGEFILE_SIZE MAXIMUM_PAGEFILE_SIZE64
57#elif defined (_M_IA64)
58/* 32 TB */
59 #define MAXIMUM_PAGEFILE_SIZE (32ULL * TERABYTE)
60#elif defined(_M_ARM)
61/* Around 2 GB */
62 // NOTE: No changes for NTDDI_WIN10
63 #if (NTDDI_VERSION >= NTDDI_WINBLUE) // NTDDI_WIN81
64 #define MAXIMUM_PAGEFILE_SIZE ((512ULL * 1024 - 1) * PAGE_SIZE)
65 // PAGE_ROUND_DOWN(2ULL * GIGABYTE - 1)
66 #else
67/* 4095 MB */
68 #define MAXIMUM_PAGEFILE_SIZE MAXIMUM_PAGEFILE_SIZE32
69 #endif
70#else
71/* On unknown architectures, default to either one of the 32 or 64 bit sizes */
72#pragma message("Unknown architecture")
73 #ifdef _WIN64
74 #define MAXIMUM_PAGEFILE_SIZE MAXIMUM_PAGEFILE_SIZE64
75 #else
76 #define MAXIMUM_PAGEFILE_SIZE MAXIMUM_PAGEFILE_SIZE32
77 #endif
78#endif
79
80/* This should be 32 MB, but we need more than that for 2nd stage setup */
81#define MINIMUM_TO_KEEP_FREE (256 * MEGABYTE)
82#define FUZZ_FACTOR (16 * MEGABYTE)
83
84//
85// Structure and flags describing each pagefile
86//
87#define SMP_PAGEFILE_CREATED 0x01
88#define SMP_PAGEFILE_DEFAULT 0x02
89#define SMP_PAGEFILE_SYSTEM_MANAGED 0x04
90#define SMP_PAGEFILE_WAS_TOO_BIG 0x08
91#define SMP_PAGEFILE_ON_ANY_DRIVE 0x10
92#define SMP_PAGEFILE_EMERGENCY 0x20
93#define SMP_PAGEFILE_DUMP_PROCESSED 0x40
95{
105
106//
107// Structure and flags describing each volume
108//
109#define SMP_VOLUME_INSERTED 0x01
110#define SMP_VOLUME_PAGEFILE_CREATED 0x04
111#define SMP_VOLUME_IS_BOOT 0x08
113{
121
125
126/* FUNCTIONS ******************************************************************/
127
128VOID
129NTAPI
131{
132 /* Initialize the two lists */
135}
136
138NTAPI
140{
142 ULONG MinSize = 0, MaxSize = 0;
143 BOOLEAN SystemManaged = FALSE, ZeroSize = TRUE;
144 PSMP_PAGEFILE_DESCRIPTOR Descriptor, ListDescriptor;
145 ULONG i;
146 WCHAR c;
147 PLIST_ENTRY NextEntry;
148 UNICODE_STRING PageFileName, Arguments, SecondArgument;
149
150 /* Make sure we don't have too many */
152 {
153 DPRINT1("SMSS:PFILE: Too many paging files specified - %lu\n",
156 }
157
158 /* Parse the specified and get the name and arguments out of it */
159 DPRINT("SMSS:PFILE: Paging file specifier `%wZ'\n", PageFileToken);
160 Status = SmpParseCommandLine(PageFileToken,
161 NULL,
162 &PageFileName,
163 NULL,
164 &Arguments);
165 if (!NT_SUCCESS(Status))
166 {
167 /* Fail */
168 DPRINT1("SMSS:PFILE: SmpParseCommandLine(%wZ) failed - Status == %lx\n",
169 PageFileToken, Status);
170 return Status;
171 }
172
173 /* Set the variable to let everyone know we have a pagefile token */
175
176 /* Parse the arguments, if any */
177 if (Arguments.Buffer)
178 {
179 /* Parse the pagefile size */
180 for (i = 0; i < Arguments.Length / sizeof(WCHAR); i++)
181 {
182 /* Check if it's zero */
183 c = Arguments.Buffer[i];
184 if ((c != L' ') && (c != L'\t') && (c != L'0'))
185 {
186 /* It isn't, break out */
187 ZeroSize = FALSE;
188 break;
189 }
190 }
191 }
192
193 /* Was a pagefile not specified, or was it specified with no size? */
194 if (!(Arguments.Buffer) || (ZeroSize))
195 {
196 /* In this case, the system will manage its size */
197 SystemManaged = TRUE;
198 }
199 else
200 {
201 /* We do have a size, so convert the arguments into a number */
202 Status = RtlUnicodeStringToInteger(&Arguments, 0, &MinSize);
203 if (!NT_SUCCESS(Status))
204 {
205 /* Fail */
206 RtlFreeUnicodeString(&PageFileName);
207 RtlFreeUnicodeString(&Arguments);
208 return Status;
209 }
210
211 /* Now advance to the next argument */
212 for (i = 0; i < Arguments.Length / sizeof(WCHAR); i++)
213 {
214 /* Found a space -- second argument must start here */
215 if (Arguments.Buffer[i] == L' ')
216 {
217 /* Use the rest of the arguments as a maximum size */
218 SecondArgument.Buffer = &Arguments.Buffer[i];
219 SecondArgument.Length = (USHORT)(Arguments.Length -
220 i * sizeof(WCHAR));
221 SecondArgument.MaximumLength = (USHORT)(Arguments.MaximumLength -
222 i * sizeof(WCHAR));
223 Status = RtlUnicodeStringToInteger(&SecondArgument, 0, &MaxSize);
224 if (!NT_SUCCESS(Status))
225 {
226 /* Fail */
227 RtlFreeUnicodeString(&PageFileName);
228 RtlFreeUnicodeString(&Arguments);
229 return Status;
230 }
231
232 break;
233 }
234 }
235 }
236
237 /* We are done parsing arguments */
238 RtlFreeUnicodeString(&Arguments);
239
240 /* Now we can allocate our descriptor */
241 Descriptor = RtlAllocateHeap(RtlGetProcessHeap(),
244 if (!Descriptor)
245 {
246 /* Fail if we couldn't */
247 RtlFreeUnicodeString(&PageFileName);
248 return STATUS_NO_MEMORY;
249 }
250
251 /* Capture all our data into the descriptor */
252 Descriptor->Token = *PageFileToken;
253 Descriptor->Name = PageFileName;
254 Descriptor->MinSize.QuadPart = MinSize * MEGABYTE;
255 Descriptor->MaxSize.QuadPart = MaxSize * MEGABYTE;
256 if (SystemManaged)
260 if (Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == '?')
261 {
263 }
264
265 /* Now loop the existing descriptors */
267 do
268 {
269 /* Are there none, or have we looped back to the beginning? */
270 if (NextEntry == &SmpPagingFileDescriptorList)
271 {
272 /* This means no duplicates exist, so insert our descriptor! */
275 DPRINT("SMSS:PFILE: Created descriptor for `%wZ' (`%wZ')\n",
276 PageFileToken, &Descriptor->Name);
277 return STATUS_SUCCESS;
278 }
279
280 /* Keep going until we find a duplicate, unless we are in "any" mode */
281 ListDescriptor = CONTAINING_RECORD(NextEntry, SMP_PAGEFILE_DESCRIPTOR, Entry);
282 NextEntry = NextEntry->Flink;
283 } while (!(ListDescriptor->Flags & SMP_PAGEFILE_ON_ANY_DRIVE) ||
285
286 /* We found a duplicate, so skip this descriptor/pagefile and fail */
287 DPRINT1("SMSS:PFILE: Skipping duplicate specifier `%wZ'\n", PageFileToken);
288 RtlFreeUnicodeString(&PageFileName);
289 RtlFreeHeap(RtlGetProcessHeap(), 0, Descriptor);
291}
292
294NTAPI
297{
302 FILE_STANDARD_INFORMATION StandardInfo;
303
304 DPRINT("SMSS:PFILE: Trying to get size for `%wZ'\n", FileName);
305 Size->QuadPart = 0;
306
308 FileName,
310 NULL,
311 NULL);
318 if (!NT_SUCCESS(Status)) return Status;
319
322 &StandardInfo,
323 sizeof(StandardInfo),
325 if (!NT_SUCCESS(Status))
326 {
327 DPRINT1("SMSS:PFILE: Failed query for size potential pagefile `%wZ' with status %X\n",
330 return Status;
331 }
332
334 Size->QuadPart = StandardInfo.AllocationSize.QuadPart;
335 return STATUS_SUCCESS;
336}
337
339NTAPI
341{
347
348 /* Open the page file */
350 FileName,
352 NULL,
353 NULL);
355 DELETE,
360 if (NT_SUCCESS(Status))
361 {
362 /* Delete it */
363 Disposition.DeleteFile = TRUE;
367 sizeof(Disposition),
369 if (!NT_SUCCESS(Status))
370 {
371 DPRINT1("SMSS:PFILE: Failed to delete page file `%wZ' (status %X)\n",
373 }
374 else
375 {
376 DPRINT("SMSS:PFILE: Deleted stale paging file - %wZ\n", FileName);
377 }
378
379 /* Close the handle */
381 }
382 else
383 {
384 DPRINT1("SMSS:PFILE: Failed to open for deletion page file `%wZ' (status %X)\n",
386 }
387
388 /* All done */
389 return Status;
390}
391
393NTAPI
395{
397 LARGE_INTEGER FreeSpace, FinalFreeSpace;
403 WCHAR PathString[32];
404 ASSERT(Volume->Flags & SMP_VOLUME_IS_BOOT); // ASSERT says "BootVolume == 1"
405
406 /* Build the standard path */
407 wcscpy(PathString, L"\\??\\A:\\");
408 RtlInitUnicodeString(&VolumeName, PathString);
410 DPRINT("SMSS:PFILE: Querying volume `%wZ' for free space\n", &VolumeName);
411
412 /* Open the volume */
414 &VolumeName,
416 NULL,
417 NULL);
424 if (!NT_SUCCESS(Status))
425 {
426 DPRINT1("SMSS:PFILE: Open volume `%wZ' failed with status %X\n", &VolumeName, Status);
427 return Status;
428 }
429
430 /* Now get size information on the volume */
433 &SizeInfo,
434 sizeof(SizeInfo),
436 if (!NT_SUCCESS(Status))
437 {
438 /* We failed */
439 DPRINT1("SMSS:PFILE: Query volume `%wZ' (handle %p) for size failed"
440 " with status %X\n",
441 &VolumeName,
443 Status);
445 return Status;
446 }
448
449 /* Compute how much free space we have */
450 FreeSpace.QuadPart = SizeInfo.AvailableAllocationUnits.QuadPart *
452 FinalFreeSpace.QuadPart = FreeSpace.QuadPart * SizeInfo.BytesPerSector;
453
454 /* Check if there is less than 32 MB free so we don't starve the disk */
455 if (FinalFreeSpace.QuadPart <= MINIMUM_TO_KEEP_FREE)
456 {
457 /* In this case, act as if there is no free space */
458 Volume->FreeSpace.QuadPart = 0;
459 }
460 else
461 {
462 /* Trim off 32 MB to give the disk a bit of breathing room */
463 Volume->FreeSpace.QuadPart = FinalFreeSpace.QuadPart -
465 }
466
467 return STATUS_SUCCESS;
468}
469
471NTAPI
473{
474 WCHAR UpLetter;
476 PLIST_ENTRY NextEntry;
477
478 /* Use upper case to reduce differences */
479 UpLetter = RtlUpcaseUnicodeChar(DriveLetter);
480
481 /* Loop each volume */
482 NextEntry = SmpVolumeDescriptorList.Flink;
483 while (NextEntry != &SmpVolumeDescriptorList)
484 {
485 /* Grab the entry */
487
488 /* Make sure it's a valid entry with an uppcase drive letter */
489 ASSERT(Volume->Flags & SMP_VOLUME_INSERTED); // Volume->Initialized in ASSERT
490 ASSERT(Volume->DriveLetter >= L'A' && Volume->DriveLetter <= L'Z');
491
492 /* Break if it matches, if not, keep going */
493 if (Volume->DriveLetter == UpLetter) break;
494 NextEntry = NextEntry->Flink;
495 }
496
497 /* Return the volume if one was found */
498 if (NextEntry == &SmpVolumeDescriptorList) Volume = NULL;
499 return Volume;
500}
501
503NTAPI
505 IN PLARGE_INTEGER MinSize,
506 IN PLARGE_INTEGER MaxSize,
508{
510
511 /* Tell the kernel to create the pagefile */
512 Status = NtCreatePagingFile(Name, MinSize, MaxSize, Priority);
513 if (NT_SUCCESS(Status))
514 {
515 DPRINT("SMSS:PFILE: NtCreatePagingFile(%wZ, 0x%I64X, 0x%I64X) succeeded\n",
516 Name,
517 MinSize->QuadPart,
518 MaxSize->QuadPart);
519 }
520 else
521 {
522 DPRINT1("SMSS:PFILE: NtCreatePagingFile(%wZ, 0x%I64X, 0x%I64X) failed with %X\n",
523 Name,
524 MinSize->QuadPart,
525 MaxSize->QuadPart,
526 Status);
527 }
528
529 /* Return the status */
530 return Status;
531}
532
534NTAPI
536 IN PLARGE_INTEGER FuzzFactor,
537 IN PLARGE_INTEGER MinimumSize)
538{
540 BOOLEAN ShouldDelete;
542 LARGE_INTEGER PageFileSize;
543 ASSERT(Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] != L'?');
544
545 /* Try to find the volume descriptor for this drive letter */
546 ShouldDelete = FALSE;
548 if (!Volume)
549 {
550 /* Couldn't find it, fail */
551 DPRINT1("SMSS:PFILE: No volume descriptor for `%wZ'\n",
552 &Descriptor->Name);
554 }
555
556 /* Check if this is the boot volume */
557 if (Volume->Flags & SMP_VOLUME_IS_BOOT)
558 {
559 /* Check if we haven't yet processed a crash dump on this volume */
561 {
562 /* Try to find a crash dump and extract it */
563 DPRINT("SMSS:PFILE: Checking for crash dump in `%wZ' on boot volume\n",
564 &Descriptor->Name);
566
567 /* Update how much free space we have now that we extracted a dump */
569 if (!NT_SUCCESS(Status))
570 {
571 DPRINT1("SMSS:PFILE: Failed to query free space for boot volume `%wC'\n",
572 Volume->DriveLetter);
573 }
574 else
575 {
576 DPRINT("Queried free space for boot volume `%wC: 0x%I64x'\n",
577 Volume->DriveLetter, Volume->FreeSpace.QuadPart);
578 }
579
580 /* Don't process crashdump on this volume anymore */
582 }
583 }
584 else
585 {
586 /* Crashdumps can only be on the boot volume */
587 DPRINT("SMSS:PFILE: Skipping crash dump checking for `%wZ' on non boot"
588 "volume `%wC'\n",
589 &Descriptor->Name,
590 Volume->DriveLetter);
591 }
592
593 /* Update the size after dump extraction */
594 Descriptor->ActualMinSize = Descriptor->MinSize;
595 Descriptor->ActualMaxSize = Descriptor->MaxSize;
596
597 /* Check how big we can make the pagefile */
598 Status = SmpGetPagingFileSize(&Descriptor->Name, &PageFileSize);
599 if (NT_SUCCESS(Status) && PageFileSize.QuadPart > 0) ShouldDelete = TRUE;
600 DPRINT("SMSS:PFILE: Detected size 0x%I64X for future paging file `%wZ'\n",
601 PageFileSize,
602 &Descriptor->Name);
603 DPRINT("SMSS:PFILE: Free space on volume `%wC' is 0x%I64X\n",
604 Volume->DriveLetter,
605 Volume->FreeSpace.QuadPart);
606
607 /* Now update our size and make sure none of these are too big */
608 PageFileSize.QuadPart += Volume->FreeSpace.QuadPart;
609 if (Descriptor->ActualMinSize.QuadPart > PageFileSize.QuadPart)
610 {
611 Descriptor->ActualMinSize = PageFileSize;
612 }
613 if (Descriptor->ActualMaxSize.QuadPart > PageFileSize.QuadPart)
614 {
615 Descriptor->ActualMaxSize = PageFileSize;
616 }
617 DPRINT("SMSS:PFILE: min 0x%I64X, max 0x%I64X, real min 0x%I64X\n",
618 Descriptor->ActualMinSize.QuadPart,
619 Descriptor->ActualMaxSize.QuadPart,
620 MinimumSize->QuadPart);
621
622 /* Keep going until we've created a pagefile of the right size */
623 while (Descriptor->ActualMinSize.QuadPart >= MinimumSize->QuadPart)
624 {
625 /* Call NT to do it */
627 &Descriptor->ActualMinSize,
628 &Descriptor->ActualMaxSize,
629 0);
630 if (NT_SUCCESS(Status))
631 {
632 /* We're done, update flags and increase the count */
635 Volume->PageFileCount++;
636 break;
637 }
638
639 /* We failed, try a slightly smaller pagefile */
640 Descriptor->ActualMinSize.QuadPart -= FuzzFactor->QuadPart;
641 }
642
643 /* Check if we weren't able to create it */
644 if (Descriptor->ActualMinSize.QuadPart < MinimumSize->QuadPart)
645 {
646 /* Delete the current page file and fail */
647 if (ShouldDelete)
648 {
650
651 /* FIXFIX: Windows Vista does this, and it seems like we should too, so try to see if this fixes KVM */
652 Volume->FreeSpace.QuadPart = PageFileSize.QuadPart;
653 }
654 DPRINT1("SMSS:PFILE: Failing for min 0x%I64X, max 0x%I64X, real min 0x%I64X\n",
655 Descriptor->ActualMinSize.QuadPart,
656 Descriptor->ActualMaxSize.QuadPart,
657 MinimumSize->QuadPart);
659 }
660
661 /* Return the status */
662 return Status;
663}
664
666NTAPI
668 IN PLARGE_INTEGER FuzzFactor,
669 IN PLARGE_INTEGER MinimumSize)
670{
673 PLIST_ENTRY NextEntry;
674 ASSERT(Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == L'?');
675
676 /* Loop the volume list */
677 NextEntry = SmpVolumeDescriptorList.Flink;
678 while (NextEntry != &SmpVolumeDescriptorList)
679 {
680 /* Get the volume */
682
683 /* Make sure it's inserted and on a valid drive letter */
684 ASSERT(Volume->Flags & SMP_VOLUME_INSERTED); // Volume->Initialized in ASSERT
685 ASSERT(Volume->DriveLetter >= L'A' && Volume->DriveLetter <= L'Z');
686
687 /* Write the drive letter to try creating it on this volume */
688 Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = Volume->DriveLetter;
690 FuzzFactor,
691 MinimumSize);
692 if (NT_SUCCESS(Status)) break;
693
694 /* It didn't work, make it an any pagefile again and keep going */
695 Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = L'?';
696 NextEntry = NextEntry->Flink;
697 }
698
699 /* Return disk full or success */
700 return Status;
701}
702
703VOID
704NTAPI
706{
707 /* The default descriptor uses 128 MB as a pagefile size */
709 Descriptor->MinSize.QuadPart = 128 * MEGABYTE;
710 Descriptor->MaxSize.QuadPart = 128 * MEGABYTE;
711}
712
713VOID
714NTAPI
716{
718 ULONGLONG MinimumSize, MaximumSize, Ram;
719 SYSTEM_BASIC_INFORMATION BasicInfo;
720
721 /* Query the page size of the system, and the amount of RAM */
723 &BasicInfo,
724 sizeof(BasicInfo),
725 NULL);
726 if (!NT_SUCCESS(Status))
727 {
728 /* If we failed, use defaults since we have no idea otherwise */
729 DPRINT1("SMSS:PFILE: NtQuerySystemInformation failed with %x\n", Status);
731 return;
732 }
733
734 /* Check how much RAM we have and set three times this amount as maximum */
735 Ram = BasicInfo.NumberOfPhysicalPages * BasicInfo.PageSize;
736 MaximumSize = 3 * Ram;
737
738 /* If we have more than 1GB, use that as minimum, otherwise, use 1.5X RAM */
739 MinimumSize = (Ram >= 1024 * MEGABYTE) ? Ram : MaximumSize / 2;
740
741 /* Write the new sizes in the descriptor and mark it as system managed */
742 Descriptor->MinSize.QuadPart = MinimumSize;
743 Descriptor->MaxSize.QuadPart = MaximumSize;
745}
746
748NTAPI
750{
752 BOOLEAN WasTooBig = FALSE;
753 ULONGLONG MinSize, MaxSize;
754#ifdef _M_IX86
755 ULONGLONG MaxPageFileSize =
756 (SharedUserData->ProcessorFeatures[PF_PAE_ENABLED])
757 ? MAXIMUM_PAGEFILE_SIZE_PAE : MAXIMUM_PAGEFILE_SIZE;
758#else
759 static const ULONGLONG MaxPageFileSize = MAXIMUM_PAGEFILE_SIZE;
760#endif
761
762 /* Capture the min and max */
763 MinSize = Descriptor->MinSize.QuadPart;
764 MaxSize = Descriptor->MaxSize.QuadPart;
765
766 DPRINT("SMSS:PFILE: Validating sizes for `%wZ' 0x%I64X 0x%I64X\n",
767 &Descriptor->Name, MinSize, MaxSize);
768
769 /* Don't let minimum be bigger than maximum */
770 if (MinSize > MaxSize)
771 MaxSize = MinSize;
772
773 /* Validate the minimum and maximum and trim them if they are too large */
774 if (MinSize > MaxPageFileSize)
775 {
776 WasTooBig = TRUE;
777 MinSize = MaxPageFileSize;
778 }
779 if (MaxSize > MaxPageFileSize)
780 {
781 WasTooBig = TRUE;
782 MaxSize = MaxPageFileSize;
783 }
784
785 /* If we trimmed, write a flag in the descriptor */
786 if (WasTooBig)
787 {
788 DPRINT("SMSS:PFILE: Trimmed size of `%wZ' to maximum allowed\n",
789 &Descriptor->Name);
791 }
792
793 /* Now write the (possibly trimmed) sizes back */
794 Descriptor->MinSize.QuadPart = MinSize;
795 Descriptor->MaxSize.QuadPart = MaxSize;
796 return Status;
797}
798
800NTAPI
802 IN BOOLEAN DecreaseSize)
803{
804 LARGE_INTEGER FuzzFactor, Size;
805
806 /* Make sure there is at least 1 paging file and that we are system-managed */
810
811 /* Keep decreasing the pagefile by this amount if we run out of space */
812 FuzzFactor.QuadPart = FUZZ_FACTOR;
813
814 /* Create the descriptor for it (mainly the right sizes) and validate */
817
818 /* Use either the minimum size in the descriptor, or 16 MB in minimal mode */
819 Size.QuadPart = DecreaseSize ? 16 * MEGABYTE : Descriptor->MinSize.QuadPart;
820
821 /* Check if this should be a fixed pagefile or an any pagefile */
822 if (Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == '?')
823 {
824 /* Find a disk for it */
825 return SmpCreatePagingFileOnAnyDrive(Descriptor, &FuzzFactor, &Size);
826 }
827
828 /* Use the disk that was given */
829 return SmpCreatePagingFileOnFixedDrive(Descriptor, &FuzzFactor, &Size);
830}
831
833NTAPI
835{
837 WCHAR Buffer[32];
838
839 /* Allocate a descriptor */
840 Descriptor = RtlAllocateHeap(RtlGetProcessHeap(),
843 if (!Descriptor) return STATUS_NO_MEMORY;
844
845 /* Initialize it */
847
848 /* Copy the default pagefile name */
849 ASSERT(sizeof(Buffer) >= sizeof(STANDARD_PAGING_FILE_NAME));
851
852 /* Fill the rest of the descriptor out */
854 Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = '?';
858
859 /* Insert it into the descriptor list */
862
863 /* Go ahead and create it now, with the minimal size possible */
865}
866
868NTAPI
870{
872 UNICODE_STRING VolumePath;
873 BOOLEAN BootVolumeFound = FALSE;
874 WCHAR StartChar, Drive, DriveDiff;
878 PROCESS_DEVICEMAP_INFORMATION ProcessInformation;
882 LARGE_INTEGER FreeSpace, FinalFreeSpace;
883 WCHAR Buffer[32];
884
885 /* We should be starting with an empty list */
887
888 /* Query the device map so we can get the drive letters */
891 &ProcessInformation.Query,
892 sizeof(ProcessInformation.Query),
893 NULL);
894 if (!NT_SUCCESS(Status))
895 {
896 DPRINT1("SMSS:PFILE: Query(ProcessDeviceMap) failed with status %X\n",
897 Status);
898 return Status;
899 }
900
901 /* Build the volume string, starting with A: (we'll edit this in place) */
902 wcscpy(Buffer, L"\\??\\A:\\");
903 RtlInitUnicodeString(&VolumePath, Buffer);
904
905 /* Start with the C drive, except on NEC PC-98 */
906 StartChar = IsNEC_98 ? L'A' : L'C';
907 for (Drive = StartChar, DriveDiff = StartChar - L'A'; Drive <= L'Z'; Drive++, DriveDiff++)
908 {
909 /* Skip the disk if it's not in the drive map */
910 if (!((1 << DriveDiff) & ProcessInformation.Query.DriveMap)) continue;
911
912 /* Write the drive letter and try to open the volume */
915 &VolumePath,
917 NULL,
918 NULL);
925 if (!NT_SUCCESS(Status))
926 {
927 /* Skip the volume if we failed */
928 DPRINT1("SMSS:PFILE: Open volume `%wZ' failed with status %X\n",
929 &VolumePath, Status);
930 continue;
931 }
932
933 /* Now query device information on the volume */
936 &DeviceInfo,
937 sizeof(DeviceInfo),
939 if (!NT_SUCCESS(Status))
940 {
941 /* Move to the next volume if we failed */
942 DPRINT1("SMSS:PFILE: Query volume `%wZ' (handle %p) for device info"
943 " failed with status %X\n",
944 &VolumePath,
946 Status);
948 continue;
949 }
950
951 /* Check if this is a fixed disk */
952 if (DeviceInfo.Characteristics & (FILE_FLOPPY_DISKETTE |
956 {
957 /* It isn't, so skip it */
958 DPRINT1("SMSS:PFILE: Volume `%wZ' (%X) cannot store a paging file\n",
959 &VolumePath,
960 DeviceInfo.Characteristics);
962 continue;
963 }
964
965 /* We found a fixed volume, allocate a descriptor for it */
966 Volume = RtlAllocateHeap(RtlGetProcessHeap(),
968 sizeof(SMP_VOLUME_DESCRIPTOR));
969 if (!Volume)
970 {
971 /* Failed to allocate memory, try the next disk */
972 DPRINT1("SMSS:PFILE: Failed to allocate a volume descriptor (%u bytes)\n",
973 sizeof(SMP_VOLUME_DESCRIPTOR));
975 continue;
976 }
977
978 /* Save the drive letter and device information */
979 Volume->DriveLetter = Drive;
980 Volume->DeviceInfo = DeviceInfo;
981
982 /* Check if this is the boot volume */
984 RtlUpcaseUnicodeChar(SharedUserData->NtSystemRoot[0]))
985 {
986 /* Save it */
987 ASSERT(BootVolumeFound == FALSE);
988 Volume->Flags |= SMP_VOLUME_IS_BOOT;
989 BootVolumeFound = TRUE;
990 }
991
992 /* Now get size information on the volume */
995 &SizeInfo,
996 sizeof(SizeInfo),
998 if (!NT_SUCCESS(Status))
999 {
1000 /* We failed -- keep going */
1001 DPRINT1("SMSS:PFILE: Query volume `%wZ' (handle %p) for size failed"
1002 " with status %X\n",
1003 &VolumePath,
1005 Status);
1006 RtlFreeHeap(RtlGetProcessHeap(), 0, Volume);
1008 continue;
1009 }
1010
1011 /* Done querying volume information, close the handle */
1013
1014 /* Compute how much free space we have */
1015 FreeSpace.QuadPart = SizeInfo.AvailableAllocationUnits.QuadPart *
1016 SizeInfo.SectorsPerAllocationUnit;
1017 FinalFreeSpace.QuadPart = FreeSpace.QuadPart * SizeInfo.BytesPerSector;
1018
1019 /* Check if there is less than 32 MB free so we don't starve the disk */
1020 if (FinalFreeSpace.QuadPart <= MINIMUM_TO_KEEP_FREE)
1021 {
1022 /* In this case, act as if there is no free space */
1023 Volume->FreeSpace.QuadPart = 0;
1024 }
1025 else
1026 {
1027 /* Trim off 32 MB to give the disk a bit of breathing room */
1028 Volume->FreeSpace.QuadPart = FinalFreeSpace.QuadPart -
1030 }
1031
1032 /* All done, add this volume to our descriptor list */
1034 Volume->Flags |= SMP_VOLUME_INSERTED;
1035 DPRINT("SMSS:PFILE: Created volume descriptor for`%wZ'\n", &VolumePath);
1036 }
1037
1038 /* We must've found at least the boot volume */
1039 ASSERT(BootVolumeFound == TRUE);
1042
1043 /* Something is really messed up if we found no disks at all */
1045}
1046
1048NTAPI
1050{
1053 LARGE_INTEGER Size, FuzzFactor;
1054 BOOLEAN Created = FALSE;
1055 PLIST_ENTRY NextEntry;
1056
1057 /* Check if no paging files were requested */
1059 {
1060 /* The list should be empty -- nothing to do */
1062 DPRINT1("SMSS:PFILE: No paging file was requested\n");
1063 return STATUS_SUCCESS;
1064 }
1065
1066 /* Initialize the volume descriptors so we can know what's available */
1068 if (!NT_SUCCESS(Status))
1069 {
1070 /* We can't make decisions without this, so fail */
1071 DPRINT1("SMSS:PFILE: Failed to create volume descriptors (status %X)\n",
1072 Status);
1073 return Status;
1074 }
1075
1076 /* If we fail creating pagefiles, try to reduce by this much each time */
1077 FuzzFactor.QuadPart = FUZZ_FACTOR;
1078
1079 /* Loop the descriptor list */
1081 while (NextEntry != &SmpPagingFileDescriptorList)
1082 {
1083 /* Check what kind of descriptor this is */
1086 {
1087 /* This is a system-managed descriptor. Create the correct file */
1088 DPRINT("SMSS:PFILE: Creating a system managed paging file (`%wZ')\n",
1089 &Descriptor->Name);
1091 if (!NT_SUCCESS(Status))
1092 {
1093 /* We failed -- try again, with size minimization this time */
1094 DPRINT("SMSS:PFILE: Trying lower sizes for (`%wZ')\n",
1095 &Descriptor->Name);
1097 }
1098 }
1099 else
1100 {
1101 /* This is a manually entered descriptor. Validate its size first */
1103
1104 /* Check if this is an ANY pagefile or a FIXED pagefile */
1105 DPRINT("SMSS:PFILE: Creating a normal paging file (`%wZ')\n",
1106 &Descriptor->Name);
1107 if (Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == L'?')
1108 {
1109 /* It's an any pagefile, try to create it wherever possible */
1110 Size = Descriptor->MinSize;
1112 &FuzzFactor,
1113 &Size);
1114 if (!NT_SUCCESS(Status))
1115 {
1116 /* We failed to create it. Try again with a smaller size */
1117 DPRINT("SMSS:PFILE: Trying lower sizes for (`%wZ')\n",
1118 &Descriptor->Name);
1119 Size.QuadPart = 16 * MEGABYTE;
1121 &FuzzFactor,
1122 &Size);
1123 }
1124 }
1125 else
1126 {
1127 /* It's a fixed pagefile: override the minimum and use ours */
1128 Size.QuadPart = 16 * MEGABYTE;
1130 &FuzzFactor,
1131 &Size);
1132 }
1133 }
1134
1135 /* Go to the next descriptor */
1136 if (NT_SUCCESS(Status)) Created = TRUE;
1137 NextEntry = NextEntry->Flink;
1138 }
1139
1140 /* Check if none of the code in our loops above was able to create it */
1141 if (!Created)
1142 {
1143 /* Build an emergency pagefile ourselves */
1144 DPRINT1("SMSS:PFILE: Creating emergency paging file.\n");
1146 }
1147
1148 /* All done */
1149 return Status;
1150}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define DPRINT1
Definition: precomp.h:8
PWCHAR Drive
Definition: chkdsk.c:73
#define SMP_PAGEFILE_DEFAULT
Definition: pagefile.c:88
PSMP_VOLUME_DESCRIPTOR NTAPI SmpSearchVolumeDescriptor(IN WCHAR DriveLetter)
Definition: pagefile.c:472
LIST_ENTRY SmpVolumeDescriptorList
Definition: pagefile.c:122
struct _SMP_PAGEFILE_DESCRIPTOR * PSMP_PAGEFILE_DESCRIPTOR
NTSTATUS NTAPI SmpCreateEmergencyPagingFile(VOID)
Definition: pagefile.c:834
#define SMP_PAGEFILE_DUMP_PROCESSED
Definition: pagefile.c:93
VOID NTAPI SmpPagingFileInitialize(VOID)
Definition: pagefile.c:130
NTSTATUS NTAPI SmpCreatePagingFileOnAnyDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize)
Definition: pagefile.c:667
#define SMP_VOLUME_INSERTED
Definition: pagefile.c:109
NTSTATUS NTAPI SmpCreatePagingFiles(VOID)
Definition: pagefile.c:1049
struct _SMP_VOLUME_DESCRIPTOR SMP_VOLUME_DESCRIPTOR
#define STANDARD_DRIVE_LETTER_OFFSET
Definition: pagefile.c:22
NTSTATUS NTAPI SmpCreatePagingFile(IN PUNICODE_STRING Name, IN PLARGE_INTEGER MinSize, IN PLARGE_INTEGER MaxSize, IN ULONG Priority)
Definition: pagefile.c:504
#define FUZZ_FACTOR
Definition: pagefile.c:82
#define SMP_PAGEFILE_SYSTEM_MANAGED
Definition: pagefile.c:89
#define SMP_PAGEFILE_WAS_TOO_BIG
Definition: pagefile.c:90
#define STANDARD_PAGING_FILE_NAME
Definition: pagefile.c:21
#define SMP_PAGEFILE_CREATED
Definition: pagefile.c:87
NTSTATUS NTAPI SmpCreatePagingFileDescriptor(IN PUNICODE_STRING PageFileToken)
Definition: pagefile.c:139
NTSTATUS NTAPI SmpGetVolumeFreeSpace(IN PSMP_VOLUME_DESCRIPTOR Volume)
Definition: pagefile.c:394
#define MEGABYTE
Definition: pagefile.c:24
NTSTATUS NTAPI SmpCreatePagingFileOnFixedDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize)
Definition: pagefile.c:535
VOID NTAPI SmpMakeDefaultPagingFileDescriptor(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
Definition: pagefile.c:705
#define SMP_PAGEFILE_ON_ANY_DRIVE
Definition: pagefile.c:91
VOID NTAPI SmpMakeSystemManagedPagingFileDescriptor(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
Definition: pagefile.c:715
BOOLEAN SmpRegistrySpecifierPresent
Definition: pagefile.c:123
NTSTATUS NTAPI SmpDeletePagingFile(IN PUNICODE_STRING FileName)
Definition: pagefile.c:340
#define MAXIMUM_PAGEFILE_SIZE
Definition: pagefile.c:76
#define SMP_VOLUME_IS_BOOT
Definition: pagefile.c:111
ULONG SmpNumberOfPagingFiles
Definition: pagefile.c:124
NTSTATUS NTAPI SmpCreateSystemManagedPagingFile(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN BOOLEAN DecreaseSize)
Definition: pagefile.c:801
#define MAX_PAGING_FILES
Definition: pagefile.c:23
LIST_ENTRY SmpPagingFileDescriptorList
Definition: pagefile.c:122
struct _SMP_VOLUME_DESCRIPTOR * PSMP_VOLUME_DESCRIPTOR
#define MINIMUM_TO_KEEP_FREE
Definition: pagefile.c:81
NTSTATUS NTAPI SmpCreateVolumeDescriptors(VOID)
Definition: pagefile.c:869
#define SMP_PAGEFILE_EMERGENCY
Definition: pagefile.c:92
struct _SMP_PAGEFILE_DESCRIPTOR SMP_PAGEFILE_DESCRIPTOR
NTSTATUS NTAPI SmpValidatePagingFileSizes(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
Definition: pagefile.c:749
NTSTATUS NTAPI SmpGetPagingFileSize(IN PUNICODE_STRING FileName, OUT PLARGE_INTEGER Size)
Definition: pagefile.c:295
#define SMP_VOLUME_PAGEFILE_CREATED
Definition: pagefile.c:110
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
BOOLEAN NTAPI SmpCheckForCrashDump(IN PUNICODE_STRING FileName)
Definition: crashdmp.c:20
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ SystemBasicInformation
Definition: ntddk_ex.h:11
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2283
@ FileDispositionInformation
Definition: from_kernel.h:74
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
@ FileFsDeviceInformation
Definition: from_kernel.h:222
@ FileFsSizeInformation
Definition: from_kernel.h:221
Status
Definition: gdiplustypes.h:25
const GLubyte * c
Definition: glext.h:8905
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 OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
@ ProcessDeviceMap
Definition: winternl.h:879
#define c
Definition: ke_i.h:80
UNICODE_STRING Volume
Definition: fltkernel.h:1172
#define ASSERT(a)
Definition: mode.c:44
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:362
WCHAR NTAPI RtlUpcaseUnicodeChar(_In_ WCHAR Source)
Definition: nlsboot.c:176
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:3952
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_REMOTE_DEVICE
Definition: nt_native.h:811
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define NtCurrentProcess()
Definition: nt_native.h:1657
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:3096
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
#define FILE_READ_ONLY_DEVICE
Definition: nt_native.h:808
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DELETE
Definition: nt_native.h:57
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
NTSTATUS NTAPI NtCreatePagingFile(_In_ PUNICODE_STRING FileName, _In_ PLARGE_INTEGER MinimumSize, _In_ PLARGE_INTEGER MaximumSize, _In_ ULONG Reserved)
Definition: pagefile.c:366
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_UNEXPECTED_IO_ERROR
Definition: ntstatus.h:469
#define STATUS_TOO_MANY_PAGING_FILES
Definition: ntstatus.h:387
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define FileStandardInformation
Definition: propsheet.cpp:61
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define SharedUserData
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
#define STATUS_SUCCESS
Definition: shellext.h:65
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 DPRINT
Definition: sndvol32.h:71
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
base of all file and directory entries
Definition: entries.h:83
LARGE_INTEGER AvailableAllocationUnits
Definition: from_kernel.h:264
LARGE_INTEGER AllocationSize
Definition: propsheet.cpp:54
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _PROCESS_DEVICEMAP_INFORMATION::@4170::@4172 Query
LARGE_INTEGER ActualMinSize
Definition: pagefile.c:101
UNICODE_STRING Name
Definition: pagefile.c:97
UNICODE_STRING Token
Definition: pagefile.c:98
LARGE_INTEGER MinSize
Definition: pagefile.c:99
LARGE_INTEGER ActualMaxSize
Definition: pagefile.c:102
LARGE_INTEGER MaxSize
Definition: pagefile.c:100
LARGE_INTEGER FreeSpace
Definition: pagefile.c:118
FILE_FS_DEVICE_INFORMATION DeviceInfo
Definition: pagefile.c:119
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
#define PF_PAE_ENABLED
Definition: ketypes.h:133
#define IsNEC_98
Definition: ketypes.h:911
__wchar_t WCHAR
Definition: xmlstorage.h:180