mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:03:00 +00:00
[SMSS2]: Implement the rest of the code to create page files. All that's missing is the actual call to NtCreatePagingFile.
svn path=/trunk/; revision=55400
This commit is contained in:
parent
b7f8e21b52
commit
b1e15cc96d
3 changed files with 407 additions and 7 deletions
|
@ -15,3 +15,12 @@
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
SmpCheckForCrashDump(IN PUNICODE_STRING FileName)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,11 +46,13 @@ typedef struct _SMP_PAGEFILE_DESCRIPTOR
|
||||||
// Structure and flags describing each volume
|
// Structure and flags describing each volume
|
||||||
//
|
//
|
||||||
#define SMP_VOLUME_INSERTED 0x01
|
#define SMP_VOLUME_INSERTED 0x01
|
||||||
|
#define SMP_VOLUME_PAGEFILE_CREATED 0x04
|
||||||
#define SMP_VOLUME_IS_BOOT 0x08
|
#define SMP_VOLUME_IS_BOOT 0x08
|
||||||
typedef struct _SMP_VOLUME_DESCRIPTOR
|
typedef struct _SMP_VOLUME_DESCRIPTOR
|
||||||
{
|
{
|
||||||
LIST_ENTRY Entry;
|
LIST_ENTRY Entry;
|
||||||
ULONG Flags;
|
USHORT Flags;
|
||||||
|
USHORT PageFileCount;
|
||||||
WCHAR DriveLetter;
|
WCHAR DriveLetter;
|
||||||
LARGE_INTEGER FreeSpace;
|
LARGE_INTEGER FreeSpace;
|
||||||
FILE_FS_DEVICE_INFORMATION DeviceInfo;
|
FILE_FS_DEVICE_INFORMATION DeviceInfo;
|
||||||
|
@ -228,15 +230,371 @@ SmpCreatePagingFileDescriptor(IN PUNICODE_STRING PageFileToken)
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
SmpGetPagingFileSize(IN PUNICODE_STRING FileName,
|
||||||
|
OUT PLARGE_INTEGER Size)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
HANDLE FileHandle;
|
||||||
|
FILE_STANDARD_INFORMATION StandardInfo;
|
||||||
|
|
||||||
|
DPRINT1("SMSS:PFILE: Trying to get size for `%wZ'\n", FileName);
|
||||||
|
Size->QuadPart = 0;
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
FileName,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = NtOpenFile(&FileHandle,
|
||||||
|
FILE_READ_ATTRIBUTES | SYNCHRONIZE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatusBlock,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
|
if (!NT_SUCCESS(Status)) return Status;
|
||||||
|
|
||||||
|
Status = NtQueryInformationFile(FileHandle,
|
||||||
|
&IoStatusBlock,
|
||||||
|
&StandardInfo,
|
||||||
|
sizeof(StandardInfo),
|
||||||
|
FileStandardInformation);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("SMSS:PFILE: Failed query for size potential pagefile `%wZ' with status %X \n",
|
||||||
|
FileName, Status);
|
||||||
|
NtClose(FileHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtClose(FileHandle);
|
||||||
|
Size->LowPart = StandardInfo.AllocationSize.LowPart;
|
||||||
|
Size->HighPart = StandardInfo.AllocationSize.HighPart;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
SmpDeletePagingFile(IN PUNICODE_STRING FileName)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
HANDLE FileHandle;
|
||||||
|
FILE_DISPOSITION_INFORMATION Disposition;
|
||||||
|
|
||||||
|
/* Open the page file */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
FileName,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = NtOpenFile(&FileHandle,
|
||||||
|
DELETE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatusBlock,
|
||||||
|
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
FILE_NON_DIRECTORY_FILE);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Delete it */
|
||||||
|
Disposition.DeleteFile = TRUE;
|
||||||
|
Status = NtSetInformationFile(FileHandle,
|
||||||
|
&IoStatusBlock,
|
||||||
|
&Disposition,
|
||||||
|
sizeof(Disposition),
|
||||||
|
FileDispositionInformation);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("SMSS:PFILE: Failed to delete page file `%wZ' (status %X)\n",
|
||||||
|
FileName, Status);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("SMSS:PFILE: Deleted stale paging file - %wZ\n", FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the handle */
|
||||||
|
NtClose(FileHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("SMSS:PFILE: Failed to open for deletion page file `%wZ' (status %X)\n",
|
||||||
|
FileName, Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All done */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
SmpGetVolumeFreeSpace(IN PSMP_VOLUME_DESCRIPTOR Volume)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
LARGE_INTEGER FreeSpace, FinalFreeSpace;
|
||||||
|
FILE_FS_SIZE_INFORMATION SizeInfo;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
UNICODE_STRING VolumeName;
|
||||||
|
HANDLE VolumeHandle;
|
||||||
|
WCHAR PathString[32];
|
||||||
|
ASSERT(Volume->Flags & SMP_VOLUME_IS_BOOT); // ASSERT says "BootVolume == 1"
|
||||||
|
|
||||||
|
/* Build the standard path */
|
||||||
|
wcscpy(PathString, L"\\??\\A:\\");
|
||||||
|
VolumeName.Buffer = PathString;
|
||||||
|
VolumeName.Length = wcslen(PathString) * sizeof(WCHAR);
|
||||||
|
VolumeName.MaximumLength = VolumeName.Length + sizeof(UNICODE_NULL);
|
||||||
|
VolumeName.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = Volume->DriveLetter;
|
||||||
|
DPRINT1("SMSS:PFILE: Querying volume `%wZ' for free space \n", &VolumeName);
|
||||||
|
|
||||||
|
/* Open the volume */
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
&VolumeName,
|
||||||
|
OBJ_CASE_INSENSITIVE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
Status = NtOpenFile(&VolumeHandle,
|
||||||
|
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&IoStatusBlock,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("SMSS:PFILE: Open volume `%wZ' failed with status %X \n", &VolumeName, Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now get size information on the volume */
|
||||||
|
Status = NtQueryVolumeInformationFile(VolumeHandle,
|
||||||
|
&IoStatusBlock,
|
||||||
|
&SizeInfo,
|
||||||
|
sizeof(SizeInfo),
|
||||||
|
FileFsSizeInformation);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* We failed -- keep going */
|
||||||
|
DPRINT1("SMSS:PFILE: Query volume `%wZ' (handle %p) for size failed"
|
||||||
|
" with status %X \n",
|
||||||
|
&VolumeName,
|
||||||
|
VolumeHandle,
|
||||||
|
Status);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Volume);
|
||||||
|
NtClose(VolumeHandle);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
NtClose(VolumeHandle);
|
||||||
|
|
||||||
|
/* Compute how much free space we have */
|
||||||
|
FreeSpace.QuadPart = SizeInfo.AvailableAllocationUnits.QuadPart *
|
||||||
|
SizeInfo.SectorsPerAllocationUnit;
|
||||||
|
FinalFreeSpace.QuadPart = FreeSpace.QuadPart * SizeInfo.BytesPerSector;
|
||||||
|
Volume->FreeSpace = FinalFreeSpace;
|
||||||
|
|
||||||
|
/* Check if there's less than 32MB free so we don't starve the disk */
|
||||||
|
if (FinalFreeSpace.QuadPart <= 0x2000000)
|
||||||
|
{
|
||||||
|
/* In this case, act as if there's no free space */
|
||||||
|
Volume->FreeSpace.QuadPart = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Trim off 32MB to give the disk a bit of breathing room */
|
||||||
|
Volume->FreeSpace.QuadPart = FinalFreeSpace.QuadPart - 0x2000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSMP_VOLUME_DESCRIPTOR
|
||||||
|
NTAPI
|
||||||
|
SmpSearchVolumeDescriptor(IN WCHAR DriveLetter)
|
||||||
|
{
|
||||||
|
WCHAR UpLetter;
|
||||||
|
PSMP_VOLUME_DESCRIPTOR Volume = NULL;
|
||||||
|
PLIST_ENTRY NextEntry;
|
||||||
|
|
||||||
|
/* Use upper case to reduce differences */
|
||||||
|
UpLetter = RtlUpcaseUnicodeChar(DriveLetter);
|
||||||
|
|
||||||
|
/* Loop each volume */
|
||||||
|
NextEntry = SmpVolumeDescriptorList.Flink;
|
||||||
|
while (NextEntry != &SmpVolumeDescriptorList)
|
||||||
|
{
|
||||||
|
/* Grab the entry */
|
||||||
|
Volume = CONTAINING_RECORD(NextEntry, SMP_VOLUME_DESCRIPTOR, Entry);
|
||||||
|
|
||||||
|
/* Make sure it's a valid entry with an uppcase drive letter */
|
||||||
|
ASSERT(Volume->Flags & SMP_VOLUME_INSERTED); // Volume->Initialized in ASSERT
|
||||||
|
ASSERT(Volume->DriveLetter >= L'A' && Volume->DriveLetter <= L'Z');
|
||||||
|
|
||||||
|
/* Break if it matches, if not, keep going */
|
||||||
|
if (Volume->DriveLetter == UpLetter) break;
|
||||||
|
NextEntry = NextEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the volume if one was found */
|
||||||
|
if (NextEntry == &SmpVolumeDescriptorList) Volume = NULL;
|
||||||
|
return Volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
SmpCreatePagingFile(IN PUNICODE_STRING Name,
|
||||||
|
IN PLARGE_INTEGER MinSize,
|
||||||
|
IN PLARGE_INTEGER MaxSize,
|
||||||
|
IN ULONG Priority)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
DPRINT1("Should request pagefile: %wZ with size %I64x and %I64x\n", Name, MinSize->QuadPart, MaxSize->QuadPart);
|
||||||
|
|
||||||
|
/* Tell the kernel to create the pagefile */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
//Status = NtCreatePagingFile(Name, MinSize, MaxSize, Priority);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("SMSS:PFILE: NtCreatePagingFile (%wZ, %I64X, %I64X) succeeded. \n",
|
||||||
|
Name,
|
||||||
|
MinSize->QuadPart,
|
||||||
|
MaxSize->QuadPart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("SMSS:PFILE: NtCreatePagingFile (%wZ, %I64X, %I64X) failed with %X \n",
|
||||||
|
Name,
|
||||||
|
MinSize->QuadPart,
|
||||||
|
MaxSize->QuadPart,
|
||||||
|
Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
SmpCreatePagingFileOnFixedDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor,
|
SmpCreatePagingFileOnFixedDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor,
|
||||||
IN PLARGE_INTEGER FuzzFactor,
|
IN PLARGE_INTEGER FuzzFactor,
|
||||||
IN PLARGE_INTEGER MinimumSize)
|
IN PLARGE_INTEGER MinimumSize)
|
||||||
{
|
{
|
||||||
DPRINT1("Should create fixed pagefile of sizes: %I64d %I64d\n",
|
PSMP_VOLUME_DESCRIPTOR Volume;
|
||||||
FuzzFactor->QuadPart, MinimumSize->QuadPart);
|
BOOLEAN ShouldDelete;
|
||||||
return STATUS_SUCCESS;
|
NTSTATUS Status;
|
||||||
|
LARGE_INTEGER PageFileSize;
|
||||||
|
ASSERT(Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] != L'?');
|
||||||
|
|
||||||
|
/* Try to find the volume descriptor for this drive letter */
|
||||||
|
ShouldDelete = FALSE;
|
||||||
|
Volume = SmpSearchVolumeDescriptor(Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET]);
|
||||||
|
if (!Volume)
|
||||||
|
{
|
||||||
|
/* Couldn't find it, fail */
|
||||||
|
DPRINT1("SMSS:PFILE: No volume descriptor for `%wZ' \n",
|
||||||
|
&Descriptor->Name);
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if this is the boot volume */
|
||||||
|
if (Volume->Flags & SMP_VOLUME_IS_BOOT)
|
||||||
|
{
|
||||||
|
/* Check if we haven't yet processed a crash dump on this volume */
|
||||||
|
if (!(Descriptor->Flags & SMP_PAGEFILE_DUMP_PROCESSED))
|
||||||
|
{
|
||||||
|
/* Try to find a crash dump and extract it */
|
||||||
|
DPRINT1("SMSS:PFILE: Checking for crash dump in `%wZ' on boot volume \n",
|
||||||
|
&Descriptor->Name);
|
||||||
|
SmpCheckForCrashDump(&Descriptor->Name);
|
||||||
|
|
||||||
|
/* Update how much free space we have now that we extracted a dump */
|
||||||
|
Status = SmpGetVolumeFreeSpace(Volume);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("SMSS:PFILE: Failed to query free space for boot volume `%wC'\n",
|
||||||
|
Volume->DriveLetter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't process crashdump on this volume anymore */
|
||||||
|
Descriptor->Flags |= SMP_PAGEFILE_DUMP_PROCESSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Crashdumps can only be on the boot volume */
|
||||||
|
DPRINT1("SMSS:PFILE: Skipping crash dump checking for `%wZ' on non boot"
|
||||||
|
"volume `%wC' \n",
|
||||||
|
&Descriptor->Name,
|
||||||
|
Volume->DriveLetter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the size after dump extraction */
|
||||||
|
Descriptor->ActualMinSize = Descriptor->MinSize;
|
||||||
|
Descriptor->ActualMaxSize = Descriptor->MaxSize;
|
||||||
|
|
||||||
|
/* Check how big we can make the pagefile */
|
||||||
|
Status = SmpGetPagingFileSize(&Descriptor->Name, &PageFileSize);
|
||||||
|
if (PageFileSize.QuadPart > 0) ShouldDelete = TRUE;
|
||||||
|
DPRINT1("SMSS:PFILE: Detected size %I64X for future paging file `%wZ'\n",
|
||||||
|
PageFileSize,
|
||||||
|
&Descriptor->Name);
|
||||||
|
DPRINT1("SMSS:PFILE: Free space on volume `%wC' is %I64X \n",
|
||||||
|
Volume->DriveLetter,
|
||||||
|
Volume->FreeSpace.QuadPart);
|
||||||
|
|
||||||
|
/* Now update our size and make sure none of these are too big */
|
||||||
|
PageFileSize.QuadPart += Volume->FreeSpace.QuadPart;
|
||||||
|
if (Descriptor->ActualMinSize.QuadPart > PageFileSize.QuadPart)
|
||||||
|
{
|
||||||
|
Descriptor->ActualMinSize = PageFileSize;
|
||||||
|
}
|
||||||
|
if (Descriptor->ActualMaxSize.QuadPart > PageFileSize.QuadPart)
|
||||||
|
{
|
||||||
|
Descriptor->ActualMaxSize = PageFileSize;
|
||||||
|
}
|
||||||
|
DPRINT1("SMSS:PFILE: min %I64X, max %I64X, real min %I64X \n",
|
||||||
|
Descriptor->ActualMinSize.QuadPart,
|
||||||
|
Descriptor->ActualMaxSize.QuadPart,
|
||||||
|
MinimumSize->QuadPart);
|
||||||
|
|
||||||
|
/* Keep going until we've created a pagefile of the right size */
|
||||||
|
while (Descriptor->ActualMinSize.QuadPart >= MinimumSize->QuadPart)
|
||||||
|
{
|
||||||
|
/* Call NT to do it */
|
||||||
|
Status = SmpCreatePagingFile(&Descriptor->Name,
|
||||||
|
&Descriptor->ActualMinSize,
|
||||||
|
&Descriptor->ActualMaxSize,
|
||||||
|
0);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* We're done, update flags and increase the count */
|
||||||
|
Descriptor->Flags |= SMP_PAGEFILE_CREATED;
|
||||||
|
Volume->Flags |= SMP_VOLUME_PAGEFILE_CREATED;
|
||||||
|
Volume->PageFileCount++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We failed, try a slighly smaller pagefile */
|
||||||
|
Descriptor->ActualMinSize.QuadPart -= FuzzFactor->QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we weren't able to create it */
|
||||||
|
if (Descriptor->ActualMinSize.QuadPart < MinimumSize->QuadPart)
|
||||||
|
{
|
||||||
|
/* Delete the current page file and fail */
|
||||||
|
if (ShouldDelete) SmpDeletePagingFile(&Descriptor->Name);
|
||||||
|
DPRINT1("SMSS:PFILE: Failing for min %I64X, max %I64X, real min %I64X \n",
|
||||||
|
Descriptor->ActualMinSize.QuadPart,
|
||||||
|
Descriptor->ActualMaxSize.QuadPart,
|
||||||
|
MinimumSize->QuadPart);
|
||||||
|
Status = STATUS_DISK_FULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the status */
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -245,9 +603,36 @@ SmpCreatePagingFileOnAnyDrive(IN PSMP_PAGEFILE_DESCRIPTOR Descriptor,
|
||||||
IN PLARGE_INTEGER FuzzFactor,
|
IN PLARGE_INTEGER FuzzFactor,
|
||||||
IN PLARGE_INTEGER MinimumSize)
|
IN PLARGE_INTEGER MinimumSize)
|
||||||
{
|
{
|
||||||
DPRINT1("Should create 'any' pagefile of sizes: %I64d %I64d\n",
|
PSMP_VOLUME_DESCRIPTOR Volume;
|
||||||
FuzzFactor->QuadPart, MinimumSize->QuadPart);
|
NTSTATUS Status = STATUS_DISK_FULL;
|
||||||
return STATUS_SUCCESS;
|
PLIST_ENTRY NextEntry;
|
||||||
|
ASSERT(Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] == L'?');
|
||||||
|
|
||||||
|
/* Loop the volume list */
|
||||||
|
NextEntry = SmpVolumeDescriptorList.Flink;
|
||||||
|
while (NextEntry != &SmpVolumeDescriptorList)
|
||||||
|
{
|
||||||
|
/* Get the volume */
|
||||||
|
Volume = CONTAINING_RECORD(NextEntry, SMP_VOLUME_DESCRIPTOR, Entry);
|
||||||
|
|
||||||
|
/* Make sure it's inserted and on a valid drive letter */
|
||||||
|
ASSERT(Volume->Flags & SMP_VOLUME_INSERTED); // Volume->Initialized in ASSERT
|
||||||
|
ASSERT(Volume->DriveLetter >= L'A' && Volume->DriveLetter <= L'Z');
|
||||||
|
|
||||||
|
/* Write the drive letter to try creating it on this volume */
|
||||||
|
Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = Volume->DriveLetter;
|
||||||
|
Status = SmpCreatePagingFileOnFixedDrive(Descriptor,
|
||||||
|
FuzzFactor,
|
||||||
|
MinimumSize);
|
||||||
|
if (NT_SUCCESS(Status)) break;
|
||||||
|
|
||||||
|
/* It didn't work, make it an any pagefile again and keep going */
|
||||||
|
Descriptor->Name.Buffer[STANDARD_DRIVE_LETTER_OFFSET] = L'?';
|
||||||
|
NextEntry = NextEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return disk full or success */
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -181,4 +181,10 @@ SmpRestoreBootStatusData(
|
||||||
IN BOOLEAN ShutdownOkay
|
IN BOOLEAN ShutdownOkay
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
SmpCheckForCrashDump(
|
||||||
|
IN PUNICODE_STRING FileName
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue