2 Process Capsule On Disk.
4 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include <Library/BaseLib.h>
10 #include <Library/DebugLib.h>
11 #include <Library/BaseMemoryLib.h>
12 #include <Library/MemoryAllocationLib.h>
13 #include <Library/UefiBootServicesTableLib.h>
14 #include <Library/UefiRuntimeServicesTableLib.h>
15 #include <Library/UefiLib.h>
16 #include <Library/PrintLib.h>
17 #include <Library/DevicePathLib.h>
18 #include <Library/FileHandleLib.h>
19 #include <Library/UefiBootManagerLib.h>
20 #include <Protocol/SimpleFileSystem.h>
21 #include <Protocol/Shell.h>
22 #include <Guid/FileInfo.h>
23 #include <Guid/GlobalVariable.h>
26 #define MAX_CAPSULE_NUM 10
28 EFI_GUID mCapsuleOnDiskBootOptionGuid
= { 0x4CC29BB7, 0x2413, 0x40A2, { 0xB0, 0x6D, 0x25, 0x3E, 0x37, 0x10, 0xF5, 0x32 } };
33 @return Pointer to shell protocol.
42 Get file name from file path.
44 @param FilePath File path.
46 @return Pointer to file name.
55 EFI_SHELL_PROTOCOL
*ShellProtocol
;
56 SHELL_FILE_HANDLE Handle
;
57 EFI_FILE_INFO
*FileInfo
;
59 ShellProtocol
= GetShellProtocol ();
60 if (ShellProtocol
== NULL
) {
65 // Open file by FileName.
67 Status
= ShellProtocol
->OpenFileByName (
72 if (EFI_ERROR (Status
)) {
77 // Get file name from EFI_FILE_INFO.
79 FileInfo
= ShellProtocol
->GetFileInfo (Handle
);
80 ShellProtocol
->CloseFile (Handle
);
81 if (FileInfo
== NULL
) {
85 return FileInfo
->FileName
;
89 Check if the device path is EFI system Partition.
91 @param DevicePath The ESP device path.
93 @retval TRUE DevicePath is a device path for ESP.
94 @retval FALSE DevicePath is not a device path for ESP.
98 IsEfiSysPartitionDevicePath (
99 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
103 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
104 HARDDRIVE_DEVICE_PATH
*Hd
;
108 // Check if the device path contains GPT node
110 TempDevicePath
= DevicePath
;
112 while (!IsDevicePathEnd (TempDevicePath
)) {
113 if ((DevicePathType (TempDevicePath
) == MEDIA_DEVICE_PATH
) &&
114 (DevicePathSubType (TempDevicePath
) == MEDIA_HARDDRIVE_DP
)) {
115 Hd
= (HARDDRIVE_DEVICE_PATH
*)TempDevicePath
;
116 if (Hd
->MBRType
== MBR_TYPE_EFI_PARTITION_TABLE_HEADER
) {
120 TempDevicePath
= NextDevicePathNode (TempDevicePath
);
123 if (!IsDevicePathEnd (TempDevicePath
)) {
125 // Search for EFI system partition protocol on full device path in Boot Option
127 Status
= gBS
->LocateDevicePath (&gEfiPartTypeSystemPartGuid
, &DevicePath
, &Handle
);
128 return EFI_ERROR (Status
) ? FALSE
: TRUE
;
135 Dump all EFI System Partition.
139 DumpAllEfiSysPartition (
143 EFI_HANDLE
*SimpleFileSystemHandles
;
144 UINTN NumberSimpleFileSystemHandles
;
146 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
147 UINTN NumberEfiSystemPartitions
;
148 EFI_SHELL_PROTOCOL
*ShellProtocol
;
150 NumberEfiSystemPartitions
= 0;
152 ShellProtocol
= GetShellProtocol ();
153 if (ShellProtocol
== NULL
) {
154 Print (L
"Get Shell Protocol Fail\n");;
158 Print (L
"EFI System Partition list:\n");
160 gBS
->LocateHandleBuffer (
162 &gEfiSimpleFileSystemProtocolGuid
,
164 &NumberSimpleFileSystemHandles
,
165 &SimpleFileSystemHandles
168 for (Index
= 0; Index
< NumberSimpleFileSystemHandles
; Index
++) {
169 DevicePath
= DevicePathFromHandle (SimpleFileSystemHandles
[Index
]);
170 if (IsEfiSysPartitionDevicePath (DevicePath
)) {
171 NumberEfiSystemPartitions
++;
172 Print(L
" %s\n %s\n", ShellProtocol
->GetMapFromDevicePath (&DevicePath
), ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
));
176 if (NumberEfiSystemPartitions
== 0) {
177 Print(L
" No ESP found.\n");
182 Check if capsule is provisioned.
184 @retval TRUE Capsule is provisioned previously.
185 @retval FALSE No capsule is provisioned.
189 IsCapsuleProvisioned (
198 DataSize
= sizeof(UINT64
);
199 Status
= gRT
->GetVariable (
201 &gEfiGlobalVariableGuid
,
206 if (!EFI_ERROR (Status
) &&
207 (OsIndication
& EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
) != 0) {
215 Get one active Efi System Partition.
217 @param[out] FsDevicePath The device path of Fs
218 @param[out] Fs The file system within EfiSysPartition
220 @retval EFI_SUCCESS Get file system successfully
221 @retval EFI_NOT_FOUND No valid file system found
226 OUT EFI_DEVICE_PATH_PROTOCOL
**FsDevicePath
,
227 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
230 EFI_HANDLE
*SimpleFileSystemHandles
;
231 UINTN NumberSimpleFileSystemHandles
;
233 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
236 Status
= gBS
->LocateHandleBuffer (
238 &gEfiSimpleFileSystemProtocolGuid
,
240 &NumberSimpleFileSystemHandles
,
241 &SimpleFileSystemHandles
244 if (EFI_ERROR (Status
)) {
245 return EFI_NOT_FOUND
;
248 for (Index
= 0; Index
< NumberSimpleFileSystemHandles
; Index
++) {
249 DevicePath
= DevicePathFromHandle (SimpleFileSystemHandles
[Index
]);
250 if (IsEfiSysPartitionDevicePath (DevicePath
)) {
251 Status
= gBS
->HandleProtocol (SimpleFileSystemHandles
[Index
], &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)Fs
);
252 if (!EFI_ERROR (Status
)) {
253 *FsDevicePath
= DevicePath
;
259 return EFI_NOT_FOUND
;
263 Check if Active Efi System Partition within GPT is in the device path.
265 @param[in] DevicePath The device path
266 @param[out] FsDevicePath The device path of Fs
267 @param[out] Fs The file system within EfiSysPartition
269 @retval EFI_SUCCESS Get file system successfully
270 @retval EFI_NOT_FOUND No valid file system found
271 @retval others Get file system failed
275 GetEfiSysPartitionFromDevPath (
276 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
277 OUT EFI_DEVICE_PATH_PROTOCOL
**FsDevicePath
,
278 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
282 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
283 HARDDRIVE_DEVICE_PATH
*Hd
;
287 // Check if the device path contains GPT node
289 TempDevicePath
= DevicePath
;
290 while (!IsDevicePathEnd (TempDevicePath
)) {
291 if ((DevicePathType (TempDevicePath
) == MEDIA_DEVICE_PATH
) &&
292 (DevicePathSubType (TempDevicePath
) == MEDIA_HARDDRIVE_DP
)) {
293 Hd
= (HARDDRIVE_DEVICE_PATH
*)TempDevicePath
;
294 if (Hd
->MBRType
== MBR_TYPE_EFI_PARTITION_TABLE_HEADER
) {
298 TempDevicePath
= NextDevicePathNode (TempDevicePath
);
301 if (!IsDevicePathEnd (TempDevicePath
)) {
303 // Search for EFI system partition protocol on full device path in Boot Option
305 Status
= gBS
->LocateDevicePath (&gEfiPartTypeSystemPartGuid
, &DevicePath
, &Handle
);
308 // Search for simple file system on this handler
310 if (!EFI_ERROR (Status
)) {
311 Status
= gBS
->HandleProtocol (Handle
, &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)Fs
);
312 if (!EFI_ERROR (Status
)) {
313 *FsDevicePath
= DevicePathFromHandle (Handle
);
319 return EFI_NOT_FOUND
;
323 Get SimpleFileSystem from boot option file path.
325 @param[in] DevicePath The file path of boot option
326 @param[out] FullPath The full device path of boot device
327 @param[out] Fs The file system within EfiSysPartition
329 @retval EFI_SUCCESS Get file system successfully
330 @retval EFI_NOT_FOUND No valid file system found
331 @retval others Get file system failed
336 GetEfiSysPartitionFromBootOptionFilePath (
337 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
338 OUT EFI_DEVICE_PATH_PROTOCOL
**FullPath
,
339 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
343 EFI_DEVICE_PATH_PROTOCOL
*CurFullPath
;
344 EFI_DEVICE_PATH_PROTOCOL
*PreFullPath
;
345 EFI_DEVICE_PATH_PROTOCOL
*FsFullPath
;
350 // Try every full device Path generated from bootoption
353 PreFullPath
= CurFullPath
;
354 CurFullPath
= EfiBootManagerGetNextLoadOptionDevicePath (DevicePath
, CurFullPath
);
356 if (PreFullPath
!= NULL
) {
357 FreePool (PreFullPath
);
360 if (CurFullPath
== NULL
) {
362 // No Active EFI system partition is found in BootOption device path
364 Status
= EFI_NOT_FOUND
;
369 CHAR16
*DevicePathStr
;
371 DevicePathStr
= ConvertDevicePathToText (CurFullPath
, TRUE
, TRUE
);
372 if (DevicePathStr
!= NULL
){
373 DEBUG ((DEBUG_INFO
, "Full device path %s\n", DevicePathStr
));
374 FreePool (DevicePathStr
);
378 Status
= GetEfiSysPartitionFromDevPath (CurFullPath
, &FsFullPath
, Fs
);
379 } while (EFI_ERROR (Status
));
382 *FullPath
= FsFullPath
;
385 return EFI_NOT_FOUND
;
390 Get a valid SimpleFileSystem within EFI system partition.
392 @param[in] Map The FS mapping capsule write to
393 @param[out] BootNext The value of BootNext Variable
394 @param[out] Fs The file system within EfiSysPartition
395 @param[out] UpdateBootNext The flag to indicate whether update BootNext Variable
397 @retval EFI_SUCCESS Get FS successfully
398 @retval EFI_NOT_FOUND No valid FS found
399 @retval others Get FS failed
404 GetUpdateFileSystem (
406 OUT UINT16
*BootNext
,
407 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
,
408 OUT BOOLEAN
*UpdateBootNext
412 CHAR16 BootOptionName
[20];
414 CONST EFI_DEVICE_PATH_PROTOCOL
*MappedDevicePath
;
415 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
416 EFI_DEVICE_PATH_PROTOCOL
*FullPath
;
417 UINT16
*BootNextData
;
418 EFI_BOOT_MANAGER_LOAD_OPTION BootNextOption
;
419 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOptionBuffer
;
420 UINTN BootOptionCount
;
421 EFI_SHELL_PROTOCOL
*ShellProtocol
;
422 EFI_BOOT_MANAGER_LOAD_OPTION NewOption
;
424 MappedDevicePath
= NULL
;
425 BootOptionBuffer
= NULL
;
427 ShellProtocol
= GetShellProtocol ();
428 if (ShellProtocol
== NULL
) {
429 Print (L
"Get Shell Protocol Fail\n");;
430 return EFI_NOT_FOUND
;
434 // 1. If Fs is not assigned and there are capsule provisioned before,
435 // Get EFI system partition from BootNext.
437 if (IsCapsuleProvisioned () && Map
== NULL
) {
438 Status
= GetVariable2 (
440 &gEfiGlobalVariableGuid
,
441 (VOID
**)&BootNextData
,
444 if (EFI_ERROR (Status
) || BootNextData
== NULL
) {
445 Print (L
"Get Boot Next Data Fail. Status = %r\n", Status
);
446 return EFI_NOT_FOUND
;
448 UnicodeSPrint (BootOptionName
, sizeof (BootOptionName
), L
"Boot%04x", *BootNextData
);
449 Status
= EfiBootManagerVariableToLoadOption (BootOptionName
, &BootNextOption
);
450 if (!EFI_ERROR (Status
)) {
451 DevicePath
= BootNextOption
.FilePath
;
452 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
453 if (!EFI_ERROR (Status
)) {
454 *UpdateBootNext
= FALSE
;
455 Print(L
"Get EFI system partition from BootNext : %s\n", BootNextOption
.Description
);
456 Print(L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
464 // Check if Map is valid.
467 MappedDevicePath
= ShellProtocol
->GetDevicePathFromMap (Map
);
468 if (MappedDevicePath
== NULL
) {
469 Print(L
"'%s' is not a valid mapping.\n", Map
);
470 return EFI_INVALID_PARAMETER
;
471 } else if (!IsEfiSysPartitionDevicePath (DuplicateDevicePath (MappedDevicePath
))) {
472 Print(L
"'%s' is not a EFI System Partition.\n", Map
);
473 return EFI_INVALID_PARAMETER
;
478 // 2. Get EFI system partition form boot options.
480 BootOptionBuffer
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
481 if ( (BootOptionBuffer
== NULL
) ||
482 (BootOptionCount
== 0 && Map
== NULL
)
484 return EFI_NOT_FOUND
;
487 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
489 // Get the boot option from the link list
491 DevicePath
= BootOptionBuffer
[Index
].FilePath
;
494 // Skip inactive or legacy boot options
496 if ((BootOptionBuffer
[Index
].Attributes
& LOAD_OPTION_ACTIVE
) == 0 ||
497 DevicePathType (DevicePath
) == BBS_DEVICE_PATH
) {
502 CHAR16
*DevicePathStr
;
504 DevicePathStr
= ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
);
505 if (DevicePathStr
!= NULL
){
506 DEBUG ((DEBUG_INFO
, "Try BootOption %s\n", DevicePathStr
));
507 FreePool (DevicePathStr
);
509 DEBUG ((DEBUG_INFO
, "DevicePathToStr failed\n"));
513 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
514 if (!EFI_ERROR (Status
)) {
516 *BootNext
= (UINT16
) BootOptionBuffer
[Index
].OptionNumber
;
517 *UpdateBootNext
= TRUE
;
518 Print (L
"Found EFI system partition on Boot%04x: %s\n", *BootNext
, BootOptionBuffer
[Index
].Description
);
519 Print (L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
523 if (StrnCmp (Map
, ShellProtocol
->GetMapFromDevicePath (&FullPath
), StrLen (Map
)) == 0) {
524 *BootNext
= (UINT16
) BootOptionBuffer
[Index
].OptionNumber
;
525 *UpdateBootNext
= TRUE
;
526 Print (L
"Found Boot Option on %s : %s\n", Map
, BootOptionBuffer
[Index
].Description
);
533 // 3. If no ESP is found on boot option, try to find a ESP and create boot option for it.
537 // If map is assigned, try to get ESP from mapped Fs.
539 DevicePath
= DuplicateDevicePath (MappedDevicePath
);
540 Status
= GetEfiSysPartitionFromDevPath (DevicePath
, &FullPath
, Fs
);
541 if (EFI_ERROR (Status
)) {
542 Print (L
"Error: Cannot get EFI system partiion from '%s' - %r\n", Map
, Status
);
543 return EFI_NOT_FOUND
;
545 Print (L
"Warning: Cannot find Boot Option on '%s'!\n", Map
);
547 Status
= GetEfiSysPartition (&DevicePath
, Fs
);
548 if (EFI_ERROR (Status
)) {
549 Print (L
"Error: Cannot find a EFI system partition!\n");
550 return EFI_NOT_FOUND
;
554 Print (L
"Create Boot option for capsule on disk:\n");
555 Status
= EfiBootManagerInitializeLoadOption (
557 LoadOptionNumberUnassigned
,
560 L
"UEFI Capsule On Disk",
562 (UINT8
*) &mCapsuleOnDiskBootOptionGuid
,
565 if (!EFI_ERROR (Status
)) {
566 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, (UINTN
) -1); {
567 if (!EFI_ERROR (Status
)) {
568 *UpdateBootNext
= TRUE
;
569 *BootNext
= (UINT16
) NewOption
.OptionNumber
;
570 Print (L
" Boot%04x: %s\n", *BootNext
, ConvertDevicePathToText(DevicePath
, TRUE
, TRUE
));
576 Print (L
"ERROR: Cannot create boot option! - %r\n", Status
);
578 return EFI_NOT_FOUND
;
582 Write files to a given SimpleFileSystem.
584 @param[in] Buffer The buffer array
585 @param[in] BufferSize The buffer size array
586 @param[in] FileName The file name array
587 @param[in] BufferNum The buffer number
588 @param[in] Fs The SimpleFileSystem handle to be written
590 @retval EFI_SUCCESS Write file successfully
591 @retval EFI_NOT_FOUND SFS protocol not found
592 @retval others Write file failed
598 IN UINTN
*BufferSize
,
599 IN CHAR16
**FileName
,
601 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
606 EFI_FILE
*FileHandle
;
607 EFI_FILE_PROTOCOL
*DirHandle
;
618 // Open Root from SFS
620 Status
= Fs
->OpenVolume (Fs
, &Root
);
621 if (EFI_ERROR (Status
)) {
622 Print (L
"Cannot open volume. Status = %r\n", Status
);
623 return EFI_NOT_FOUND
;
627 // Ensure that efi and updatecapsule directories exist
629 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
630 if (EFI_ERROR (Status
)) {
631 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
632 if (EFI_ERROR (Status
)) {
633 Print(L
"Unable to create %s directory\n", L
"\\EFI");
634 return EFI_NOT_FOUND
;
637 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
638 if (EFI_ERROR (Status
)) {
639 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
640 if (EFI_ERROR (Status
)) {
641 Print(L
"Unable to create %s directory\n", EFI_CAPSULE_FILE_DIRECTORY
);
642 return EFI_NOT_FOUND
;
646 for (Index
= 0; Index
< BufferNum
; Index
++) {
650 // Open UpdateCapsule file
652 Status
= DirHandle
->Open (DirHandle
, &FileHandle
, FileName
[Index
], EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
, 0);
653 if (EFI_ERROR (Status
)) {
654 Print (L
"Unable to create %s file\n", FileName
[Index
]);
655 return EFI_NOT_FOUND
;
659 // Empty the file contents
661 Status
= FileHandleGetSize (FileHandle
, &FileInfo
);
662 if (EFI_ERROR (Status
)) {
663 FileHandleClose (FileHandle
);
664 Print (L
"Error Reading %s\n", FileName
[Index
]);
665 return EFI_DEVICE_ERROR
;
669 // If the file size is already 0, then it has been empty.
673 // Set the file size to 0.
676 Status
= FileHandleSetSize (FileHandle
, FileInfo
);
677 if (EFI_ERROR (Status
)) {
678 Print (L
"Error Deleting %s\n", FileName
[Index
]);
679 FileHandleClose (FileHandle
);
685 // Write Filebuffer to file
687 Filebuffer
= Buffer
[Index
];
688 FileSize
= BufferSize
[Index
];
689 Status
= FileHandleWrite (FileHandle
, &FileSize
, Filebuffer
);
690 if (EFI_ERROR (Status
)) {
691 Print (L
"Unable to write Capsule Update to %s, Status = %r\n", FileName
[Index
], Status
);
692 return EFI_NOT_FOUND
;
695 Print (L
"Succeed to write %s\n", FileName
[Index
]);
696 FileHandleClose (FileHandle
);
703 Set capsule status variable.
705 @param[in] SetCap Set or clear the capsule flag.
707 @retval EFI_SUCCESS Succeed to set SetCap variable.
708 @retval others Fail to set the variable.
712 SetCapsuleStatusVariable (
721 DataSize
= sizeof(UINT64
);
722 Status
= gRT
->GetVariable (
724 &gEfiGlobalVariableGuid
,
729 if (EFI_ERROR (Status
)) {
733 OsIndication
|= ((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
736 OsIndication
&= ~((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
738 Status
= gRT
->SetVariable (
740 &gEfiGlobalVariableGuid
,
741 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
750 Check if Capsule On Disk is supported.
752 @retval TRUE Capsule On Disk is supported.
753 @retval FALSE Capsule On Disk is not supported.
757 IsCapsuleOnDiskSupported (
762 UINT64 OsIndicationsSupported
;
765 DataSize
= sizeof(UINT64
);
766 Status
= gRT
->GetVariable (
767 L
"OsIndicationsSupported",
768 &gEfiGlobalVariableGuid
,
771 &OsIndicationsSupported
773 if (EFI_ERROR (Status
)) {
777 if (OsIndicationsSupported
& EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
) {
785 Process Capsule On Disk.
787 @param[in] CapsuleBuffer An array of pointer to capsule images
788 @param[in] CapsuleBufferSize An array of UINTN to capsule images size
789 @param[in] FilePath An array of capsule images file path
790 @param[in] Map File system mapping string
791 @param[in] CapsuleNum The count of capsule images
793 @retval EFI_SUCCESS Capsule on disk success.
794 @retval others Capsule on disk fail.
798 ProcessCapsuleOnDisk (
799 IN VOID
**CapsuleBuffer
,
800 IN UINTN
*CapsuleBufferSize
,
801 IN CHAR16
**FilePath
,
808 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
;
809 BOOLEAN UpdateBootNext
;
810 CHAR16
*FileName
[MAX_CAPSULE_NUM
];
814 // Check if Capsule On Disk is supported
816 if (!IsCapsuleOnDiskSupported ()) {
817 Print (L
"CapsuleApp: Capsule On Disk is not supported.\n");
818 return EFI_UNSUPPORTED
;
822 // Get a valid file system from boot path
826 Status
= GetUpdateFileSystem (Map
, &BootNext
, &Fs
, &UpdateBootNext
);
827 if (EFI_ERROR (Status
)) {
828 Print (L
"CapsuleApp: cannot find a valid file system on boot devies. Status = %r\n", Status
);
833 // Get file name from file path
835 for (Index
= 0; Index
< CapsuleNum
; Index
++) {
836 FileName
[Index
] = GetFileNameFromPath (FilePath
[Index
]);
840 // Copy capsule image to '\efi\UpdateCapsule\'
842 Status
= WriteUpdateFile (CapsuleBuffer
, CapsuleBufferSize
, FileName
, CapsuleNum
, Fs
);
843 if (EFI_ERROR (Status
)) {
844 Print (L
"CapsuleApp: capsule image could not be copied for update.\n");
849 // Set variable then reset
851 Status
= SetCapsuleStatusVariable (TRUE
);
852 if (EFI_ERROR (Status
)) {
853 Print (L
"CapsuleApp: unable to set OSIndication variable.\n");
857 if (UpdateBootNext
) {
858 Status
= gRT
->SetVariable (
860 &gEfiGlobalVariableGuid
,
861 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
865 if (EFI_ERROR (Status
)){
866 Print (L
"CapsuleApp: unable to set BootNext variable.\n");