ReactOS 0.4.16-dev-329-g9223134
pagefile.c File Reference
#include "smss.h"
#include <debug.h>
Include dependency graph for pagefile.c:

Go to the source code of this file.

Classes

struct  _SMP_PAGEFILE_DESCRIPTOR
 
struct  _SMP_VOLUME_DESCRIPTOR
 

Macros

#define NDEBUG
 
#define STANDARD_PAGING_FILE_NAME   L"\\??\\?:\\pagefile.sys"
 
#define STANDARD_DRIVE_LETTER_OFFSET   4
 
#define MAX_PAGING_FILES   16
 
#define MEGABYTE   (1024 * 1024)
 
#define GIGABYTE   (1024ULL * MEGABYTE)
 
#define TERABYTE   (1024ULL * GIGABYTE)
 
#define MAXIMUM_PAGEFILE_SIZE32   ((1ULL * 1024 * 1024 - 1) * PAGE_SIZE)
 
#define MAXIMUM_PAGEFILE_SIZE64   ((4ULL * 1024 * 1024 * 1024 - 1) * PAGE_SIZE)
 
#define MAXIMUM_PAGEFILE_SIZE   MAXIMUM_PAGEFILE_SIZE32
 
#define MINIMUM_TO_KEEP_FREE   (256 * MEGABYTE)
 
#define FUZZ_FACTOR   (16 * MEGABYTE)
 
#define SMP_PAGEFILE_CREATED   0x01
 
#define SMP_PAGEFILE_DEFAULT   0x02
 
#define SMP_PAGEFILE_SYSTEM_MANAGED   0x04
 
#define SMP_PAGEFILE_WAS_TOO_BIG   0x08
 
#define SMP_PAGEFILE_ON_ANY_DRIVE   0x10
 
#define SMP_PAGEFILE_EMERGENCY   0x20
 
#define SMP_PAGEFILE_DUMP_PROCESSED   0x40
 
#define SMP_VOLUME_INSERTED   0x01
 
#define SMP_VOLUME_PAGEFILE_CREATED   0x04
 
#define SMP_VOLUME_IS_BOOT   0x08
 

Typedefs

typedef struct _SMP_PAGEFILE_DESCRIPTOR SMP_PAGEFILE_DESCRIPTOR
 
typedef struct _SMP_PAGEFILE_DESCRIPTORPSMP_PAGEFILE_DESCRIPTOR
 
typedef struct _SMP_VOLUME_DESCRIPTOR SMP_VOLUME_DESCRIPTOR
 
typedef struct _SMP_VOLUME_DESCRIPTORPSMP_VOLUME_DESCRIPTOR
 

Functions

VOID NTAPI SmpPagingFileInitialize (VOID)
 
NTSTATUS NTAPI SmpCreatePagingFileDescriptor (IN PUNICODE_STRING PageFileToken)
 
NTSTATUS NTAPI SmpGetPagingFileSize (IN PUNICODE_STRING FileName, OUT PLARGE_INTEGER Size)
 
NTSTATUS NTAPI SmpDeletePagingFile (IN PUNICODE_STRING FileName)
 
NTSTATUS NTAPI SmpGetVolumeFreeSpace (IN PSMP_VOLUME_DESCRIPTOR Volume)
 
PSMP_VOLUME_DESCRIPTOR NTAPI SmpSearchVolumeDescriptor (IN WCHAR DriveLetter)
 
NTSTATUS NTAPI SmpCreatePagingFile (IN PUNICODE_STRING Name, IN PLARGE_INTEGER MinSize, IN PLARGE_INTEGER MaxSize, IN ULONG Priority)
 
NTSTATUS NTAPI SmpCreatePagingFileOnFixedDrive (IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize)
 
NTSTATUS NTAPI SmpCreatePagingFileOnAnyDrive (IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize)
 
