Process Capsule On Disk.\r
\r
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
-#include <Uefi.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/FileHandleLib.h>\r
-#include <Library/UefiBootManagerLib.h>\r
-#include <Protocol/SimpleFileSystem.h>\r
-#include <Protocol/Shell.h>\r
-#include <Guid/FileInfo.h>\r
-#include <Guid/GlobalVariable.h>\r
-#include <Guid/Gpt.h>\r
-\r
-EFI_GUID mCapsuleOnDiskBootOptionGuid = { 0x4CC29BB7, 0x2413, 0x40A2, { 0xB0, 0x6D, 0x25, 0x3E, 0x37, 0x10, 0xF5, 0x32 } };\r
\r
-/**\r
- Get shell protocol.\r
+#include "CapsuleApp.h"\r
\r
- @return Pointer to shell protocol.\r
-\r
-**/\r
-EFI_SHELL_PROTOCOL *\r
-GetShellProtocol (\r
- VOID\r
- );\r
+EFI_GUID mCapsuleOnDiskBootOptionGuid = { 0x4CC29BB7, 0x2413, 0x40A2, { 0xB0, 0x6D, 0x25, 0x3E, 0x37, 0x10, 0xF5, 0x32 } };\r
\r
/**\r
Get file name from file path.\r
UINTN NumberEfiSystemPartitions;\r
EFI_SHELL_PROTOCOL *ShellProtocol;\r
\r
- ShellProtocol = GetShellProtocol ();\r
NumberEfiSystemPartitions = 0;\r
\r
+ ShellProtocol = GetShellProtocol ();\r
+ if (ShellProtocol == NULL) {\r
+ Print (L"Get Shell Protocol Fail\n");;\r
+ return ;\r
+ }\r
+\r
Print (L"EFI System Partition list:\n");\r
\r
gBS->LocateHandleBuffer (\r
\r
**/\r
EFI_STATUS\r
-EFIAPI\r
GetEfiSysPartitionFromBootOptionFilePath (\r
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,\r
//\r
do {\r
PreFullPath = CurFullPath;\r
- CurFullPath = EfiBootManagerGetNextFullDevicePath (DevicePath, CurFullPath);\r
+ CurFullPath = EfiBootManagerGetNextLoadOptionDevicePath (DevicePath, CurFullPath);\r
\r
if (PreFullPath != NULL) {\r
FreePool (PreFullPath);\r
break;\r
}\r
\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
CHAR16 *DevicePathStr;\r
\r
DevicePathStr = ConvertDevicePathToText (CurFullPath, TRUE, TRUE);\r
DEBUG ((DEBUG_INFO, "Full device path %s\n", DevicePathStr));\r
FreePool (DevicePathStr);\r
}\r
- );\r
+ DEBUG_CODE_END ();\r
\r
Status = GetEfiSysPartitionFromDevPath (CurFullPath, &FsFullPath, Fs);\r
} while (EFI_ERROR (Status));\r
\r
**/\r
EFI_STATUS\r
-EFIAPI\r
GetUpdateFileSystem (\r
IN CHAR16 *Map,\r
OUT UINT16 *BootNext,\r
EFI_BOOT_MANAGER_LOAD_OPTION NewOption;\r
\r
MappedDevicePath = NULL;\r
+ BootOptionBuffer = NULL;\r
+\r
ShellProtocol = GetShellProtocol ();\r
+ if (ShellProtocol == NULL) {\r
+ Print (L"Get Shell Protocol Fail\n");;\r
+ return EFI_NOT_FOUND;\r
+ }\r
\r
//\r
// 1. If Fs is not assigned and there are capsule provisioned before,\r
(VOID **)&BootNextData,\r
NULL\r
);\r
- if (!EFI_ERROR (Status)) {\r
+ if (EFI_ERROR (Status) || BootNextData == NULL) {\r
+ Print (L"Get Boot Next Data Fail. Status = %r\n", Status);\r
+ return EFI_NOT_FOUND;\r
+ } else {\r
UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04x", *BootNextData);\r
Status = EfiBootManagerVariableToLoadOption (BootOptionName, &BootNextOption);\r
if (!EFI_ERROR (Status)) {\r
// 2. Get EFI system partition form boot options.\r
//\r
BootOptionBuffer = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
- if (BootOptionCount == 0 && Map == NULL) {\r
+ if ( (BootOptionBuffer == NULL) ||\r
+ (BootOptionCount == 0 && Map == NULL)\r
+ ) {\r
return EFI_NOT_FOUND;\r
}\r
\r
continue;\r
}\r
\r
- DEBUG_CODE (\r
+ DEBUG_CODE_BEGIN ();\r
CHAR16 *DevicePathStr;\r
\r
DevicePathStr = ConvertDevicePathToText (DevicePath, TRUE, TRUE);\r
} else {\r
DEBUG ((DEBUG_INFO, "DevicePathToStr failed\n"));\r
}\r
- );\r
+ DEBUG_CODE_END ();\r
\r
Status = GetEfiSysPartitionFromBootOptionFilePath (DevicePath, &FullPath, Fs);\r
if (!EFI_ERROR (Status)) {\r
DevicePath = DuplicateDevicePath (MappedDevicePath);\r
Status = GetEfiSysPartitionFromDevPath (DevicePath, &FullPath, Fs);\r
if (EFI_ERROR (Status)) {\r
- Print (L"Error: Cannot get EFI system partiion from '%s' - %r\n", Map, Status);\r
+ Print (L"Error: Cannot get EFI system partition from '%s' - %r\n", Map, Status);\r
return EFI_NOT_FOUND;\r
}\r
Print (L"Warning: Cannot find Boot Option on '%s'!\n", Map);\r
return Status;\r
}\r
\r
+/**\r
+ Check if Capsule On Disk is supported.\r
+\r
+ @retval TRUE Capsule On Disk is supported.\r
+ @retval FALSE Capsule On Disk is not supported.\r
+\r
+**/\r
+BOOLEAN\r
+IsCapsuleOnDiskSupported (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT64 OsIndicationsSupported;\r
+ UINTN DataSize;\r
+\r
+ DataSize = sizeof(UINT64);\r
+ Status = gRT->GetVariable (\r
+ L"OsIndicationsSupported",\r
+ &gEfiGlobalVariableGuid,\r
+ NULL,\r
+ &DataSize,\r
+ &OsIndicationsSupported\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return FALSE;\r
+ }\r
+\r
+ if ((OsIndicationsSupported & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) != 0) {\r
+ return TRUE;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
/**\r
Process Capsule On Disk.\r
\r
UINT16 BootNext;\r
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;\r
BOOLEAN UpdateBootNext;\r
+ CHAR16 *FileName[MAX_CAPSULE_NUM];\r
+ UINTN Index;\r
+\r
+ //\r
+ // Check if Capsule On Disk is supported\r
+ //\r
+ if (!IsCapsuleOnDiskSupported ()) {\r
+ Print (L"CapsuleApp: Capsule On Disk is not supported.\n");\r
+ return EFI_UNSUPPORTED;\r
+ }\r
\r
//\r
// Get a valid file system from boot path\r
\r
Status = GetUpdateFileSystem (Map, &BootNext, &Fs, &UpdateBootNext);\r
if (EFI_ERROR (Status)) {\r
- Print (L"CapsuleApp: cannot find a valid file system on boot devies. Status = %r\n", Status);\r
+ Print (L"CapsuleApp: cannot find a valid file system on boot devices. Status = %r\n", Status);\r
return Status;\r
}\r
\r
+ //\r
+ // Get file name from file path\r
+ //\r
+ for (Index = 0; Index < CapsuleNum; Index ++) {\r
+ FileName[Index] = GetFileNameFromPath (FilePath[Index]);\r
+ }\r
+\r
//\r
// Copy capsule image to '\efi\UpdateCapsule\'\r
//\r
- Status = WriteUpdateFile (CapsuleBuffer, CapsuleBufferSize, FilePath, CapsuleNum, Fs);\r
+ Status = WriteUpdateFile (CapsuleBuffer, CapsuleBufferSize, FileName, CapsuleNum, Fs);\r
if (EFI_ERROR (Status)) {\r
Print (L"CapsuleApp: capsule image could not be copied for update.\n");\r
return Status;\r