Compare commits
3 Commits
d759302400
...
2751b0f7bb
Author | SHA1 | Date | |
---|---|---|---|
2751b0f7bb | |||
6a868b45ba | |||
831a676af8 |
@ -31,15 +31,14 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
ImageHandle - Handle for the boot manager image.
|
ImageHandle - EFI handle for the boot manager image.
|
||||||
|
|
||||||
SystemTable - Pointer to the EFI system table.
|
SystemTable - Pointer to the EFI system table.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
EFI_SUCCESS if successful.
|
EFI_INVALID_PARAMETER if EfiInitCreateInputParameters() fails.
|
||||||
EFI_INVALID_PARAMEER if input parameter structure creation fails.
|
Any status code returned by EfiGetEfiStatusCode(BmMain()).
|
||||||
Any other value defined in efierr.h.
|
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
|
@ -28,12 +28,11 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
DataStore - pointer to memory to put the data store handle in.
|
DataStore - Pointer to a HANDLE that recieves the data store handle.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
STATUS_SUCCESS if successful,
|
STATUS_SUCCESS.
|
||||||
Other NTSTATUS value on failure.
|
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
|
@ -106,25 +106,33 @@ typedef struct {
|
|||||||
ULONG MdlOffset;
|
ULONG MdlOffset;
|
||||||
ULONG DescriptorCount;
|
ULONG DescriptorCount;
|
||||||
ULONG DescriptorSize;
|
ULONG DescriptorSize;
|
||||||
ULONG BasePageOffset;
|
ULONG FirstPageOffset;
|
||||||
} BOOT_MEMORY_INFO, *PBOOT_MEMORY_INFO;
|
} BOOT_MEMORY_INFO, *PBOOT_MEMORY_INFO;
|
||||||
|
|
||||||
/* Memory descriptor caching attributes */
|
//
|
||||||
|
// Memory descriptor caching attributes.
|
||||||
|
//
|
||||||
#define MEMORY_ATTRIBUTE_UC 0x0000000000000001
|
#define MEMORY_ATTRIBUTE_UC 0x0000000000000001
|
||||||
#define MEMORY_ATTRIBUTE_WC 0x0000000000000002
|
#define MEMORY_ATTRIBUTE_WC 0x0000000000000002
|
||||||
#define MEMORY_ATTRIBUTE_WT 0x0000000000000004
|
#define MEMORY_ATTRIBUTE_WT 0x0000000000000004
|
||||||
#define MEMORY_ATTRIBUTE_WB 0x0000000000000008
|
#define MEMORY_ATTRIBUTE_WB 0x0000000000000008
|
||||||
#define MEMORY_ATTRIBUTE_UCE 0x0000000000000010
|
#define MEMORY_ATTRIBUTE_UCE 0x0000000000000010
|
||||||
|
|
||||||
/* Memory descriptor protection attributes */
|
//
|
||||||
|
// Memory descriptor protection attributes.
|
||||||
|
//
|
||||||
#define MEMORY_ATTRIBUTE_WP 0x000000000000100
|
#define MEMORY_ATTRIBUTE_WP 0x000000000000100
|
||||||
#define MEMORY_ATTRIBUTE_RP 0x000000000000200
|
#define MEMORY_ATTRIBUTE_RP 0x000000000000200
|
||||||
#define MEMORY_ATTRIBUTE_XP 0x000000000000400
|
#define MEMORY_ATTRIBUTE_XP 0x000000000000400
|
||||||
|
|
||||||
/* Memory descriptor location attributes */
|
//
|
||||||
|
// Memory descriptor location attributes.
|
||||||
|
//
|
||||||
#define MEMORY_ATTRIBUTE_BELOW_1MIB 0x80000
|
#define MEMORY_ATTRIBUTE_BELOW_1MIB 0x80000
|
||||||
|
|
||||||
/* Memory descriptor runtime mapping attributes */
|
//
|
||||||
|
// Memory descriptor runtime mapping attributes.
|
||||||
|
//
|
||||||
#define MEMORY_ATTRIBUTE_RUNTIME 0x1000000
|
#define MEMORY_ATTRIBUTE_RUNTIME 0x1000000
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -146,11 +154,12 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
|
|
||||||
ULONGLONG BasePage;
|
ULONGLONG FirstPage;
|
||||||
ULONG Pages;
|
ULONGLONG MappedFirstPage;
|
||||||
|
ULONG PageCount;
|
||||||
|
|
||||||
ULONG Attributes;
|
ULONG Attributes;
|
||||||
ULONG Type;
|
MEMORY_TYPE Type;
|
||||||
} MEMORY_DESCRIPTOR, *PMEMORY_DESCRIPTOR;
|
} MEMORY_DESCRIPTOR, *PMEMORY_DESCRIPTOR;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -18,12 +18,27 @@ Abstract:
|
|||||||
|
|
||||||
#include "bootlib.h"
|
#include "bootlib.h"
|
||||||
|
|
||||||
|
#define MDL_OPERATION_FLAGS_TRUNCATE 0x02
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmFwGetMemoryMap (
|
MmFwGetMemoryMap (
|
||||||
IN OUT PMEMORY_DESCRIPTOR_LIST Mdl,
|
IN OUT PMEMORY_DESCRIPTOR_LIST Mdl,
|
||||||
IN ULONG Flags
|
IN ULONG Flags
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
MmMdpHasPrecedence (
|
||||||
|
IN MEMORY_TYPE A,
|
||||||
|
IN MEMORY_TYPE B
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
MmMdpTruncateDescriptor (
|
||||||
|
IN PMEMORY_DESCRIPTOR_LIST Mdl,
|
||||||
|
IN PMEMORY_DESCRIPTOR Descriptor,
|
||||||
|
IN ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmMdAddDescriptorToList (
|
MmMdAddDescriptorToList (
|
||||||
IN PMEMORY_DESCRIPTOR_LIST Mdl,
|
IN PMEMORY_DESCRIPTOR_LIST Mdl,
|
||||||
@ -49,8 +64,8 @@ MmMdFreeList (
|
|||||||
|
|
||||||
PMEMORY_DESCRIPTOR
|
PMEMORY_DESCRIPTOR
|
||||||
MmMdInitDescriptor (
|
MmMdInitDescriptor (
|
||||||
IN ULONGLONG BasePage,
|
IN ULONGLONG FirstPage,
|
||||||
IN ULONGLONG MappedBasePage,
|
IN ULONGLONG MappedFirstPage,
|
||||||
IN ULONGLONG PageCount,
|
IN ULONGLONG PageCount,
|
||||||
IN ULONG Attributes,
|
IN ULONG Attributes,
|
||||||
IN MEMORY_TYPE Type
|
IN MEMORY_TYPE Type
|
||||||
|
@ -32,7 +32,7 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
String - string to print.
|
String.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
@ -58,9 +58,9 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
Format - format string handled by vswprintf().
|
Format - Format string handled by vswprintf().
|
||||||
|
|
||||||
... - arguments.
|
... - Arguments.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ Arguments:
|
|||||||
|
|
||||||
Stage - 0 or 1.
|
Stage - 0 or 1.
|
||||||
|
|
||||||
FirmwareData - firmware data structure to use for initialization.
|
FirmwareData - Pointer to BOOT_FIRMWARE_DATA.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
|
@ -41,15 +41,15 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
Destination - the path to append to.
|
Destination - Path to append Source to.
|
||||||
|
|
||||||
BufferSize - the maximum number of bytes to append.
|
BufferSize - Maximum number of bytes to append to Destination.
|
||||||
|
|
||||||
Source - the source path to append to Destination.
|
Source - Source path to append to Destination.
|
||||||
|
|
||||||
SourceSize - the size of Source, in bytes.
|
SourceSize - Size of Source, in bytes.
|
||||||
|
|
||||||
BufferUsed - pointer to a ULONG to store the number of bytes appended in.
|
BufferUsed - Pointer to a ULONG recieving the number of bytes appended in.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
@ -138,27 +138,21 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
DevicePath - EFI device path to search.
|
DevicePath - EFI_DEVICE_PATH *.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
Pointer to the last device path node.
|
EFI_DEVICE_PATH *.
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
{
|
{
|
||||||
EFI_DEVICE_PATH *Node;
|
EFI_DEVICE_PATH *Node;
|
||||||
|
|
||||||
//
|
|
||||||
// Check if the current node is the end of the path.
|
|
||||||
//
|
|
||||||
if (IsDevicePathEndType(DevicePath)) {
|
if (IsDevicePathEndType(DevicePath)) {
|
||||||
return DevicePath;
|
return DevicePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Find the last non-filepath node.
|
|
||||||
//
|
|
||||||
Node = NextDevicePathNode(DevicePath);
|
Node = NextDevicePathNode(DevicePath);
|
||||||
while (!IsDevicePathEndType(Node)) {
|
while (!IsDevicePathEndType(Node)) {
|
||||||
if (DevicePathType(Node) == MEDIA_DEVICE_PATH && DevicePathSubType(Node) == MEDIA_FILEPATH_DP) {
|
if (DevicePathType(Node) == MEDIA_DEVICE_PATH && DevicePathSubType(Node) == MEDIA_FILEPATH_DP) {
|
||||||
@ -183,19 +177,19 @@ EfiInitTranslateDevicePath (
|
|||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Translates an EFI device path into boot device format.
|
Translates an EFI_DEVICE_PATH into a BOOT_DEVICE.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
EfiDevicePath - The EFI device path to be translated.
|
EfiDevicePath - Path to be translated.
|
||||||
|
|
||||||
BootDevice - Pointer to the destination device structure.
|
BootDevice - Pointer to a buffer that recieves the device.
|
||||||
|
|
||||||
BufferSize - The amount of available space in the buffer.
|
BufferSize - Amount of available bytes in the buffer.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
STATUS_SUCCESS if successful,
|
STATUS_SUCCESS if successful.
|
||||||
STATUS_INVALID_PARAMETER if the buffer is too small.
|
STATUS_INVALID_PARAMETER if the buffer is too small.
|
||||||
STATUS_UNSUCCESSFUL if the path could not be translated.
|
STATUS_UNSUCCESSFUL if the path could not be translated.
|
||||||
|
|
||||||
@ -207,17 +201,11 @@ Return Value:
|
|||||||
HARDDRIVE_DEVICE_PATH *HarddriveNode;
|
HARDDRIVE_DEVICE_PATH *HarddriveNode;
|
||||||
PBOOT_BLOCK_IDENTIFIER BlockDevice;
|
PBOOT_BLOCK_IDENTIFIER BlockDevice;
|
||||||
|
|
||||||
//
|
|
||||||
// Check for available buffer space.
|
|
||||||
//
|
|
||||||
if (BufferSize < sizeof(BOOT_DEVICE)) {
|
if (BufferSize < sizeof(BOOT_DEVICE)) {
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
BootDevice->Size = sizeof(BOOT_DEVICE);
|
BootDevice->Size = sizeof(BOOT_DEVICE);
|
||||||
|
|
||||||
//
|
|
||||||
// Memory mapped device paths are treated as ramdisks.
|
|
||||||
//
|
|
||||||
if (DevicePathType(EfiDevicePath) == HARDWARE_DEVICE_PATH && DevicePathSubType(EfiDevicePath) == HW_MEMMAP_DP) {
|
if (DevicePathType(EfiDevicePath) == HARDWARE_DEVICE_PATH && DevicePathSubType(EfiDevicePath) == HW_MEMMAP_DP) {
|
||||||
MemmapNode = (MEMMAP_DEVICE_PATH *)EfiDevicePath;
|
MemmapNode = (MEMMAP_DEVICE_PATH *)EfiDevicePath;
|
||||||
BlockDevice = &BootDevice->Block;
|
BlockDevice = &BootDevice->Block;
|
||||||
@ -230,7 +218,6 @@ Return Value:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the device node, the device the application was loaded from.
|
|
||||||
// TODO: Only media devices and ramdisks are currently supported.
|
// TODO: Only media devices and ramdisks are currently supported.
|
||||||
//
|
//
|
||||||
DeviceNode = EfiInitpGetDeviceNode(EfiDevicePath);
|
DeviceNode = EfiInitpGetDeviceNode(EfiDevicePath);
|
||||||
@ -238,15 +225,12 @@ Return Value:
|
|||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Check device node subtype.
|
|
||||||
//
|
|
||||||
switch (DevicePathSubType(DeviceNode)) {
|
switch (DevicePathSubType(DeviceNode)) {
|
||||||
case MEDIA_HARDDRIVE_DP:
|
case MEDIA_HARDDRIVE_DP:
|
||||||
HarddriveNode = (HARDDRIVE_DEVICE_PATH *)DeviceNode;
|
HarddriveNode = (HARDDRIVE_DEVICE_PATH *)DeviceNode;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Use correct block device and partition format.
|
// MBR disks still use the old partition struct.
|
||||||
//
|
//
|
||||||
if (HarddriveNode->SignatureType != SIGNATURE_TYPE_MBR) {
|
if (HarddriveNode->SignatureType != SIGNATURE_TYPE_MBR) {
|
||||||
BlockDevice = &BootDevice->PartitionEx.Parent;
|
BlockDevice = &BootDevice->PartitionEx.Parent;
|
||||||
@ -257,9 +241,6 @@ Return Value:
|
|||||||
}
|
}
|
||||||
BlockDevice->Type = BOOT_BLOCK_DEVICE_TYPE_HARDDRIVE;
|
BlockDevice->Type = BOOT_BLOCK_DEVICE_TYPE_HARDDRIVE;
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize partition based on the drive's partitioning system.
|
|
||||||
//
|
|
||||||
switch (HarddriveNode->SignatureType) {
|
switch (HarddriveNode->SignatureType) {
|
||||||
case SIGNATURE_TYPE_MBR:
|
case SIGNATURE_TYPE_MBR:
|
||||||
BlockDevice->Harddrive.PartitionType = BOOT_HARDDRIVE_PARTITION_TYPE_MBR;
|
BlockDevice->Harddrive.PartitionType = BOOT_HARDDRIVE_PARTITION_TYPE_MBR;
|
||||||
@ -301,22 +282,23 @@ EfiInitpConvertEfiDevicePath (
|
|||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Converts an EFI device path into BCD format.
|
Converts an EFI device path into option format.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
EfiDevicePath - The EFI device path to be converted.
|
EfiDevicePath - Path to be converted.
|
||||||
|
|
||||||
OptionType - The data type to be assigned to option.
|
OptionType - The data type to be assigned to Option->Type.
|
||||||
|
|
||||||
Option - Pointer to the destination option structure.
|
Option - Pointer to a buffer that recieves the option.
|
||||||
|
|
||||||
BufferSize - The amount of available space in the buffer.
|
BufferSize - The amount of available bytes in the buffer.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
STATUS_SUCCESS if successful.
|
STATUS_SUCCESS if successful.
|
||||||
other NTSTATUS value if failure occurs.
|
STATUS_INVALID_PARAMETER if the buffer is too small.
|
||||||
|
Any status code returned by EfiInitTranslateDevicePath().
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
@ -324,16 +306,10 @@ Return Value:
|
|||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PBCDE_DEVICE DeviceElement;
|
PBCDE_DEVICE DeviceElement;
|
||||||
|
|
||||||
//
|
|
||||||
// Check for available buffer space.
|
|
||||||
//
|
|
||||||
if (BufferSize < sizeof(BOOT_APPLICATION_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device)) {
|
if (BufferSize < sizeof(BOOT_APPLICATION_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device)) {
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Translate device path.
|
|
||||||
//
|
|
||||||
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_OPTION));
|
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_OPTION));
|
||||||
DeviceElement = (PBCDE_DEVICE)((PUCHAR)Option + sizeof(BOOT_APPLICATION_OPTION));
|
DeviceElement = (PBCDE_DEVICE)((PUCHAR)Option + sizeof(BOOT_APPLICATION_OPTION));
|
||||||
Status = EfiInitTranslateDevicePath(
|
Status = EfiInitTranslateDevicePath(
|
||||||
@ -345,9 +321,6 @@ Return Value:
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Set up option structure.
|
|
||||||
//
|
|
||||||
Option->Type = OptionType;
|
Option->Type = OptionType;
|
||||||
Option->DataOffset = sizeof(BOOT_APPLICATION_OPTION);
|
Option->DataOffset = sizeof(BOOT_APPLICATION_OPTION);
|
||||||
Option->DataSize = FIELD_OFFSET(BCDE_DEVICE, Device) + DeviceElement->Device.Size;
|
Option->DataSize = FIELD_OFFSET(BCDE_DEVICE, Device) + DeviceElement->Device.Size;
|
||||||
@ -367,22 +340,22 @@ EfiInitpConvertEfiFilePath (
|
|||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Converts an EFI file path into BCD format.
|
Converts an EFI file path into option format.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
EfiFilePath - The EFI file path to be converted.
|
EfiFilePath - Path to be converted.
|
||||||
|
|
||||||
OptionType - The data type to be assigned to option.
|
OptionType - The data type to be assigned to Option->Type.
|
||||||
|
|
||||||
Option - Pointer to the destination option structure.
|
Option - Pointer to a buffer that recieves the option.
|
||||||
|
|
||||||
BufferSize - The amount of available space in the buffer.
|
BufferSize - The amount of available bytes in the buffer.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
STATUS_SUCCESS if successful.
|
STATUS_SUCCESS if successful.
|
||||||
other NTSTATUS value if failure occurs.
|
STATUS_INVALID_PARAMETER if the buffer is too small.
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
@ -392,22 +365,16 @@ Return Value:
|
|||||||
PWCHAR PathStart, Position;
|
PWCHAR PathStart, Position;
|
||||||
ULONG BufferRemaining, Length, Appended;
|
ULONG BufferRemaining, Length, Appended;
|
||||||
|
|
||||||
//
|
|
||||||
// Check for available buffer space.
|
|
||||||
//
|
|
||||||
if (BufferSize < sizeof(BOOT_APPLICATION_OPTION)) {
|
if (BufferSize < sizeof(BOOT_APPLICATION_OPTION)) {
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Set up option structure.
|
|
||||||
//
|
|
||||||
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_OPTION));
|
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_OPTION));
|
||||||
Option->Type = OptionType;
|
Option->Type = OptionType;
|
||||||
Option->DataOffset = sizeof(BOOT_APPLICATION_OPTION);
|
Option->DataOffset = sizeof(BOOT_APPLICATION_OPTION);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Add to the path one file path node at a time.
|
// Loop through nodes and add one at a time.
|
||||||
//
|
//
|
||||||
Option->DataSize = 0;
|
Option->DataSize = 0;
|
||||||
BufferRemaining = BufferSize - sizeof(BOOT_APPLICATION_OPTION);
|
BufferRemaining = BufferSize - sizeof(BOOT_APPLICATION_OPTION);
|
||||||
@ -415,21 +382,33 @@ Return Value:
|
|||||||
PathStart = (PWCHAR)((PUCHAR)Option + Option->DataOffset);
|
PathStart = (PWCHAR)((PUCHAR)Option + Option->DataOffset);
|
||||||
Position = PathStart;
|
Position = PathStart;
|
||||||
while (!IsDevicePathEndType(Node)) {
|
while (!IsDevicePathEndType(Node)) {
|
||||||
|
//
|
||||||
|
// Ignore non-filepath nodes.
|
||||||
|
//
|
||||||
if (DevicePathType(Node) != MEDIA_DEVICE_PATH || DevicePathSubType(Node) != MEDIA_FILEPATH_DP) {
|
if (DevicePathType(Node) != MEDIA_DEVICE_PATH || DevicePathSubType(Node) != MEDIA_FILEPATH_DP) {
|
||||||
Node = NextDevicePathNode(Node);
|
Node = NextDevicePathNode(Node);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Find the length of this path.
|
||||||
|
//
|
||||||
Status = RtlULongSub(DevicePathNodeLength(Node), FIELD_OFFSET(FILEPATH_DEVICE_PATH, PathName), &Length);
|
Status = RtlULongSub(DevicePathNodeLength(Node), FIELD_OFFSET(FILEPATH_DEVICE_PATH, PathName), &Length);
|
||||||
if (!NT_SUCCESS(Status)) {
|
if (!NT_SUCCESS(Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Append this path to the path string.
|
||||||
|
//
|
||||||
Status = EfiInitpAppendPathString(Position, BufferRemaining, &((FILEPATH_DEVICE_PATH *)Node)->PathName[0], Length, &Appended);
|
Status = EfiInitpAppendPathString(Position, BufferRemaining, &((FILEPATH_DEVICE_PATH *)Node)->PathName[0], Length, &Appended);
|
||||||
if (!NT_SUCCESS(Status)) {
|
if (!NT_SUCCESS(Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Update counters & position.
|
||||||
|
//
|
||||||
Option->DataSize += Appended;
|
Option->DataSize += Appended;
|
||||||
BufferRemaining -= Appended;
|
BufferRemaining -= Appended;
|
||||||
Position = (PWCHAR)((PUCHAR)Position + Appended);
|
Position = (PWCHAR)((PUCHAR)Position + Appended);
|
||||||
@ -437,7 +416,7 @@ Return Value:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Terminate path string.
|
// NULL-terminate path string.
|
||||||
//
|
//
|
||||||
if (BufferRemaining < sizeof(UNICODE_NULL)) {
|
if (BufferRemaining < sizeof(UNICODE_NULL)) {
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
@ -446,7 +425,7 @@ Return Value:
|
|||||||
Option->DataSize += sizeof(UNICODE_NULL);
|
Option->DataSize += sizeof(UNICODE_NULL);
|
||||||
|
|
||||||
//
|
//
|
||||||
// The path option is invalid if the path is NULL.
|
// The option is invalid if the path is empty.
|
||||||
//
|
//
|
||||||
if (Position == PathStart) {
|
if (Position == PathStart) {
|
||||||
Option->IsInvalid = TRUE;
|
Option->IsInvalid = TRUE;
|
||||||
@ -473,29 +452,29 @@ EfiInitpCreateApplicationEntry (
|
|||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Creates an application entry structure for the boot application.
|
Creates an application entry for the boot application.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
SystemTable - Pointer to the EFI system table.
|
SystemTable - Pointer to the EFI system table.
|
||||||
|
|
||||||
Entry - A buffer to put the entry in.
|
Entry - Pointer to a buffer that recieves the entry.
|
||||||
|
|
||||||
BufferSize - The amount of available space in the buffer.
|
BufferSize - The amount of available bytes in the buffer.
|
||||||
|
|
||||||
EfiDevicePath - The device path for the application.
|
EfiDevicePath - The application's device path.
|
||||||
|
|
||||||
EfiFilePath - The file path for the application.
|
EfiFilePath - The application's file path.
|
||||||
|
|
||||||
LoadOptions - Firmware load options string.
|
LoadOptions - Firmware load options string.
|
||||||
|
|
||||||
LoadOptionsSize - Length of the string pointed to by LoadOptions.
|
LoadOptionsSize - Size in bytes of the string pointed to by LoadOptions.
|
||||||
|
|
||||||
Flags - Unused.
|
Flags - Unused.
|
||||||
|
|
||||||
BufferUsed - Returns the amount of buffer space used by the routine.
|
BufferUsed - Pointer to a ULONG that recieves the buffer space used by this routine.
|
||||||
|
|
||||||
BootDevice - Returns a pointer to the device the application was loaded from.
|
BootDevice - Pointer to a PBOOT_DEVICE that recieves the device the application was loaded from.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
@ -513,8 +492,6 @@ Return Value:
|
|||||||
PBCDE_DEVICE BootDeviceElement;
|
PBCDE_DEVICE BootDeviceElement;
|
||||||
|
|
||||||
(VOID)SystemTable;
|
(VOID)SystemTable;
|
||||||
(VOID)EfiDevicePath;
|
|
||||||
(VOID)EfiFilePath;
|
|
||||||
(VOID)Flags;
|
(VOID)Flags;
|
||||||
|
|
||||||
*BufferUsed = 0;
|
*BufferUsed = 0;
|
||||||
@ -522,23 +499,17 @@ Return Value:
|
|||||||
OptionsSize = 0;
|
OptionsSize = 0;
|
||||||
BcdIdentifierSet = FALSE;
|
BcdIdentifierSet = FALSE;
|
||||||
|
|
||||||
//
|
|
||||||
// Require enough space for the application entry.
|
|
||||||
//
|
|
||||||
BufferRemaining = BufferSize;
|
BufferRemaining = BufferSize;
|
||||||
if (BufferRemaining < sizeof(BOOT_INPUT_APPLICATION_ENTRY)) {
|
if (BufferRemaining < sizeof(BOOT_INPUT_APPLICATION_ENTRY)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Set up application entry structure.
|
|
||||||
//
|
|
||||||
RtlZeroMemory(Entry, sizeof(BOOT_INPUT_APPLICATION_ENTRY));
|
RtlZeroMemory(Entry, sizeof(BOOT_INPUT_APPLICATION_ENTRY));
|
||||||
Entry->Signature = BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE;
|
Entry->Signature = BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE;
|
||||||
BufferRemaining -= FIELD_OFFSET(BOOT_INPUT_APPLICATION_ENTRY, Options);
|
BufferRemaining -= FIELD_OFFSET(BOOT_INPUT_APPLICATION_ENTRY, Options);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Terminate load options string.
|
// Terminate load options.
|
||||||
//
|
//
|
||||||
LoadOptionsSize /= sizeof(WCHAR);
|
LoadOptionsSize /= sizeof(WCHAR);
|
||||||
if (LoadOptionsSize != 0 && wcsnlen(LoadOptions, LoadOptionsSize) == LoadOptionsSize) {
|
if (LoadOptionsSize != 0 && wcsnlen(LoadOptions, LoadOptionsSize) == LoadOptionsSize) {
|
||||||
@ -546,7 +517,7 @@ Return Value:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Parse BCD GUID if present.
|
// Parse BCD GUID option if present.
|
||||||
//
|
//
|
||||||
if (LoadOptions != NULL && (BcdOptionString = wcsstr(LoadOptions, L"BCDOBJECT=")) != NULL) {
|
if (LoadOptions != NULL && (BcdOptionString = wcsstr(LoadOptions, L"BCDOBJECT=")) != NULL) {
|
||||||
RtlInitUnicodeString(&UnicodeString, (PWCHAR)((PUCHAR)BcdOptionString + sizeof(L"BCDOBJECT=") - sizeof(UNICODE_NULL)));
|
RtlInitUnicodeString(&UnicodeString, (PWCHAR)((PUCHAR)BcdOptionString + sizeof(L"BCDOBJECT=") - sizeof(UNICODE_NULL)));
|
||||||
@ -576,7 +547,7 @@ Return Value:
|
|||||||
|
|
||||||
//
|
//
|
||||||
// Convert the EFI file path into a boot file path option.
|
// Convert the EFI file path into a boot file path option.
|
||||||
// TODO: UDP/PXE boot is not supported.
|
// TODO: UDP/PXE are not supported.
|
||||||
//
|
//
|
||||||
PrevOption = Option;
|
PrevOption = Option;
|
||||||
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
|
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
|
||||||
@ -590,7 +561,7 @@ Return Value:
|
|||||||
BufferRemaining -= Size;
|
BufferRemaining -= Size;
|
||||||
|
|
||||||
//
|
//
|
||||||
// TODO: This section is incomplete.
|
// TODO: Additional options in LoadOptions are not parsed.
|
||||||
//
|
//
|
||||||
PrevOption = Option;
|
PrevOption = Option;
|
||||||
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
|
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
|
||||||
@ -617,13 +588,14 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
ImageHandle - Handle for the boot manager image.
|
ImageHandle - EFI handle for the boot application image.
|
||||||
|
|
||||||
SystemTable - Pointer to the EFI system table.
|
SystemTable - Pointer to the EFI system table.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
Pointer to parameter structure on success or NULL on failure.
|
Pointer to parameter structure if successful.
|
||||||
|
NULL on failure.
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
@ -648,9 +620,6 @@ Return Value:
|
|||||||
BadPageAddress = 0x102 << PAGE_SHIFT;
|
BadPageAddress = 0x102 << PAGE_SHIFT;
|
||||||
SystemTable->BootServices->AllocatePages(AllocateAddress, EfiLoaderData, 1, &BadPageAddress);
|
SystemTable->BootServices->AllocatePages(AllocateAddress, EfiLoaderData, 1, &BadPageAddress);
|
||||||
|
|
||||||
//
|
|
||||||
// Get boot manager image information.
|
|
||||||
//
|
|
||||||
Status = SystemTable->BootServices->HandleProtocol(
|
Status = SystemTable->BootServices->HandleProtocol(
|
||||||
ImageHandle,
|
ImageHandle,
|
||||||
(EFI_GUID*)&EfiLoadedImageProtocol,
|
(EFI_GUID*)&EfiLoadedImageProtocol,
|
||||||
@ -660,9 +629,6 @@ Return Value:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Get boot manager image device path.
|
|
||||||
//
|
|
||||||
Status = SystemTable->BootServices->HandleProtocol(
|
Status = SystemTable->BootServices->HandleProtocol(
|
||||||
LoadedImage->DeviceHandle,
|
LoadedImage->DeviceHandle,
|
||||||
(EFI_GUID*)&EfiDevicePathProtocol,
|
(EFI_GUID*)&EfiDevicePathProtocol,
|
||||||
@ -672,9 +638,6 @@ Return Value:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Create input parameters structure.
|
|
||||||
//
|
|
||||||
InputParameters = (PBOOT_INPUT_PARAMETERS)(&EfiInitScratch[ScratchUsed]);
|
InputParameters = (PBOOT_INPUT_PARAMETERS)(&EfiInitScratch[ScratchUsed]);
|
||||||
ScratchUsed += sizeof(BOOT_INPUT_PARAMETERS);
|
ScratchUsed += sizeof(BOOT_INPUT_PARAMETERS);
|
||||||
InputParameters->Signature = BOOT_INPUT_PARAMETERS_SIGNATURE;
|
InputParameters->Signature = BOOT_INPUT_PARAMETERS_SIGNATURE;
|
||||||
@ -684,9 +647,6 @@ Return Value:
|
|||||||
InputParameters->ImageBase = LoadedImage->ImageBase;
|
InputParameters->ImageBase = LoadedImage->ImageBase;
|
||||||
InputParameters->ImageSize = LoadedImage->ImageSize;
|
InputParameters->ImageSize = LoadedImage->ImageSize;
|
||||||
|
|
||||||
//
|
|
||||||
// Create memory info structure.
|
|
||||||
//
|
|
||||||
InputParameters->MemoryInfoOffset = ScratchUsed;
|
InputParameters->MemoryInfoOffset = ScratchUsed;
|
||||||
MemoryInfo = (PBOOT_MEMORY_INFO)(&EfiInitScratch[ScratchUsed]);
|
MemoryInfo = (PBOOT_MEMORY_INFO)(&EfiInitScratch[ScratchUsed]);
|
||||||
ScratchUsed += sizeof(BOOT_MEMORY_INFO);
|
ScratchUsed += sizeof(BOOT_MEMORY_INFO);
|
||||||
@ -694,21 +654,15 @@ Return Value:
|
|||||||
MemoryInfo->MdlOffset = sizeof(BOOT_MEMORY_INFO);
|
MemoryInfo->MdlOffset = sizeof(BOOT_MEMORY_INFO);
|
||||||
MemoryInfo->DescriptorCount = 1;
|
MemoryInfo->DescriptorCount = 1;
|
||||||
MemoryInfo->DescriptorSize = sizeof(MEMORY_DESCRIPTOR);
|
MemoryInfo->DescriptorSize = sizeof(MEMORY_DESCRIPTOR);
|
||||||
MemoryInfo->BasePageOffset = FIELD_OFFSET(MEMORY_DESCRIPTOR, BasePage);
|
MemoryInfo->FirstPageOffset = FIELD_OFFSET(MEMORY_DESCRIPTOR, FirstPage);
|
||||||
|
|
||||||
//
|
|
||||||
// Create a memory descriptor for the boot manager image.
|
|
||||||
//
|
|
||||||
MemoryDescriptor = (PMEMORY_DESCRIPTOR)(&EfiInitScratch[ScratchUsed]);
|
MemoryDescriptor = (PMEMORY_DESCRIPTOR)(&EfiInitScratch[ScratchUsed]);
|
||||||
ScratchUsed += sizeof(MEMORY_DESCRIPTOR);
|
ScratchUsed += sizeof(MEMORY_DESCRIPTOR);
|
||||||
MemoryDescriptor->BasePage = (UINTN)InputParameters->ImageBase >> PAGE_SHIFT;
|
MemoryDescriptor->FirstPage = (UINTN)InputParameters->ImageBase >> PAGE_SHIFT;
|
||||||
MemoryDescriptor->Pages = ALIGN_UP(InputParameters->ImageSize, PAGE_SIZE) >> PAGE_SHIFT;
|
MemoryDescriptor->PageCount = ALIGN_UP(InputParameters->ImageSize, PAGE_SIZE) >> PAGE_SHIFT;
|
||||||
MemoryDescriptor->Attributes = MEMORY_ATTRIBUTE_WB;
|
MemoryDescriptor->Attributes = MEMORY_ATTRIBUTE_WB;
|
||||||
MemoryDescriptor->Type = MEMORY_TYPE_BOOT_APPLICATION;
|
MemoryDescriptor->Type = MEMORY_TYPE_BOOT_APPLICATION;
|
||||||
|
|
||||||
//
|
|
||||||
// Create an application entry for the boot application.
|
|
||||||
//
|
|
||||||
InputParameters->ApplicationEntryOffset = ScratchUsed;
|
InputParameters->ApplicationEntryOffset = ScratchUsed;
|
||||||
EfiInitpCreateApplicationEntry(
|
EfiInitpCreateApplicationEntry(
|
||||||
SystemTable,
|
SystemTable,
|
||||||
@ -724,9 +678,6 @@ Return Value:
|
|||||||
);
|
);
|
||||||
ScratchUsed += ApplicationEntrySize;
|
ScratchUsed += ApplicationEntrySize;
|
||||||
|
|
||||||
//
|
|
||||||
// Copy application device to scratch area.
|
|
||||||
//
|
|
||||||
InputParameters->BootDeviceOffset = ScratchUsed;
|
InputParameters->BootDeviceOffset = ScratchUsed;
|
||||||
if (BootDevice != NULL) {
|
if (BootDevice != NULL) {
|
||||||
RtlCopyMemory(&EfiInitScratch[ScratchUsed], BootDevice, BootDevice->Size);
|
RtlCopyMemory(&EfiInitScratch[ScratchUsed], BootDevice, BootDevice->Size);
|
||||||
@ -736,9 +687,6 @@ Return Value:
|
|||||||
ScratchUsed += sizeof(BOOT_DEVICE);
|
ScratchUsed += sizeof(BOOT_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Create firmware data structure.
|
|
||||||
//
|
|
||||||
InputParameters->FirmwareDataOffset = ScratchUsed;
|
InputParameters->FirmwareDataOffset = ScratchUsed;
|
||||||
FirmwareData = (PBOOT_FIRMWARE_DATA)(&EfiInitScratch[ScratchUsed]);
|
FirmwareData = (PBOOT_FIRMWARE_DATA)(&EfiInitScratch[ScratchUsed]);
|
||||||
ScratchUsed += sizeof(BOOT_FIRMWARE_DATA);
|
ScratchUsed += sizeof(BOOT_FIRMWARE_DATA);
|
||||||
@ -747,17 +695,11 @@ Return Value:
|
|||||||
FirmwareData->ImageHandle = ImageHandle;
|
FirmwareData->ImageHandle = ImageHandle;
|
||||||
FirmwareData->SystemTable = SystemTable;
|
FirmwareData->SystemTable = SystemTable;
|
||||||
|
|
||||||
//
|
|
||||||
// Create return data structure.
|
|
||||||
//
|
|
||||||
InputParameters->ReturnDataOffset = ScratchUsed;
|
InputParameters->ReturnDataOffset = ScratchUsed;
|
||||||
ReturnData = (PBOOT_RETURN_DATA)(&EfiInitScratch[ScratchUsed]);
|
ReturnData = (PBOOT_RETURN_DATA)(&EfiInitScratch[ScratchUsed]);
|
||||||
ScratchUsed += sizeof(BOOT_RETURN_DATA);
|
ScratchUsed += sizeof(BOOT_RETURN_DATA);
|
||||||
ReturnData->Version = BOOT_RETURN_DATA_VERSION;
|
ReturnData->Version = BOOT_RETURN_DATA_VERSION;
|
||||||
|
|
||||||
//
|
|
||||||
// Set and validate total size.
|
|
||||||
//
|
|
||||||
InputParameters->Size = ScratchUsed;
|
InputParameters->Size = ScratchUsed;
|
||||||
if (InputParameters->Size > sizeof(EfiInitScratch)) {
|
if (InputParameters->Size > sizeof(EfiInitScratch)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -29,7 +29,7 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
Status - The NT status code to be converted.
|
Status - The NT status code.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
Status - The EFI status code to be converted.
|
Status - The EFI status code.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
|
@ -15,8 +15,266 @@ Abstract:
|
|||||||
|
|
||||||
#include "bootmgr.h"
|
#include "bootmgr.h"
|
||||||
#include "efi.h"
|
#include "efi.h"
|
||||||
|
#include "efilib.h"
|
||||||
#include "mm.h"
|
#include "mm.h"
|
||||||
|
|
||||||
|
#define _1MiB 1048576
|
||||||
|
|
||||||
|
#define EFI_PAGE(NtPage) (((NtPage) << PAGE_SHIFT) >> EFI_PAGE_SHIFT)
|
||||||
|
#define NT_PAGE(EfiPage) (((EfiPage) << EFI_PAGE_SHIFT) >> PAGE_SHIFT)
|
||||||
|
|
||||||
|
extern EFI_BOOT_SERVICES *EfiBS;
|
||||||
|
extern PBOOT_DEVICE BlpBootDevice;
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
EfiGetMemoryMap (
|
||||||
|
IN OUT UINTN *MemoryMapSize,
|
||||||
|
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
|
||||||
|
IN OUT UINTN *MapKey,
|
||||||
|
IN OUT UINTN *DescriptorSize,
|
||||||
|
IN OUT UINT32 *DescriptorVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Wrapper for EFI_BOOT_SERVICES.GetMemoryMap(). Gets the firmware memory map
|
||||||
|
and places it into a buffer.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
MemoryMapSize - pointer to the size of the buffer.
|
||||||
|
|
||||||
|
MemoryMap - pointer to the buffer to store the memory map in.
|
||||||
|
|
||||||
|
MapKey - ponter to the memory map key.
|
||||||
|
|
||||||
|
DescriptorSize - pointer to the size of each memory map descriptor.
|
||||||
|
|
||||||
|
DescriptorVersion - pointer to the version of memory map descriptors.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
STATUS_SUCCESS if successful,
|
||||||
|
Other NTSTATUS value if an error occurs.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
return EfiGetNtStatusCode(
|
||||||
|
EfiBS->GetMemoryMap(
|
||||||
|
MemoryMapSize,
|
||||||
|
MemoryMap,
|
||||||
|
MapKey,
|
||||||
|
DescriptorSize,
|
||||||
|
DescriptorVersion
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
EfiAllocatePages (
|
||||||
|
IN EFI_ALLOCATE_TYPE Type,
|
||||||
|
IN EFI_MEMORY_TYPE MemoryType,
|
||||||
|
IN UINTN Pages,
|
||||||
|
IN OUT EFI_PHYSICAL_ADDRESS *Memory
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Wrapper for EFI_BOOT_SERVICES.AllocatePages(). Allocates contiguous pages
|
||||||
|
of physical memory.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Type - the type of allocation.
|
||||||
|
|
||||||
|
MemoryType - the type of memory to allocate.
|
||||||
|
|
||||||
|
Pages - the number of pages to allocate.
|
||||||
|
|
||||||
|
Memory - pointer to a physical address of the allocation.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
STATUS_SUCCESS if successful,
|
||||||
|
Other NTSTATUS value if an error occurs.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
return EfiGetNtStatusCode(
|
||||||
|
EfiBS->AllocatePages(
|
||||||
|
Type,
|
||||||
|
MemoryType,
|
||||||
|
Pages,
|
||||||
|
Memory
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
EfiFreePages (
|
||||||
|
IN EFI_PHYSICAL_ADDRESS Memory,
|
||||||
|
IN UINTN Pages
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Wrapper for EFI_BOOT_SERVICES.FreePages(). Frees contiguous pages
|
||||||
|
of physical memory.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Memory - physical address of the pages to be freed.
|
||||||
|
|
||||||
|
Pages - the number of pages to free.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
STATUS_SUCCESS if successful,
|
||||||
|
Other NTSTATUS value if an error occurs.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
return EfiGetNtStatusCode(
|
||||||
|
EfiBS->FreePages(
|
||||||
|
Memory,
|
||||||
|
Pages
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEMORY_TYPE
|
||||||
|
BlMmTranslateEfiMemoryType (
|
||||||
|
IN EFI_MEMORY_TYPE EfiMemoryType
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Translates an EFI memory type to an NT memory type.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
EfiMemoryType - the EFI memory type.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
The NT memory type.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
switch (EfiMemoryType) {
|
||||||
|
case EfiConventionalMemory:
|
||||||
|
return MEMORY_TYPE_FREE;
|
||||||
|
case EfiLoaderCode:
|
||||||
|
case EfiLoaderData:
|
||||||
|
return MEMORY_TYPE_BOOT_APPLICATION;
|
||||||
|
case EfiBootServicesCode:
|
||||||
|
case EfiBootServicesData:
|
||||||
|
return MEMORY_TYPE_BOOT_SERVICES;
|
||||||
|
case EfiRuntimeServicesCode:
|
||||||
|
return MEMORY_TYPE_RUNTIME_SERVICES_CODE;
|
||||||
|
case EfiRuntimeServicesData:
|
||||||
|
return MEMORY_TYPE_RUNTIME_SERVICES_DATA;
|
||||||
|
case EfiUnusableMemory:
|
||||||
|
return MEMORY_TYPE_UNUSABLE;
|
||||||
|
case EfiACPIReclaimMemory:
|
||||||
|
return MEMORY_TYPE_ACPI_RECLAIM;
|
||||||
|
case EfiACPIMemoryNVS:
|
||||||
|
return MEMORY_TYPE_ACPI_NVS;
|
||||||
|
case EfiMemoryMappedIO:
|
||||||
|
return MEMORY_TYPE_MMIO;
|
||||||
|
case EfiMemoryMappedIOPortSpace:
|
||||||
|
return MEMORY_TYPE_MMIO_PORT_SPACE;
|
||||||
|
case EfiPalCode:
|
||||||
|
return MEMORY_TYPE_PAL_CODE;
|
||||||
|
case EfiPersistentMemory:
|
||||||
|
return MEMORY_TYPE_PERSISTENT;
|
||||||
|
case EfiReservedMemoryType:
|
||||||
|
default:
|
||||||
|
if ((ULONG)EfiMemoryType < MAXLONG) {
|
||||||
|
return MEMORY_TYPE_RESERVED;
|
||||||
|
} else {
|
||||||
|
return (MEMORY_TYPE)EfiMemoryType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
MmFwpGetOsAttributeType (
|
||||||
|
IN UINT64 EfiAttributes
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Translates EFI memory descriptor attributes to NT memory descriptor attributes.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
EfiAttributes - the EFI attributes.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
The NT attributes.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
ULONG NtAttributes;
|
||||||
|
|
||||||
|
NtAttributes = 0;
|
||||||
|
|
||||||
|
if (EfiAttributes & EFI_MEMORY_UC) {
|
||||||
|
NtAttributes |= MEMORY_ATTRIBUTE_UC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EfiAttributes & EFI_MEMORY_WC) {
|
||||||
|
NtAttributes |= MEMORY_ATTRIBUTE_WC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EfiAttributes & EFI_MEMORY_WT) {
|
||||||
|
NtAttributes |= MEMORY_ATTRIBUTE_WT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EfiAttributes & EFI_MEMORY_WB) {
|
||||||
|
NtAttributes |= MEMORY_ATTRIBUTE_WB;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EfiAttributes & EFI_MEMORY_UCE) {
|
||||||
|
NtAttributes |= MEMORY_ATTRIBUTE_UCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EfiAttributes & EFI_MEMORY_WP) {
|
||||||
|
NtAttributes |= MEMORY_ATTRIBUTE_WP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EfiAttributes & EFI_MEMORY_RP) {
|
||||||
|
NtAttributes |= MEMORY_ATTRIBUTE_RP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EfiAttributes & EFI_MEMORY_XP) {
|
||||||
|
NtAttributes |= MEMORY_ATTRIBUTE_XP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EfiAttributes & EFI_MEMORY_RUNTIME) {
|
||||||
|
NtAttributes |= MEMORY_ATTRIBUTE_RUNTIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NtAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmFwGetMemoryMap (
|
MmFwGetMemoryMap (
|
||||||
IN OUT PMEMORY_DESCRIPTOR_LIST Mdl,
|
IN OUT PMEMORY_DESCRIPTOR_LIST Mdl,
|
||||||
@ -27,11 +285,13 @@ MmFwGetMemoryMap (
|
|||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Converts an NT status code into an EFI status code.
|
Gets the memory map from EFI and converts it into an MDL.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
Status - The NT status code to be converted.
|
Mdl - Pointer to the MDL to store new descriptors in.
|
||||||
|
|
||||||
|
Flags - Unused.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
@ -41,16 +301,288 @@ Return Value:
|
|||||||
--*/
|
--*/
|
||||||
|
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
UINTN EfiMapSize;
|
||||||
|
UINTN EfiMapKey;
|
||||||
|
UINTN EfiDescriptorSize;
|
||||||
|
UINT32 EfiDescriptorVersion;
|
||||||
|
UINTN PageCount, EfiPageCount;
|
||||||
|
EFI_PHYSICAL_ADDRESS EfiBuffer;
|
||||||
|
EFI_MEMORY_DESCRIPTOR *EfiMap;
|
||||||
|
BOOLEAN IsRamdisk;
|
||||||
|
MEMORY_TYPE MemoryType;
|
||||||
|
UINT64 EfiStartPage, EfiEndPage;
|
||||||
|
UINT64 EfiRamdiskStartPage, EfiRamdiskEndPage;
|
||||||
|
PMEMORY_DESCRIPTOR NtDescriptor;
|
||||||
|
|
||||||
(VOID)Flags;
|
(VOID)Flags;
|
||||||
|
|
||||||
//
|
EfiBuffer = (EFI_PHYSICAL_ADDRESS)0;
|
||||||
// Make sure Mdl is valid.
|
|
||||||
//
|
|
||||||
if (Mdl == NULL) {
|
if (Mdl == NULL) {
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
MmMdFreeList(Mdl);
|
MmMdFreeList(Mdl);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
//
|
||||||
|
// Get the memory map from firmware.
|
||||||
|
// This is a "fake" call to actually just get
|
||||||
|
// the required buffer size and other info.
|
||||||
|
//
|
||||||
|
EfiMapSize = 0;
|
||||||
|
Status = EfiGetMemoryMap(&EfiMapSize, NULL, &EfiMapKey, &EfiDescriptorSize, &EfiDescriptorVersion);
|
||||||
|
if (Status != STATUS_BUFFER_TOO_SMALL) {
|
||||||
|
DebugPrint(L"MmFwGetMemoryMap(): EfiGetMemoryMap() failed\r\n");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make sure status is not successful, just in case
|
||||||
|
// EfiGetMemoryMap() somehow succeeded.
|
||||||
|
//
|
||||||
|
if (NT_SUCCESS(Status)) {
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
EfiMapSize += 4 * EfiDescriptorSize;
|
||||||
|
PageCount = (ALIGN_UP(EfiMapSize, PAGE_SIZE) >> PAGE_SHIFT) + 1;
|
||||||
|
EfiPageCount = EFI_PAGE(PageCount);
|
||||||
|
Status = EfiAllocatePages(AllocateAnyPages, EfiLoaderData, EfiPageCount, &EfiBuffer);
|
||||||
|
if (!NT_SUCCESS(Status)) {
|
||||||
|
DebugPrint(L"MmFwGetMemoryMap(): EfiAllocatePages() failed\r\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
EfiMap = (EFI_MEMORY_DESCRIPTOR *)EfiBuffer;
|
||||||
|
Status = EfiGetMemoryMap(&EfiMapSize, EfiMap, &EfiMapKey, &EfiDescriptorSize, &EfiDescriptorVersion);
|
||||||
|
if (!NT_SUCCESS(Status)) {
|
||||||
|
DebugPrint(L"MmFwGetMemoryMap(): EfiGetMemoryMap() failed\r\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EfiDescriptorSize < sizeof(EFI_MEMORY_DESCRIPTOR) || EfiMapSize % EfiDescriptorSize) {
|
||||||
|
DebugPrint(L"MmFwGetMemoryMap(): Invalid EFI descriptor/map sizes\r\n");
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BlpBootDevice->Type == BOOT_DEVICE_TYPE_BLOCK && BlpBootDevice->Block.Type == BOOT_BLOCK_DEVICE_TYPE_RAMDISK) {
|
||||||
|
IsRamdisk = TRUE;
|
||||||
|
EfiRamdiskStartPage = BlpBootDevice->Block.Ramdisk.ImageBase.QuadPart >> EFI_PAGE_SHIFT;
|
||||||
|
EfiRamdiskEndPage = EfiRamdiskStartPage + ((BlpBootDevice->Block.Ramdisk.ImageBase.QuadPart + BlpBootDevice->Block.Ramdisk.ImageSize) >> EFI_PAGE_SHIFT);
|
||||||
|
} else {
|
||||||
|
IsRamdisk = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (
|
||||||
|
;
|
||||||
|
EfiMapSize > 0;
|
||||||
|
EfiMapSize -= EfiDescriptorSize,
|
||||||
|
EfiMap = (EFI_MEMORY_DESCRIPTOR *)((PUCHAR)EfiMap + EfiDescriptorSize)
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
// Skip desciptors with no pages.
|
||||||
|
//
|
||||||
|
if (EfiMap->NumberOfPages == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryType = BlMmTranslateEfiMemoryType(EfiMap->Type);
|
||||||
|
if (MemoryType == MEMORY_TYPE_FREE) {
|
||||||
|
EfiStartPage = ALIGN_UP(EfiMap->PhysicalStart, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
EfiStartPage = EfiMap->PhysicalStart >> EFI_PAGE_SHIFT;
|
||||||
|
}
|
||||||
|
EfiEndPage = ALIGN_DOWN(EfiStartPage + EfiMap->NumberOfPages, EFI_PAGE(1));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Regions under 1MiB are mapped differently.
|
||||||
|
//
|
||||||
|
if (EfiStartPage < (_1MiB >> EFI_PAGE_SHIFT)) {
|
||||||
|
//
|
||||||
|
// Reserve region at page 0.
|
||||||
|
//
|
||||||
|
if (EfiStartPage == 0) {
|
||||||
|
NtDescriptor = MmMdInitDescriptor(
|
||||||
|
NT_PAGE(EfiStartPage),
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
MmFwpGetOsAttributeType(EfiMap->Attribute),
|
||||||
|
MEMORY_TYPE_RESERVED
|
||||||
|
);
|
||||||
|
if (NtDescriptor == NULL) {
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = MmMdAddDescriptorToList(Mdl, NtDescriptor, MDL_OPERATION_FLAGS_TRUNCATE);
|
||||||
|
if (!NT_SUCCESS(Status)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Continue if this descriptor was only one page.
|
||||||
|
//
|
||||||
|
if (EfiEndPage == 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// For regions crossing over the 1MiB boundary,
|
||||||
|
// create two descriptors. One for <1MiB and one
|
||||||
|
// for over >=1MiB.
|
||||||
|
//
|
||||||
|
if (EfiEndPage > (_1MiB >> EFI_PAGE_SHIFT)) {
|
||||||
|
NtDescriptor = MmMdInitDescriptor(
|
||||||
|
NT_PAGE(EfiStartPage),
|
||||||
|
0,
|
||||||
|
(_1MiB >> PAGE_SHIFT) - NT_PAGE(EfiStartPage),
|
||||||
|
MmFwpGetOsAttributeType(EfiMap->Attribute),
|
||||||
|
MemoryType
|
||||||
|
);
|
||||||
|
if (NtDescriptor == NULL) {
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NtDescriptor->Type == MEMORY_TYPE_FREE) {
|
||||||
|
NtDescriptor->Attributes |= MEMORY_ATTRIBUTE_BELOW_1MIB;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = MmMdAddDescriptorToList(Mdl, NtDescriptor, MDL_OPERATION_FLAGS_TRUNCATE);
|
||||||
|
if (!NT_SUCCESS(Status)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Continue to creating the >=1MiB mapping.
|
||||||
|
//
|
||||||
|
EfiStartPage = _1MiB >> EFI_PAGE_SHIFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsRamdisk) {
|
||||||
|
if (
|
||||||
|
EfiStartPage <= EfiRamdiskStartPage
|
||||||
|
&& EfiEndPage >= EfiRamdiskEndPage
|
||||||
|
) {
|
||||||
|
if (NT_PAGE(EfiStartPage) < NT_PAGE(EfiRamdiskStartPage)) {
|
||||||
|
NtDescriptor = MmMdInitDescriptor(
|
||||||
|
NT_PAGE(EfiStartPage),
|
||||||
|
0,
|
||||||
|
NT_PAGE(EfiRamdiskStartPage) - NT_PAGE(EfiStartPage),
|
||||||
|
MmFwpGetOsAttributeType(EfiMap->Attribute),
|
||||||
|
MemoryType
|
||||||
|
);
|
||||||
|
if (NtDescriptor == NULL) {
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = MmMdAddDescriptorToList(Mdl, NtDescriptor, MDL_OPERATION_FLAGS_TRUNCATE);
|
||||||
|
if (!NT_SUCCESS(Status)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create a memory descriptor for the ramdisk.
|
||||||
|
//
|
||||||
|
NtDescriptor = MmMdInitDescriptor(
|
||||||
|
NT_PAGE(EfiRamdiskStartPage),
|
||||||
|
0,
|
||||||
|
NT_PAGE(EfiRamdiskEndPage) - NT_PAGE(EfiRamdiskStartPage),
|
||||||
|
MmFwpGetOsAttributeType(EfiMap->Attribute),
|
||||||
|
MemoryType
|
||||||
|
);
|
||||||
|
if (NtDescriptor == NULL) {
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = MmMdAddDescriptorToList(Mdl, NtDescriptor, MDL_OPERATION_FLAGS_TRUNCATE);
|
||||||
|
if (!NT_SUCCESS(Status)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Continue if there is no more memory to map inside the ramdisk.
|
||||||
|
//
|
||||||
|
if (NT_PAGE(EfiEndPage) <= NT_PAGE(EfiRamdiskEndPage)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
EfiStartPage = EFI_PAGE(NT_PAGE(EfiRamdiskEndPage - 1) + 1);
|
||||||
|
} else if (
|
||||||
|
NT_PAGE(EfiStartPage) < NT_PAGE(EfiRamdiskStartPage)
|
||||||
|
&& NT_PAGE(EfiEndPage) > NT_PAGE(EfiRamdiskStartPage)
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
// Remove the region inside the start of the ramdisk.
|
||||||
|
//
|
||||||
|
EfiEndPage = EfiRamdiskStartPage;
|
||||||
|
} else if (
|
||||||
|
NT_PAGE(EfiStartPage) < NT_PAGE(EfiRamdiskEndPage)
|
||||||
|
&& NT_PAGE(EfiEndPage) > NT_PAGE(EfiRamdiskEndPage)
|
||||||
|
) {
|
||||||
|
//
|
||||||
|
// Remove the region inside the end of the ramdisk.
|
||||||
|
//
|
||||||
|
EfiStartPage = EfiRamdiskEndPage;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Continue if the region is now empty.
|
||||||
|
//
|
||||||
|
if (NT_PAGE(EfiStartPage) == NT_PAGE(EfiEndPage)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create a memory descriptor for the region.
|
||||||
|
//
|
||||||
|
NtDescriptor = MmMdInitDescriptor(
|
||||||
|
NT_PAGE(EfiStartPage),
|
||||||
|
0,
|
||||||
|
NT_PAGE(EfiEndPage) - NT_PAGE(EfiStartPage),
|
||||||
|
MmFwpGetOsAttributeType(EfiMap->Attribute),
|
||||||
|
MemoryType
|
||||||
|
);
|
||||||
|
if (NtDescriptor == NULL) {
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set attribute if below 1MiB.
|
||||||
|
//
|
||||||
|
if (NtDescriptor->Type == MEMORY_TYPE_FREE && EfiEndPage <= (_1MiB >> EFI_PAGE_SHIFT)) {
|
||||||
|
NtDescriptor->Attributes |= MEMORY_ATTRIBUTE_BELOW_1MIB;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = MmMdAddDescriptorToList(Mdl, NtDescriptor, MDL_OPERATION_FLAGS_TRUNCATE);
|
||||||
|
if (!NT_SUCCESS(Status)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Account for possible MDL changes due to EfiFreePages(EfiBuffer).
|
||||||
|
//
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (EfiBuffer) {
|
||||||
|
EfiFreePages(EfiBuffer, EfiPageCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status)) {
|
||||||
|
MmMdFreeList(Mdl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
@ -32,11 +32,11 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
MemoryInfo - pointer to the memory info structure.
|
MemoryInfo - Pointer to the memory info.
|
||||||
|
|
||||||
TranslationType - the current translation type being used.
|
TranslationType - The current translation type.
|
||||||
|
|
||||||
LibraryParameters - pointer to the library parameters structure.
|
LibraryParameters - Pointer to the library parameters.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
|
@ -22,10 +22,316 @@ Abstract:
|
|||||||
MEMORY_DESCRIPTOR MmStaticMemoryDescriptors[MAX_STATIC_DESCRIPTOR_COUNT];
|
MEMORY_DESCRIPTOR MmStaticMemoryDescriptors[MAX_STATIC_DESCRIPTOR_COUNT];
|
||||||
|
|
||||||
PMEMORY_DESCRIPTOR MmGlobalMemoryDescriptors;
|
PMEMORY_DESCRIPTOR MmGlobalMemoryDescriptors;
|
||||||
ULONG MmGlobalMemoryDescriptorCount;
|
ULONG MmGlobalMemoryDescriptorCount, MmGlobalMemoryDescriptorsUsed;
|
||||||
|
|
||||||
PMEMORY_DESCRIPTOR MmDynamicMemoryDescriptors;
|
PMEMORY_DESCRIPTOR MmDynamicMemoryDescriptors;
|
||||||
ULONG MmDynamicMemoryDescriptorCount;
|
ULONG MmDynamicMemoryDescriptorCount, MmDynamicMemoryDescriptorsUsed;
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
MmMdpHasPrecedence (
|
||||||
|
IN MEMORY_TYPE A,
|
||||||
|
IN MEMORY_TYPE B
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Compares two memory types to determine which has precedence.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
A - memory type A.
|
||||||
|
|
||||||
|
B - memory type B.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
TRUE if A has precedence over B, or if neither has precedence.
|
||||||
|
FALSE if B has precedence over A.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
ULONG ClassA, ClassB;
|
||||||
|
|
||||||
|
ClassA = A >> 28;
|
||||||
|
ClassB = B >> 28;
|
||||||
|
|
||||||
|
if (B == MEMORY_TYPE_FREE) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (A == MEMORY_TYPE_FREE) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ClassA > 0x0F) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ClassB > 0x0F) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ClassA != 0x0F) {
|
||||||
|
return (ClassB != 0x0F && (ClassA == 0x0D || ClassB != 0x0D)) ? TRUE:FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ClassB != 0x0F) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: Incomplete.
|
||||||
|
//
|
||||||
|
ConsolePrint(L"MmMdpHasPrecedence() is incomplete\r\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
MmMdpTruncateDescriptor (
|
||||||
|
IN PMEMORY_DESCRIPTOR_LIST Mdl,
|
||||||
|
IN PMEMORY_DESCRIPTOR Descriptor,
|
||||||
|
IN ULONG Flags
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Trunactes a memory descriptor that overlaps
|
||||||
|
with adjacent descriptors.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Mdl - The MDL containing Descriptor.
|
||||||
|
|
||||||
|
Descriptor - The descriptor to truncate.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
TRUE if Descriptor was deleted from Mdl.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
PMEMORY_DESCRIPTOR PrevDescriptor, NextDescriptor, NewDescriptor;
|
||||||
|
ULONGLONG DescriptorEnd, PrevDescriptorEnd, NextDescriptorEnd;
|
||||||
|
ULONGLONG MappedFirstPage;
|
||||||
|
ULONGLONG Change;
|
||||||
|
|
||||||
|
PrevDescriptor = (PMEMORY_DESCRIPTOR)Descriptor->ListEntry.Blink;
|
||||||
|
NextDescriptor = (PMEMORY_DESCRIPTOR)Descriptor->ListEntry.Flink;
|
||||||
|
|
||||||
|
DescriptorEnd = Descriptor->FirstPage + Descriptor->PageCount;
|
||||||
|
PrevDescriptorEnd = PrevDescriptor->FirstPage + PrevDescriptor->PageCount;
|
||||||
|
NextDescriptorEnd = NextDescriptor->FirstPage + NextDescriptor->PageCount;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if overlapping with previous descriptor.
|
||||||
|
//
|
||||||
|
if (Descriptor->ListEntry.Blink != Mdl->Head && Descriptor->FirstPage < PrevDescriptorEnd) {
|
||||||
|
if (MmMdpHasPrecedence(Descriptor->Type, PrevDescriptor->Type)) {
|
||||||
|
PrevDescriptor->PageCount = Descriptor->FirstPage - PrevDescriptor->FirstPage;
|
||||||
|
|
||||||
|
if (DescriptorEnd < PrevDescriptorEnd) {
|
||||||
|
if (PrevDescriptor->MappedFirstPage) {
|
||||||
|
MappedFirstPage = PrevDescriptor->MappedFirstPage + DescriptorEnd - PrevDescriptor->FirstPage;
|
||||||
|
} else {
|
||||||
|
MappedFirstPage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewDescriptor = MmMdInitDescriptor(
|
||||||
|
DescriptorEnd,
|
||||||
|
MappedFirstPage,
|
||||||
|
PrevDescriptorEnd - DescriptorEnd,
|
||||||
|
PrevDescriptor->Attributes,
|
||||||
|
PrevDescriptor->Type
|
||||||
|
);
|
||||||
|
if (NewDescriptor != NULL) {
|
||||||
|
MmMdAddDescriptorToList(Mdl, NewDescriptor, Flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Delete and free the previous
|
||||||
|
// descriptor if it is now empty.
|
||||||
|
//
|
||||||
|
if (PrevDescriptor->PageCount == 0) {
|
||||||
|
MmMdRemoveDescriptorFromList(Mdl, PrevDescriptor);
|
||||||
|
MmMdFreeDescriptor(PrevDescriptor);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Remove if completely overlapping.
|
||||||
|
//
|
||||||
|
if (DescriptorEnd <= PrevDescriptorEnd) {
|
||||||
|
MmMdRemoveDescriptorFromList(Mdl, Descriptor);
|
||||||
|
MmMdFreeDescriptor(Descriptor);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Otherwise, move the descriptor.
|
||||||
|
//
|
||||||
|
Change = PrevDescriptorEnd - Descriptor->FirstPage;
|
||||||
|
Descriptor->FirstPage += Change;
|
||||||
|
Descriptor->PageCount -= Change;
|
||||||
|
if (Descriptor->MappedFirstPage) {
|
||||||
|
Descriptor->MappedFirstPage += Change;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if overlapping with next descriptor.
|
||||||
|
//
|
||||||
|
if (Descriptor->ListEntry.Flink != Mdl->Head && NextDescriptor->FirstPage < DescriptorEnd) {
|
||||||
|
if (MmMdpHasPrecedence(NextDescriptor->Type, Descriptor->Type)) {
|
||||||
|
Descriptor->PageCount = NextDescriptor->FirstPage - Descriptor->FirstPage;
|
||||||
|
|
||||||
|
if (NextDescriptorEnd < DescriptorEnd) {
|
||||||
|
if (Descriptor->MappedFirstPage) {
|
||||||
|
MappedFirstPage = Descriptor->MappedFirstPage + NextDescriptorEnd - Descriptor->FirstPage;
|
||||||
|
} else {
|
||||||
|
MappedFirstPage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewDescriptor = MmMdInitDescriptor(
|
||||||
|
NextDescriptorEnd,
|
||||||
|
MappedFirstPage,
|
||||||
|
DescriptorEnd - NextDescriptorEnd,
|
||||||
|
Descriptor->Attributes,
|
||||||
|
Descriptor->Type
|
||||||
|
);
|
||||||
|
if (NewDescriptor != NULL) {
|
||||||
|
MmMdAddDescriptorToList(Mdl, NewDescriptor, Flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Delete and free the previous
|
||||||
|
// descriptor if it is now empty.
|
||||||
|
//
|
||||||
|
if (Descriptor->PageCount == 0) {
|
||||||
|
MmMdRemoveDescriptorFromList(Mdl, Descriptor);
|
||||||
|
MmMdFreeDescriptor(Descriptor);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// Remove if completely overlapping.
|
||||||
|
//
|
||||||
|
if (NextDescriptorEnd <= DescriptorEnd) {
|
||||||
|
MmMdRemoveDescriptorFromList(Mdl, NextDescriptor);
|
||||||
|
MmMdFreeDescriptor(NextDescriptor);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Otherwise, move the next descriptor.
|
||||||
|
//
|
||||||
|
Change = DescriptorEnd - NextDescriptor->FirstPage;
|
||||||
|
NextDescriptor->FirstPage += Change;
|
||||||
|
NextDescriptor->PageCount -= Change;
|
||||||
|
if (NextDescriptor->MappedFirstPage) {
|
||||||
|
NextDescriptor->MappedFirstPage += Change;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmMdAddDescriptorToList (
|
||||||
|
IN PMEMORY_DESCRIPTOR_LIST Mdl,
|
||||||
|
IN PMEMORY_DESCRIPTOR Descriptor,
|
||||||
|
IN ULONG Flags
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Adds a descriptor to a MDL.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Mdl - the MDL to add Descriptor to.
|
||||||
|
|
||||||
|
Descriptor - the descriptor to add to Mdl.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
STATUS_SUCCESS if successful,
|
||||||
|
STATUS_INVALID_PARAMETER if Mdl or Descriptor are invalid.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
PLIST_ENTRY Entry;
|
||||||
|
PMEMORY_DESCRIPTOR CurrentDescriptor;
|
||||||
|
|
||||||
|
if (Mdl == NULL || Descriptor == NULL) {
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Mdl->Current) {
|
||||||
|
if (Descriptor->FirstPage < ((PMEMORY_DESCRIPTOR)Mdl->Current)->FirstPage) {
|
||||||
|
Entry = Mdl->Head->Flink;
|
||||||
|
} else {
|
||||||
|
Entry = Mdl->Current;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Entry = Mdl->Head->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Search for an existing descriptor for this region.
|
||||||
|
//
|
||||||
|
while (Entry != Mdl->Head) {
|
||||||
|
CurrentDescriptor = (PMEMORY_DESCRIPTOR)Entry;
|
||||||
|
|
||||||
|
if (
|
||||||
|
Descriptor->FirstPage >= CurrentDescriptor->FirstPage && (Descriptor->FirstPage != CurrentDescriptor->FirstPage
|
||||||
|
|| !MmMdpHasPrecedence(Descriptor->Type, CurrentDescriptor->Type))
|
||||||
|
) {
|
||||||
|
Entry = Entry->Flink;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Insert descriptor into the list
|
||||||
|
// right before the current entry.
|
||||||
|
//
|
||||||
|
Descriptor->ListEntry.Blink = Entry->Blink;
|
||||||
|
Descriptor->ListEntry.Flink = Entry;
|
||||||
|
Entry->Blink->Flink = &Descriptor->ListEntry;
|
||||||
|
Entry->Blink = &Descriptor->ListEntry;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Truncate overlapping descriptors
|
||||||
|
// into one larger descriptor.
|
||||||
|
//
|
||||||
|
if (Flags & MDL_OPERATION_FLAGS_TRUNCATE) {
|
||||||
|
MmMdpTruncateDescriptor(Mdl, Descriptor, Flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If there are no existing descriptors for this region
|
||||||
|
// (or the list is empty), insert and truncate the descriptor.
|
||||||
|
//
|
||||||
|
InsertTailList(Mdl->Head, &Descriptor->ListEntry);
|
||||||
|
if (Flags & MDL_OPERATION_FLAGS_TRUNCATE) {
|
||||||
|
MmMdpTruncateDescriptor(Mdl, Descriptor, Flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmMdRemoveDescriptorFromList (
|
MmMdRemoveDescriptorFromList (
|
||||||
@ -55,10 +361,6 @@ Return Value:
|
|||||||
PLIST_ENTRY Blink;
|
PLIST_ENTRY Blink;
|
||||||
|
|
||||||
Blink = Descriptor->ListEntry.Blink;
|
Blink = Descriptor->ListEntry.Blink;
|
||||||
|
|
||||||
//
|
|
||||||
// Remove the descriptor from the MDL.
|
|
||||||
//
|
|
||||||
RemoveEntryList(&Descriptor->ListEntry);
|
RemoveEntryList(&Descriptor->ListEntry);
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -129,7 +431,7 @@ Return Value:
|
|||||||
// Free the descriptor from the heap.
|
// Free the descriptor from the heap.
|
||||||
// TODO: Use BlMmFreeHeap()
|
// TODO: Use BlMmFreeHeap()
|
||||||
//
|
//
|
||||||
ConsolePrint(L"Cannot free memory descriptor: BlMmFreeHeap() is not implemented\r\n");
|
ConsolePrint(L"MmMdFreeDescriptor(): need BlMmFreeHeap() to free descriptor\r\n");
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
// return BlMmFreeHeap(Descriptor);
|
// return BlMmFreeHeap(Descriptor);
|
||||||
}
|
}
|
||||||
@ -147,7 +449,7 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
Mdl - the MDL to free.
|
Mdl - the MDL.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
@ -166,6 +468,56 @@ Return Value:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PMEMORY_DESCRIPTOR
|
||||||
|
MmMdInitDescriptor (
|
||||||
|
IN ULONGLONG FirstPage,
|
||||||
|
IN ULONGLONG MappedFirstPage,
|
||||||
|
IN ULONGLONG PageCount,
|
||||||
|
IN ULONG Attributes,
|
||||||
|
IN MEMORY_TYPE Type
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Initializes a memory descriptor.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
FirstPage - The first page in the region.
|
||||||
|
|
||||||
|
MappedFirstPage - The first page in the mapping.
|
||||||
|
|
||||||
|
Attributes - Memory attributes of the region.
|
||||||
|
|
||||||
|
Type - Memory type of the region.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
Pointer to the memory descriptor,
|
||||||
|
NULL if an error occurs.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
PMEMORY_DESCRIPTOR Descriptor;
|
||||||
|
|
||||||
|
if (MmGlobalMemoryDescriptorsUsed >= MmGlobalMemoryDescriptorCount) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Descriptor = &MmGlobalMemoryDescriptors[MmGlobalMemoryDescriptorsUsed++];
|
||||||
|
Descriptor->FirstPage = FirstPage;
|
||||||
|
Descriptor->MappedFirstPage = MappedFirstPage;
|
||||||
|
Descriptor->PageCount = PageCount;
|
||||||
|
Descriptor->Attributes = Attributes;
|
||||||
|
Descriptor->Type = Type;
|
||||||
|
InitializeListHead(&Descriptor->ListEntry);
|
||||||
|
|
||||||
|
return Descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmMdInitialize (
|
MmMdInitialize (
|
||||||
IN ULONG Unused,
|
IN ULONG Unused,
|
||||||
@ -201,6 +553,7 @@ Return Value:
|
|||||||
//
|
//
|
||||||
MmGlobalMemoryDescriptors = &MmStaticMemoryDescriptors[0];
|
MmGlobalMemoryDescriptors = &MmStaticMemoryDescriptors[0];
|
||||||
MmGlobalMemoryDescriptorCount = MAX_STATIC_DESCRIPTOR_COUNT;
|
MmGlobalMemoryDescriptorCount = MAX_STATIC_DESCRIPTOR_COUNT;
|
||||||
|
MmGlobalMemoryDescriptorsUsed = 0;
|
||||||
RtlZeroMemory(MmGlobalMemoryDescriptors, MAX_STATIC_DESCRIPTOR_COUNT * sizeof(MEMORY_DESCRIPTOR));
|
RtlZeroMemory(MmGlobalMemoryDescriptors, MAX_STATIC_DESCRIPTOR_COUNT * sizeof(MEMORY_DESCRIPTOR));
|
||||||
DebugPrintf(L"Global memory descriptor count: %x\r\n", MmGlobalMemoryDescriptorCount);
|
DebugPrintf(L"Global memory descriptor count: %x\r\n", MmGlobalMemoryDescriptorCount);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
Mdl - the MDL to initialize.
|
Mdl - Pointer to the MDL.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
@ -72,9 +72,9 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
MemoryInfo - pointer to the memory info structure.
|
MemoryInfo - Pointer to the memory info structure.
|
||||||
|
|
||||||
MinimumAllocation - minimum amount of pages to grow the pool by at a time.
|
MinimumAllocation - Minimum amount of pages to grow the pool by at a time.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
|
@ -16,9 +16,6 @@ Abstract:
|
|||||||
#include <ntrtl.h>
|
#include <ntrtl.h>
|
||||||
#include "bootlib.h"
|
#include "bootlib.h"
|
||||||
|
|
||||||
//
|
|
||||||
// Total size of required structures.
|
|
||||||
//
|
|
||||||
#define MIN_INPUT_PARAMETERS_SIZE ( \
|
#define MIN_INPUT_PARAMETERS_SIZE ( \
|
||||||
sizeof(BOOT_INPUT_PARAMETERS) + \
|
sizeof(BOOT_INPUT_PARAMETERS) + \
|
||||||
sizeof(BOOT_MEMORY_INFO) + \
|
sizeof(BOOT_MEMORY_INFO) + \
|
||||||
@ -40,13 +37,13 @@ InitializeLibrary (
|
|||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Internal routine to initialize the boot library.
|
Initializes the boot library.
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
InputParameters - pointer to the input parameters structure.
|
InputParameters - Pointer to the application's input parameters.
|
||||||
|
|
||||||
LibraryParameters - pointer to the library parameters structure.
|
LibraryParameters - Pointer to the library parameters.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
@ -64,18 +61,12 @@ Return Value:
|
|||||||
|
|
||||||
(VOID)LibraryParameters;
|
(VOID)LibraryParameters;
|
||||||
|
|
||||||
//
|
|
||||||
// Verify input parameters structure.
|
|
||||||
//
|
|
||||||
if (InputParameters == NULL ||
|
if (InputParameters == NULL ||
|
||||||
InputParameters->Signature != BOOT_INPUT_PARAMETERS_SIGNATURE ||
|
InputParameters->Signature != BOOT_INPUT_PARAMETERS_SIGNATURE ||
|
||||||
InputParameters->Size < MIN_INPUT_PARAMETERS_SIZE) {
|
InputParameters->Size < MIN_INPUT_PARAMETERS_SIZE) {
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Calculate structure addresses from offsets.
|
|
||||||
//
|
|
||||||
MemoryInfo = (PBOOT_MEMORY_INFO)((PUCHAR)InputParameters + InputParameters->MemoryInfoOffset);
|
MemoryInfo = (PBOOT_MEMORY_INFO)((PUCHAR)InputParameters + InputParameters->MemoryInfoOffset);
|
||||||
ApplicationEntry = (PBOOT_INPUT_APPLICATION_ENTRY)((PUCHAR)InputParameters + InputParameters->ApplicationEntryOffset);
|
ApplicationEntry = (PBOOT_INPUT_APPLICATION_ENTRY)((PUCHAR)InputParameters + InputParameters->ApplicationEntryOffset);
|
||||||
BlpBootDevice = (PBOOT_DEVICE)((PUCHAR)InputParameters + InputParameters->BootDeviceOffset);
|
BlpBootDevice = (PBOOT_DEVICE)((PUCHAR)InputParameters + InputParameters->BootDeviceOffset);
|
||||||
@ -91,31 +82,22 @@ Return Value:
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Print image information.
|
|
||||||
//
|
|
||||||
ConsolePrintf(L"Image base: %x %x\r\n", (ULONG)((ULONG_PTR)InputParameters->ImageBase >> 32), (ULONG)((ULONG_PTR)InputParameters->ImageBase));
|
ConsolePrintf(L"Image base: %x %x\r\n", (ULONG)((ULONG_PTR)InputParameters->ImageBase >> 32), (ULONG)((ULONG_PTR)InputParameters->ImageBase));
|
||||||
ConsolePrintf(L"Image size: %x\r\n", InputParameters->ImageSize);
|
ConsolePrintf(L"Image size: %x\r\n", InputParameters->ImageSize);
|
||||||
|
|
||||||
//
|
|
||||||
// Check application entry signature.
|
|
||||||
//
|
|
||||||
if (ApplicationEntry->Signature != BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE) {
|
if (ApplicationEntry->Signature != BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE) {
|
||||||
DebugPrint(L"InitializeLibrary(): ApplicationEntry Signature is invalid\r\n");
|
DebugPrint(L"InitializeLibrary(): ApplicationEntry Signature is invalid\r\n");
|
||||||
return STATUS_INVALID_PARAMETER_9;
|
return STATUS_INVALID_PARAMETER_9;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Save input parameters and application entry data.
|
// Save input parameters and application entry.
|
||||||
//
|
//
|
||||||
BlpApplicationParameters = InputParameters;
|
BlpApplicationParameters = InputParameters;
|
||||||
BlpApplicationEntry.Attributes = ApplicationEntry->Attributes;
|
BlpApplicationEntry.Attributes = ApplicationEntry->Attributes;
|
||||||
RtlCopyMemory(&BlpApplicationEntry.BcdIdentifier, &ApplicationEntry->BcdIdentifier, sizeof(GUID));
|
RtlCopyMemory(&BlpApplicationEntry.BcdIdentifier, &ApplicationEntry->BcdIdentifier, sizeof(GUID));
|
||||||
BlpApplicationEntry.Options = &ApplicationEntry->Options;
|
BlpApplicationEntry.Options = &ApplicationEntry->Options;
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize memory manager.
|
|
||||||
//
|
|
||||||
Status = BlpMmInitialize(MemoryInfo, InputParameters->TranslationType, LibraryParameters);
|
Status = BlpMmInitialize(MemoryInfo, InputParameters->TranslationType, LibraryParameters);
|
||||||
if (!NT_SUCCESS(Status)) {
|
if (!NT_SUCCESS(Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
@ -191,13 +173,13 @@ BlInitializeLibrary (
|
|||||||
|
|
||||||
Routine Description:
|
Routine Description:
|
||||||
|
|
||||||
Initializes the boot library.
|
Initializes the boot library. Wrapper for InitializeLibrary().
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
InputParameters - pointer to the input parameters structure.
|
InputParameters - Pointer to the application's input parameters.
|
||||||
|
|
||||||
LibraryParameters - pointer to the library parameters structure.
|
LibraryParameters - Pointer to the library parameters.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
@ -226,8 +208,7 @@ Arguments:
|
|||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
STATUS_SUCCESS if successful.
|
STATUS_SUCCESS.
|
||||||
Error status if an error is encountered.
|
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
Option - the boot option to get the size of.
|
Option - The boot option.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
@ -65,11 +65,11 @@ Routine Description:
|
|||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
||||||
Options - the boot option list to get the size of.
|
Options - The boot option list.
|
||||||
|
|
||||||
Return Value:
|
Return Value:
|
||||||
|
|
||||||
The size of the options.
|
The size of the option list.
|
||||||
|
|
||||||
--*/
|
--*/
|
||||||
|
|
||||||
|
@ -260,6 +260,66 @@ Return Value:
|
|||||||
Head->Flink = Head;
|
Head->Flink = Head;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
InsertHeadList (
|
||||||
|
IN PLIST_ENTRY Head,
|
||||||
|
IN PLIST_ENTRY Entry
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Inserts a list entry at the head of a list.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Entry - The list entry.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
Entry->Flink = Head->Flink;
|
||||||
|
Entry->Blink = Head;
|
||||||
|
Head->Flink->Blink = Entry;
|
||||||
|
Head->Flink = Entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
InsertTailList (
|
||||||
|
IN PLIST_ENTRY Head,
|
||||||
|
IN PLIST_ENTRY Entry
|
||||||
|
)
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Inserts a list entry at the tail of a list.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Entry - The list entry.
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
{
|
||||||
|
Entry->Blink = Head->Blink;
|
||||||
|
Entry->Flink = Head;
|
||||||
|
Head->Blink->Flink = Entry;
|
||||||
|
Head->Blink = Entry;
|
||||||
|
}
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
RemoveEntryList (
|
RemoveEntryList (
|
||||||
|
Loading…
Reference in New Issue
Block a user