VOID NTAPI SmpMakeDefaultPagingFileDescriptor (IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
 
VOID NTAPI SmpMakeSystemManagedPagingFileDescriptor (IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
 
NTSTATUS NTAPI SmpValidatePagingFileSizes (IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
 
NTSTATUS NTAPI SmpCreateSystemManagedPagingFile (IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN BOOLEAN DecreaseSize)
 
NTSTATUS NTAPI SmpCreateEmergencyPagingFile (VOID)
 
NTSTATUS NTAPI SmpCreateVolumeDescriptors (VOID)
 
NTSTATUS NTAPI SmpCreatePagingFiles (VOID)
 

Variables

LIST_ENTRY SmpPagingFileDescriptorList
 
LIST_ENTRY SmpVolumeDescriptorList
 
BOOLEAN SmpRegistrySpecifierPresent
 
ULONG SmpNumberOfPagingFiles
 

Macro Definition Documentation

◆ FUZZ_FACTOR

#define FUZZ_FACTOR   (16 * MEGABYTE)

Definition at line 82 of file pagefile.c.

◆ GIGABYTE

#define GIGABYTE   (1024ULL * MEGABYTE)

Definition at line 30 of file pagefile.c.

◆ MAX_PAGING_FILES

#define MAX_PAGING_FILES   16

Definition at line 23 of file pagefile.c.

◆ MAXIMUM_PAGEFILE_SIZE

#define MAXIMUM_PAGEFILE_SIZE   MAXIMUM_PAGEFILE_SIZE32

Definition at line 76 of file pagefile.c.

◆ MAXIMUM_PAGEFILE_SIZE32

#define MAXIMUM_PAGEFILE_SIZE32   ((1ULL * 1024 * 1024 - 1) * PAGE_SIZE)

Definition at line 35 of file pagefile.c.

◆ MAXIMUM_PAGEFILE_SIZE64

#define MAXIMUM_PAGEFILE_SIZE64   ((4ULL * 1024 * 1024 * 1024 - 1) * PAGE_SIZE)

Definition at line 44 of file pagefile.c.

◆ MEGABYTE

#define MEGABYTE   (1024 * 1024)

Definition at line 24 of file pagefile.c.

◆ MINIMUM_TO_KEEP_FREE

#define MINIMUM_TO_KEEP_FREE   (256 * MEGABYTE)

Definition at line 81 of file pagefile.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file pagefile.c.

◆ SMP_PAGEFILE_CREATED

#define SMP_PAGEFILE_CREATED   0x01

Definition at line 87 of file pagefile.c.

◆ SMP_PAGEFILE_DEFAULT

#define SMP_PAGEFILE_DEFAULT   0x02

Definition at line 88 of file pagefile.c.

◆ SMP_PAGEFILE_DUMP_PROCESSED

#define SMP_PAGEFILE_DUMP_PROCESSED   0x40

Definition at line 93 of file pagefile.c.

◆ SMP_PAGEFILE_EMERGENCY

#define SMP_PAGEFILE_EMERGENCY   0x20

Definition at line 92 of file pagefile.c.

◆ SMP_PAGEFILE_ON_ANY_DRIVE

#define SMP_PAGEFILE_ON_ANY_DRIVE   0x10

Definition at line 91 of file pagefile.c.

◆ SMP_PAGEFILE_SYSTEM_MANAGED

#define SMP_PAGEFILE_SYSTEM_MANAGED   0x04

Definition at line 89 of file pagefile.c.

◆ SMP_PAGEFILE_WAS_TOO_BIG

#define SMP_PAGEFILE_WAS_TOO_BIG   0x08

Definition at line 90 of file pagefile.c.

◆ SMP_VOLUME_INSERTED

#define SMP_VOLUME_INSERTED   0x01

Definition at line 109 of file pagefile.c.

◆ SMP_VOLUME_IS_BOOT

#define SMP_VOLUME_IS_BOOT   0x08

Definition at line 111 of file pagefile.c.

◆ SMP_VOLUME_PAGEFILE_CREATED

#define SMP_VOLUME_PAGEFILE_CREATED   0x04

Definition at line 110 of file pagefile.c.

◆ STANDARD_DRIVE_LETTER_OFFSET

#define STANDARD_DRIVE_LETTER_OFFSET   4

Definition at line 22 of file pagefile.c.

◆ STANDARD_PAGING_FILE_NAME

#define STANDARD_PAGING_FILE_NAME   L"\\??\\?:\\pagefile.sys"

Definition at line 21 of file pagefile.c.

◆ TERABYTE

#define TERABYTE   (1024ULL * GIGABYTE)

Definition at line 31 of file pagefile.c.

Typedef Documentation

◆ PSMP_PAGEFILE_DESCRIPTOR

◆ PSMP_VOLUME_DESCRIPTOR

◆ SMP_PAGEFILE_DESCRIPTOR

◆ SMP_VOLUME_DESCRIPTOR

Function Documentation

◆ SmpCreateEmergencyPagingFile()

NTSTATUS NTAPI SmpCreateEmergencyPagingFile ( VOID  )

Definition at line 834 of file pagefile.c.

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}
#define STANDARD_DRIVE_LETTER_OFFSET
Definition: pagefile.c:22
#define SMP_PAGEFILE_SYSTEM_MANAGED
Definition: pagefile.c:89
#define STANDARD_PAGING_FILE_NAME
Definition: pagefile.c:21
#define SMP_PAGEFILE_ON_ANY_DRIVE
Definition: pagefile.c:91
ULONG SmpNumberOfPagingFiles
Definition: pagefile.c:124
NTSTATUS NTAPI SmpCreateSystemManagedPagingFile(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN BOOLEAN DecreaseSize)
Definition: pagefile.c:801
LIST_ENTRY SmpPagingFileDescriptorList
Definition: pagefile.c:122
#define SMP_PAGEFILE_EMERGENCY
Definition: pagefile.c:92
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
Definition: bufpool.h:45
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define InsertHeadList(ListHead, Entry)
#define ASSERT(a)
Definition: mode.c:44
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by SmpCreatePagingFiles().

◆ SmpCreatePagingFile()

NTSTATUS NTAPI SmpCreatePagingFile ( IN PUNICODE_STRING  Name,
IN PLARGE_INTEGER  MinSize,
IN PLARGE_INTEGER  MaxSize,
IN ULONG  Priority 
)

Definition at line 504 of file pagefile.c.

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}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
NTSTATUS NTAPI NtCreatePagingFile(_In_ PUNICODE_STRING FileName, _In_ PLARGE_INTEGER MinimumSize, _In_ PLARGE_INTEGER MaximumSize, _In_ ULONG Reserved)
Definition: pagefile.c:366
#define DPRINT
Definition: sndvol32.h:73
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:655

Referenced by SmpCreatePagingFileOnFixedDrive().

◆ SmpCreatePagingFileDescriptor()

NTSTATUS NTAPI SmpCreatePagingFileDescriptor ( IN PUNICODE_STRING  PageFileToken)

Definition at line 139 of file pagefile.c.

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}
unsigned char BOOLEAN
#define MEGABYTE
Definition: pagefile.c:24
BOOLEAN SmpRegistrySpecifierPresent
Definition: pagefile.c:123
#define MAX_PAGING_FILES
Definition: pagefile.c:23
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define FALSE
Definition: types.h:117
#define InsertTailList(ListHead, Entry)
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 c
Definition: ke_i.h:80
WCHAR NTAPI RtlUpcaseUnicodeChar(_In_ WCHAR Source)
Definition: nlsboot.c:176
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#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 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
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by SmpLoadDataFromRegistry().

