Author: ekohl
Date: Tue Jun 1 00:34:16 2010
New Revision: 47505
URL:
http://svn.reactos.org/svn/reactos?rev=47505&view=rev
Log:
[SMSS]
- Create a new default paging file if no paging files exist.
- Set the calculated paging file sizes in the registry.
- Remove predefined paging file name from the hivesys*.inf files.
Fixes bug #4048.
Modified:
trunk/reactos/base/system/smss/initpage.c
trunk/reactos/boot/bootdata/hivesys_arm.inf
trunk/reactos/boot/bootdata/hivesys_i386.inf
Modified: trunk/reactos/base/system/smss/initpage.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/smss/initpage.…
==============================================================================
--- trunk/reactos/base/system/smss/initpage.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/smss/initpage.c [iso-8859-1] Tue Jun 1 00:34:16 2010
@@ -225,34 +225,288 @@
}
+static NTSTATUS
+SmpGetFreeDiskSpace(IN PWSTR PageFileName,
+ OUT PLARGE_INTEGER FreeDiskSpaceInMB)
+{
+ FILE_FS_SIZE_INFORMATION FileFsSize;
+ IO_STATUS_BLOCK IoStatusBlock;
+ HANDLE hFile;
+ UNICODE_STRING NtPathU;
+ LARGE_INTEGER FreeBytes;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ WCHAR RootPath[5];
+ NTSTATUS Status;
+
+ /*
+ * copy the drive letter, the colon and the slash,
+ * tack a null on the end
+ */
+ RootPath[0] = PageFileName[0];
+ RootPath[1] = L':';
+ RootPath[2] = L'\\';
+ RootPath[3] = L'\0';
+
+ DPRINT("Root drive X:\\...\"%S\"\n",RootPath);
+
+ if (!RtlDosPathNameToNtPathName_U(RootPath,
+ &NtPathU,
+ NULL,
+ NULL))
+ {
+ DPRINT1("Invalid path to root of drive\n");
+ return STATUS_OBJECT_PATH_INVALID;
+ }
+
+ 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);
+
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ NtPathU.Buffer);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not open a handle to the volume.\n");
+ return Status;
+ }
+
+ 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");
+ return Status;
+ }
+
+ FreeBytes.QuadPart = FileFsSize.BytesPerSector *
+ FileFsSize.SectorsPerAllocationUnit *
+ FileFsSize.AvailableAllocationUnits.QuadPart;
+
+ FreeDiskSpaceInMB->QuadPart = FreeBytes.QuadPart >> 20;
+
+ return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+SmpSetDefaultPageFileData(IN PWSTR PageFileName,
+ IN PLARGE_INTEGER InitialSizeInMB,
+ IN PLARGE_INTEGER MaximumSizeInMB)
+{
+ WCHAR ValueString[MAX_PATH * 2];
+ ULONG ValueLength;
+
+ /* Format the value string */
+ swprintf(ValueString,
+ L"%s %I64u %I64u",
+ PageFileName,
+ InitialSizeInMB->QuadPart,
+ MaximumSizeInMB->QuadPart);
+
+ /*
+ * Append another zero character because it is a multi string value
+ * (REG_MULTI_SZ) and calculate the total string length.
+ */
+ ValueLength = wcslen(ValueString) + 1;
+ ValueString[ValueLength] = 0;
+ ValueLength++;
+
+ /* Write the page file data */
+ return RtlWriteRegistryValue(RTL_REGISTRY_CONTROL,
+ L"\\Session Manager\\Memory Management",
+ L"PagingFiles",
+ REG_MULTI_SZ,
+ ValueString,
+ ValueLength * sizeof(WCHAR));
+}
+
+
+static NTSTATUS
+SmpCreatePageFile(IN PWSTR PageFileName,
+ IN PLARGE_INTEGER InitialSizeInMB,
+ IN PLARGE_INTEGER MaximumSizeInMB)
+{
+ LARGE_INTEGER InitialSize;
+ LARGE_INTEGER MaximumSize;
+ UNICODE_STRING FileName;
+ NTSTATUS Status;
+
+ /* Get the NT path name of the page file */
+ if (!RtlDosPathNameToNtPathName_U(PageFileName,
+ &FileName,
+ NULL,
+ NULL))
+ {
+ return STATUS_OBJECT_PATH_INVALID;
+ }
+
+ /* Convert sizes in megabytes to sizes in bytes */
+ InitialSize.QuadPart = InitialSizeInMB->QuadPart << 20;
+ MaximumSize.QuadPart = MaximumSizeInMB->QuadPart << 20;
+
+ /* Create the pageing file */
+ Status = NtCreatePagingFile(&FileName,
+ &InitialSize,
+ &MaximumSize,
+ 0);
+ if (! NT_SUCCESS(Status))
+ {
+ DPRINT("Creation of paging file %wZ with size %I64d MB failed (status
0x%x)\n",
+ &FileName, InitialSizeInMB->QuadPart, Status);
+ }
+
+ /* Release the file name */
+ RtlFreeHeap(RtlGetProcessHeap(),
+ 0,
+ FileName.Buffer);
+
+ return Status;
+}
+
+
+static NTSTATUS
+SmpCreateDefaultPagingFile(VOID)
+{
+ SYSTEM_BASIC_INFORMATION SysBasicInfo;
+ LARGE_INTEGER MemorySizeInMB;
+ LARGE_INTEGER FreeDiskSpaceInMB;
+ LARGE_INTEGER InitialSizeInMB;
+ LARGE_INTEGER MaximumSizeInMB;
+ NTSTATUS Status = STATUS_SUCCESS;
+ WCHAR PageFileName[MAX_PATH];
+
+ DPRINT("Creating a default paging file\n");
+
+ Status = NtQuerySystemInformation(SystemBasicInformation,
+ &SysBasicInfo,
+ sizeof(SysBasicInfo),
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not query for physical memory size.\n");
+ return Status;
+ }
+
+ DPRINT("PageSize: %d, PhysicalPages: %d, TotalMem: %d\n",
+ SysBasicInfo.PageSize,
+ SysBasicInfo.NumberOfPhysicalPages,
+ (SysBasicInfo.NumberOfPhysicalPages * SysBasicInfo.PageSize) / 1024);
+
+ MemorySizeInMB.QuadPart = (SysBasicInfo.NumberOfPhysicalPages *
SysBasicInfo.PageSize) >> 20;
+
+ DPRINT("MemorySize %I64u MB\n",
+ MemorySizeInMB.QuadPart);
+
+ /* Build the default page file name */
+ PageFileName[0] = SharedUserData->NtSystemRoot[0];
+ PageFileName[1] = 0;
+ wcscat(PageFileName, L":\\pagefile.sys");
+
+ Status = SmpGetFreeDiskSpace(PageFileName,
+ &FreeDiskSpaceInMB);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ DPRINT("FreeDiskSpace %I64u MB\n",
+ FreeDiskSpaceInMB.QuadPart);
+
+ InitialSizeInMB.QuadPart = MemorySizeInMB.QuadPart + (MemorySizeInMB.QuadPart / 2);
+ MaximumSizeInMB.QuadPart = InitialSizeInMB.QuadPart * 2;
+
+ if (InitialSizeInMB.QuadPart > (FreeDiskSpaceInMB.QuadPart / 4))
+ {
+ DPRINT("Inital Size took more then 25%% of free disk space\n");
+
+ /*
+ * Set by percentage of free space
+ * intial is 20%, and max is 25%
+ */
+ InitialSizeInMB.QuadPart = FreeDiskSpaceInMB.QuadPart / 5;
+ MaximumSizeInMB.QuadPart = FreeDiskSpaceInMB.QuadPart / 4;
+
+ /* The page file is more then a gig, size it down */
+ if (InitialSizeInMB.QuadPart > 1024)
+ {
+ InitialSizeInMB.QuadPart = 1024; /* 1GB */
+ MaximumSizeInMB.QuadPart = 1536; /* 1.5GB */
+ }
+ }
+
+ DPRINT("InitialSize %I64u MB MaximumSize %I64u MB\n",
+ InitialSizeInMB.QuadPart,
+ MaximumSizeInMB.QuadPart);
+
+ Status = SmpSetDefaultPageFileData(PageFileName,
+ &InitialSizeInMB,
+ &MaximumSizeInMB);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ return SmpCreatePageFile(PageFileName,
+ &InitialSizeInMB,
+ &MaximumSizeInMB);
+}
+
+
NTSTATUS
SmCreatePagingFiles(VOID)
{
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- NTSTATUS Status;
-
- DPRINT("creating system paging files\n");
- /*
- * Disable paging file on MiniNT/Live CD.
- */
- if (RtlCheckRegistryKey(RTL_REGISTRY_CONTROL, L"MiniNT") == STATUS_SUCCESS)
- {
- return STATUS_SUCCESS;
- }
-
- RtlZeroMemory(&QueryTable,
- sizeof(QueryTable));
-
- QueryTable[0].Name = L"PagingFiles";
- QueryTable[0].QueryRoutine = SmpPagingFilesQueryRoutine;
-
- Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
- L"\\Session Manager\\Memory Management",
- QueryTable,
- NULL,
- NULL);
-
- return(Status);
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ NTSTATUS Status;
+
+ DPRINT("creating system paging files\n");
+
+ /* Disable paging file on MiniNT/Live CD. */
+ if (RtlCheckRegistryKey(RTL_REGISTRY_CONTROL, L"MiniNT") ==
STATUS_SUCCESS)
+ {
+ return STATUS_SUCCESS;
+ }
+
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].Name = L"PagingFiles";
+ QueryTable[0].QueryRoutine = SmpPagingFilesQueryRoutine;
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_CONTROL,
+ L"\\Session Manager\\Memory Management",
+ QueryTable,
+ NULL,
+ NULL);
+ if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ Status = SmpCreateDefaultPagingFile();
+ }
+
+ return Status;
}
Modified: trunk/reactos/boot/bootdata/hivesys_arm.inf
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/bootdata/hivesys_arm.…
==============================================================================
--- trunk/reactos/boot/bootdata/hivesys_arm.inf [iso-8859-1] (original)
+++ trunk/reactos/boot/bootdata/hivesys_arm.inf [iso-8859-1] Tue Jun 1 00:34:16 2010
@@ -783,9 +783,8 @@
HKLM,"SYSTEM\CurrentControlSet\Control\Session
Manager\KnownDlls","wininet",0x00000000,"wininet.dll"
HKLM,"SYSTEM\CurrentControlSet\Control\Session
Manager\KnownDlls","wldap32",0x00000000,"wldap32.dll"
-; Pagefile settings
-HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory
Management","PagingFiles",0x00010000, \
- "C:\pagefile.sys"
+; Memory Management
+HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory
Management",,0x00000012
; Subsystems
HKLM,"SYSTEM\CurrentControlSet\Control\Session
Manager\Subsystems","Debug",0x00020000,""
Modified: trunk/reactos/boot/bootdata/hivesys_i386.inf
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/bootdata/hivesys_i386…
==============================================================================
--- trunk/reactos/boot/bootdata/hivesys_i386.inf [iso-8859-1] (original)
+++ trunk/reactos/boot/bootdata/hivesys_i386.inf [iso-8859-1] Tue Jun 1 00:34:16 2010
@@ -930,9 +930,8 @@
HKLM,"SYSTEM\CurrentControlSet\Control\Session
Manager\KnownDlls","wininet",0x00000000,"wininet.dll"
HKLM,"SYSTEM\CurrentControlSet\Control\Session
Manager\KnownDlls","wldap32",0x00000000,"wldap32.dll"
-; Pagefile settings
-HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory
Management","PagingFiles",0x00010000, \
- "C:\pagefile.sys"
+; Memory Management
+HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory
Management",,0x00000012
; Subsystems
HKLM,"SYSTEM\CurrentControlSet\Control\Session
Manager\Subsystems","Debug",0x00020000,""