Compare commits

..

6 Commits

Author SHA1 Message Date
11683762c3 [NTOSKRNL:CC] Calculate Dirty Pages like NT5 2024-08-18 07:28:25 +02:00
3ae19eaf01 [NTOSKRNL::CC] Implement CcOkToAddWriteBehindThread 2024-08-17 20:13:20 +02:00
e75a2adeec [NTOSKRNL:CC] Implement CcAdjustWriteBehindThreadPool and CcAdjustWriteBehindThreadPoolIfNeeded
These two function are responsible for  calling threadpool,when needed
2024-08-17 15:32:37 +02:00
1c173364a1 [NTOSKRNL::CC]Implement CcRescheduleLazyWriteScan CcSetLazyWriteScanQueued
These two function Rescheduling and Scheduling Lazy write scan
2024-08-17 15:08:39 +02:00
104a0212e0 [NTOSKRNL:CC] Add CcQueueLazyWriteScanThread
Implemented CcQueueLazyWriteScanThread
2024-08-17 08:47:34 +02:00
1dec536c4d [NTOSKRNL:CC] Threadpool 2024-08-16 07:53:05 +02:00
16 changed files with 415 additions and 1317 deletions

View File

@@ -49,7 +49,6 @@ Return Value:
// //
Status = BlInitializeLibrary(InputParameters, &LibraryParameters); Status = BlInitializeLibrary(InputParameters, &LibraryParameters);
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
ConsolePrintf(L"BlInitializeLibrary() failed: 0x%x\r\n", Status);
goto Exit; goto Exit;
} }

View File

