Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
btwise
OpenCorePKG_MOD
提交
f4897c9b
O
OpenCorePKG_MOD
项目概览
btwise
/
OpenCorePKG_MOD
通知
26
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
OpenCorePKG_MOD
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
f4897c9b
编写于
4月 28, 2019
作者:
D
Download-Fritz
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
OcBootManagementLib: Determine the default boot option
上级
033ea98b
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
365 addition
and
4 deletion
+365
-4
Include/Library/OcBootManagementLib.h
Include/Library/OcBootManagementLib.h
+5
-0
Library/OcBootManagementLib/OcBootManagementLib.c
Library/OcBootManagementLib/OcBootManagementLib.c
+358
-4
Library/OcBootManagementLib/OcBootManagementLib.inf
Library/OcBootManagementLib/OcBootManagementLib.inf
+2
-0
未找到文件。
Include/Library/OcBootManagementLib.h
浏览文件 @
f4897c9b
...
...
@@ -46,6 +46,11 @@ typedef struct OC_BOOT_ENTRY_ {
// Heuristical value signalising about Windows os (otherwise macOS).
//
BOOLEAN
IsWindows
;
//
// Load option data (usually "boot args")
//
UINT32
LoadOptionsSize
;
VOID
*
LoadOptions
;
}
OC_BOOT_ENTRY
;
/**
...
...
Library/OcBootManagementLib/OcBootManagementLib.c
浏览文件 @
f4897c9b
...
...
@@ -18,6 +18,7 @@
#include <Guid/AppleApfsInfo.h>
#include <Guid/AppleBless.h>
#include <Guid/FileInfo.h>
#include <Guid/GlobalVariable.h>
#include <Protocol/AppleBootPolicy.h>
#include <Protocol/SimpleFileSystem.h>
...
...
@@ -41,6 +42,8 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/FileHandleLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Protocol/LoadedImage.h>
typedef
struct
{
EFI_DEVICE_PATH_PROTOCOL
*
DevicePath
;
...
...
@@ -504,6 +507,343 @@ OcDescribeBootEntry (
return
EFI_SUCCESS
;
}
/**
Retrieves booting relevant data from an UEFI Boot#### option.
If BootName is NULL, a BDS-style process is assumed and inactive as well as
non-Boot type applications are ignored.
@param[in] BootOption The boot option's index.
@param[out] BootName On output, the boot option's description.
@param[out] OptionalDataSize On output, the optional data size.
@param[out] OptionalData On output, a pointer to the optional data.
**/
STATIC
EFI_DEVICE_PATH_PROTOCOL
*
InternalGetBootOptionData
(
IN
UINT16
BootOption
,
OUT
CHAR16
**
BootName
OPTIONAL
,
OUT
UINT32
*
OptionalDataSize
OPTIONAL
,
OUT
VOID
**
OptionalData
OPTIONAL
)
{
EFI_STATUS
Status
;
CHAR16
BootVarName
[
L_STR_LEN
(
L"Boot####"
)
+
1
];
UINTN
LoadOptionSize
;
EFI_LOAD_OPTION
*
LoadOption
;
UINT8
*
LoadOptionPtr
;
UINT32
Attributes
;
CONST
CHAR16
*
Description
;
UINTN
DescriptionSize
;
UINT16
FilePathListSize
;
EFI_DEVICE_PATH_PROTOCOL
*
FilePathList
;
CHAR16
*
BootOptionName
;
VOID
*
OptionalDataBuffer
;
UnicodeSPrint
(
BootVarName
,
sizeof
(
BootVarName
),
L"Boot%04x"
,
BootOption
);
Status
=
GetEfiGlobalVariable2
(
BootVarName
,
(
VOID
**
)
&
LoadOption
,
&
LoadOptionSize
);
if
(
EFI_ERROR
(
Status
)
||
(
LoadOptionSize
<
sizeof
(
*
LoadOption
)))
{
return
NULL
;
}
Attributes
=
LoadOption
->
Attributes
;
if
((
BootName
==
NULL
)
&&
(((
Attributes
&
LOAD_OPTION_ACTIVE
)
==
0
)
||
((
Attributes
&
LOAD_OPTION_CATEGORY
)
!=
LOAD_OPTION_CATEGORY_BOOT
)))
{
FreePool
(
LoadOption
);
return
NULL
;
}
FilePathListSize
=
LoadOption
->
FilePathListLength
;
LoadOptionPtr
=
(
UINT8
*
)(
LoadOption
+
1
);
LoadOptionSize
-=
sizeof
(
*
LoadOption
);
if
(
FilePathListSize
>
LoadOptionSize
)
{
FreePool
(
LoadOption
);
return
NULL
;
}
LoadOptionSize
-=
FilePathListSize
;
Description
=
(
CHAR16
*
)
LoadOptionPtr
;
DescriptionSize
=
StrnSizeS
(
Description
,
(
LoadOptionSize
/
sizeof
(
CHAR16
)));
if
(
DescriptionSize
>
LoadOptionSize
)
{
FreePool
(
LoadOption
);
return
NULL
;
}
LoadOptionPtr
+=
DescriptionSize
;
LoadOptionSize
-=
DescriptionSize
;
FilePathList
=
(
EFI_DEVICE_PATH_PROTOCOL
*
)
LoadOptionPtr
;
if
(
!
IsDevicePathValid
(
FilePathList
,
FilePathListSize
))
{
FreePool
(
LoadOption
);
return
NULL
;
}
LoadOptionPtr
+=
FilePathListSize
;
BootOptionName
=
NULL
;
if
(
BootName
!=
NULL
)
{
BootOptionName
=
AllocateCopyPool
(
DescriptionSize
,
Description
);
}
OptionalDataBuffer
=
NULL
;
if
(
OptionalDataSize
!=
NULL
)
{
ASSERT
(
OptionalData
!=
NULL
);
if
(
LoadOptionSize
>
0
)
{
OptionalDataBuffer
=
AllocateCopyPool
(
LoadOptionSize
,
LoadOptionPtr
);
if
(
OptionalDataBuffer
==
NULL
)
{
LoadOptionSize
=
0
;
}
}
*
OptionalDataSize
=
(
UINT32
)
LoadOptionSize
;
}
//
// Use the allocated Load Option buffer for the Device Path.
//
CopyMem
(
LoadOption
,
FilePathList
,
FilePathListSize
);
FilePathList
=
(
EFI_DEVICE_PATH_PROTOCOL
*
)
LoadOption
;
if
(
BootName
!=
NULL
)
{
*
BootName
=
BootOptionName
;
}
if
(
OptionalData
!=
NULL
)
{
*
OptionalData
=
OptionalDataBuffer
;
}
return
FilePathList
;
}
OC_BOOT_ENTRY
*
InternalGetDefaultBootEntry
(
IN
OUT
OC_BOOT_ENTRY
*
BootEntries
,
IN
UINTN
NumBootEntries
,
IN
EFI_HANDLE
LoadHandle
OPTIONAL
)
{
EFI_STATUS
Status
;
INTN
CmpResult
;
UINT32
BootNextAttributes
;
UINTN
BootNextSize
;
BOOLEAN
IsBootNext
;
UINT16
*
BootOrder
;
UINTN
BootOrderSize
;
UINTN
RootDevicePathSize
;
EFI_DEVICE_PATH_PROTOCOL
*
UefiDevicePath
;
EFI_DEVICE_PATH_PROTOCOL
*
UefiRemainingDevicePath
;
EFI_DEVICE_PATH_PROTOCOL
*
OcDevicePath
;
EFI_DEVICE_PATH_PROTOCOL
*
OcRemainingDevicePath
;
UINT32
OptionalDataSize
;
VOID
*
OptionalData
;
CHAR16
*
DefaultDevicePathText
;
EFI_DEVICE_PATH_PROTOCOL
*
DevicePath
;
EFI_HANDLE
DeviceHandle
;
UINT16
BootNextOptionIndex
;
OC_BOOT_ENTRY
*
BootEntry
;
UINTN
Index
;
ASSERT
(
BootEntries
!=
NULL
);
ASSERT
(
NumBootEntries
>
0
);
IsBootNext
=
FALSE
;
OptionalData
=
NULL
;
BootNextSize
=
sizeof
(
BootNextOptionIndex
);
Status
=
gRT
->
GetVariable
(
EFI_BOOT_NEXT_VARIABLE_NAME
,
&
gEfiGlobalVariableGuid
,
&
BootNextAttributes
,
&
BootNextSize
,
&
BootNextOptionIndex
);
if
(
Status
==
EFI_NOT_FOUND
)
{
Status
=
GetEfiGlobalVariable2
(
EFI_BOOT_ORDER_VARIABLE_NAME
,
(
VOID
**
)
&
BootOrder
,
&
BootOrderSize
);
if
(
EFI_ERROR
(
Status
))
{
return
NULL
;
}
if
(
BootOrderSize
<
sizeof
(
*
BootOrder
))
{
FreePool
(
BootOrder
);
return
NULL
;
}
UefiDevicePath
=
InternalGetBootOptionData
(
BootOrder
[
0
],
NULL
,
NULL
,
NULL
);
if
(
UefiDevicePath
==
NULL
)
{
FreePool
(
BootOrder
);
return
NULL
;
}
DevicePath
=
UefiDevicePath
;
Status
=
gBS
->
LocateDevicePath
(
&
gEfiSimpleFileSystemProtocolGuid
,
&
DevicePath
,
&
DeviceHandle
);
if
(
!
EFI_ERROR
(
Status
)
&&
(
DeviceHandle
==
LoadHandle
))
{
//
// Skip BOOTx64.EFI at BootOrder[0].
//
FreePool
(
UefiDevicePath
);
if
(
BootOrderSize
<
(
2
*
sizeof
(
*
BootOrder
)))
{
FreePool
(
BootOrder
);
return
NULL
;
}
UefiDevicePath
=
InternalGetBootOptionData
(
BootOrder
[
1
],
NULL
,
NULL
,
NULL
);
if
(
UefiDevicePath
==
NULL
)
{
FreePool
(
BootOrder
);
return
NULL
;
}
}
FreePool
(
BootOrder
);
}
else
if
(
!
EFI_ERROR
(
Status
))
{
//
// BootNext must be deleted before attempting to start the image - delete
// it here because not attempting to boot the image implies user's choice.
//
gRT
->
SetVariable
(
EFI_BOOT_NEXT_VARIABLE_NAME
,
&
gEfiGlobalVariableGuid
,
BootNextAttributes
,
0
,
NULL
);
IsBootNext
=
TRUE
;
UefiDevicePath
=
InternalGetBootOptionData
(
BootNextOptionIndex
,
NULL
,
&
OptionalDataSize
,
&
OptionalData
);
if
(
UefiDevicePath
==
NULL
)
{
return
NULL
;
}
}
else
{
return
NULL
;
}
OcFixAppleBootDevicePath
(
UefiDevicePath
);
DEBUG_CODE
(
DefaultDevicePathText
=
ConvertDevicePathToText
(
UefiDevicePath
,
FALSE
,
FALSE
);
if
(
DefaultDevicePathText
!=
NULL
)
{
DEBUG
((
DEBUG_INFO
,
"Default boot Device Path: %s
\n
"
,
DefaultDevicePathText
));
FreePool
(
DefaultDevicePathText
);
}
);
UefiRemainingDevicePath
=
UefiDevicePath
;
Status
=
gBS
->
LocateDevicePath
(
&
gEfiSimpleFileSystemProtocolGuid
,
&
UefiRemainingDevicePath
,
&
DeviceHandle
);
if
(
EFI_ERROR
(
Status
))
{
return
NULL
;
}
RootDevicePathSize
=
((
UINT8
*
)
UefiRemainingDevicePath
-
(
UINT8
*
)
UefiDevicePath
);
for
(
Index
=
0
;
Index
<
NumBootEntries
;
++
Index
)
{
BootEntry
=
&
BootEntries
[
Index
];
OcDevicePath
=
BootEntry
->
DevicePath
;
if
((
GetDevicePathSize
(
OcDevicePath
)
-
END_DEVICE_PATH_LENGTH
)
<
RootDevicePathSize
)
{
continue
;
}
CmpResult
=
CompareMem
(
OcDevicePath
,
UefiDevicePath
,
RootDevicePathSize
);
if
(
CmpResult
!=
0
)
{
continue
;
}
OcRemainingDevicePath
=
(
EFI_DEVICE_PATH_PROTOCOL
*
)(
(
UINT8
*
)
OcDevicePath
+
RootDevicePathSize
);
if
(
!
IsBootNext
)
{
//
// For non-BootNext boot, the File Paths must match for the entries to be
// matched. Startup Disk however only stores the drive's Device Path
// excluding the booter path, which we treat as a match as well.
//
if
(
!
IsDevicePathEnd
(
UefiRemainingDevicePath
)
&&
!
IsDevicePathEqual
(
UefiRemainingDevicePath
,
OcRemainingDevicePath
)
)
{
continue
;
}
FreePool
(
UefiDevicePath
);
}
else
{
//
// BootNext is allowed to override both the exact file path as well as
// the used load options.
//
BootEntry
->
LoadOptionsSize
=
OptionalDataSize
;
BootEntry
->
LoadOptions
=
OptionalData
;
//
// Only use the BootNext path when it has a file path.
//
if
(
!
IsDevicePathEnd
(
UefiRemainingDevicePath
))
{
FreePool
(
BootEntry
->
DevicePath
);
BootEntry
->
DevicePath
=
UefiDevicePath
;
}
else
{
FreePool
(
UefiDevicePath
);
}
}
DEBUG
((
DEBUG_INFO
,
"Matched default boot option: %s
\n
"
,
BootEntry
->
Name
));
return
BootEntry
;
}
if
(
OptionalData
!=
NULL
)
{
FreePool
(
OptionalData
);
}
FreePool
(
UefiDevicePath
);
DEBUG
((
DEBUG_INFO
,
"Failed to match a default boot option
\n
"
));
return
NULL
;
}
VOID
OcResetBootEntry
(
IN
OUT
OC_BOOT_ENTRY
*
BootEntry
...
...
@@ -1235,8 +1575,10 @@ InternalLoadBootEntry (
)
{
EFI_STATUS
Status
;
EFI_STATUS
OptionalStatus
;
EFI_DEVICE_PATH_PROTOCOL
*
DevicePath
;
CHAR16
*
UnicodeDevicePath
;
EFI_LOADED_IMAGE_PROTOCOL
*
LoadedImage
;
//
// TODO: support Apple loaded image, policy, and dmg boot.
...
...
@@ -1278,7 +1620,17 @@ InternalLoadBootEntry (
Status
=
gBS
->
LoadImage
(
FALSE
,
ParentHandle
,
DevicePath
,
NULL
,
0
,
EntryHandle
);
if
(
EFI_ERROR
(
Status
))
{
if
(
!
EFI_ERROR
(
Status
))
{
OptionalStatus
=
gBS
->
HandleProtocol
(
ParentHandle
,
&
gEfiLoadedImageProtocolGuid
,
(
VOID
**
)
&
LoadedImage
);
if
(
!
EFI_ERROR
(
OptionalStatus
))
{
LoadedImage
->
LoadOptionsSize
=
BootEntry
->
LoadOptionsSize
;
LoadedImage
->
LoadOptions
=
BootEntry
->
LoadOptions
;
}
}
else
{
InternalUnloadDmg
(
DmgLoadContext
);
}
...
...
@@ -1323,6 +1675,7 @@ OcRunSimpleBootPicker (
APPLE_BOOT_POLICY_PROTOCOL
*
AppleBootPolicy
;
OC_BOOT_ENTRY
*
Chosen
;
OC_BOOT_ENTRY
*
Entries
;
OC_BOOT_ENTRY
*
Entry
;
UINTN
EntryCount
;
EFI_HANDLE
BooterHandle
;
UINT32
DefaultEntry
;
...
...
@@ -1354,10 +1707,11 @@ OcRunSimpleBootPicker (
DEBUG
((
DEBUG_INFO
,
"Performing OcShowSimpleBootMenu...
\n
"
));
//
// TODO: obtain default entry!
//
DefaultEntry
=
0
;
Entry
=
InternalGetDefaultBootEntry
(
Entries
,
EntryCount
,
LoadHandle
);
if
(
Entry
!=
NULL
)
{
DefaultEntry
=
(
UINT32
)(
Entry
-
Entries
);
}
if
(
ShowPicker
)
{
Status
=
OcShowSimpleBootMenu
(
...
...
Library/OcBootManagementLib/OcBootManagementLib.inf
浏览文件 @
f4897c9b
...
...
@@ -45,10 +45,12 @@
gAppleBlessedSystemFolderInfoGuid ## SOMETIMES_CONSUMES
gAppleBlessedOsxFolderInfoGuid ## SOMETIMES_CONSUMES
gEfiFileInfoGuid ## SOMETIMES_CONSUMES
gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES
[Protocols]
gAppleBootPolicyProtocolGuid ## PRODUCES
gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES
[LibraryClasses]
BaseLib
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录