◆ SmpCreatePagingFileOnAnyDrive()

NTSTATUS NTAPI SmpCreatePagingFileOnAnyDrive ( IN PSMP_PAGEFILE_DESCRIPTOR  Descriptor,
IN PLARGE_INTEGER  FuzzFactor,
IN PLARGE_INTEGER  MinimumSize 
)

Definition at line 667 of file pagefile.c.

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}
LIST_ENTRY SmpVolumeDescriptorList
Definition: pagefile.c:122
#define SMP_VOLUME_INSERTED
Definition: pagefile.c:109
NTSTATUS NTAPI SmpCreatePagingFileOnFixedDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize)
Definition: pagefile.c:535
UNICODE_STRING Volume
Definition: fltkernel.h:1172
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155

Referenced by SmpCreatePagingFiles(), and SmpCreateSystemManagedPagingFile().

◆ SmpCreatePagingFileOnFixedDrive()

NTSTATUS NTAPI SmpCreatePagingFileOnFixedDrive ( IN PSMP_PAGEFILE_DESCRIPTOR  Descriptor,
IN PLARGE_INTEGER  FuzzFactor,
IN PLARGE_INTEGER  MinimumSize 
)

Definition at line 535 of file pagefile.c.

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}
PSMP_VOLUME_DESCRIPTOR NTAPI SmpSearchVolumeDescriptor(IN WCHAR DriveLetter)
Definition: pagefile.c:472
#define SMP_PAGEFILE_DUMP_PROCESSED
Definition: pagefile.c:93
NTSTATUS NTAPI SmpCreatePagingFile(IN PUNICODE_STRING Name, IN PLARGE_INTEGER MinSize, IN PLARGE_INTEGER MaxSize, IN ULONG Priority)
Definition: pagefile.c:504
#define SMP_PAGEFILE_CREATED
Definition: pagefile.c:87
NTSTATUS NTAPI SmpGetVolumeFreeSpace(IN PSMP_VOLUME_DESCRIPTOR Volume)
Definition: pagefile.c:394
NTSTATUS NTAPI SmpDeletePagingFile(IN PUNICODE_STRING FileName)
Definition: pagefile.c:340
#define SMP_VOLUME_IS_BOOT
Definition: pagefile.c:111
NTSTATUS NTAPI SmpGetPagingFileSize(IN PUNICODE_STRING FileName, OUT PLARGE_INTEGER Size)
Definition: pagefile.c:295
#define SMP_VOLUME_PAGEFILE_CREATED
Definition: pagefile.c:110
BOOLEAN NTAPI SmpCheckForCrashDump(IN PUNICODE_STRING FileName)
Definition: crashdmp.c:20
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by SmpCreatePagingFileOnAnyDrive(), SmpCreatePagingFiles(), and SmpCreateSystemManagedPagingFile().