@@ -23,33 +23,6 @@ typedef struct {
ULONG Flags; ULONG Flags;
} BOOT_LIBRARY_PARAMETERS, *PBOOT_LIBRARY_PARAMETERS; } BOOT_LIBRARY_PARAMETERS, *PBOOT_LIBRARY_PARAMETERS;
VOID
ConsolePrint (
IN PWSTR String
);
VOID
ConsolePrintf (
IN PWSTR Format,
...
);
ULONG
BlGetBootOptionSize (
IN PBOOT_APPLICATION_ENTRY_OPTION Option
);
ULONG
BlGetBootOptionListSize (
IN PBOOT_APPLICATION_ENTRY_OPTION Options
);
NTSTATUS
BlpFwInitialize (
IN ULONG Stage,
IN PBOOT_FIRMWARE_DATA FirmwareData
);
NTSTATUS NTSTATUS
BlInitializeLibrary ( BlInitializeLibrary (
IN PBOOT_INPUT_PARAMETERS InputParameters, IN PBOOT_INPUT_PARAMETERS InputParameters,

View File

@@ -67,29 +67,18 @@ typedef struct {
ULONG BootDeviceOffset; ULONG BootDeviceOffset;
ULONG FirmwareDataOffset; ULONG FirmwareDataOffset;
ULONG ReturnDataOffset; ULONG ReturnDataOffset;
ULONG PlatformDataOffset; ULONG PlatformDataOffset;
} BOOT_INPUT_PARAMETERS, *PBOOT_INPUT_PARAMETERS; } BOOT_INPUT_PARAMETERS, *PBOOT_INPUT_PARAMETERS;
typedef struct {
ULONG Type;
ULONG DataOffset;
ULONG DataSize;
ULONG OtherOptionsOffset;
ULONG NextOptionOffset;
BOOLEAN IsInvalid;
UCHAR Unknown[3];
} BOOT_APPLICATION_ENTRY_OPTION, *PBOOT_APPLICATION_ENTRY_OPTION;
#define BOOT_APPLICATION_ENTRY_SIGNATURE 0x544e4550415442 /* "BTAPENT" */ #define BOOT_APPLICATION_ENTRY_SIGNATURE 0x544e4550415442 /* "BTAPENT" */
#define BOOT_APPLICATION_ENTRY_NO_BCD_IDENTIFIER 0x01 #define BOOT_APPLICATION_ENTRY_BCD_IDENTIFIER_NOT_SET 0x01
typedef struct { typedef struct {
ULONGLONG Signature; ULONGLONG Signature;
ULONG Attributes; ULONG Attributes;
GUID BcdIdentifier; GUID BcdIdentifier;
UCHAR Unknown[16];
BOOT_APPLICATION_ENTRY_OPTION Options;
} BOOT_APPLICATION_ENTRY, *PBOOT_APPLICATION_ENTRY; } BOOT_APPLICATION_ENTRY, *PBOOT_APPLICATION_ENTRY;
#define BOOT_MEMORY_INFO_VERSION 1 #define BOOT_MEMORY_INFO_VERSION 1
@@ -134,116 +123,9 @@ typedef struct {
} BOOT_RETURN_DATA, *PBOOT_RETURN_DATA; } BOOT_RETURN_DATA, *PBOOT_RETURN_DATA;
typedef struct { typedef struct {
LARGE_INTEGER ImageBase;
ULONG ImageSize;
ULONG ImageOffset;
} BOOT_RAMDISK_IDENTIFIER, *PBOOT_RAMDISK_IDENTIFIER;
#define BOOT_HARDDRIVE_PARTITION_TYPE_GPT 0x00
#define BOOT_HARDDRIVE_PARTITION_TYPE_MBR 0x01
#define BOOT_HARDDRIVE_PARTITION_TYPE_RAW 0x02
typedef struct {
ULONG PartitionType;
union {
struct {
ULONG Signature;
} Mbr;
struct {
GUID Signature;
} Gpt;
struct {
ULONG DriveNumber;
} Raw;
};
} BOOT_HARDDRIVE_IDENTIFIER, *PBOOT_HARDDRIVE_IDENTIFIER;
typedef struct {
ULONG DriveNumber;
} BOOT_CDROM_IDENTIFIER, *PBOOT_CDROM_IDENTIFIER;
#define BOOT_BLOCK_DEVICE_TYPE_HARDDRIVE 0x00
#define BOOT_BLOCK_DEVICE_TYPE_CDROM 0x02
#define BOOT_BLOCK_DEVICE_TYPE_RAMDISK 0x03
typedef struct {
ULONG Type;
union {
BOOT_RAMDISK_IDENTIFIER Ramdisk;
BOOT_HARDDRIVE_IDENTIFIER Harddrive;
BOOT_CDROM_IDENTIFIER Cdrom;
};
} BOOT_BLOCK_IDENTIFIER, *PBOOT_BLOCK_IDENTIFIER;
typedef struct {
union {
struct {
ULONG PartitionNumber;
} Mbr;
struct {
GUID PartitionIdentifier;
} Gpt;
struct {
ULONG BootEntry;
} ElTorito;
};
BOOT_BLOCK_IDENTIFIER Parent;
} BOOT_PARTITION_IDENTIFIER, *PBOOT_PARTITION_IDENTIFIER;
typedef struct {
union {
struct {
PVOID PartitionOffset;
} Mbr;
struct {
GUID PartitionIdentifier;
} Gpt;
struct {
ULONG BootEntry;
} ElTorito;
};
BOOT_BLOCK_IDENTIFIER Parent;
} BOOT_PARTITION_IDENTIFIER_EX, *PBOOT_PARTITION_IDENTIFIER_EX;
#define BOOT_DEVICE_TYPE_BLOCK 0x00
#define BOOT_DEVICE_TYPE_PARTITION 0x02
#define BOOT_DEVICE_TYPE_PARTITION_EX 0x06
#define BOOT_DEVICE_ATTRIBUTE_NO_PARENT_SIGNATURE 0x04
typedef struct {
ULONG Type;
ULONG Attributes;
ULONG Size; ULONG Size;
ULONG Pad;
union {
BOOT_BLOCK_IDENTIFIER Block;
BOOT_PARTITION_IDENTIFIER Partition;
BOOT_PARTITION_IDENTIFIER_EX PartitionEx;
};
} BOOT_DEVICE, *PBOOT_DEVICE; } BOOT_DEVICE, *PBOOT_DEVICE;
typedef enum {
BCDE_DATA_TYPE_APPLICATION_DEVICE = 0x11000001,
BCDE_DATA_TYPE_APPLICATION_PATH = 0x22000002
} BCDE_DATA_TYPE;
typedef struct {
GUID OtherOptions;
BOOT_DEVICE Device;
} BCDE_DEVICE, *PBCDE_DEVICE;
NTSTATUS NTSTATUS
BmMain ( BmMain (
IN PBOOT_INPUT_PARAMETERS InputParameters IN PBOOT_INPUT_PARAMETERS InputParameters

View File

@@ -24,40 +24,8 @@ typedef struct _EFI_DEVICE_PATH_PROTOCOL {
typedef struct _EFI_DEVICE_PATH_PROTOCOL _EFI_DEVICE_PATH; typedef struct _EFI_DEVICE_PATH_PROTOCOL _EFI_DEVICE_PATH;
typedef EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH; typedef EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH;
#define END_DEVICE_PATH_TYPE 0x7f
#define HARDWARE_DEVICE_PATH 0x01
#define HW_MEMMAP_DP 0x03
typedef struct {
EFI_DEVICE_PATH Header;
UINT32 MemoryType;
EFI_PHYSICAL_ADDRESS StartingAddress;
EFI_PHYSICAL_ADDRESS EndingAddress;
} MEMMAP_DEVICE_PATH;
#define MEDIA_DEVICE_PATH 0x04 #define MEDIA_DEVICE_PATH 0x04
#define MEDIA_HARDDRIVE_DP 0x01
typedef struct {
EFI_DEVICE_PATH Header;
UINT32 PartitionNumber;
UINT64 PartitionStart;
UINT64 PartitionSize;
UINT8 Signature[16];
UINT8 MBRType;
UINT8 SignatureType;
} HARDDRIVE_DEVICE_PATH;
#define MBR_TYPE_PCAT 0x01
#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
#define NO_DISK_SIGNATURE 0x00
#define SIGNATURE_TYPE_MBR 0x01
#define SIGNATURE_TYPE_GUID 0x02
#define MEDIA_CDROM_DP 0x02 #define MEDIA_CDROM_DP 0x02
typedef struct { typedef struct {
@@ -67,13 +35,6 @@ typedef struct {
UINT64 PartitionSize; UINT64 PartitionSize;
} CDROM_DEVICE_PATH; } CDROM_DEVICE_PATH;
#define MEDIA_FILEPATH_DP 0x04
typedef struct {
EFI_DEVICE_PATH Header;
CHAR16 PathName[1];
} FILEPATH_DEVICE_PATH;
FORCEINLINE FORCEINLINE
UINT8 UINT8
DevicePathType ( DevicePathType (

View File

@@ -1,82 +0,0 @@
/*++
Copyright (c) 2024, Quinn Stephens.
Provided under the BSD 3-Clause license.
Module Name:
eficon.c
Abstract:
Provides EFI console utilities.
--*/
#include <stdarg.h>
#include <wchar.h>
#include "bootmgr.h"
extern SIMPLE_TEXT_OUTPUT_INTERFACE *EfiConOut;
VOID
ConsolePrint (
IN PWSTR String
)
/*++
Routine Description:
Prints a string to the console.
Arguments:
String - string to print.
Return Value:
None.
--*/
{
EfiConOut->OutputString(EfiConOut, String);
}
VOID
ConsolePrintf (
IN PWSTR Format,
...
)
/*++
Routine Description:
Prints a formatted string to the console.
Arguments:
Format - format string handled by vswprintf().
... - arguments.
Return Value:
None.
--*/
{
int Status;
va_list Args;
WCHAR Buffer[256];
va_start(Args, Format);
Status = vswprintf(Buffer, sizeof(Buffer) / sizeof(WCHAR) - 1, Format, Args);
va_end(Args);
if (Status > 0) {
ConsolePrint(Buffer);
}
}

View File

@@ -1,64 +0,0 @@
/*++
Copyright (c) 2024, Quinn Stephens.
Provided under the BSD 3-Clause license.
Module Name:
efifw.c
Abstract:
Provides EFI firmware utilities.
--*/
#include "bootlib.h"
#include "bootmgr.h"
EFI_SYSTEM_TABLE *EfiST;
EFI_BOOT_SERVICES *EfiBS;
EFI_RUNTIME_SERVICES *EfiRT;
SIMPLE_TEXT_OUTPUT_INTERFACE *EfiConOut;
SIMPLE_INPUT_INTERFACE *EfiConIn;
NTSTATUS
BlpFwInitialize (
IN ULONG Stage,
IN PBOOT_FIRMWARE_DATA FirmwareData
)
/*++
Routine Description:
Internal routine to initialize the boot library.
Arguments:
Stage - 0 or 1.
FirmwareData - firmware data structure to use for initialization.
Return Value:
STATUS_SUCCESS if successful,
STATUS_INVALID_PARAMETER if FirmwareData is invalid.
--*/
{
if (FirmwareData == NULL || FirmwareData->Version == 0) {
return STATUS_INVALID_PARAMETER;
}
if (Stage == 0) {
EfiST = FirmwareData->SystemTable;
EfiBS = EfiST->BootServices;
EfiRT = EfiST->RuntimeServices;
EfiConOut = EfiST->ConOut;
EfiConIn = EfiST->ConIn;
}
return STATUS_SUCCESS;
}

View File

@@ -16,7 +16,6 @@ Abstract:
#include <ntrtl.h> #include <ntrtl.h>
#include <string.h> #include <string.h>
#include <wchar.h> #include <wchar.h>
#include "bootlib.h"
#include "bootmgr.h" #include "bootmgr.h"
#include "efi.h" #include "efi.h"
@@ -24,447 +23,15 @@ UCHAR EfiInitScratch[2048];
const EFI_GUID EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL; const EFI_GUID EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
const EFI_GUID EfiDevicePathProtocol = DEVICE_PATH_PROTOCOL; const EFI_GUID EfiDevicePathProtocol = DEVICE_PATH_PROTOCOL;
NTSTATUS
EfiInitpAppendPathString (
IN PWCHAR Destination,
IN ULONG BufferSize,
IN PWCHAR Source,
IN ULONG SourceSize,
IN OUT PULONG BufferUsed
)
/*++
Routine Description:
Appends a soure path to a destination path.
Arguments:
Destination - the path to append to.
BufferSize - the maximum number of bytes to append.
Source - the source path to append to Destination.
SourceSize - the size of Source, in bytes.
BufferUsed - pointer to a ULONG to store the number of bytes appended in.
Return Value:
STATUS_SUCCESS if successful,
STATUS_INVALID_PARAMETER if Destination is not valid,
STATUS_BUFFER_TOO_SMALL if BufferSize is too small.
--*/
{
ULONG Position;
//
// Verify that Source uses wide characters.
//
if (SourceSize % sizeof(WCHAR) != 0) {
return STATUS_INVALID_PARAMETER;
}
//
// Remove NULL terminator.
//
if (SourceSize >= sizeof(WCHAR)) {
Position = (SourceSize / sizeof(WCHAR)) - 1;
if (Source[Position] == UNICODE_NULL) {
SourceSize -= sizeof(UNICODE_NULL);
}
}
//
// Remove leading separator.
//
if (SourceSize >= sizeof(WCHAR)) {
if (Source[0] == L'\\') {
Source++;
SourceSize -= sizeof(WCHAR);
}
}
//
// Remove trailing separator.
//
if (SourceSize >= sizeof(WCHAR)) {
Position = (SourceSize / sizeof(WCHAR)) - 1;
if (Source[Position] == L'\\') {
SourceSize -= sizeof(WCHAR);
}
}
//
// Check if Source is empty.
//
if (SourceSize == 0) {
*BufferUsed = 0;
return STATUS_SUCCESS;
}
//
// Make sure the buffer is large enough.
//
if (BufferSize < SourceSize + sizeof(WCHAR)) {
return STATUS_BUFFER_TOO_SMALL;
}
//
// Append separator and Source to Destination.
//
Destination[0] = L'\\';
RtlCopyMemory(Destination + 1, Source, SourceSize);
*BufferUsed = SourceSize + sizeof(WCHAR);
return STATUS_SUCCESS;
}
EFI_DEVICE_PATH *
EfiInitpGetDeviceNode (
IN EFI_DEVICE_PATH *DevicePath
)
/*++
Routine Description:
Searches an EFI device path for the last device path node
before a file path node.
Arguments:
DevicePath - EFI device path to search.
Return Value:
Pointer to the last device path node.
--*/
{
EFI_DEVICE_PATH *Node;
//
// Check if the current node is the end of the path.
//
if (IsDevicePathEndType(DevicePath)) {
return DevicePath;
}
//
// Find the last non-filepath node.
//
Node = NextDevicePathNode(DevicePath);
while (!IsDevicePathEndType(Node)) {
if (DevicePathType(Node) == MEDIA_DEVICE_PATH && DevicePathSubType(Node) == MEDIA_FILEPATH_DP) {
break;
}
DevicePath = Node;
Node = NextDevicePathNode(Node);
}
return DevicePath;
}
NTSTATUS
EfiInitTranslateDevicePath (
IN EFI_DEVICE_PATH *EfiDevicePath,
IN OUT PBOOT_DEVICE BootDevice,
IN ULONG BufferSize
)
/*++
Routine Description:
Translates an EFI device path into boot device format.
Arguments:
EfiDevicePath - The EFI device path to be translated.
BootDevice - Pointer to the destination device structure.
BufferSize - The amount of available space in the buffer.
Return Value:
STATUS_SUCCESS if successful,
STATUS_INVALID_PARAMETER if the buffer is too small.
STATUS_UNSUCCESSFUL if the path could not be translated.
--*/
{
EFI_DEVICE_PATH *DeviceNode;
MEMMAP_DEVICE_PATH *MemmapNode;
HARDDRIVE_DEVICE_PATH *HarddriveNode;
PBOOT_BLOCK_IDENTIFIER BlockDevice;
//
// Check for available buffer space.
//
if (BufferSize < sizeof(BOOT_DEVICE)) {
return STATUS_INVALID_PARAMETER;
}
BootDevice->Size = sizeof(BOOT_DEVICE);
//
// Memory mapped device paths are treated as ramdisks.
//
if (DevicePathType(EfiDevicePath) == HARDWARE_DEVICE_PATH && DevicePathSubType(EfiDevicePath) == HW_MEMMAP_DP) {
MemmapNode = (MEMMAP_DEVICE_PATH *)EfiDevicePath;
BlockDevice = &BootDevice->Block;
BootDevice->Type = BOOT_DEVICE_TYPE_BLOCK;
BlockDevice->Type = BOOT_BLOCK_DEVICE_TYPE_RAMDISK;
BlockDevice->Ramdisk.ImageBase.QuadPart = MemmapNode->StartingAddress;
BlockDevice->Ramdisk.ImageSize = MemmapNode->EndingAddress - MemmapNode->StartingAddress;
BlockDevice->Ramdisk.ImageOffset = 0;
return STATUS_SUCCESS;
}
//
// Get the device node, the device the application was loaded from.
// TODO: Only media devices and ramdisks are currently supported.
//
DeviceNode = EfiInitpGetDeviceNode(EfiDevicePath);
if (DevicePathType(DeviceNode) != MEDIA_DEVICE_PATH) {
return STATUS_UNSUCCESSFUL;
}
//
// Check device node subtype.
//
switch (DevicePathSubType(DeviceNode)) {
case MEDIA_HARDDRIVE_DP:
HarddriveNode = (HARDDRIVE_DEVICE_PATH *)DeviceNode;
//
// Use correct block device and partition format.
//
if (HarddriveNode->SignatureType != SIGNATURE_TYPE_MBR) {
BlockDevice = &BootDevice->PartitionEx.Parent;
BootDevice->Type = BOOT_DEVICE_TYPE_PARTITION_EX;
} else {
BlockDevice = &BootDevice->Partition.Parent;
BootDevice->Type = BOOT_DEVICE_TYPE_PARTITION;
}
BlockDevice->Type = BOOT_BLOCK_DEVICE_TYPE_HARDDRIVE;
//
// Initialize partition based on the drive's partitioning system.
//
switch (HarddriveNode->SignatureType) {
case SIGNATURE_TYPE_MBR:
BlockDevice->Harddrive.PartitionType = BOOT_HARDDRIVE_PARTITION_TYPE_MBR;
BlockDevice->Harddrive.Mbr.Signature = *((ULONG *)HarddriveNode->Signature);
BootDevice->Partition.Mbr.PartitionNumber = HarddriveNode->PartitionNumber;
break;
case SIGNATURE_TYPE_GUID:
BootDevice->Attributes |= BOOT_DEVICE_ATTRIBUTE_NO_PARENT_SIGNATURE;
BlockDevice->Harddrive.PartitionType = BOOT_HARDDRIVE_PARTITION_TYPE_GPT;
RtlCopyMemory(&BootDevice->PartitionEx.Gpt.PartitionIdentifier, &HarddriveNode->Signature, sizeof(HarddriveNode->Signature));
break;
default:
BlockDevice->Harddrive.PartitionType = BOOT_HARDDRIVE_PARTITION_TYPE_RAW;
BlockDevice->Harddrive.Raw.DriveNumber = 0;
}
break;
case MEDIA_CDROM_DP:
BootDevice->Type = BOOT_DEVICE_TYPE_BLOCK;
BootDevice->Block.Type = BOOT_BLOCK_DEVICE_TYPE_CDROM;
BootDevice->Block.Cdrom.DriveNumber = 0;
break;
default:
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
NTSTATUS
EfiInitpConvertEfiDevicePath (
IN EFI_DEVICE_PATH *EfiDevicePath,
IN BCDE_DATA_TYPE OptionType,
IN OUT PBOOT_APPLICATION_ENTRY_OPTION Option,
IN ULONG BufferSize
)
/*++
Routine Description:
Converts an EFI device path into BCD format.
Arguments:
EfiDevicePath - The EFI device path to be converted.
OptionType - The data type to be assigned to option.
Option - Pointer to the destination option structure.
BufferSize - The amount of available space in the buffer.
Return Value:
STATUS_SUCCESS if successful.
other NTSTATUS value if failure occurs.
--*/
{
NTSTATUS Status;
PBCDE_DEVICE DeviceElement;
//
// Check for available buffer space.
//
if (BufferSize < sizeof(BOOT_APPLICATION_ENTRY_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device)) {
return STATUS_INVALID_PARAMETER;
}
//
// Translate device path.
//
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_ENTRY_OPTION));
DeviceElement = (PBCDE_DEVICE)((PUCHAR)Option + sizeof(BOOT_APPLICATION_ENTRY_OPTION));
Status = EfiInitTranslateDevicePath(
EfiDevicePath,
&DeviceElement->Device,
BufferSize - (sizeof(BOOT_APPLICATION_ENTRY_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device))
);
if (!NT_SUCCESS(Status)) {
return Status;
}
//
// Set up option structure.
//
Option->Type = OptionType;
Option->DataOffset = sizeof(BOOT_APPLICATION_ENTRY_OPTION);
Option->DataSize = FIELD_OFFSET(BCDE_DEVICE, Device) + DeviceElement->Device.Size;
return STATUS_SUCCESS;
}
NTSTATUS
EfiInitpConvertEfiFilePath (
IN EFI_DEVICE_PATH *EfiFilePath,
IN BCDE_DATA_TYPE OptionType,
IN OUT PBOOT_APPLICATION_ENTRY_OPTION Option,
IN ULONG BufferSize
)
/*++
Routine Description:
Converts an EFI file path into BCD format.
Arguments:
EfiFilePath - The EFI file path to be converted.
OptionType - The data type to be assigned to option.
Option - Pointer to the destination option structure.
BufferSize - The amount of available space in the buffer.
Return Value:
STATUS_SUCCESS if successful.
other NTSTATUS value if failure occurs.
--*/
{
NTSTATUS Status;
EFI_DEVICE_PATH *Node;
PWCHAR PathStart, Position;
ULONG BufferRemaining, Length, Appended;
//
// Check for available buffer space.
//
if (BufferSize < sizeof(BOOT_APPLICATION_ENTRY_OPTION)) {
return STATUS_INVALID_PARAMETER;
}
//
// Set up option structure.
//
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_ENTRY_OPTION));
Option->Type = OptionType;
Option->DataOffset = sizeof(BOOT_APPLICATION_ENTRY_OPTION);
//
// Add to the path one file path node at a time.
//
Option->DataSize = 0;
BufferRemaining = BufferSize - sizeof(BOOT_APPLICATION_ENTRY_OPTION);
Node = EfiFilePath;
PathStart = (PWCHAR)((PUCHAR)Option + Option->DataOffset);
Position = PathStart;
while (!IsDevicePathEndType(Node)) {
if (DevicePathType(Node) != MEDIA_DEVICE_PATH || DevicePathSubType(Node) != MEDIA_FILEPATH_DP) {
Node = NextDevicePathNode(Node);
continue;
}
Status = RtlULongSub(DevicePathNodeLength(Node), FIELD_OFFSET(FILEPATH_DEVICE_PATH, PathName), &Length);
if (!NT_SUCCESS(Status)) {
return Status;
}
Status = EfiInitpAppendPathString(Position, BufferRemaining, &((FILEPATH_DEVICE_PATH *)Node)->PathName[0], Length, &Appended);
if (!NT_SUCCESS(Status)) {
return Status;
}
Option->DataSize += Appended;
BufferRemaining -= Appended;
Position = (PWCHAR)((PUCHAR)Position + Appended);
Node = NextDevicePathNode(Node);
}
//
// Terminate path string.
//
if (BufferRemaining < sizeof(UNICODE_NULL)) {
return STATUS_INVALID_PARAMETER;
}
*Position = L'\0';
Option->DataSize += sizeof(UNICODE_NULL);
//
// The path option is invalid if the path is NULL.
//
if (Position == PathStart) {
Option->IsInvalid = TRUE;
}
return STATUS_SUCCESS;
}
VOID VOID
EfiInitpCreateApplicationEntry ( EfiInitpCreateApplicationEntry (
IN EFI_SYSTEM_TABLE *SystemTable, IN EFI_SYSTEM_TABLE *SystemTable,
IN OUT PBOOT_APPLICATION_ENTRY Entry, IN OUT PBOOT_APPLICATION_ENTRY Entry,
IN ULONG BufferSize, IN ULONG BufferSize,
IN EFI_DEVICE_PATH *EfiDevicePath, IN EFI_DEVICE_PATH *DevicePath,
IN EFI_DEVICE_PATH *EfiFilePath, IN EFI_DEVICE_PATH *FilePath,
IN PWCHAR LoadOptions, IN PWCHAR LoadOptions,
IN ULONG LoadOptionsSize, IN ULONG LoadOptionsSize,
IN ULONG Flags,
OUT PULONG BufferUsed, OUT PULONG BufferUsed,
OUT PBOOT_DEVICE *BootDevice OUT PBOOT_DEVICE *BootDevice
) )
@@ -483,16 +50,14 @@ Arguments:
BufferSize - The amount of available space in the buffer. BufferSize - The amount of available space in the buffer.
EfiDevicePath - The device path for the application. DevicePath - The device path for the application.
EfiFilePath - The file path for the application. FilePath - The file path for the application.
LoadOptions - Firmware load options string. LoadOptions - Firmware load options string.
LoadOptionsSize - Length of the string pointed to by LoadOptions. LoadOptionsSize - Length of the string pointed to by LoadOptions.
Flags - Unused.
BufferUsed - Returns the amount of buffer space used by the routine. BufferUsed - Returns the amount of buffer space used by the routine.
BootDevice - Returns a pointer to the device the application was loaded from. BootDevice - Returns a pointer to the device the application was loaded from.
@@ -504,39 +69,21 @@ Return Value:
--*/ --*/
{ {
NTSTATUS Status;
ULONG BufferRemaining, OptionsSize, Size;
PWCHAR BcdOptionString; PWCHAR BcdOptionString;
BOOLEAN BcdIdentifierSet; BOOLEAN BcdIdentifierSet;
UNICODE_STRING UnicodeString; UNICODE_STRING UnicodeString;
PBOOT_APPLICATION_ENTRY_OPTION Option, PrevOption;
PBCDE_DEVICE BootDeviceElement;
(VOID)SystemTable;
(VOID)EfiDevicePath;
(VOID)EfiFilePath;
(VOID)Flags;
*BufferUsed = 0; *BufferUsed = 0;
*BootDevice = NULL; *BootDevice = NULL;
OptionsSize = 0;
BcdIdentifierSet = FALSE; BcdIdentifierSet = FALSE;
// //
// Require enough space for the application entry. // Require enough space for the application entry.
// //
BufferRemaining = BufferSize; if (BufferSize < sizeof(BOOT_APPLICATION_ENTRY)) {
if (BufferRemaining < sizeof(BOOT_APPLICATION_ENTRY)) {
return; return;
} }
//
// Set up application entry structure.
//
RtlZeroMemory(Entry, sizeof(BOOT_APPLICATION_ENTRY));
Entry->Signature = BOOT_APPLICATION_ENTRY_SIGNATURE;
BufferRemaining -= FIELD_OFFSET(BOOT_APPLICATION_ENTRY, Options);
// //
// Terminate load options string. // Terminate load options string.
// //
@@ -545,6 +92,13 @@ Return Value:
LoadOptions[LoadOptionsSize - 1] = L'\0'; LoadOptions[LoadOptionsSize - 1] = L'\0';
} }
//
// Set up application entry structure.
//
RtlZeroMemory(Entry, sizeof(BOOT_APPLICATION_ENTRY));
Entry->Signature = BOOT_APPLICATION_ENTRY_SIGNATURE;
*BufferUsed = sizeof(BOOT_APPLICATION_ENTRY);
// //
// Parse BCD GUID if present. // Parse BCD GUID if present.
// //
@@ -556,51 +110,15 @@ Return Value:
} }
if (!BcdIdentifierSet) { if (!BcdIdentifierSet) {
Entry->Attributes |= BOOT_APPLICATION_ENTRY_NO_BCD_IDENTIFIER; Entry->Attributes |= BOOT_APPLICATION_ENTRY_BCD_IDENTIFIER_NOT_SET;
} }
// //
// Convert the EFI device path into a boot device option. // TODO: This routine is not fully implemented.
// //
Option = &Entry->Options; (VOID)SystemTable;
Status = EfiInitpConvertEfiDevicePath(EfiDevicePath, BCDE_DATA_TYPE_APPLICATION_DEVICE, Option, BufferRemaining); (VOID)DevicePath;
if (!NT_SUCCESS(Status)) { (VOID)FilePath;
Option->IsInvalid = TRUE;
goto exit;
}
BootDeviceElement = (PBCDE_DEVICE)((PUCHAR)Option + Option->DataOffset);
*BootDevice = &BootDeviceElement->Device;
Size = BlGetBootOptionSize(Option);
OptionsSize += Size;
BufferRemaining -= Size;
//
// Convert the EFI file path into a boot file path option.
// TODO: UDP/PXE boot is not supported.
//
PrevOption = Option;
Option = (PBOOT_APPLICATION_ENTRY_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
Status = EfiInitpConvertEfiFilePath(EfiFilePath, BCDE_DATA_TYPE_APPLICATION_PATH, Option, BufferRemaining);
if (!NT_SUCCESS(Status)) {
goto exit;
}
PrevOption->NextOptionOffset = (PUCHAR)Option - (PUCHAR)&Entry->Options;
Size = BlGetBootOptionSize(Option);
OptionsSize += Size;
BufferRemaining -= Size;
//
// TODO: This section is incomplete.
//
PrevOption = Option;
Option = (PBOOT_APPLICATION_ENTRY_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
// Status = Unknown(LoadOptions, &Entry->Options, RemainingSize, &OptionsSize, &PrevOption, &Size);
if (!NT_SUCCESS(Status)) {
goto exit;
}
exit:
*BufferUsed = BufferSize - BufferRemaining;
} }
PBOOT_INPUT_PARAMETERS PBOOT_INPUT_PARAMETERS
@@ -718,7 +236,6 @@ Return Value:
LoadedImage->FilePath, LoadedImage->FilePath,
LoadedImage->LoadOptions, LoadedImage->LoadOptions,
LoadedImage->LoadOptionsSize, LoadedImage->LoadOptionsSize,
0,
&ApplicationEntrySize, &ApplicationEntrySize,
&BootDevice &BootDevice
); );

