mirror of https://github.com/acidanthera/audk.git
ArmPkg/BdsLib: Replaced BdsLoadApplication() by LocateEfiApplicationInFv()
Replaced the function BdsLoadApplication() by two explicit functions that load the EFI application either by its GUID or its Name. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <Olivier.Martin@arm.com> Reviewed-by: Ronald Cron <Ronald.Cron@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17966 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
4fc18df913
commit
0c72676d37
|
@ -193,24 +193,6 @@ BdsStartEfiApplication (
|
||||||
IN VOID* LoadOptions
|
IN VOID* LoadOptions
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
Start an EFI Application from any Firmware Volume
|
|
||||||
|
|
||||||
@param EfiApp EFI Application Name
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS All drivers have been connected
|
|
||||||
@retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
|
|
||||||
@retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
BdsLoadApplication (
|
|
||||||
IN EFI_HANDLE ParentImageHandle,
|
|
||||||
IN CHAR16* EfiApp,
|
|
||||||
IN UINTN LoadOptionsSize,
|
|
||||||
IN VOID* LoadOptions
|
|
||||||
);
|
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BdsLoadImage (
|
BdsLoadImage (
|
||||||
IN EFI_DEVICE_PATH *DevicePath,
|
IN EFI_DEVICE_PATH *DevicePath,
|
||||||
|
@ -227,4 +209,38 @@ ShutdownUefiBootServices (
|
||||||
VOID
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Locate an EFI application in a the Firmware Volumes by its name
|
||||||
|
|
||||||
|
@param EfiAppGuid Guid of the EFI Application into the Firmware Volume
|
||||||
|
@param DevicePath EFI Device Path of the EFI application
|
||||||
|
|
||||||
|
@return EFI_SUCCESS The function completed successfully.
|
||||||
|
@return EFI_NOT_FOUND The protocol could not be located.
|
||||||
|
@return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
LocateEfiApplicationInFvByName (
|
||||||
|
IN CONST CHAR16* EfiAppName,
|
||||||
|
OUT EFI_DEVICE_PATH **DevicePath
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Locate an EFI application in a the Firmware Volumes by its GUID
|
||||||
|
|
||||||
|
@param EfiAppGuid Guid of the EFI Application into the Firmware Volume
|
||||||
|
@param DevicePath EFI Device Path of the EFI application
|
||||||
|
|
||||||
|
@return EFI_SUCCESS The function completed successfully.
|
||||||
|
@return EFI_NOT_FOUND The protocol could not be located.
|
||||||
|
@return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
LocateEfiApplicationInFvByGuid (
|
||||||
|
IN CONST EFI_GUID *EfiAppGuid,
|
||||||
|
OUT EFI_DEVICE_PATH **DevicePath
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/** @file
|
/** @file
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
|
* Copyright (c) 2011-2015, ARM Limited. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program and the accompanying materials
|
* This program and the accompanying materials
|
||||||
* are licensed and made available under the terms and conditions of the BSD License
|
* are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -14,18 +14,23 @@
|
||||||
|
|
||||||
#include "BdsInternal.h"
|
#include "BdsInternal.h"
|
||||||
|
|
||||||
//#include <Library/DxeServicesLib.h>
|
/**
|
||||||
|
Locate an EFI application in a the Firmware Volumes by its Name
|
||||||
|
|
||||||
STATIC
|
@param EfiAppGuid Guid of the EFI Application into the Firmware Volume
|
||||||
|
@param DevicePath EFI Device Path of the EFI application
|
||||||
|
|
||||||
|
@return EFI_SUCCESS The function completed successfully.
|
||||||
|
@return EFI_NOT_FOUND The protocol could not be located.
|
||||||
|
@return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
|
||||||
|
|
||||||
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
BdsLoadFileFromFirmwareVolume (
|
LocateEfiApplicationInFvByName (
|
||||||
IN EFI_HANDLE FvHandle,
|
IN CONST CHAR16* EfiAppName,
|
||||||
IN CHAR16 *FilePath,
|
OUT EFI_DEVICE_PATH **DevicePath
|
||||||
IN EFI_FV_FILETYPE FileTypeFilter,
|
|
||||||
OUT EFI_DEVICE_PATH **EfiAppDevicePath
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
|
|
||||||
VOID *Key;
|
VOID *Key;
|
||||||
EFI_STATUS Status, FileStatus;
|
EFI_STATUS Status, FileStatus;
|
||||||
EFI_GUID NameGuid;
|
EFI_GUID NameGuid;
|
||||||
|
@ -37,108 +42,212 @@ BdsLoadFileFromFirmwareVolume (
|
||||||
UINT32 Authentication;
|
UINT32 Authentication;
|
||||||
EFI_DEVICE_PATH *FvDevicePath;
|
EFI_DEVICE_PATH *FvDevicePath;
|
||||||
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileDevicePath;
|
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileDevicePath;
|
||||||
|
EFI_HANDLE *HandleBuffer;
|
||||||
|
UINTN NumberOfHandles;
|
||||||
|
UINTN Index;
|
||||||
|
EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
|
||||||
|
|
||||||
Status = gBS->HandleProtocol (FvHandle,&gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FvProtocol);
|
ASSERT (DevicePath != NULL);
|
||||||
if (EFI_ERROR(Status)) {
|
|
||||||
|
// Length of FilePath
|
||||||
|
UiStringLen = StrLen (EfiAppName);
|
||||||
|
|
||||||
|
// Locate all the Firmware Volume protocols.
|
||||||
|
Status = gBS->LocateHandleBuffer (
|
||||||
|
ByProtocol,
|
||||||
|
&gEfiFirmwareVolume2ProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
&NumberOfHandles,
|
||||||
|
&HandleBuffer
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Length of FilePath
|
*DevicePath = NULL;
|
||||||
UiStringLen = StrLen (FilePath);
|
|
||||||
|
|
||||||
// Allocate Key
|
// Looking for FV with ACPI storage file
|
||||||
Key = AllocatePool (FvProtocol->KeySize);
|
for (Index = 0; Index < NumberOfHandles; Index++) {
|
||||||
ASSERT (Key != NULL);
|
//
|
||||||
ZeroMem (Key, FvProtocol->KeySize);
|
// Get the protocol on this handle
|
||||||
|
// This should not fail because of LocateHandleBuffer
|
||||||
|
//
|
||||||
|
Status = gBS->HandleProtocol (
|
||||||
|
HandleBuffer[Index],
|
||||||
|
&gEfiFirmwareVolume2ProtocolGuid,
|
||||||
|
(VOID**) &FvInstance
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto FREE_HANDLE_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
// Allocate Key
|
||||||
// Search in all files
|
Key = AllocatePool (FvInstance->KeySize);
|
||||||
FileType = FileTypeFilter;
|
ASSERT (Key != NULL);
|
||||||
|
ZeroMem (Key, FvInstance->KeySize);
|
||||||
|
|
||||||
Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size);
|
do {
|
||||||
if (!EFI_ERROR (Status)) {
|
// Search in all files
|
||||||
|
FileType = EFI_FV_FILETYPE_ALL;
|
||||||
|
|
||||||
|
Status = FvInstance->GetNextFile (FvInstance, Key, &FileType, &NameGuid, &Attributes, &Size);
|
||||||
|
if (!EFI_ERROR (Status)) {
|
||||||
|
UiSection = NULL;
|
||||||
|
FileStatus = FvInstance->ReadSection (
|
||||||
|
FvInstance,
|
||||||
|
&NameGuid,
|
||||||
|
EFI_SECTION_USER_INTERFACE,
|
||||||
|
0,
|
||||||
|
(VOID **)&UiSection,
|
||||||
|
&Size,
|
||||||
|
&Authentication
|
||||||
|
);
|
||||||
|
if (!EFI_ERROR (FileStatus)) {
|
||||||
|
if (StrnCmp (EfiAppName, UiSection, UiStringLen) == 0) {
|
||||||
|
//
|
||||||
|
// We found a UiString match.
|
||||||
|
//
|
||||||
|
Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
|
||||||
|
|
||||||
|
// Generate the Device Path for the file
|
||||||
|
EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);
|
||||||
|
*DevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);
|
||||||
|
ASSERT (*DevicePath != NULL);
|
||||||
|
|
||||||
|
FreePool (Key);
|
||||||
|
FreePool (UiSection);
|
||||||
|
FreePool (HandleBuffer);
|
||||||
|
return FileStatus;
|
||||||
|
}
|
||||||
|
FreePool (UiSection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (!EFI_ERROR (Status));
|
||||||
|
|
||||||
|
FreePool (Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE_HANDLE_BUFFER:
|
||||||
|
FreePool (HandleBuffer);
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Locate an EFI application in a the Firmware Volumes by its GUID
|
||||||
|
|
||||||
|
@param EfiAppGuid Guid of the EFI Application into the Firmware Volume
|
||||||
|
@param DevicePath EFI Device Path of the EFI application
|
||||||
|
|
||||||
|
@return EFI_SUCCESS The function completed successfully.
|
||||||
|
@return EFI_NOT_FOUND The protocol could not be located.
|
||||||
|
@return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
|
||||||
|
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
LocateEfiApplicationInFvByGuid (
|
||||||
|
IN CONST EFI_GUID *EfiAppGuid,
|
||||||
|
OUT EFI_DEVICE_PATH **DevicePath
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
EFI_DEVICE_PATH *FvDevicePath;
|
||||||
|
EFI_HANDLE *HandleBuffer;
|
||||||
|
UINTN NumberOfHandles;
|
||||||
|
UINTN Index;
|
||||||
|
EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
|
||||||
|
EFI_FV_FILE_ATTRIBUTES Attributes;
|
||||||
|
UINT32 AuthenticationStatus;
|
||||||
|
EFI_FV_FILETYPE Type;
|
||||||
|
UINTN Size;
|
||||||
|
CHAR16 *UiSection;
|
||||||
|
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileDevicePath;
|
||||||
|
|
||||||
|
ASSERT (DevicePath != NULL);
|
||||||
|
|
||||||
|
// Locate all the Firmware Volume protocols.
|
||||||
|
Status = gBS->LocateHandleBuffer (
|
||||||
|
ByProtocol,
|
||||||
|
&gEfiFirmwareVolume2ProtocolGuid,
|
||||||
|
NULL,
|
||||||
|
&NumberOfHandles,
|
||||||
|
&HandleBuffer
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
*DevicePath = NULL;
|
||||||
|
|
||||||
|
// Looking for FV with ACPI storage file
|
||||||
|
for (Index = 0; Index < NumberOfHandles; Index++) {
|
||||||
|
//
|
||||||
|
// Get the protocol on this handle
|
||||||
|
// This should not fail because of LocateHandleBuffer
|
||||||
|
//
|
||||||
|
Status = gBS->HandleProtocol (
|
||||||
|
HandleBuffer[Index],
|
||||||
|
&gEfiFirmwareVolume2ProtocolGuid,
|
||||||
|
(VOID**) &FvInstance
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
goto FREE_HANDLE_BUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = FvInstance->ReadFile (
|
||||||
|
FvInstance,
|
||||||
|
EfiAppGuid,
|
||||||
|
NULL,
|
||||||
|
&Size,
|
||||||
|
&Type,
|
||||||
|
&Attributes,
|
||||||
|
&AuthenticationStatus
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// Skip if no EFI application file in the FV
|
||||||
|
//
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
UiSection = NULL;
|
UiSection = NULL;
|
||||||
FileStatus = FvProtocol->ReadSection (
|
Status = FvInstance->ReadSection (
|
||||||
FvProtocol,
|
FvInstance,
|
||||||
&NameGuid,
|
EfiAppGuid,
|
||||||
EFI_SECTION_USER_INTERFACE,
|
EFI_SECTION_USER_INTERFACE,
|
||||||
0,
|
0,
|
||||||
(VOID **)&UiSection,
|
(VOID **)&UiSection,
|
||||||
&Size,
|
&Size,
|
||||||
&Authentication
|
&AuthenticationStatus
|
||||||
);
|
);
|
||||||
if (!EFI_ERROR (FileStatus)) {
|
if (!EFI_ERROR (Status)) {
|
||||||
if (StrnCmp (FilePath, UiSection, UiStringLen) == 0) {
|
//
|
||||||
//
|
// Create the EFI Device Path for the application using the Filename of the application
|
||||||
// We found a UiString match.
|
//
|
||||||
//
|
*DevicePath = FileDevicePath (HandleBuffer[Index], UiSection);
|
||||||
Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
|
} else {
|
||||||
|
Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID**)&FvDevicePath);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
|
||||||
// Generate the Device Path for the file
|
//
|
||||||
//DevicePath = DuplicateDevicePath(FvDevicePath);
|
// Create the EFI Device Path for the application using the EFI GUID of the application
|
||||||
EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);
|
//
|
||||||
*EfiAppDevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);
|
EfiInitializeFwVolDevicepathNode (&FvFileDevicePath, EfiAppGuid);
|
||||||
|
|
||||||
FreePool (Key);
|
*DevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FvFileDevicePath);
|
||||||
FreePool (UiSection);
|
ASSERT (*DevicePath != NULL);
|
||||||
return FileStatus;
|
|
||||||
}
|
|
||||||
FreePool (UiSection);
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
} while (!EFI_ERROR (Status));
|
|
||||||
|
|
||||||
FreePool(Key);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Start an EFI Application from any Firmware Volume
|
|
||||||
|
|
||||||
@param EfiApp EFI Application Name
|
|
||||||
|
|
||||||
@retval EFI_SUCCESS All drivers have been connected
|
|
||||||
@retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
|
|
||||||
@retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
|
|
||||||
|
|
||||||
**/
|
|
||||||
EFI_STATUS
|
|
||||||
BdsLoadApplication (
|
|
||||||
IN EFI_HANDLE ParentImageHandle,
|
|
||||||
IN CHAR16* EfiApp,
|
|
||||||
IN UINTN LoadOptionsSize,
|
|
||||||
IN VOID* LoadOptions
|
|
||||||
)
|
|
||||||
{
|
|
||||||
EFI_STATUS Status;
|
|
||||||
UINTN NoHandles, HandleIndex;
|
|
||||||
EFI_HANDLE *Handles;
|
|
||||||
EFI_DEVICE_PATH *EfiAppDevicePath;
|
|
||||||
|
|
||||||
// Need to connect every drivers to ensure no dependencies are missing for the application
|
|
||||||
Status = BdsConnectAllDrivers();
|
|
||||||
if (EFI_ERROR(Status)) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search the application in any Firmware Volume
|
|
||||||
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles);
|
|
||||||
if (EFI_ERROR (Status) || (NoHandles == 0)) {
|
|
||||||
DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n"));
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search in all Firmware Volume for the EFI Application
|
|
||||||
for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {
|
|
||||||
EfiAppDevicePath = NULL;
|
|
||||||
Status = BdsLoadFileFromFirmwareVolume (Handles[HandleIndex], EfiApp, EFI_FV_FILETYPE_APPLICATION, &EfiAppDevicePath);
|
|
||||||
if (!EFI_ERROR (Status)) {
|
|
||||||
// Start the application
|
|
||||||
Status = BdsStartEfiApplication (ParentImageHandle, EfiAppDevicePath, LoadOptionsSize, LoadOptions);
|
|
||||||
return Status;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
FREE_HANDLE_BUFFER:
|
||||||
|
//
|
||||||
|
// Free any allocated buffers
|
||||||
|
//
|
||||||
|
FreePool (HandleBuffer);
|
||||||
|
|
||||||
|
if (*DevicePath == NULL) {
|
||||||
|
return EFI_NOT_FOUND;
|
||||||
|
} else {
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
ArmPkg/ArmPkg.dec
|
ArmPkg/ArmPkg.dec
|
||||||
ArmPlatformPkg/ArmPlatformPkg.dec
|
ArmPlatformPkg/ArmPlatformPkg.dec
|
||||||
EmbeddedPkg/EmbeddedPkg.dec
|
EmbeddedPkg/EmbeddedPkg.dec
|
||||||
|
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
BdsLib
|
BdsLib
|
||||||
|
@ -79,5 +80,7 @@
|
||||||
gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths
|
gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths
|
||||||
gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths
|
gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths
|
||||||
|
|
||||||
|
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
TRUE
|
TRUE
|
||||||
|
|
|
@ -1069,17 +1069,27 @@ BootShell (
|
||||||
IN LIST_ENTRY *BootOptionsList
|
IN LIST_ENTRY *BootOptionsList
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
EFI_DEVICE_PATH* EfiShellDevicePath;
|
||||||
|
|
||||||
// Start EFI Shell
|
// Find the EFI Shell
|
||||||
Status = BdsLoadApplication (gImageHandle, L"Shell", 0, NULL);
|
Status = LocateEfiApplicationInFvByName (L"Shell", &EfiShellDevicePath);
|
||||||
if (Status == EFI_NOT_FOUND) {
|
if (Status == EFI_NOT_FOUND) {
|
||||||
Print (L"Error: EFI Application not found.\n");
|
Print (L"Error: EFI Application not found.\n");
|
||||||
} else if (EFI_ERROR(Status)) {
|
return Status;
|
||||||
Print (L"Error: Status Code: 0x%X\n",(UINT32)Status);
|
} else if (EFI_ERROR (Status)) {
|
||||||
}
|
Print (L"Error: Status Code: 0x%X\n", (UINT32)Status);
|
||||||
|
return Status;
|
||||||
|
} else {
|
||||||
|
// Need to connect every drivers to ensure no dependencies are missing for the application
|
||||||
|
Status = BdsConnectAllDrivers ();
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
return Status;
|
return BdsStartEfiApplication (gImageHandle, EfiShellDevicePath, 0, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BOOT_MAIN_ENTRY {
|
struct BOOT_MAIN_ENTRY {
|
||||||
|
|
Loading…
Reference in New Issue