◆ SmpCreatePagingFiles()

NTSTATUS NTAPI SmpCreatePagingFiles ( VOID  )

Definition at line 1049 of file pagefile.c.

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}
NTSTATUS NTAPI SmpCreateEmergencyPagingFile(VOID)
Definition: pagefile.c:834
NTSTATUS NTAPI SmpCreatePagingFileOnAnyDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor, IN PLARGE_INTEGER FuzzFactor, IN PLARGE_INTEGER MinimumSize)
Definition: pagefile.c:667
#define FUZZ_FACTOR
Definition: pagefile.c:82
NTSTATUS NTAPI SmpCreateVolumeDescriptors(VOID)
Definition: pagefile.c:869
NTSTATUS NTAPI SmpValidatePagingFileSizes(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
Definition: pagefile.c:749
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by SmpLoadDataFromRegistry().

◆ SmpCreateSystemManagedPagingFile()

NTSTATUS NTAPI SmpCreateSystemManagedPagingFile ( IN PSMP_PAGEFILE_DESCRIPTOR  Descriptor,
IN BOOLEAN  DecreaseSize 
)

Definition at line 801 of file pagefile.c.

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}
VOID NTAPI SmpMakeSystemManagedPagingFileDescriptor(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
Definition: pagefile.c:715

Referenced by SmpCreateEmergencyPagingFile(), and SmpCreatePagingFiles().

◆ SmpCreateVolumeDescriptors()

NTSTATUS NTAPI SmpCreateVolumeDescriptors ( VOID  )

Definition at line 869 of file pagefile.c.

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}
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
PWCHAR Drive
Definition: chkdsk.c:73
#define MINIMUM_TO_KEEP_FREE
Definition: pagefile.c:81
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define FILE_SHARE_READ
Definition: compat.h:136
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2283
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
@ FileFsDeviceInformation
Definition: from_kernel.h:222
@ FileFsSizeInformation
Definition: from_kernel.h:221
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
@ ProcessDeviceMap
Definition: winternl.h:879
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
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
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define FILE_READ_ONLY_DEVICE
Definition: nt_native.h:808
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
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_UNEXPECTED_IO_ERROR
Definition: ntstatus.h:469
#define SharedUserData
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
LARGE_INTEGER AvailableAllocationUnits
Definition: from_kernel.h:264
struct _PROCESS_DEVICEMAP_INFORMATION::@4177::@4179 Query
#define IsNEC_98
Definition: ketypes.h:911