View File

@@ -25,84 +25,6 @@ Abstract:
sizeof(BOOT_RETURN_DATA) \ sizeof(BOOT_RETURN_DATA) \
) )
ULONG
BlGetBootOptionListSize (
IN PBOOT_APPLICATION_ENTRY_OPTION Options
);
ULONG
BlGetBootOptionSize (
IN PBOOT_APPLICATION_ENTRY_OPTION Option
)
/*++
Routine Description:
Gets the size of a boot option.
Arguments:
Option - the boot option to get the size of.
Return Value:
The size of the option.
--*/
{
ULONG TotalSize;
if (Option->DataOffset != 0) {
TotalSize = Option->DataOffset + Option->DataSize;
} else {
TotalSize = sizeof(BOOT_APPLICATION_ENTRY_OPTION);
}
if (Option->OtherOptionsOffset != 0) {
TotalSize += BlGetBootOptionListSize((PBOOT_APPLICATION_ENTRY_OPTION)((PUCHAR)Option + Option->OtherOptionsOffset));
}
return TotalSize;
}
ULONG
BlGetBootOptionListSize (
IN PBOOT_APPLICATION_ENTRY_OPTION Options
)
/*++
Routine Description:
Gets the total size of a list boot options.
Arguments:
Options - the boot option list to get the size of.
Return Value:
The size of the options.
--*/
{
ULONG TotalSize, NextOffset;
PBOOT_APPLICATION_ENTRY_OPTION Option;
TotalSize = 0;
NextOffset = 0;
do {
Option = (PBOOT_APPLICATION_ENTRY_OPTION)((PUCHAR)Options + NextOffset);
NextOffset = Option->NextOptionOffset;
TotalSize += BlGetBootOptionSize(Option);
} while (NextOffset != 0);
return TotalSize;
}
NTSTATUS NTSTATUS
InitializeLibrary ( InitializeLibrary (
IN PBOOT_INPUT_PARAMETERS InputParameters, IN PBOOT_INPUT_PARAMETERS InputParameters,
@@ -128,9 +50,6 @@ Return Value:
--*/ --*/
{ {
NTSTATUS Status;
PBOOT_FIRMWARE_DATA FirmwareData;
(VOID)LibraryParameters; (VOID)LibraryParameters;
// //
@@ -142,15 +61,6 @@ Return Value:
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
//
// Initialize firmware library.
//
FirmwareData = (PBOOT_FIRMWARE_DATA)((PUCHAR)InputParameters + InputParameters->FirmwareDataOffset);
Status = BlpFwInitialize(0, FirmwareData);
if (!NT_SUCCESS(Status)) {
return Status;
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View File

@@ -1,210 +0,0 @@
/*
* PROJECT: Alcyone System Kernel
* LICENSE: BSD Clause 3
* PURPOSE: Cache Controller:: External Cache Compatibility Layer
* NT KERNEL: 5.11.9360
* COPYRIGHT: 2023-2029 Dibymartanda Samanta <>
*/
NOTE::Alcyone will not notify,in case of Empty External Cache at the moment, feature is planned for threadpool revamp
/* Move Typedef later cctypes.hpp */
typedef struct alignas(24) _DIRTY_PAGE_STATISTICS {
ULONGLONG DirtyPages; // 0x0
ULONGLONG DirtyPagesLastScan; // 0x8
ULONG DirtyPagesScheduledLastScan; // 0x10
} DIRTY_PAGE_STATISTICS, *PDIRTY_PAGE_STATISTICS; // 0x18 bytes (sizeof)
typedef struct alignas(30) _CC_EXTERNAL_CACHE_INFO {
VOID (*Callback)(VOID* arg1, ULONGLONG arg2, ULONG arg3); // 0x0
struct _DIRTY_PAGE_STATISTICS DirtyPageStatistics; // 0x8
struct _LIST_ENTRY Links; // 0x20
} CC_EXTERNAL_CACHE_INFO, *PCC_EXTERNAL_CACHE_INFO; // 0x30 bytes (sizeof)
VOID
NTAPI
CcDeductDirtyPagesFromExternalCache(
IN PCC_EXTERNAL_CACHE_INFO ExternalCacheContext,
IN ULONG Pages
)
{
KIRQL OldIrql ={0};
ULONG PagesToDeduct = {0};
if (Pages > 0)
{
/* Acquire the master lock */
KeAcquireQueuedSpinLock(LockQueueMasterLock, &OldIrql);
/* Calculate the number of pages to deduct */
PagesToDeduct = min(Pages, ExternalCacheContext->DirtyPageStatistics.DirtyPages);
/* Deduct the pages from the external cache context */
ExternalCacheContext->DirtyPageStatistics.DirtyPages -= PagesToDeduct;
/* Deduct the pages from the global statistics */
CcTotalDirtyPages -= PagesToDeduct;
/* Release the master lock */
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
}
/* Check if there are any deferred writes and post them if necessary */
if (!IsListEmpty(&CcDeferredWrites))
{
CcPostDeferredWrites();
}
}
VOID
NTAPI
CcAddExternalCache(
IN PCC_EXTERNAL_CACHE_INFO CacheInfo
)
{
KLOCK_QUEUE_HANDLE LockHandle ={0};
/* Acquire the external cache list lock */
KeAcquireInStackQueuedSpinLock(&CcExternalCacheListLock,&LockHandle);
/* Insert the new cache info at the end of the list */
InsertTailList(&CcExternalCacheList, &CacheInfo->Links);
/* Increment the number of external caches */
if (_InterlockedIncrement(&CcNumberOfExternalCaches) <= 0)
{
/* Overflow occurred, bug check */
KeBugCheckEx(CACHE_MANAGER,0,STATUS_INTEGER_OVERFLOW,0,0);
}
/* Release the external cache list lock */
KeReleaseInStackQueuedSpinLock(&LockHandle);
}
VOID
NTAPI
CcRemoveExternalCache(
IN PCC_EXTERNAL_CACHE_INFO CacheInfo
)
{
KLOCK_QUEUE_HANDLE LockHandle ={0};
/* Acquire the external cache list lock */
KeAcquireInStackQueuedSpinLock(&CcExternalCacheListLock,&LockHandle);
/* Remove the entry from the list */
RemoveTailList(&CacheInfo->Links.Blink);
/* Decrement the number of external caches */
if (_InterlockedDecrement(&CcNumberOfExternalCaches) < 0)
{
/* Underflow occurred, bug check */
KeBugCheckEx(CACHE_MANAGER,0,STATUS_INTEGER_OVERFLOW,0,0);
}
/* Release the external cache list lock */
KeReleaseInStackQueuedSpinLock(&LockHandle);
}
/*Exported */
VOID
NTAPI
CcAddDirtyPagesToExternalCache(
IN PCC_EXTERNAL_CACHE_INFO ExternalCacheContext,
IN ULONG Pages
)
{
KIRQL OldIrql ={0};
/* Only proceed if there are pages to add */
if (Pages == 0)
{
return;
}
/* Acquire the master lock */
KeAcquireQueuedSpinLock(LockQueueMasterLock, &OldIrql);
/* If this is the first dirty page, schedule a lazy write scan */
if (ExternalCacheContext->DirtyPageStatistics.DirtyPages == 0)
{
CcScheduleLazyWriteScan(FALSE, NULL);
}
/* Increment the dirty page count */
ExternalCacheContext->DirtyPageStatistics.DirtyPages += Pages;
/* Charge the dirty pages */
CcChargeDirtyPages(NULL, NULL, NULL, Pages);
/* Release the master lock */
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
}
VOID
NTAPI
CcUnregisterExternalCache(
IN PCC_EXTERNAL_CACHE_INFO ExternalCacheContext
)
{
/* Remove the external cache from the list */
CcRemoveExternalCache(ExternalCacheContext);
/* Deduct any remaining dirty pages */
if (ExternalCacheContext->DirtyPageStatistics.DirtyPages > 0)
{
CcDeductDirtyPagesFromExternalCache(ExternalCacheContext,ExternalCacheContext->DirtyPageStatistics.DirtyPages);
}
/* Free the external cache context */
ExFreePoolWithTag(ExternalCacheContext, CC_EXTERNAL_CACHE_INFO_TAG);
}
NTSTATUS
NTAPI
CcRegisterExternalCache(
IN PCC_EXTERNAL_CACHE_CALLBACK Callback,
OUT PVOID *ExternalCacheContext
)
{
NTSTATUS Status = STATUS_SUCCESS;
PCC_EXTERNAL_CACHE_INFO CacheInfo;
/* Ensure the Cache Manager is initialized */
if (!CcInitializationComplete)
{
KeBugCheckEx(CACHE_MANAGER,0,STATUS_UNSUCCESSFUL,0,0);
}
/* Allocate memory for the external cache info structure */
CacheInfo = ExAllocatePoolWithTag(NonPagedPool,
sizeof(CC_EXTERNAL_CACHE_INFO),
CC_EXTERNAL_CACHE_INFO_TAG);
if (CacheInfo == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Initialize the cache info structure */
RtlZeroMemory(CacheInfo, sizeof(CC_EXTERNAL_CACHE_INFO));
CacheInfo->Callback = Callback;
/* Add the external cache to the list */
CcAddExternalCache(CacheInfo);
/* Return the cache info as the context */
*ExternalCacheContext = CacheInfo;
return Status;
}

View File

@@ -13,7 +13,341 @@
extern "C" extern "C"
/*Internal Function*/ /* Move Typedef Later to cctypes.hpp */
typedef struct _WRITE_BEHIND_THROUGHPUT
{
ULONG PagesYetToWrite;
ULONG Throughput;
} WRITE_BEHIND_THROUGHPUT, *PWRITE_BEHIND_THROUGHPUT;
BOOLEAN
CcOkToAddWriteBehindThread(VOID)
{
ULONG ActiveExtraWriteBehindThreads = {0};
PWRITE_BEHIND_THROUGHPUT ThroughputStats = nullptr;
ULONG PagesYetToWrite = {0};
ULONG Throughput = {0};
ULONG PreviousThroughput = {0};
LONG ThroughputTrend = {0};
BOOLEAN Result = false;
ActiveExtraWriteBehindThreads = CcActiveExtraWriteBehindThreads;
ThroughputStats = CcThroughputStats;
PagesYetToWrite = CcPagesYetToWrite;
Throughput = ThroughputStats[ActiveExtraWriteBehindThreads].PagesYetToWrite;
PreviousThroughput = 0;
if (Throughput >= PagesYetToWrite)
{
Throughput -= PagesYetToWrite;
}
else
{
Throughput = 0;
}
ThroughputStats[ActiveExtraWriteBehindThreads].PagesYetToWrite = PagesYetToWrite;
Result = true;
if (ActiveExtraWriteBehindThreads > 0)
{
PreviousThroughput = ThroughputStats[ActiveExtraWriteBehindThreads - 1].Throughput;
}
ThroughputStats[ActiveExtraWriteBehindThreads].Throughput = Throughput;
if (Throughput > 0)
{
ThroughputTrend = CcThroughputTrend;
if (Throughput < PreviousThroughput)
{
if (ThroughputTrend > 0)
ThroughputTrend = 0;
ThroughputTrend--;
}
else
{
if (ThroughputTrend < 0)
ThroughputTrend = 0;
ThroughputTrend++;
}
CcThroughputTrend = ThroughputTrend;
if (ThroughputTrend == 3)
{
CcThroughputTrend = 0;
Result = true;
if (ActiveExtraWriteBehindThreads < CcMaxExtraWriteBehindThreads)
{
ThroughputStats[ActiveExtraWriteBehindThreads + 1].Throughput = 0;
ThroughputStats[ActiveExtraWriteBehindThreads + 1].PagesYetToWrite = PagesYetToWrite;
}
}
else if (ThroughputTrend == -3)
{
CcThroughputTrend = 0;
Result = true;
if (ActiveExtraWriteBehindThreads > 0)
{
ThroughputStats[ActiveExtraWriteBehindThreads - 1].Throughput = 0;
ThroughputStats[ActiveExtraWriteBehindThreads - 1].PagesYetToWrite = PagesYetToWrite;
}
}
}
return Result;
}
VOID
NTAPI
CcSetLazyWriteScanQueued(
IN ULONG FlushReason,
IN BOOLEAN QueuedState)
{
switch (FlushReason)
{
case 1:
LazyWriter.PendingLowMemoryScan = QueuedState;
break;
case 2:
LazyWriter.PendingPowerScan = QueuedState;
break;
case 4:
LazyWriter.PendingPeriodicScan = QueuedState;
break;
case 8:
LazyWriter.PendingTeardownScan = QueuedState;
break;
case 16:
LazyWriter.PendingCoalescingFlushScan = QueuedState;
break;
default:
break;
}
}
BOOLEAN
VECTORCALL
CcIsLazyWriteScanQueued(
_In_ ULONG ReasonForFlush
)
{
switch (ReasonForFlush)
{
case 0:
return false;
case 1:
case 2:
case 16:
if (LazyWriter.PendingLowMemoryScan ||
LazyWriter.PendingPowerScan ||
LazyWriter.PendingCoalescingFlushScan)
{
return true;
}
return false;
case 4:
if (LazyWriter.PendingPeriodicScan ||
LazyWriter.PendingTeardownScan)
{
return true;
}
return false;
case 8:
return (BOOLEAN)LazyWriter.PendingTeardownScan;
default:
return false;
}
}
VOID
NTAPI
CcQueueLazyWriteScanThread(
_In_ PVOID NULL_PARAM
)
{
UNREFERENCED_PARAMETER(NULL_PARAM);
ULONG Reason = 0;
BOOLEAN NeedAdjustment;
NTSTATUS Status;
KIRQL OldIrql;
PWORK_QUEUE_ENTRY WorkQueueEntry;
PVOID WaitObjects[5];
WaitObjects[0] = &CcLowMemoryEvent;
WaitObjects[1] = &CcPowerEvent;
WaitObjects[2] = &CcPeriodicEvent;
WaitObjects[3] = &CcWaitingForTeardownEvent;
WaitObjects[4] = &CcCoalescingFlushEvent;
for (;;)
{
NeedAdjustment = false;
Status = KeWaitForMultipleObjects(
5,
WaitObjects,
WaitAny,
WrFreePage,
KernelMode,
false,
NULL,
WaitBlockArray);
switch (Status)
{
case STATUS_WAIT_0:
Reason = 1;
NeedAdjustment = true;
break;
case STATUS_WAIT_1:
Reason = 2;
break;
case STATUS_WAIT_2:
Reason = 4;
break;
case STATUS_WAIT_3:
Reason = 8;
break;
case STATUS_WAIT_4:
Reason = 16;
break;
default:
continue;
}
if (CcNumberOfExternalCaches && !IsListEmpty(&CcExternalCacheList))
{
CcNotifyExternalCaches(Reason);
}
CcAdjustWriteBehindThreadPoolIfNeeded(NeedAdjustment);
OldIrql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
if (CcIsLazyWriteScanQueued(Reason))
{
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
continue;
}
CcSetLazyWriteScanQueued(Reason, true);
KeReleaseQueuedSpinLock(LockQueueMasterLock, OldIrql);
if (!NT_SUCCESS(CcAllocateWorkQueueEntry(&WorkQueueEntry)))
{
KSPIN_LOCK_QUEUE_NUMBER queueNumber = LockQueueMasterLock;
SpinLockGuard guard(queueNumber);
LazyWriter.ScanActive = false;
CcSetLazyWriteScanQueued(Reason, false);
}
else
{
WorkQueueEntry->Function = 3;
WorkQueueEntry->Parameters.Notification.Reason = Reason;
CcPostWorkQueue(
WorkQueueEntry,
(Reason != 8) ? &CcRegularWorkQueue : &CcFastTeardownWorkQueue);
}
}
}
VOID
NTAPI
CcRescheduleLazyWriteScan( IN PLARGE_INTEGER NextScanDelay)
{
UNREFERENCED_PARAMETER(NextScanDelay);
LARGE_INTEGER Delay = {0};
if (LazyWriter.ScanActive)
{
if (NextScanDelay && NextScanDelay->QuadPart != 0x7FFFFFFFFFFFFFFF && NextScanDelay->QuadPart != 0)
{
Delay.QuadPart = NextScanDelay->QuadPart * KeMaximumIncrement;
if (Delay.QuadPart > 160000000)
Delay.QuadPart = 160000000;
if(Delay.QuadPart < 10000000 )
Delay = CcIdleDelay;
}
KeSetCoalescableTimer(&LazyWriter.ScanTimer,CcIdleDelay,0,1000,&LazyWriter.ScanDpc);
}
else
{
CcScheduleLazyWriteScan(0, 0);
}
}
VOID
NTAPI
CcComputeNextScanTime(PLARGE_INTEGER OldestTICKTIMEForMetadata, PLARGE_INTEGER NextScanDelay)
{
NextScanDelay- = 0;
LARGE_INTEGER CurrentTickCount = {0};
LARGE_INTEGER TICKTIME = {0};
LARGE_INTEGER WRITE_DELAY = {0};
LARGE_INTEGER TICK_ELAPSED = {0};
if (CcMaxWriteBehindThreads < CcNumberofWorkerThreads)
{
KeQueryTickCount(&CurrentTickCount);
// Calculate Tick Time based on the current tick count and the oldest scan time
TICKTIME.QuadPart = 160000000 / KeMaximumIncrement;
WRITE_DELAY.QuadPart = (OldestTICKTIMEForMetadata->QuadPart - CurrentTickCount.QuadPart) / KeMaximumIncrement;
// Increment the consecutive workless lazy scan count
++CcConsecutiveWorklessLazyScanCount;
// Check if the oldest scan time is not the maximum and the calculated delay is greater than the current tick
// count
if (OldestTICKTIMEForMetadata->QuadPart != -1 && OldestTICKTIMEForMetadata->QuadPart != 0x7FFFFFFFFFFFFFFF &&
(TICKTIME.QuadPart + OldestTICKTIMEForMetadata->QuadPart) > CurrentTickCount.QuadPart)
{
TICK_ELAPSED.QuadPart = OldestTICKTIMEForMetadata->QuadPart - CurrentTickCount.QuadPart;
// Calculate the next scan delay
NextScanDelay->QuadPart = TICKTIME.QuadPart + TICK_ELAPSED.QuadPart;
// Reset the consecutive workless lazy scan count
CcConsecutiveWorklessLazyScanCount = 0;
}
// Check if the number of consecutive workless lazy scans has reached the maximum
if (CcConsecutiveWorklessLazyScanCount >= CcMaxWorklessLazywriteScans)
{
// Disable the scan by setting the next scan delay to the maximum values
NextScanDelay->QuadPart = -1;
CcConsecutiveWorklessLazyScanCount = 0;
NextScanDelay->HighPart = 0x7FFFFFFF;
}
}
}
VOID VOID
VECTORCALL VECTORCALL
@@ -900,10 +1234,10 @@ NTAPI CcLazyWriteScan()
CcPostWorkQueue(workItem, &CcRegularWorkQueue); CcPostWorkQueue(workItem, &CcRegularWorkQueue);
} }
// CcComputeNextScanTime(&OldestLWSTimeStamp, &NextScanDelay); Enable When Threadpool is finished CcComputeNextScanTime(&OldestLWSTimeStamp, &NextScanDelay);
// if (!IsListEmpty(&PostWorkList) || !IsListEmpty(&CcDeferredWrites) || MmRegistryStatus.ProductStatus ||NextScanDelay.QuadPart != 0x7FFFFFFFFFFFFFFF)) if (!IsListEmpty(&PostWorkList) || !IsListEmpty(&CcDeferredWrites) || MmRegistryStatus.ProductStatus ||
if (!IsListEmpty(&PostWorkList) || !IsListEmpty(&CcDeferredWrites) || MmRegistryStatus.ProductStatus)) NextScanDelay.QuadPart != 0x7FFFFFFFFFFFFFFF))
{ {
/* Schedule a lazy write scan */ /* Schedule a lazy write scan */
CcRescheduleLazyWriteScan(&NextScanDelay); CcRescheduleLazyWriteScan(&NextScanDelay);
@@ -930,44 +1264,7 @@ NTAPI CcLazyWriteScan()
CcScheduleLazyWriteScan(FALSE); CcScheduleLazyWriteScan(FALSE);
} }
} }
NTSTATUS CcWaitForCurrentLazyWriterActivity()
{
NTSTATUS result;
PWORK_QUEUE_ENTRY WorkQueueEntry = nullptr;
KEVENT Event = {0};
KIRQL irql = {0};
result = CcAllocateWorkQueueEntry(&WorkQueueEntry);
if (NT_SUCCESS(result))
{
WorkQueueEntry->Function = SetDone;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
WorkQueueEntry->Parameters.Notification.Reason = (ULONG_PTR)&Event;
if ((PerfGlobalGroupMask.Masks[4] & 0x20000) != 0)
CcPerfLogWorkItemEnqueue(&CcPostTickWorkQueue, WorkQueueEntry, 0, 0);
irql = KeAcquireQueuedSpinLock(LockQueueMasterLock);
WorkQueueEntry->WorkQueueLinks.Flink = &CcPostTickWorkQueue;
WorkQueueEntry->WorkQueueLinks.Blink = CcPostTickWorkQueue.Blink;
CcPostTickWorkQueue.Blink->Flink = &WorkQueueEntry->WorkQueueLinks;
CcPostTickWorkQueue.Blink = &WorkQueueEntry->WorkQueueLinks;
LazyWriter.OtherWork = 1;
_InterlockedIncrement(&CcPostTickWorkItemCount);
CcScheduleLazyWriteScan(1, 1);
KeReleaseQueuedSpinLock(LockQueueMasterLock, irql);
result = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
_InterlockedDecrement(&CcPostTickWorkItemCount);
}
return result;
}
VOID VECTORCALL CcReEngageWorkerThreads( VOID VECTORCALL CcReEngageWorkerThreads(
ULONG NormalThreadsToActivate, ULONG NormalThreadsToActivate,
ULONG ExtraWriteBehindThreadsToActivate ULONG ExtraWriteBehindThreadsToActivate
@@ -1036,6 +1333,62 @@ VOID VECTORCALL CcReEngageWorkerThreads(
ExQueueWorkItem(currentExtraThreadEntry, CriticalWorkQueue); ExQueueWorkItem(currentExtraThreadEntry, CriticalWorkQueue);
} }
} }
VOID
NTAPI
CcAdjustWriteBehindThreadPool(
IN BOOLEAN IsThreadPriorityLow)
{
if (IsThreadPriorityLow)
{
CcMaxNumberOfWriteBehindThreads = 1;
if (CcAddExtraWriteBehindThreads)
{
CcAddExtraWriteBehindThreads = false;
}
}
else
{
CcMaxNumberOfWriteBehindThreads = (ULONG)-1;
if (!IsListEmpty(&CcRegularWorkQueue) && !CcQueueThrottle)
{
CcReEngageWorkerThreads(CcNumberofWorkerThreads, 0);
}
}
}
VOID
NTAPI
CcAdjustWriteBehindThreadPoolIfNeeded(
IN BOOLEAN NeedAdjustment)
{
BOOLEAN NeedBoost = false;
KSPIN_LOCK_QUEUE_NUMBER queueNumber = LockQueueMasterLock;
SpinLockGuard guard(queueNumber);
if (CcPostTickWorkItemCount != 0)
{
if (CcIsWriteBehindThreadpoolAtLowPriority())
{
CcAdjustWriteBehindThreadPool(false);
}
}
else
{ auto DirtyPages = (CcTotalDirtyPages + CcPagesWrittenLastTime);
if (DirtyPages > 0x2000 || NeedAdjustment)
{
if (CcIsWriteBehindThreadpoolAtLowPriority())
{
CcAdjustWriteBehindThreadPool(false);
}
}
else if (!CcExecutingWriteBehindWorkItems && IsListEmpty(&CcRegularWorkQueue))
{
CcAdjustWriteBehindThreadPool(true);
}
}
}
VOID VOID
NTAPI NTAPI
CcWorkerThread(PVOID Parameter) CcWorkerThread(PVOID Parameter)
@@ -1066,7 +1419,7 @@ CcWorkerThread(PVOID Parameter)
{ {
CcQueueThrottle = FALSE; CcQueueThrottle = FALSE;
DropThrottle = FALSE; DropThrottle = FALSE;
// CcReEngageWorkerThreads(CcThreadsActiveBeforeThrottle, CcExtraThreadsActiveBeforeThrottle); Enable When Threadpool is ready CcReEngageWorkerThreads(CcThreadsActiveBeforeThrottle, CcExtraThreadsActiveBeforeThrottle);
} }
if (IoStatus.Information == 0x8A5E) if (IoStatus.Information == 0x8A5E)

