mirror of
https://github.com/reactos/reactos.git
synced 2024-08-12 06:06:27 +00:00
Better page file creation that allows for system managed setting. A lot of thanks to Thomas on this patch.
svn path=/trunk/; revision=20334
This commit is contained in:
parent
60f9e8b3c5
commit
5caea08853
|
@ -28,66 +28,207 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define GIGABYTE (1024 * 1024 * 1024) /* One Gigabyte */
|
||||
|
||||
static NTSTATUS STDCALL
|
||||
SmpPagingFilesQueryRoutine(PWSTR ValueName,
|
||||
ULONG ValueType,
|
||||
PVOID ValueData,
|
||||
ULONG ValueLength,
|
||||
PVOID Context,
|
||||
PVOID EntryContext)
|
||||
ULONG ValueType,
|
||||
PVOID ValueData,
|
||||
ULONG ValueLength,
|
||||
PVOID Context,
|
||||
PVOID EntryContext)
|
||||
{
|
||||
UNICODE_STRING FileName;
|
||||
LARGE_INTEGER InitialSize;
|
||||
LARGE_INTEGER MaximumSize;
|
||||
NTSTATUS Status;
|
||||
LPWSTR p;
|
||||
LARGE_INTEGER InitialSize = {{0, 0}};
|
||||
LARGE_INTEGER MaximumSize = {{0, 0}};
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PWSTR p, ValueString = (PWSTR)ValueData;
|
||||
WCHAR RootDriveLetter[5] = {0};
|
||||
|
||||
DPRINT("ValueName '%S' Type %lu Length %lu\n", ValueName, ValueType, ValueLength);
|
||||
DPRINT("ValueData '%S'\n", (PWSTR)ValueData);
|
||||
if (ValueLength > 3 * sizeof(WCHAR) &&
|
||||
(ValueLength % sizeof(WCHAR) != 0 ||
|
||||
ValueString[(ValueLength / sizeof(WCHAR)) - 1] != L'\0'))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (ValueType != REG_SZ)
|
||||
{
|
||||
return(STATUS_SUCCESS);
|
||||
return STATUS_INVALID_PARAMETER_2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Format: "<path>[ <initial_size>[ <maximum_size>]]"
|
||||
*/
|
||||
if ((p = wcschr(ValueData, ' ')) != NULL)
|
||||
* Format: "<path>[ <initial_size>[ <maximum_size>]]"
|
||||
*/
|
||||
if ((p = wcschr(ValueString, L' ')) != NULL)
|
||||
{
|
||||
*p = L'\0';
|
||||
InitialSize.QuadPart = wcstoul(p + 1, &p, 0) * 256 * 4096;
|
||||
if (*p == ' ')
|
||||
{
|
||||
MaximumSize.QuadPart = wcstoul(p + 1, NULL, 0) * 256 * 4096;
|
||||
}
|
||||
{
|
||||
MaximumSize.QuadPart = wcstoul(p + 1, NULL, 0) * 256 * 4096;
|
||||
}
|
||||
else
|
||||
MaximumSize = InitialSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
InitialSize.QuadPart = 50 * 4096;
|
||||
MaximumSize.QuadPart = 80 * 4096;
|
||||
{
|
||||
MaximumSize = InitialSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U ((LPWSTR)ValueData,
|
||||
&FileName,
|
||||
NULL,
|
||||
NULL))
|
||||
if (!RtlDosPathNameToNtPathName_U (ValueString,
|
||||
&FileName,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
return (STATUS_SUCCESS);
|
||||
return STATUS_OBJECT_PATH_INVALID;
|
||||
}
|
||||
|
||||
DPRINT("SMSS: Created paging file %wZ with size %dKB\n",
|
||||
&FileName, InitialSize.QuadPart / 1024);
|
||||
/* If there is only a file name or if initial and max are both 0
|
||||
* the system will pick the sizes. Then it makes intial the size of phyical memory
|
||||
* and makes max the size of 1.5 * initial. If there isnt enough free space then it will
|
||||
* fall back to intial 20% of free space and max 25%. There is a max of 1 gig before
|
||||
* it doesnt make it bigger. */
|
||||
if ((InitialSize.QuadPart == 0 && MaximumSize.QuadPart == 0) || p == NULL)
|
||||
{
|
||||
FILE_FS_SIZE_INFORMATION FileFsSize;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HANDLE hFile;
|
||||
SYSTEM_BASIC_INFORMATION SysBasicInfo;
|
||||
UNICODE_STRING NtPathU;
|
||||
LARGE_INTEGER FreeBytes = {{0, 0}};
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
|
||||
DPRINT("System managed pagefile...\n");
|
||||
/* Make sure the path that is given for the file actually has the drive in it.
|
||||
At this point if there is not file name, no sizes will be set therefore no page
|
||||
file will be created */
|
||||
if (wcslen(ValueString) <= 3 ||
|
||||
ValueString[1] != L':' ||
|
||||
ValueString[2] != L'\\')
|
||||
{
|
||||
DPRINT1("Invalid path for pagefile.\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
Status = NtQuerySystemInformation(SystemBasicInformation,
|
||||
&SysBasicInfo,
|
||||
sizeof(SysBasicInfo),
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Could not query for physical memory size.\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
DPRINT("PageSize: %d, PhysicalPages: %d, TotalMem: %d\n", SysBasicInfo.PageSize, SysBasicInfo.NumberOfPhysicalPages, (SysBasicInfo.NumberOfPhysicalPages * SysBasicInfo.PageSize) / 1024);
|
||||
|
||||
InitialSize.QuadPart = SysBasicInfo.NumberOfPhysicalPages *
|
||||
SysBasicInfo.PageSize;
|
||||
MaximumSize.QuadPart = InitialSize.QuadPart * 2;
|
||||
|
||||
DPRINT("InitialSize: %I64d PhysicalPages: %lu PageSize: %lu\n",InitialSize.QuadPart,SysBasicInfo.NumberOfPhysicalPages,SysBasicInfo.PageSize);
|
||||
|
||||
/* copy the drive letter, the colon and the slash,
|
||||
tack a null on the end */
|
||||
RootDriveLetter[0] = ValueString[0];
|
||||
RootDriveLetter[1] = L':';
|
||||
RootDriveLetter[2] = L'\\';
|
||||
RootDriveLetter[3] = L'\0';
|
||||
DPRINT("Root drive X:\\...\"%S\"\n",RootDriveLetter);
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U(RootDriveLetter,
|
||||
&NtPathU,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
DPRINT1("Invalid path to root of drive\n");
|
||||
Status = STATUS_OBJECT_PATH_INVALID;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&NtPathU,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* Get a handle to the root to find the free space on the drive */
|
||||
Status = NtCreateFile(&hFile,
|
||||
0,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
0,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_OPEN,
|
||||
0,
|
||||
NULL,
|
||||
0);
|
||||
|
||||
RtlFreeUnicodeString(&NtPathU);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Could not open a handle to the volume.\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
Status = NtQueryVolumeInformationFile(hFile,
|
||||
&IoStatusBlock,
|
||||
&FileFsSize,
|
||||
sizeof(FILE_FS_SIZE_INFORMATION),
|
||||
FileFsSizeInformation);
|
||||
|
||||
NtClose(hFile);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Querying the volume free space failed!\n");
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
FreeBytes.QuadPart = FileFsSize.BytesPerSector *
|
||||
FileFsSize.SectorsPerAllocationUnit *
|
||||
FileFsSize.AvailableAllocationUnits.QuadPart;
|
||||
|
||||
DPRINT("Free bytes: %I64d Inital Size based on memory: %I64d \n",FreeBytes.QuadPart,InitialSize.QuadPart);
|
||||
|
||||
|
||||
if (InitialSize.QuadPart > (FreeBytes.QuadPart / 4) || InitialSize.QuadPart == 0)
|
||||
{
|
||||
DPRINT("Inital Size took more then 25%% of free space\n");
|
||||
/* Set by percentage of free space
|
||||
* intial is 20%, and max is 25% */
|
||||
InitialSize.QuadPart = FreeBytes.QuadPart / 5;
|
||||
MaximumSize.QuadPart = FreeBytes.QuadPart / 4;
|
||||
/* The page file is more then a gig, size it down */
|
||||
if (InitialSize.QuadPart > GIGABYTE)
|
||||
{
|
||||
InitialSize.QuadPart = GIGABYTE;
|
||||
MaximumSize.QuadPart = GIGABYTE * 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Make sure that max is not smaller then initial */
|
||||
if (InitialSize.QuadPart > MaximumSize.QuadPart)
|
||||
{
|
||||
DPRINT("Max page file size was bigger then inital.\n");
|
||||
MaximumSize.QuadPart = InitialSize.QuadPart;
|
||||
}
|
||||
|
||||
DPRINT1("SMSS: Created paging file %wZ with size %I64d KB\n",
|
||||
&FileName, InitialSize.QuadPart / 1024);
|
||||
|
||||
Status = NtCreatePagingFile(&FileName,
|
||||
&InitialSize,
|
||||
&MaximumSize,
|
||||
0);
|
||||
&InitialSize,
|
||||
&MaximumSize,
|
||||
0);
|
||||
|
||||
Cleanup:
|
||||
RtlFreeUnicodeString(&FileName);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,7 +238,7 @@ SmCreatePagingFiles(VOID)
|
|||
RTL_QUERY_REGISTRY_TABLE QueryTable[2];
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("SM: creating system paging files\n");
|
||||
DbgPrint("SM: creating system paging files\n");
|
||||
/*
|
||||
* Disable paging file on MiniNT/Live CD.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue