2015-09-04 14:16:56 +00:00
|
|
|
/*
|
|
|
|
* COPYRIGHT: See COPYING.ARM in the top level directory
|
|
|
|
* PROJECT: ReactOS UEFI Boot Manager
|
2015-09-26 16:31:49 +00:00
|
|
|
* FILE: boot/environ/app/bootmgr/efiemu.c
|
2015-09-04 14:16:56 +00:00
|
|
|
* PURPOSE: UEFI Entrypoint for Boot Manager
|
|
|
|
* PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
|
|
|
#include "bootmgr.h"
|
2015-09-05 16:05:20 +00:00
|
|
|
|
|
|
|
/* DATA STRUCTURES ***********************************************************/
|
|
|
|
|
|
|
|
typedef struct _BOOT_APPLICATION_PARAMETER_BLOCK_SCRATCH
|
|
|
|
{
|
|
|
|
BOOT_APPLICATION_PARAMETER_BLOCK;
|
|
|
|
BL_MEMORY_DATA BootMemoryData;
|
|
|
|
BL_MEMORY_DESCRIPTOR MemEntry;
|
|
|
|
UCHAR AppEntry[788];
|
|
|
|
} BOOT_APPLICATION_PARAMETER_BLOCK_SCRATCH;
|
|
|
|
|
|
|
|
/* DATA VARIABLES ************************************************************/
|
|
|
|
|
|
|
|
BOOT_APPLICATION_PARAMETER_BLOCK_SCRATCH EfiInitScratch;
|
2015-09-04 14:16:56 +00:00
|
|
|
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2015-09-05 19:18:54 +00:00
|
|
|
/*++
|
|
|
|
* @name AhCreateLoadOptionsList
|
|
|
|
*
|
2021-09-13 01:33:14 +00:00
|
|
|
* The AhCreateLoadOptionsList routine
|
2015-09-05 19:18:54 +00:00
|
|
|
*
|
|
|
|
* @param CommandLine
|
|
|
|
* UEFI Image Handle for the current loaded application.
|
|
|
|
*
|
|
|
|
* @param BootOptions
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param MaximumLength
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param OptionSize
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param PreviousOption
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param PreviousOptionSize
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*
|
|
|
|
*--*/
|
2015-09-05 16:05:20 +00:00
|
|
|
NTSTATUS
|
|
|
|
AhCreateLoadOptionsList (
|
|
|
|
_In_ PWCHAR CommandLine,
|
2015-09-05 19:18:54 +00:00
|
|
|
_In_ PBL_BCD_OPTION BootOptions,
|
2015-09-05 16:05:20 +00:00
|
|
|
_In_ ULONG MaximumLength,
|
|
|
|
_Out_ PULONG OptionSize,
|
2015-09-05 19:18:54 +00:00
|
|
|
_In_ PBL_BCD_OPTION* PreviousOption,
|
2015-09-05 16:05:20 +00:00
|
|
|
_In_ PULONG PreviousOptionSize
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2015-09-05 19:38:20 +00:00
|
|
|
/*++
|
|
|
|
* @name EfiInitpAppendPathString
|
|
|
|
*
|
2021-09-13 01:33:14 +00:00
|
|
|
* The EfiInitpAppendPathString routine
|
2015-09-05 19:38:20 +00:00
|
|
|
*
|
|
|
|
* @param DestinationPath
|
|
|
|
* UEFI Image Handle for the current loaded application.
|
|
|
|
*
|
|
|
|
* @param RemainingSize
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param AppendPath
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param AppendLength
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param BytesAppended
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
NTSTATUS
|
|
|
|
EfiInitpAppendPathString (
|
|
|
|
_In_ PWCHAR PathString,
|
|
|
|
_In_ ULONG MaximumLength,
|
|
|
|
_In_ PWCHAR NewPathString,
|
|
|
|
_In_ ULONG NewPathLength,
|
|
|
|
_Out_ PULONG ResultLength
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
ULONG FinalPathLength;
|
|
|
|
|
|
|
|
/* We deal in Unicode, validate the length */
|
|
|
|
if (NewPathLength & 1)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Is the new element at least a character? */
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
if (NewPathLength >= sizeof(WCHAR))
|
|
|
|
{
|
|
|
|
/* Is the last character already a NULL character? */
|
|
|
|
if (NewPathString[(NewPathLength - sizeof(WCHAR)) / sizeof(WCHAR)] ==
|
|
|
|
UNICODE_NULL)
|
|
|
|
{
|
|
|
|
/* Then we won't need to count it */
|
|
|
|
NewPathLength -= sizeof(UNICODE_NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Was it more than just a NULL character? */
|
|
|
|
if (NewPathLength >= sizeof(WCHAR))
|
|
|
|
{
|
|
|
|
/* Yep -- but does it have a separator? */
|
|
|
|
if (*NewPathString == OBJ_NAME_PATH_SEPARATOR)
|
|
|
|
{
|
|
|
|
/* Skip it, we'll add our own later */
|
|
|
|
NewPathString++;
|
|
|
|
NewPathLength -= sizeof(OBJ_NAME_PATH_SEPARATOR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Was it more than just a separator? */
|
|
|
|
if (NewPathLength >= sizeof(WCHAR))
|
|
|
|
{
|
|
|
|
/* Yep -- but does it end with a separator? */
|
|
|
|
if (NewPathString[(NewPathLength - sizeof(WCHAR)) / sizeof(WCHAR)] ==
|
|
|
|
OBJ_NAME_PATH_SEPARATOR)
|
|
|
|
{
|
|
|
|
/* That's something else we won't need for now */
|
|
|
|
NewPathLength -= sizeof(OBJ_NAME_PATH_SEPARATOR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if anything needs to be appended after all */
|
|
|
|
if (NewPathLength != 0)
|
|
|
|
{
|
|
|
|
/* We will append the length of the new path element, plus a separator */
|
|
|
|
FinalPathLength = NewPathLength + sizeof(OBJ_NAME_PATH_SEPARATOR);
|
|
|
|
if (MaximumLength >= FinalPathLength)
|
|
|
|
{
|
|
|
|
/* Add a separator to the existing path*/
|
|
|
|
*PathString = OBJ_NAME_PATH_SEPARATOR;
|
|
|
|
|
|
|
|
/* Followed by the new path element */
|
|
|
|
RtlCopyMemory(PathString + 1, NewPathString, NewPathLength);
|
|
|
|
|
|
|
|
/* Return the number of bytes appended */
|
|
|
|
*ResultLength = FinalPathLength;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* There's not enough space to do this */
|
|
|
|
Status = STATUS_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Nothing to append */
|
|
|
|
*ResultLength = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2015-09-05 19:18:54 +00:00
|
|
|
/*++
|
|
|
|
* @name EfiInitpConvertEfiDevicePath
|
|
|
|
*
|
2021-09-13 01:33:14 +00:00
|
|
|
* The EfiInitpConvertEfiDevicePath routine
|
2015-09-05 19:18:54 +00:00
|
|
|
*
|
|
|
|
* @param DevicePath
|
|
|
|
* UEFI Image Handle for the current loaded application.
|
|
|
|
*
|
|
|
|
* @param DeviceType
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param Option
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param MaximumLength
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*
|
|
|
|
*--*/
|
2015-09-05 16:05:20 +00:00
|
|
|
NTSTATUS
|
|
|
|
EfiInitpConvertEfiFilePath (
|
2015-09-05 19:38:20 +00:00
|
|
|
_In_ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
2015-09-05 16:05:20 +00:00
|
|
|
_In_ ULONG PathType,
|
2015-09-05 19:18:54 +00:00
|
|
|
_In_ PBL_BCD_OPTION Option,
|
2015-09-05 16:05:20 +00:00
|
|
|
_In_ ULONG MaximumLength
|
|
|
|
)
|
|
|
|
{
|
2015-09-05 19:38:20 +00:00
|
|
|
ULONG BytesAppended, DataSize, StringLength;
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
PWCHAR StringEntry, PathString;
|
2015-09-05 19:38:20 +00:00
|
|
|
FILEPATH_DEVICE_PATH *FilePath;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Make sure we have enough space for the option */
|
|
|
|
if (MaximumLength < sizeof(*Option))
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the initial size of the option, and consume from our buffer */
|
|
|
|
DataSize = sizeof(*Option);
|
|
|
|
MaximumLength -= sizeof(*Option);
|
|
|
|
|
|
|
|
/* Zero out and fill the option header */
|
|
|
|
RtlZeroMemory(Option, DataSize);
|
|
|
|
Option->Type = PathType;
|
|
|
|
Option->DataOffset = sizeof(*Option);
|
|
|
|
|
|
|
|
/* Extract the string option */
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
StringEntry = (PWCHAR)(Option + 1);
|
|
|
|
PathString = StringEntry;
|
2015-09-05 19:38:20 +00:00
|
|
|
|
|
|
|
/* Start parsing the device path */
|
|
|
|
FilePath = (FILEPATH_DEVICE_PATH*)DevicePath;
|
|
|
|
while (IsDevicePathEndType(FilePath) == FALSE)
|
|
|
|
{
|
|
|
|
/* Is this a file path? */
|
|
|
|
if ((FilePath->Header.Type == MEDIA_DEVICE_PATH) &&
|
|
|
|
(FilePath->Header.SubType == MEDIA_FILEPATH_DP))
|
|
|
|
{
|
|
|
|
/* Get the length of the file path string, avoiding overflow */
|
|
|
|
StringLength = DevicePathNodeLength(FilePath) -
|
|
|
|
FIELD_OFFSET(FILEPATH_DEVICE_PATH, PathName);
|
2015-09-06 03:02:56 +00:00
|
|
|
if (StringLength < (ULONG)FIELD_OFFSET(FILEPATH_DEVICE_PATH, PathName))
|
2015-09-05 19:38:20 +00:00
|
|
|
{
|
|
|
|
Status = STATUS_INTEGER_OVERFLOW;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Append this path string to the current path string */
|
|
|
|
Status = EfiInitpAppendPathString(PathString,
|
|
|
|
MaximumLength,
|
|
|
|
FilePath->PathName,
|
|
|
|
StringLength,
|
|
|
|
&BytesAppended);
|
2015-09-09 05:48:50 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
2015-09-05 19:38:20 +00:00
|
|
|
|
|
|
|
/* Increase the size of the data, consume buffer space */
|
|
|
|
DataSize += BytesAppended;
|
|
|
|
MaximumLength -= BytesAppended;
|
|
|
|
|
|
|
|
/* Move to the next path string */
|
|
|
|
PathString = (PWCHAR)((ULONG_PTR)PathString + BytesAppended);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Move to the next path node */
|
|
|
|
FilePath = (FILEPATH_DEVICE_PATH*)NextDevicePathNode(FilePath);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if we still have space for a NULL-terminator */
|
|
|
|
if (MaximumLength < sizeof(UNICODE_NULL))
|
|
|
|
{
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We do -- NULL-terminate the string */
|
|
|
|
*PathString = UNICODE_NULL;
|
|
|
|
DataSize += sizeof(UNICODE_NULL);
|
|
|
|
|
|
|
|
/* Check if all of this has amounted to a single NULL-char */
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
if (PathString == StringEntry)
|
2015-09-05 19:38:20 +00:00
|
|
|
{
|
|
|
|
/* Then this option is empty */
|
2015-09-06 03:02:56 +00:00
|
|
|
Option->Empty = TRUE;
|
2015-09-05 19:38:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the final size of the option */
|
|
|
|
Option->DataSize = DataSize;
|
|
|
|
|
|
|
|
Quickie:
|
|
|
|
return STATUS_SUCCESS;
|
2015-09-05 16:05:20 +00:00
|
|
|
}
|
|
|
|
|
2015-09-05 19:18:54 +00:00
|
|
|
/*++
|
|
|
|
* @name EfiInitpGetDeviceNode
|
|
|
|
*
|
2021-09-13 01:33:14 +00:00
|
|
|
* The EfiInitpGetDeviceNode routine
|
2015-09-05 19:18:54 +00:00
|
|
|
*
|
|
|
|
* @param DevicePath
|
|
|
|
* UEFI Image Handle for the current loaded application.
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
EFI_DEVICE_PATH_PROTOCOL*
|
|
|
|
EfiInitpGetDeviceNode (
|
|
|
|
_In_ EFI_DEVICE_PATH_PROTOCOL *DevicePath
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_DEVICE_PATH_PROTOCOL* NextPath;
|
|
|
|
|
|
|
|
/* Check if we hit the end terminator */
|
|
|
|
if (IsDevicePathEndType(DevicePath))
|
|
|
|
{
|
|
|
|
return DevicePath;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Loop each device path, until we get to the end or to a file path device node */
|
|
|
|
for ((NextPath = NextDevicePathNode(DevicePath));
|
Three tiny squirmy subtle bugs combined themselves with the bug that was just fixed to make bootmgfw believe it was being booted from a raw removable disk (floppy). Because bootmgfw now correctly enumerates boot devices and detects the DVD/CDROM media, it could no longer 'find itself', believing it was on a floppy.
[BOOTLIB]: When failing to find a block device, keep going searching for more, instead of giving up (critical, because the CDROM FAT12 image is now device path #1, not #0).
[BOOTMGR]: Correctly use the right logical operator in EfiInitpGetDeviceNode to get the deepest-level media device node. We now get the CDROM node, not the raw node.
[CDMAKE]: Don't actually create an EFI/BOOT directory on the CDROM itself, but rather in the FAT12 image. Otherwise, this can confuse UEFI implementations to boot the boot manager off the raw CDROM, instead of the FAT12 image on the CDROM.
svn path=/trunk/; revision=70542
2016-01-08 01:18:08 +00:00
|
|
|
!(IsDevicePathEndType(NextPath)) && ((NextPath->Type != MEDIA_DEVICE_PATH) ||
|
2015-09-05 19:18:54 +00:00
|
|
|
(NextPath->SubType != MEDIA_FILEPATH_DP));
|
|
|
|
(NextPath = NextDevicePathNode(NextPath)))
|
|
|
|
{
|
|
|
|
/* Keep iterating down */
|
|
|
|
DevicePath = NextPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the path found */
|
|
|
|
return DevicePath;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
* @name EfiInitTranslateDevicePath
|
|
|
|
*
|
2021-09-13 01:33:14 +00:00
|
|
|
* The EfiInitTranslateDevicePath routine
|
2015-09-05 19:18:54 +00:00
|
|
|
*
|
|
|
|
* @param DevicePath
|
|
|
|
* UEFI Image Handle for the current loaded application.
|
|
|
|
*
|
|
|
|
* @param DeviceEntry
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
NTSTATUS
|
2015-09-09 05:48:50 +00:00
|
|
|
EfiInitTranslateDevicePath (
|
2015-09-05 19:18:54 +00:00
|
|
|
_In_ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
|
|
|
_In_ PBL_DEVICE_DESCRIPTOR DeviceEntry
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
EFI_DEVICE_PATH_PROTOCOL* DeviceNode;
|
|
|
|
MEMMAP_DEVICE_PATH* MemDevicePath;
|
|
|
|
ACPI_HID_DEVICE_PATH *AcpiPath;
|
|
|
|
HARDDRIVE_DEVICE_PATH *DiskPath;
|
|
|
|
|
|
|
|
/* Assume failure */
|
|
|
|
Status = STATUS_UNSUCCESSFUL;
|
|
|
|
|
|
|
|
/* Set size first */
|
|
|
|
DeviceEntry->Size = sizeof(*DeviceEntry);
|
|
|
|
|
|
|
|
/* Check if we are booting from a RAM Disk */
|
|
|
|
if ((DevicePath->Type == HARDWARE_DEVICE_PATH) &&
|
|
|
|
(DevicePath->SubType == HW_MEMMAP_DP))
|
|
|
|
{
|
|
|
|
/* Get the EFI data structure matching this */
|
|
|
|
MemDevicePath = (MEMMAP_DEVICE_PATH*)DevicePath;
|
|
|
|
|
|
|
|
/* Set the boot library specific device types */
|
|
|
|
DeviceEntry->DeviceType = LocalDevice;
|
|
|
|
DeviceEntry->Local.Type = RamDiskDevice;
|
|
|
|
|
|
|
|
/* Extract the base, size, and offset */
|
|
|
|
DeviceEntry->Local.RamDisk.ImageBase.QuadPart = MemDevicePath->StartingAddress;
|
|
|
|
DeviceEntry->Local.RamDisk.ImageSize.QuadPart = MemDevicePath->EndingAddress -
|
|
|
|
MemDevicePath->StartingAddress;
|
|
|
|
DeviceEntry->Local.RamDisk.ImageOffset = 0;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Otherwise, check what kind of device node this is */
|
|
|
|
DeviceNode = EfiInitpGetDeviceNode(DevicePath);
|
|
|
|
switch (DeviceNode->Type)
|
|
|
|
{
|
|
|
|
/* ACPI */
|
|
|
|
case ACPI_DEVICE_PATH:
|
|
|
|
|
|
|
|
/* We only support floppy drives */
|
|
|
|
AcpiPath = (ACPI_HID_DEVICE_PATH*)DeviceNode;
|
|
|
|
if ((AcpiPath->HID != EISA_PNP_ID(0x604)) &&
|
|
|
|
(AcpiPath->HID != EISA_PNP_ID(0x700)))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the boot library specific device types */
|
|
|
|
DeviceEntry->DeviceType = LocalDevice;
|
|
|
|
DeviceEntry->Local.Type = FloppyDevice;
|
|
|
|
|
|
|
|
/* The ACPI UID is the drive number */
|
|
|
|
DeviceEntry->Local.FloppyDisk.DriveNumber = AcpiPath->UID;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
|
|
|
/* Network, ATAPI, SCSI, USB */
|
|
|
|
case MESSAGING_DEVICE_PATH:
|
|
|
|
|
|
|
|
/* Check if it's network */
|
|
|
|
if ((DeviceNode->SubType == MSG_MAC_ADDR_DP) ||
|
|
|
|
(DeviceNode->SubType == MSG_IPv4_DP))
|
|
|
|
{
|
|
|
|
/* Set the boot library specific device types */
|
|
|
|
DeviceEntry->DeviceType = UdpDevice;
|
|
|
|
DeviceEntry->Remote.Unknown = 256;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Other types should come in as MEDIA_DEVICE_PATH -- Windows assumes this is a floppy */
|
2015-09-09 05:48:50 +00:00
|
|
|
DeviceEntry->DeviceType = DiskDevice;
|
2015-09-05 19:18:54 +00:00
|
|
|
DeviceEntry->Local.Type = FloppyDevice;
|
|
|
|
DeviceEntry->Local.FloppyDisk.DriveNumber = 0;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
|
|
|
|
/* Disk or CDROM */
|
|
|
|
case MEDIA_DEVICE_PATH:
|
|
|
|
|
|
|
|
/* Extract the disk path and check if it's a physical disk */
|
|
|
|
DiskPath = (HARDDRIVE_DEVICE_PATH*)DeviceNode;
|
|
|
|
if (DeviceNode->SubType == MEDIA_HARDDRIVE_DP)
|
|
|
|
{
|
|
|
|
/* Check if this is an MBR partition */
|
|
|
|
if (DiskPath->SignatureType == SIGNATURE_TYPE_MBR)
|
|
|
|
{
|
|
|
|
/* Set that this is a local partition */
|
2015-09-09 05:48:50 +00:00
|
|
|
DeviceEntry->DeviceType = LegacyPartitionDevice;
|
2015-09-05 19:18:54 +00:00
|
|
|
DeviceEntry->Partition.Disk.Type = LocalDevice;
|
|
|
|
|
|
|
|
DeviceEntry->Partition.Disk.HardDisk.PartitionType = MbrPartition;
|
|
|
|
DeviceEntry->Partition.Disk.HardDisk.Mbr.PartitionSignature =
|
|
|
|
*(PULONG)&DiskPath->Signature[0];
|
|
|
|
DeviceEntry->Partition.Mbr.PartitionNumber = DiskPath->PartitionNumber;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check if it's a GPT partition */
|
|
|
|
if (DiskPath->SignatureType == SIGNATURE_TYPE_GUID)
|
|
|
|
{
|
|
|
|
/* Set that this is a local disk */
|
2015-09-09 05:48:50 +00:00
|
|
|
DeviceEntry->DeviceType = PartitionDevice;
|
2015-09-05 19:18:54 +00:00
|
|
|
DeviceEntry->Partition.Disk.Type = LocalDevice;
|
|
|
|
|
|
|
|
/* Set GPT partition ID */
|
|
|
|
DeviceEntry->Partition.Disk.HardDisk.PartitionType = GptPartition;
|
|
|
|
|
2015-09-05 19:38:20 +00:00
|
|
|
/* Copy the signature GUID */
|
2015-09-05 19:18:54 +00:00
|
|
|
RtlCopyMemory(&DeviceEntry->Partition.Gpt.PartitionGuid,
|
2021-09-13 01:33:14 +00:00
|
|
|
DiskPath->Signature,
|
2015-09-05 19:18:54 +00:00
|
|
|
sizeof(GUID));
|
|
|
|
|
|
|
|
DeviceEntry->Flags |= 4u;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2015-09-09 05:48:50 +00:00
|
|
|
/* Otherwise, raw boot is not supported */
|
|
|
|
DeviceEntry->DeviceType = PartitionDevice;
|
|
|
|
DeviceEntry->Partition.Disk.Type = LocalDevice;
|
2015-09-05 19:18:54 +00:00
|
|
|
DeviceEntry->Partition.Disk.HardDisk.PartitionType = RawPartition;
|
|
|
|
DeviceEntry->Partition.Disk.HardDisk.Raw.DiskNumber = 0;
|
|
|
|
}
|
|
|
|
else if (DeviceNode->SubType == MEDIA_CDROM_DP)
|
|
|
|
{
|
|
|
|
/* Set the right type for a CDROM */
|
2015-09-09 05:48:50 +00:00
|
|
|
DeviceEntry->DeviceType = DiskDevice;
|
2015-09-05 19:18:54 +00:00
|
|
|
DeviceEntry->Local.Type = CdRomDevice;
|
|
|
|
|
|
|
|
/* Set the drive number to zero */
|
|
|
|
DeviceEntry->Local.FloppyDisk.DriveNumber = 0;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fail anything else */
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return here only on failure */
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
* @name EfiInitpConvertEfiDevicePath
|
|
|
|
*
|
2021-09-13 01:33:14 +00:00
|
|
|
* The EfiInitpConvertEfiDevicePath routine
|
2015-09-05 19:18:54 +00:00
|
|
|
*
|
|
|
|
* @param DevicePath
|
|
|
|
* UEFI Image Handle for the current loaded application.
|
|
|
|
*
|
|
|
|
* @param DeviceType
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param Option
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param MaximumLength
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*
|
|
|
|
*--*/
|
2015-09-05 16:05:20 +00:00
|
|
|
NTSTATUS
|
|
|
|
EfiInitpConvertEfiDevicePath (
|
|
|
|
_In_ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
|
|
|
|
_In_ ULONG DeviceType,
|
2015-09-05 19:18:54 +00:00
|
|
|
_In_ PBL_BCD_OPTION Option,
|
2015-09-05 16:05:20 +00:00
|
|
|
_In_ ULONG MaximumLength
|
|
|
|
)
|
|
|
|
{
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
PBCD_DEVICE_OPTION BcdDevice;
|
2015-09-05 19:18:54 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Make sure we have enough space for the option */
|
|
|
|
if (MaximumLength < sizeof(*Option))
|
|
|
|
{
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Zero out the option */
|
|
|
|
RtlZeroMemory(Option, sizeof(*Option));
|
|
|
|
|
|
|
|
/* Make sure we have enough space for the device entry */
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
if ((MaximumLength - sizeof(*Option)) <
|
|
|
|
(ULONG)FIELD_OFFSET(BCD_DEVICE_OPTION, DeviceDescriptor))
|
2015-09-05 19:18:54 +00:00
|
|
|
{
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fill it out */
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
BcdDevice = (PBCD_DEVICE_OPTION)(Option + 1);
|
|
|
|
Status = EfiInitTranslateDevicePath(DevicePath,
|
|
|
|
&BcdDevice->DeviceDescriptor);
|
2015-09-05 19:18:54 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Fill out the rest of the option structure */
|
|
|
|
Option->DataOffset = sizeof(*Option);
|
|
|
|
Option->Type = DeviceType;
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
Option->DataSize = FIELD_OFFSET(BCD_DEVICE_OPTION, DeviceDescriptor) +
|
|
|
|
BcdDevice->DeviceDescriptor.Size;
|
2015-09-05 19:18:54 +00:00
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
Quickie:
|
|
|
|
return Status;
|
2015-09-05 16:05:20 +00:00
|
|
|
}
|
|
|
|
|
2015-09-05 19:18:54 +00:00
|
|
|
/*++
|
|
|
|
* @name EfiInitpCreateApplicationEntry
|
|
|
|
*
|
2021-09-13 01:33:14 +00:00
|
|
|
* The EfiInitpCreateApplicationEntry routine
|
2015-09-05 19:18:54 +00:00
|
|
|
*
|
|
|
|
* @param SystemTable
|
|
|
|
* UEFI Image Handle for the current loaded application.
|
|
|
|
*
|
|
|
|
* @param Entry
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param MaximumLength
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param DevicePath
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param FilePath
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param LoadOptions
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param LoadOptionsSize
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param Flags
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param ResultLength
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @param AppEntryDevice
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @return None
|
|
|
|
*
|
|
|
|
*--*/
|
2015-09-05 16:05:20 +00:00
|
|
|
VOID
|
|
|
|
EfiInitpCreateApplicationEntry (
|
|
|
|
__in EFI_SYSTEM_TABLE *SystemTable,
|
|
|
|
__in PBL_APPLICATION_ENTRY Entry,
|
|
|
|
__in ULONG MaximumLength,
|
|
|
|
__in EFI_DEVICE_PATH *DevicePath,
|
|
|
|
__in EFI_DEVICE_PATH *FilePath,
|
|
|
|
__in PWCHAR LoadOptions,
|
|
|
|
__in ULONG LoadOptionsSize,
|
|
|
|
__in ULONG Flags,
|
|
|
|
__out PULONG ResultLength,
|
|
|
|
__out PBL_DEVICE_DESCRIPTOR *AppEntryDevice
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PBL_WINDOWS_LOAD_OPTIONS WindowsOptions;
|
|
|
|
PWCHAR ObjectString, CommandLine;
|
2015-09-05 19:18:54 +00:00
|
|
|
PBL_BCD_OPTION Option, PreviousOption;
|
2015-09-05 16:05:20 +00:00
|
|
|
ULONG HeaderSize, TotalOptionSize, Size, CommandLineSize, RemainingSize;
|
|
|
|
NTSTATUS Status;
|
|
|
|
UNICODE_STRING GuidString;
|
|
|
|
GUID ObjectGuid;
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
PBCD_DEVICE_OPTION BcdDevice;
|
2015-09-05 16:05:20 +00:00
|
|
|
BOOLEAN HaveBinaryOptions, HaveGuid;
|
|
|
|
PBL_FILE_PATH_DESCRIPTOR OsPath;
|
|
|
|
EFI_DEVICE_PATH *OsDevicePath;
|
|
|
|
|
|
|
|
/* Initialize everything */
|
|
|
|
TotalOptionSize = 0;
|
|
|
|
*AppEntryDevice = NULL;
|
|
|
|
HeaderSize = 0;
|
|
|
|
|
|
|
|
/* Check if the load options are in binary Windows format */
|
|
|
|
WindowsOptions = (PBL_WINDOWS_LOAD_OPTIONS)LoadOptions;
|
|
|
|
if ((WindowsOptions != NULL) &&
|
|
|
|
(LoadOptionsSize >= sizeof(BL_WINDOWS_LOAD_OPTIONS)) &&
|
|
|
|
(WindowsOptions->Length >= sizeof(BL_WINDOWS_LOAD_OPTIONS)) &&
|
|
|
|
!(strncmp(WindowsOptions->Signature, "WINDOWS", 7)))
|
|
|
|
{
|
|
|
|
/* They are, so firmware must have loaded us -- extract arguments */
|
|
|
|
CommandLine = WindowsOptions->LoadOptions;
|
|
|
|
CommandLineSize = LoadOptionsSize - FIELD_OFFSET(BL_WINDOWS_LOAD_OPTIONS,
|
|
|
|
LoadOptions);
|
|
|
|
|
|
|
|
/* Remember that we used binary options */
|
|
|
|
HaveBinaryOptions = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Nope -- so treat them as raw command-line options */
|
|
|
|
CommandLine = LoadOptions;
|
|
|
|
CommandLineSize = LoadOptionsSize;
|
|
|
|
|
|
|
|
/* No binary options */
|
|
|
|
HaveBinaryOptions = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EFI uses UTF-16LE, like NT, so convert to characters */
|
|
|
|
CommandLineSize /= sizeof(WCHAR);
|
|
|
|
if (CommandLineSize != 0)
|
|
|
|
{
|
|
|
|
/* And check if the options are not NULL-terminated */
|
|
|
|
if (wcsnlen(CommandLine, CommandLineSize) == CommandLineSize)
|
|
|
|
{
|
|
|
|
/* NULL-terminate them */
|
|
|
|
CommandLine[CommandLineSize - 1] = UNICODE_NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Begin by making sure we at least have space for the app entry header */
|
|
|
|
RemainingSize = MaximumLength;
|
|
|
|
if (RemainingSize < sizeof(BL_APPLICATION_ENTRY))
|
|
|
|
{
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* On exit, return that we've at least consumed this much */
|
|
|
|
HeaderSize = FIELD_OFFSET(BL_APPLICATION_ENTRY, BcdData);
|
|
|
|
|
|
|
|
/* Zero out the header, and write down the signature */
|
|
|
|
RtlZeroMemory(Entry, sizeof(BL_APPLICATION_ENTRY));
|
2015-09-05 20:31:14 +00:00
|
|
|
RtlCopyMemory(Entry->Signature, BL_APP_ENTRY_SIGNATURE, 7);
|
2015-09-05 16:05:20 +00:00
|
|
|
|
|
|
|
/* Check if a BCD object was passed on the command-line */
|
|
|
|
ObjectString = wcsstr(CommandLine, L"BCDOBJECT=");
|
|
|
|
if (ObjectString != NULL)
|
|
|
|
{
|
|
|
|
/* Convert the BCD object to a GUID */
|
|
|
|
RtlInitUnicodeString(&GuidString, ObjectString + 10);
|
|
|
|
RtlGUIDFromString(&GuidString, &ObjectGuid);
|
|
|
|
|
|
|
|
/* Store it in the application entry */
|
|
|
|
Entry->Guid = ObjectGuid;
|
|
|
|
|
|
|
|
/* Remember one was passed */
|
|
|
|
HaveGuid = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Remember that no identifier was passed */
|
|
|
|
Entry->Flags |= BL_APPLICATION_ENTRY_FLAG_NO_GUID;
|
|
|
|
HaveGuid = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* At this point, the header is consumed, and we must now handle BCD options */
|
|
|
|
RemainingSize -= FIELD_OFFSET(BL_APPLICATION_ENTRY, BcdData);
|
|
|
|
|
|
|
|
/* Convert the device path into a BCD option */
|
|
|
|
Status = EfiInitpConvertEfiDevicePath(DevicePath,
|
|
|
|
BcdLibraryDevice_ApplicationDevice,
|
|
|
|
&Entry->BcdData,
|
|
|
|
RemainingSize);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* We failed, so mark the option as such and return an empty one */
|
2015-09-06 03:02:56 +00:00
|
|
|
Entry->BcdData.Empty = TRUE;
|
2015-09-05 19:18:54 +00:00
|
|
|
TotalOptionSize = sizeof(BL_BCD_OPTION);
|
2015-09-05 16:05:20 +00:00
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Extract the device descriptor and return it */
|
|
|
|
BcdDevice = (PVOID)((ULONG_PTR)&Entry->BcdData + Entry->BcdData.DataOffset);
|
[BOOTLIB]:
- WIP work to begin reading, parsing, mounting and loading the BCD hive into a data store. Untested, has missing pieces.
- Implement BlFileSet/GetInformation, BlFileReadEx, BlFileReadAtOffsetEx and helper structures/functions. Document multiple previously unknown/magic flags.
- Implement BlMmAllocatePhysicalPages. Stub BlMmFreePhysicalPages.
- Implement MmUnmapVirtualAddress, BlMmUnmapVirtualAddressEx when operating in real mode.
- Implement ImgpGetFileSize, ImgpReadFileAtOffset, ImgpOpenFile, ImgpCloseFile, BlImgAllocateImageBuffer, BlImgLoadImageWithProgress2.
- Implement BdDebuggerInitialized, BlBdDebuggerEnabled, BlStatusPrint, BlStatuserror. Stub BlBdPullRemoteFile.
- Implement BlGetBootOptionDevice.
- Implement BiReferenceHive, BiDereferenceHive, BiCloseKey, BiOpenKey. Stub BiFlushKey, BiLoadHive.
- Implement BiAddStoreFromFile, BcdOpenStoreFromFile.
- Stub BlUtlUpdateProcess and BlResourceFindMessage.
- Other misc. cleanups.
[BOOTMGR]:
- Implement BmpFatalErrorMessageFilter, BmErrorPurge, BmpErrorLog, BmFatalErrorEx.
- Implement BmpFwGetFullPath.
- Implement BmOpenDataStore.
- Stub BmOpenBootIni
svn path=/trunk/; revision=69447
2015-10-04 21:07:12 +00:00
|
|
|
*AppEntryDevice = &BcdDevice->DeviceDescriptor;
|
2015-09-05 16:05:20 +00:00
|
|
|
|
|
|
|
/* Calculate how big this option was and consume that from the buffer */
|
|
|
|
TotalOptionSize = BlGetBootOptionSize(&Entry->BcdData);
|
|
|
|
RemainingSize -= TotalOptionSize;
|
|
|
|
|
|
|
|
/* Calculate where the next option should go */
|
|
|
|
Option = (PVOID)((ULONG_PTR)&Entry->BcdData + TotalOptionSize);
|
|
|
|
|
|
|
|
/* Check if we're PXE booting or not */
|
|
|
|
if ((*AppEntryDevice)->DeviceType == UdpDevice)
|
|
|
|
{
|
|
|
|
/* lol */
|
|
|
|
Status = STATUS_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Convert the local file path into a BCD option */
|
|
|
|
Status = EfiInitpConvertEfiFilePath(FilePath,
|
|
|
|
BcdLibraryString_ApplicationPath,
|
|
|
|
Option,
|
|
|
|
RemainingSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Bail out on failure */
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The next option is right after this one */
|
|
|
|
Entry->BcdData.NextEntryOffset = TotalOptionSize;
|
|
|
|
|
|
|
|
/* Now compute the size of the next option, and add to the rolling sum */
|
|
|
|
Size = BlGetBootOptionSize(Option);
|
|
|
|
TotalOptionSize += Size;
|
|
|
|
|
|
|
|
/* Remember the previous option so we can update its next offset */
|
|
|
|
PreviousOption = Option;
|
|
|
|
|
|
|
|
/* Consume the option from the buffer */
|
|
|
|
RemainingSize -= Size;
|
|
|
|
|
|
|
|
/* Calculate where the next option should go */
|
|
|
|
Option = (PVOID)((ULONG_PTR)Option + Size);
|
|
|
|
|
|
|
|
/* Check if we were using binary options without a BCD GUID */
|
|
|
|
if ((HaveBinaryOptions) && !(HaveGuid))
|
|
|
|
{
|
|
|
|
/* Then this means we have to convert the OS paths to BCD too */
|
|
|
|
WindowsOptions = (PBL_WINDOWS_LOAD_OPTIONS)LoadOptions;
|
|
|
|
OsPath = (PVOID)((ULONG_PTR)WindowsOptions + WindowsOptions->OsPathOffset);
|
|
|
|
|
|
|
|
/* IS the OS path in EFI format? */
|
2015-09-05 19:18:54 +00:00
|
|
|
if ((OsPath->Length > (ULONG)FIELD_OFFSET(BL_FILE_PATH_DESCRIPTOR, Path)) &&
|
2015-09-05 16:05:20 +00:00
|
|
|
(OsPath->PathType == EfiPath))
|
|
|
|
{
|
|
|
|
/* Convert the device portion */
|
|
|
|
OsDevicePath = (EFI_DEVICE_PATH*)OsPath->Path;
|
|
|
|
Status = EfiInitpConvertEfiDevicePath(OsDevicePath,
|
|
|
|
BcdOSLoaderDevice_OSDevice,
|
|
|
|
Option,
|
|
|
|
RemainingSize);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update the offset of the previous option */
|
|
|
|
PreviousOption->NextEntryOffset = (ULONG_PTR)Option - (ULONG_PTR)&Entry->BcdData;
|
|
|
|
|
|
|
|
/* Now compute the size of the next option, and add to the rolling sum */
|
|
|
|
Size = BlGetBootOptionSize(Option);
|
|
|
|
TotalOptionSize += Size;
|
|
|
|
|
|
|
|
/* Remember the previous option so we can update its next offset */
|
|
|
|
PreviousOption = Option;
|
|
|
|
|
|
|
|
/* Consume the option from the buffer */
|
|
|
|
RemainingSize -= Size;
|
|
|
|
|
|
|
|
/* Calculate where the next option should go */
|
|
|
|
Option = (PVOID)((ULONG_PTR)Option + Size);
|
|
|
|
|
2015-10-05 01:02:56 +00:00
|
|
|
/* Convert the path option */
|
2015-09-05 16:05:20 +00:00
|
|
|
Status = EfiInitpConvertEfiFilePath(OsDevicePath,
|
|
|
|
BcdOSLoaderString_SystemRoot,
|
|
|
|
Option,
|
|
|
|
RemainingSize);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
goto Quickie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Update the offset of the previous option */
|
|
|
|
PreviousOption->NextEntryOffset = (ULONG_PTR)Option - (ULONG_PTR)&Entry->BcdData;
|
|
|
|
|
|
|
|
/* Now compute the size of the next option, and add to the rolling sum */
|
|
|
|
Size = BlGetBootOptionSize(Option);
|
|
|
|
TotalOptionSize += Size;
|
|
|
|
|
|
|
|
/* Remember the previous option so we can update its next offset */
|
|
|
|
PreviousOption = Option;
|
|
|
|
|
|
|
|
/* Consume the option from the buffer */
|
|
|
|
RemainingSize -= Size;
|
|
|
|
|
|
|
|
/* Calculate where the next option should go */
|
|
|
|
Option = (PVOID)((ULONG_PTR)Option + Size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now convert everything else */
|
|
|
|
AhCreateLoadOptionsList(CommandLine,
|
|
|
|
&Entry->BcdData,
|
|
|
|
RemainingSize,
|
|
|
|
&TotalOptionSize,
|
|
|
|
&PreviousOption,
|
|
|
|
&Size);
|
|
|
|
|
|
|
|
Quickie:
|
|
|
|
/* Return the final size */
|
|
|
|
*ResultLength = HeaderSize + TotalOptionSize;
|
|
|
|
}
|
|
|
|
|
2015-09-04 14:16:56 +00:00
|
|
|
/*++
|
|
|
|
* @name EfiInitCreateInputParametersEx
|
|
|
|
*
|
|
|
|
* The EfiInitCreateInputParametersEx routine converts UEFI entrypoint
|
|
|
|
* parameters to the ones expected by Windows Boot Applications
|
|
|
|
*
|
|
|
|
* @param ImageHandle
|
|
|
|
* UEFI Image Handle for the current loaded application.
|
|
|
|
*
|
|
|
|
* @param SystemTable
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @return A PBOOT_APPLICATION_PARAMETER_BLOCK structure containing the data
|
|
|
|
* from UEFI, translated to the Boot Library-compatible format.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
PBOOT_APPLICATION_PARAMETER_BLOCK
|
|
|
|
EfiInitCreateInputParametersEx (
|
|
|
|
_In_ EFI_HANDLE ImageHandle,
|
|
|
|
_In_ EFI_SYSTEM_TABLE *SystemTable
|
|
|
|
)
|
|
|
|
{
|
2015-09-05 16:05:20 +00:00
|
|
|
EFI_BOOT_SERVICES* BootServices;
|
|
|
|
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
|
|
|
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
|
|
|
PBL_FIRMWARE_DESCRIPTOR FirmwareData;
|
|
|
|
PBL_RETURN_ARGUMENTS ReturnArguments;
|
|
|
|
ULONG FirmwareOffset, ConsumedSize;
|
|
|
|
PBL_DEVICE_DESCRIPTOR AppDevice;
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
/* Initialize the header with the signature and version */
|
|
|
|
EfiInitScratch.Signature[0] = BOOT_APPLICATION_SIGNATURE_1;
|
|
|
|
EfiInitScratch.Signature[1] = BOOT_APPLICATION_SIGNATURE_2;
|
|
|
|
EfiInitScratch.Version = BOOT_APPLICATION_VERSION;
|
|
|
|
|
|
|
|
/* Set the image type to x86 */
|
|
|
|
EfiInitScratch.ImageType = EFI_IMAGE_MACHINE_IA32;
|
|
|
|
|
|
|
|
/* Set the translation type to physical */
|
|
|
|
EfiInitScratch.MemoryTranslationType = BOOT_MEMORY_TRANSLATION_TYPE_PHYSICAL;
|
|
|
|
|
|
|
|
/* Indicate that the data was converted from EFI */
|
|
|
|
BlpApplicationFlags |= BL_APPLICATION_FLAG_CONVERTED_FROM_EFI;
|
|
|
|
|
|
|
|
/* Grab the loaded image protocol, which has our base and size */
|
|
|
|
BootServices = SystemTable->BootServices;
|
|
|
|
Status = BootServices->HandleProtocol(ImageHandle,
|
|
|
|
&EfiLoadedImageProtocol,
|
|
|
|
(VOID**)&LoadedImage);
|
|
|
|
if (Status != EFI_SUCCESS)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Capture it in the boot application parameters */
|
|
|
|
EfiInitScratch.ImageBase = (ULONG_PTR)LoadedImage->ImageBase;
|
|
|
|
EfiInitScratch.ImageSize = (ULONG)LoadedImage->ImageSize;
|
|
|
|
|
|
|
|
/* Now grab our device path protocol, so we can convert the path later on */
|
2015-09-06 03:02:56 +00:00
|
|
|
Status = BootServices->HandleProtocol(LoadedImage->DeviceHandle,
|
2015-09-05 16:05:20 +00:00
|
|
|
&EfiDevicePathProtocol,
|
|
|
|
(VOID**)&DevicePath);
|
|
|
|
if (Status != EFI_SUCCESS)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The built-in boot memory data comes right after our block */
|
|
|
|
EfiInitScratch.MemoryDataOffset =
|
|
|
|
FIELD_OFFSET(BOOT_APPLICATION_PARAMETER_BLOCK_SCRATCH, BootMemoryData);
|
|
|
|
|
|
|
|
/* Build the boot memory data structure, with 1 descriptor */
|
|
|
|
EfiInitScratch.BootMemoryData.Version = BL_MEMORY_DATA_VERSION;
|
|
|
|
EfiInitScratch.BootMemoryData.MdListOffset =
|
|
|
|
FIELD_OFFSET(BOOT_APPLICATION_PARAMETER_BLOCK_SCRATCH, MemEntry) -
|
|
|
|
EfiInitScratch.MemoryDataOffset;
|
|
|
|
EfiInitScratch.BootMemoryData.DescriptorSize = sizeof(BL_MEMORY_DESCRIPTOR);
|
|
|
|
EfiInitScratch.BootMemoryData.DescriptorCount = 1;
|
2015-09-06 06:15:08 +00:00
|
|
|
EfiInitScratch.BootMemoryData.DescriptorOffset = FIELD_OFFSET(BL_MEMORY_DESCRIPTOR, BasePage);
|
2015-09-05 16:05:20 +00:00
|
|
|
|
|
|
|
/* Build the memory entry descriptor for this image itself */
|
2015-09-06 06:15:08 +00:00
|
|
|
EfiInitScratch.MemEntry.Flags = BlMemoryWriteBack;
|
2015-09-05 16:05:20 +00:00
|
|
|
EfiInitScratch.MemEntry.Type = BlLoaderMemory;
|
|
|
|
EfiInitScratch.MemEntry.BasePage = EfiInitScratch.ImageBase >> PAGE_SHIFT;
|
|
|
|
EfiInitScratch.MemEntry.PageCount = ALIGN_UP_BY(EfiInitScratch.ImageSize, PAGE_SIZE) >> PAGE_SHIFT;
|
|
|
|
|
|
|
|
/* The built-in application entry comes right after the memory descriptor*/
|
|
|
|
EfiInitScratch.AppEntryOffset =
|
|
|
|
FIELD_OFFSET(BOOT_APPLICATION_PARAMETER_BLOCK_SCRATCH, AppEntry);
|
|
|
|
|
|
|
|
/* Go and build it */
|
|
|
|
EfiInitpCreateApplicationEntry(SystemTable,
|
|
|
|
(PBL_APPLICATION_ENTRY)&EfiInitScratch.AppEntry,
|
|
|
|
sizeof(EfiInitScratch.AppEntry),
|
|
|
|
DevicePath,
|
|
|
|
LoadedImage->FilePath,
|
|
|
|
LoadedImage->LoadOptions,
|
|
|
|
LoadedImage->LoadOptionsSize,
|
|
|
|
EfiInitScratch.MemEntry.PageCount,
|
|
|
|
&ConsumedSize,
|
|
|
|
&AppDevice);
|
|
|
|
|
|
|
|
/* Boot device information comes right after the application entry */
|
|
|
|
EfiInitScratch.BootDeviceOffset = ConsumedSize + EfiInitScratch.AppEntryOffset;
|
|
|
|
|
|
|
|
/* Check if we have a boot device */
|
|
|
|
if (AppDevice != NULL)
|
|
|
|
{
|
|
|
|
/* We do -- copy it */
|
|
|
|
RtlCopyMemory(EfiInitScratch.AppEntry + ConsumedSize,
|
|
|
|
AppDevice,
|
|
|
|
AppDevice->Size);
|
|
|
|
|
|
|
|
/* Firmware data follows right after the boot device entry */
|
|
|
|
FirmwareOffset = AppDevice->Size + EfiInitScratch.BootDeviceOffset;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We do not, so zero out the space where a full boot device structure would fit */
|
|
|
|
RtlZeroMemory(EfiInitScratch.AppEntry + ConsumedSize,
|
|
|
|
sizeof(BL_DEVICE_DESCRIPTOR));
|
|
|
|
|
|
|
|
/* And start the firmware data past that */
|
|
|
|
FirmwareOffset = EfiInitScratch.BootDeviceOffset + sizeof(BL_DEVICE_DESCRIPTOR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set the computed firmware data offset */
|
|
|
|
EfiInitScratch.FirmwareParametersOffset = FirmwareOffset;
|
|
|
|
|
|
|
|
/* Fill out the firmware data that's there */
|
|
|
|
FirmwareData = (PVOID)((ULONG_PTR)&EfiInitScratch + EfiInitScratch.FirmwareParametersOffset);
|
|
|
|
FirmwareData->Version = BL_FIRMWARE_DESCRIPTOR_VERSION;
|
|
|
|
FirmwareData->ImageHandle = ImageHandle;
|
|
|
|
FirmwareData->SystemTable = SystemTable;
|
|
|
|
|
|
|
|
/* Finally, set the return argument offset */
|
|
|
|
EfiInitScratch.ReturnArgumentsOffset = FirmwareOffset + sizeof(BL_FIRMWARE_DESCRIPTOR);
|
|
|
|
|
|
|
|
/* And fill out the return argument data */
|
|
|
|
ReturnArguments = (PVOID)((ULONG_PTR)&EfiInitScratch + EfiInitScratch.ReturnArgumentsOffset);
|
|
|
|
ReturnArguments->Version = BL_RETURN_ARGUMENTS_VERSION;
|
2015-09-04 14:16:56 +00:00
|
|
|
|
2015-09-05 16:05:20 +00:00
|
|
|
/* We're done, compute the final size and return the block */
|
|
|
|
EfiInitScratch.Size = EfiInitScratch.ReturnArgumentsOffset + sizeof(BL_RETURN_ARGUMENTS);
|
|
|
|
return (PBOOT_APPLICATION_PARAMETER_BLOCK)&EfiInitScratch;
|
2015-09-04 14:16:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
* @name EfiEntry
|
|
|
|
*
|
|
|
|
* The EfiEntry routine implements the UEFI entrypoint for the application.
|
|
|
|
*
|
|
|
|
* @param ImageHandle
|
|
|
|
* UEFI Image Handle for the current loaded application.
|
|
|
|
*
|
|
|
|
* @param SystemTable
|
|
|
|
* Pointer to the UEFI System Table.
|
|
|
|
*
|
|
|
|
* @return EFI_SUCCESS if the image was loaded correctly, relevant error code
|
|
|
|
* otherwise.
|
|
|
|
*
|
|
|
|
*--*/
|
|
|
|
EFI_STATUS
|
2015-09-06 03:02:56 +00:00
|
|
|
EFIAPI
|
2015-09-04 14:16:56 +00:00
|
|
|
EfiEntry (
|
|
|
|
_In_ EFI_HANDLE ImageHandle,
|
|
|
|
_In_ EFI_SYSTEM_TABLE *SystemTable
|
|
|
|
)
|
|
|
|
{
|
|
|
|
NTSTATUS Status;
|
|
|
|
PBOOT_APPLICATION_PARAMETER_BLOCK BootParameters;
|
|
|
|
|
|
|
|
/* Convert EFI parameters to Windows Boot Application parameters */
|
|
|
|
BootParameters = EfiInitCreateInputParametersEx(ImageHandle, SystemTable);
|
|
|
|
if (BootParameters != NULL)
|
|
|
|
{
|
|
|
|
/* Conversion was good -- call the Boot Manager Entrypoint */
|
|
|
|
Status = BmMain(BootParameters);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Conversion failed, bail out */
|
|
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert the NT status code to an EFI code */
|
|
|
|
return EfiGetEfiStatusCode(Status);
|
|
|
|
}
|
|
|
|
|