View File

@@ -1,92 +0,0 @@
/*++
Copyright (c) 2024, Quinn Stephens.
Provided under the BSD 3-Clause license.
Module Name:
printf.c
Abstract:
Provides wide formatted string printing routines.
--*/
#include <wchar.h>
static
size_t
print_hex (
wchar_t *wcs,
size_t maxlen,
unsigned int num
)
{
wchar_t *dest;
size_t n;
int shift;
unsigned int x;
dest = wcs;
n = 0;
shift = 28;
while (n < maxlen && shift >= 0) {
x = (num >> shift) & 0xf;
if (x >= 0xa) {
*dest = 'a' + (x - 0xa);
} else {
*dest = '0' + x;
}
dest++;
n++;
shift -= 4;
}
return n;
}
int
vswprintf (
wchar_t *wcs,
size_t maxlen,
const wchar_t *format,
va_list args
)
{
wchar_t *dest;
size_t n, size;
dest = wcs;
n = 0;
while (n < maxlen && *format != '\0') {
if (*format != '%') {
*dest++ = *format++;
n++;
continue;
}
format++;
switch (*format) {
case 'x':
size = print_hex(dest, maxlen - n, va_arg(args, unsigned int));
n += size;
dest += size;
format++;
break;
case '\0':
break;
case '%':
default:
*dest++ = *format++;
n++;
break;
}
}
wcs[n] = '\0';
return (int)n;
}