Referenced by SmpCreatePagingFiles().

◆ SmpDeletePagingFile()

NTSTATUS NTAPI SmpDeletePagingFile ( IN PUNICODE_STRING  FileName)

Definition at line 340 of file pagefile.c.

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}
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
@ FileDispositionInformation
Definition: from_kernel.h:74
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:56
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
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define DELETE
Definition: nt_native.h:57

Referenced by SmpCreatePagingFileOnFixedDrive().

◆ SmpGetPagingFileSize()

NTSTATUS NTAPI SmpGetPagingFileSize ( IN PUNICODE_STRING  FileName,
OUT PLARGE_INTEGER  Size 
)

Definition at line 295 of file pagefile.c.

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}
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
#define FileStandardInformation
Definition: propsheet.cpp:61
LARGE_INTEGER AllocationSize
Definition: propsheet.cpp:54

Referenced by SmpCreatePagingFileOnFixedDrive().

◆ SmpGetVolumeFreeSpace()

NTSTATUS NTAPI SmpGetVolumeFreeSpace ( IN PSMP_VOLUME_DESCRIPTOR  Volume)

Definition at line 394 of file pagefile.c.

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}
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117

Referenced by SmpCreatePagingFileOnFixedDrive().

◆ SmpMakeDefaultPagingFileDescriptor()

VOID NTAPI SmpMakeDefaultPagingFileDescriptor ( IN PSMP_PAGEFILE_DESCRIPTOR  Descriptor)

Definition at line 705 of file pagefile.c.

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}
#define SMP_PAGEFILE_DEFAULT
Definition: pagefile.c:88

Referenced by SmpMakeSystemManagedPagingFileDescriptor().

◆ SmpMakeSystemManagedPagingFileDescriptor()

VOID NTAPI SmpMakeSystemManagedPagingFileDescriptor ( IN PSMP_PAGEFILE_DESCRIPTOR  Descriptor)

Definition at line 715 of file pagefile.c.

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}
VOID NTAPI SmpMakeDefaultPagingFileDescriptor(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor)
Definition: pagefile.c:705
@ SystemBasicInformation
Definition: ntddk_ex.h:11
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER MaximumSize
Definition: mmfuncs.h:362
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by SmpCreateSystemManagedPagingFile().

◆ SmpPagingFileInitialize()

VOID NTAPI SmpPagingFileInitialize ( VOID  )

Definition at line 130 of file pagefile.c.

131{
132 /* Initialize the two lists */
135}
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944

Referenced by SmpLoadDataFromRegistry().

◆ SmpSearchVolumeDescriptor()

PSMP_VOLUME_DESCRIPTOR NTAPI SmpSearchVolumeDescriptor ( IN WCHAR  DriveLetter)

Definition at line 472 of file pagefile.c.

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}

Referenced by SmpCreatePagingFileOnFixedDrive().

◆ SmpValidatePagingFileSizes()

NTSTATUS NTAPI SmpValidatePagingFileSizes ( IN PSMP_PAGEFILE_DESCRIPTOR  Descriptor)

Definition at line 749 of file pagefile.c.

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}
#define SMP_PAGEFILE_WAS_TOO_BIG
Definition: pagefile.c:90
#define MAXIMUM_PAGEFILE_SIZE
Definition: pagefile.c:76
#define PF_PAE_ENABLED
Definition: ketypes.h:133

Referenced by SmpCreatePagingFiles(), and SmpCreateSystemManagedPagingFile().

Variable Documentation

◆ SmpNumberOfPagingFiles

◆ SmpPagingFileDescriptorList

◆ SmpRegistrySpecifierPresent

BOOLEAN SmpRegistrySpecifierPresent

Definition at line 123 of file pagefile.c.

Referenced by SmpCreatePagingFileDescriptor(), and SmpCreatePagingFiles().

◆ SmpVolumeDescriptorList