mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 12:40:33 +00:00
[NTOSKRNL] Properly open a page file and set appropriate attributes
This commit is contained in:
parent
0ad4ef6002
commit
2969c28a27
1 changed files with 43 additions and 23 deletions
|
@ -46,6 +46,7 @@ typedef struct _PAGINGFILE
|
||||||
{
|
{
|
||||||
LIST_ENTRY PagingFileListEntry;
|
LIST_ENTRY PagingFileListEntry;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
|
HANDLE FileHandle;
|
||||||
LARGE_INTEGER MaximumSize;
|
LARGE_INTEGER MaximumSize;
|
||||||
LARGE_INTEGER CurrentSize;
|
LARGE_INTEGER CurrentSize;
|
||||||
PFN_NUMBER FreePages;
|
PFN_NUMBER FreePages;
|
||||||
|
@ -502,7 +503,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
KPROCESSOR_MODE PreviousMode;
|
||||||
UNICODE_STRING CapturedFileName;
|
UNICODE_STRING CapturedFileName;
|
||||||
LARGE_INTEGER SafeInitialSize, SafeMaximumSize;
|
LARGE_INTEGER SafeInitialSize, SafeMaximumSize, AllocationSize;
|
||||||
|
|
||||||
DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n",
|
DPRINT("NtCreatePagingFile(FileName %wZ, InitialSize %I64d)\n",
|
||||||
FileName, InitialSize->QuadPart);
|
FileName, InitialSize->QuadPart);
|
||||||
|
@ -568,25 +569,56 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
/* Make sure we can at least store a complete page:
|
||||||
|
* If we have 2048 BytesPerAllocationUnit (FAT16 < 128MB) there is
|
||||||
|
* a problem if the paging file is fragmented. Suppose the first cluster
|
||||||
|
* of the paging file is cluster 3042 but cluster 3043 is NOT part of the
|
||||||
|
* paging file but of another file. We can't write a complete page (4096
|
||||||
|
* bytes) to the physical location of cluster 3042 then. */
|
||||||
|
AllocationSize.QuadPart = SafeInitialSize.QuadPart + PAGE_SIZE;
|
||||||
|
|
||||||
|
/* First, attempt to replace the page file, if existing */
|
||||||
Status = IoCreateFile(&FileHandle,
|
Status = IoCreateFile(&FileHandle,
|
||||||
FILE_ALL_ACCESS,
|
SYNCHRONIZE | WRITE_DAC | FILE_READ_DATA | FILE_WRITE_DATA,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
&IoStatus,
|
&IoStatus,
|
||||||
NULL,
|
&AllocationSize,
|
||||||
0,
|
FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN,
|
||||||
0,
|
FILE_SHARE_WRITE,
|
||||||
FILE_OPEN_IF,
|
FILE_SUPERSEDE,
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT,
|
FILE_DELETE_ON_CLOSE | FILE_NO_COMPRESSION | FILE_NO_INTERMEDIATE_BUFFERING,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
CreateFileTypeNone,
|
CreateFileTypeNone,
|
||||||
NULL,
|
NULL,
|
||||||
SL_OPEN_PAGING_FILE | IO_NO_PARAMETER_CHECKING);
|
SL_OPEN_PAGING_FILE | IO_NO_PARAMETER_CHECKING);
|
||||||
|
/* If we failed, relax a bit constraints, someone may be already holding the
|
||||||
|
* the file, so share write, don't attempt to replace and don't delete on close
|
||||||
|
* (basically, don't do anything conflicting)
|
||||||
|
*/
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Status = IoCreateFile(&FileHandle,
|
||||||
|
SYNCHRONIZE | FILE_WRITE_DATA,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatus,
|
||||||
|
&AllocationSize,
|
||||||
|
FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN,
|
||||||
|
FILE_SHARE_WRITE | FILE_SHARE_READ,
|
||||||
|
FILE_OPEN,
|
||||||
|
FILE_NO_COMPRESSION | FILE_NO_INTERMEDIATE_BUFFERING,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
CreateFileTypeNone,
|
||||||
|
NULL,
|
||||||
|
SL_OPEN_PAGING_FILE | IO_NO_PARAMETER_CHECKING);
|
||||||
|
}
|
||||||
|
|
||||||
ReleaseCapturedUnicodeString(&CapturedFileName,
|
ReleaseCapturedUnicodeString(&CapturedFileName,
|
||||||
PreviousMode);
|
PreviousMode);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
DPRINT1("Failed creating page file: %lx\n", Status);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,25 +635,14 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
||||||
|
|
||||||
BytesPerAllocationUnit = FsSizeInformation.SectorsPerAllocationUnit *
|
BytesPerAllocationUnit = FsSizeInformation.SectorsPerAllocationUnit *
|
||||||
FsSizeInformation.BytesPerSector;
|
FsSizeInformation.BytesPerSector;
|
||||||
/* FIXME: If we have 2048 BytesPerAllocationUnit (FAT16 < 128MB) there is
|
|
||||||
* a problem if the paging file is fragmented. Suppose the first cluster
|
|
||||||
* of the paging file is cluster 3042 but cluster 3043 is NOT part of the
|
|
||||||
* paging file but of another file. We can't write a complete page (4096
|
|
||||||
* bytes) to the physical location of cluster 3042 then. */
|
|
||||||
if (BytesPerAllocationUnit % PAGE_SIZE)
|
|
||||||
{
|
|
||||||
DPRINT1("BytesPerAllocationUnit %lu is not a multiple of PAGE_SIZE %d\n",
|
|
||||||
BytesPerAllocationUnit, PAGE_SIZE);
|
|
||||||
ZwClose(FileHandle);
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Set its end of file to initial size */
|
||||||
Status = ZwSetInformationFile(FileHandle,
|
Status = ZwSetInformationFile(FileHandle,
|
||||||
&IoStatus,
|
&IoStatus,
|
||||||
&SafeInitialSize,
|
&SafeInitialSize,
|
||||||
sizeof(LARGE_INTEGER),
|
sizeof(LARGE_INTEGER),
|
||||||
FileAllocationInformation);
|
FileEndOfFileInformation);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status) || !NT_SUCCESS(IoStatus.Status))
|
||||||
{
|
{
|
||||||
ZwClose(FileHandle);
|
ZwClose(FileHandle);
|
||||||
return(Status);
|
return(Status);
|
||||||
|
@ -722,6 +743,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
||||||
|
|
||||||
RtlZeroMemory(PagingFile, sizeof(*PagingFile));
|
RtlZeroMemory(PagingFile, sizeof(*PagingFile));
|
||||||
|
|
||||||
|
PagingFile->FileHandle = FileHandle;
|
||||||
PagingFile->FileObject = FileObject;
|
PagingFile->FileObject = FileObject;
|
||||||
PagingFile->MaximumSize.QuadPart = SafeMaximumSize.QuadPart;
|
PagingFile->MaximumSize.QuadPart = SafeMaximumSize.QuadPart;
|
||||||
PagingFile->CurrentSize.QuadPart = SafeInitialSize.QuadPart;
|
PagingFile->CurrentSize.QuadPart = SafeInitialSize.QuadPart;
|
||||||
|
@ -817,8 +839,6 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
|
||||||
MmNumberOfPagingFiles++;
|
MmNumberOfPagingFiles++;
|
||||||
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
||||||
|
|
||||||
ZwClose(FileHandle);
|
|
||||||
|
|
||||||
MmSwapSpaceMessage = FALSE;
|
MmSwapSpaceMessage = FALSE;
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
|
Loading…
Reference in a new issue