View File

@@ -22,7 +22,6 @@ Abstract:
extern "C" { extern "C" {
#endif #endif
#include <stdarg.h>
#include <string.h> #include <string.h>
size_t wcslen(const wchar_t *str); size_t wcslen(const wchar_t *str);
@@ -36,8 +35,6 @@ wchar_t *wmemset(wchar_t *dest, wchar_t c, size_t count);
wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, size_t count); wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, size_t count);
wchar_t *wmemmove(wchar_t *dest, const wchar_t *src, size_t count); wchar_t *wmemmove(wchar_t *dest, const wchar_t *src, size_t count);
int vswprintf(wchar_t *wcs, size_t maxlen, const wchar_t *format, va_list args);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -144,8 +144,6 @@ typedef ULONGLONG *PULONGLONG;
// //
typedef ULONG LOGICAL; typedef ULONG LOGICAL;
typedef ULONG *PLOGICAL; typedef ULONG *PLOGICAL;
typedef int BOOL;
typedef BOOL *PBOOL;
typedef UCHAR BOOLEAN; typedef UCHAR BOOLEAN;
typedef BOOLEAN *PBOOLEAN; typedef BOOLEAN *PBOOLEAN;

View File

@@ -18,7 +18,6 @@ Abstract:
#include <string.h> #include <string.h>
#include <ntdef.h> #include <ntdef.h>
#include <ntstatus.h>
// //
// Memory operations. // Memory operations.
@@ -28,47 +27,6 @@ Abstract:
#define RtlFillMemory(Destination, Length, Fill) memset((Destination), (Fill), (Length)) #define RtlFillMemory(Destination, Length, Fill) memset((Destination), (Fill), (Length))
#define RtlZeroMemory(Destination, Length) memset((Destination), 0, (Length)) #define RtlZeroMemory(Destination, Length) memset((Destination), 0, (Length))
#define ULONG_ERROR 0xFFFFFFFFUL
FORCEINLINE
NTSTATUS
RtlULongSub (
IN ULONG ulMinuend,
IN ULONG ulSubtrahend,
IN OUT PULONG pulResult
)
/*++
Routine Description:
Calculates the difference of two ULONG values.
Arguments:
ulMinuend - The value to subtract ulSubtrahend from.
ulSubtrahend - The value to subtract from ulMinuend.
pulResult - Pointer to a ULONG to store the difference in.
Return Value:
STATUS_SUCCESS if successful.
STATUS_INTEGER_OVERFLOW if unsuccessful.
--*/
{
if (ulMinuend >= ulSubtrahend) {
*pulResult = ulMinuend - ulSubtrahend;
return STATUS_SUCCESS;
}
*pulResult = ULONG_ERROR;
return STATUS_INTEGER_OVERFLOW;
}
VOID VOID
NTAPI NTAPI
RtlInitUnicodeString ( RtlInitUnicodeString (

View File

@@ -22,14 +22,12 @@ Abstract:
// TODO: There are an insane amount of status values. // TODO: There are an insane amount of status values.
// //
#define STATUS_MEDIA_CHANGED ((NTSTATUS) 0x8000001CL) #define STATUS_MEDIA_CHANGED ((NTSTATUS) 0x8000001CL)
#define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L)
#define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xC000000DL) #define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xC000000DL)
#define STATUS_ACCESS_DENIED ((NTSTATUS) 0xC0000022L) #define STATUS_ACCESS_DENIED ((NTSTATUS) 0xC0000022L)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xC0000023L) #define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xC0000023L)
#define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS) 0xC0000032L) #define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS) 0xC0000032L)
#define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS) 0xC0000038L) #define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS) 0xC0000038L)
#define STATUS_DISK_FULL ((NTSTATUS) 0xC000007FL) #define STATUS_DISK_FULL ((NTSTATUS) 0xC000007FL)
#define STATUS_INTEGER_OVERFLOW ((NTSTATUS) 0xC0000095L)
#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS) 0xC000009AL) #define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS) 0xC000009AL)
#define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS) 0xC00000A2L) #define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS) 0xC00000A2L)
#define STATUS_DEVICE_NOT_READY ((NTSTATUS) 0xC00000A3L) #define STATUS_DEVICE_NOT_READY ((NTSTATUS) 0xC00000A3L)

View File

@@ -49,7 +49,7 @@ project("BOOTMGR")
libdirs({ "BUILD/SDK" }) libdirs({ "BUILD/SDK" })
objdir("BUILD/BOOT") objdir("BUILD/BOOT")
targetdir("BUILD/BOOT") targetdir("BUILD/BOOT")
files({ "BOOT/ENVIRON/INC/**.h", "BOOT/ENVIRON/LIB/**.c", "BOOT/ENVIRON/APP/BOOTMGR/**.c" }) files({ "BOOT/ENVIRON/INC/**.h", "BOOT/ENVIRON/**.c" })
filter("toolset:clang") filter("toolset:clang")
buildoptions({ "-fshort-wchar", "-fno-strict-aliasing", "-fno-stack-protector", "-fno-stack-check", "-mno-red-zone" }) buildoptions({ "-fshort-wchar", "-fno-strict-aliasing", "-fno-stack-protector", "-fno-stack-check", "-mno-red-zone" })