2 Process Capsule On Disk.
4 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Library/BaseLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/MemoryAllocationLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/UefiRuntimeServicesTableLib.h>
21 #include <Library/UefiLib.h>
22 #include <Library/PrintLib.h>
23 #include <Library/DevicePathLib.h>
24 #include <Library/FileHandleLib.h>
25 #include <Library/UefiBootManagerLib.h>
26 #include <Protocol/SimpleFileSystem.h>
27 #include <Protocol/Shell.h>
28 #include <Guid/FileInfo.h>
29 #include <Guid/GlobalVariable.h>
32 EFI_GUID mCapsuleOnDiskBootOptionGuid
= { 0x4CC29BB7, 0x2413, 0x40A2, { 0xB0, 0x6D, 0x25, 0x3E, 0x37, 0x10, 0xF5, 0x32 } };
37 @return Pointer to shell protocol.
46 Get file name from file path.
48 @param FilePath File path.
50 @return Pointer to file name.
59 EFI_SHELL_PROTOCOL
*ShellProtocol
;
60 SHELL_FILE_HANDLE Handle
;
61 EFI_FILE_INFO
*FileInfo
;
63 ShellProtocol
= GetShellProtocol ();
64 if (ShellProtocol
== NULL
) {
69 // Open file by FileName.
71 Status
= ShellProtocol
->OpenFileByName (
76 if (EFI_ERROR (Status
)) {
81 // Get file name from EFI_FILE_INFO.
83 FileInfo
= ShellProtocol
->GetFileInfo (Handle
);
84 ShellProtocol
->CloseFile (Handle
);
85 if (FileInfo
== NULL
) {
89 return FileInfo
->FileName
;
93 Check if the device path is EFI system Partition.
95 @param DevicePath The ESP device path.
97 @retval TRUE DevicePath is a device path for ESP.
98 @retval FALSE DevicePath is not a device path for ESP.
102 IsEfiSysPartitionDevicePath (
103 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
107 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
108 HARDDRIVE_DEVICE_PATH
*Hd
;
112 // Check if the device path contains GPT node
114 TempDevicePath
= DevicePath
;
116 while (!IsDevicePathEnd (TempDevicePath
)) {
117 if ((DevicePathType (TempDevicePath
) == MEDIA_DEVICE_PATH
) &&
118 (DevicePathSubType (TempDevicePath
) == MEDIA_HARDDRIVE_DP
)) {
119 Hd
= (HARDDRIVE_DEVICE_PATH
*)TempDevicePath
;
120 if (Hd
->MBRType
== MBR_TYPE_EFI_PARTITION_TABLE_HEADER
) {
124 TempDevicePath
= NextDevicePathNode (TempDevicePath
);
127 if (!IsDevicePathEnd (TempDevicePath
)) {
129 // Search for EFI system partition protocol on full device path in Boot Option
131 Status
= gBS
->LocateDevicePath (&gEfiPartTypeSystemPartGuid
, &DevicePath
, &Handle
);
132 return EFI_ERROR (Status
) ? FALSE
: TRUE
;
139 Dump all EFI System Partition.
143 DumpAllEfiSysPartition (
147 EFI_HANDLE
*SimpleFileSystemHandles
;
148 UINTN NumberSimpleFileSystemHandles
;
150 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
151 UINTN NumberEfiSystemPartitions
;
152 EFI_SHELL_PROTOCOL
*ShellProtocol
;
154 ShellProtocol
= GetShellProtocol ();
155 NumberEfiSystemPartitions
= 0;
157 Print (L
"EFI System Partition list:\n");
159 gBS
->LocateHandleBuffer (
161 &gEfiSimpleFileSystemProtocolGuid
,
163 &NumberSimpleFileSystemHandles
,
164 &SimpleFileSystemHandles
167 for (Index
= 0; Index
< NumberSimpleFileSystemHandles
; Index
++) {
168 DevicePath
= DevicePathFromHandle (SimpleFileSystemHandles
[Index
]);
169 if (IsEfiSysPartitionDevicePath (DevicePath
)) {
170 NumberEfiSystemPartitions
++;
171 Print(L
" %s\n %s\n", ShellProtocol
->GetMapFromDevicePath (&DevicePath
), ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
));
175 if (NumberEfiSystemPartitions
== 0) {
176 Print(L
" No ESP found.\n");
181 Check if capsule is provisioned.
183 @retval TRUE Capsule is provisioned previously.
184 @retval FALSE No capsule is provisioned.
188 IsCapsuleProvisioned (
197 DataSize
= sizeof(UINT64
);
198 Status
= gRT
->GetVariable (
200 &gEfiGlobalVariableGuid
,
205 if (!EFI_ERROR (Status
) &&
206 (OsIndication
& EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
) != 0) {
214 Get one active Efi System Partition.
216 @param[out] FsDevicePath The device path of Fs
217 @param[out] Fs The file system within EfiSysPartition
219 @retval EFI_SUCCESS Get file system successfully
220 @retval EFI_NOT_FOUND No valid file system found
225 OUT EFI_DEVICE_PATH_PROTOCOL
**FsDevicePath
,
226 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
229 EFI_HANDLE
*SimpleFileSystemHandles
;
230 UINTN NumberSimpleFileSystemHandles
;
232 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
235 Status
= gBS
->LocateHandleBuffer (
237 &gEfiSimpleFileSystemProtocolGuid
,
239 &NumberSimpleFileSystemHandles
,
240 &SimpleFileSystemHandles
243 if (EFI_ERROR (Status
)) {
244 return EFI_NOT_FOUND
;
247 for (Index
= 0; Index
< NumberSimpleFileSystemHandles
; Index
++) {
248 DevicePath
= DevicePathFromHandle (SimpleFileSystemHandles
[Index
]);
249 if (IsEfiSysPartitionDevicePath (DevicePath
)) {
250 Status
= gBS
->HandleProtocol (SimpleFileSystemHandles
[Index
], &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)Fs
);
251 if (!EFI_ERROR (Status
)) {
252 *FsDevicePath
= DevicePath
;
258 return EFI_NOT_FOUND
;
262 Check if Active Efi System Partition within GPT is in the device path.
264 @param[in] DevicePath The device path
265 @param[out] FsDevicePath The device path of Fs
266 @param[out] Fs The file system within EfiSysPartition
268 @retval EFI_SUCCESS Get file system successfully
269 @retval EFI_NOT_FOUND No valid file system found
270 @retval others Get file system failed
274 GetEfiSysPartitionFromDevPath (
275 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
276 OUT EFI_DEVICE_PATH_PROTOCOL
**FsDevicePath
,
277 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
281 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
282 HARDDRIVE_DEVICE_PATH
*Hd
;
286 // Check if the device path contains GPT node
288 TempDevicePath
= DevicePath
;
289 while (!IsDevicePathEnd (TempDevicePath
)) {
290 if ((DevicePathType (TempDevicePath
) == MEDIA_DEVICE_PATH
) &&
291 (DevicePathSubType (TempDevicePath
) == MEDIA_HARDDRIVE_DP
)) {
292 Hd
= (HARDDRIVE_DEVICE_PATH
*)TempDevicePath
;
293 if (Hd
->MBRType
== MBR_TYPE_EFI_PARTITION_TABLE_HEADER
) {
297 TempDevicePath
= NextDevicePathNode (TempDevicePath
);
300 if (!IsDevicePathEnd (TempDevicePath
)) {
302 // Search for EFI system partition protocol on full device path in Boot Option
304 Status
= gBS
->LocateDevicePath (&gEfiPartTypeSystemPartGuid
, &DevicePath
, &Handle
);
307 // Search for simple file system on this handler
309 if (!EFI_ERROR (Status
)) {
310 Status
= gBS
->HandleProtocol (Handle
, &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)Fs
);
311 if (!EFI_ERROR (Status
)) {
312 *FsDevicePath
= DevicePathFromHandle (Handle
);
318 return EFI_NOT_FOUND
;
322 Get SimpleFileSystem from boot option file path.
324 @param[in] DevicePath The file path of boot option
325 @param[out] FullPath The full device path of boot device
326 @param[out] Fs The file system within EfiSysPartition
328 @retval EFI_SUCCESS Get file system successfully
329 @retval EFI_NOT_FOUND No valid file system found
330 @retval others Get file system failed
335 GetEfiSysPartitionFromBootOptionFilePath (
336 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
337 OUT EFI_DEVICE_PATH_PROTOCOL
**FullPath
,
338 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
342 EFI_DEVICE_PATH_PROTOCOL
*CurFullPath
;
343 EFI_DEVICE_PATH_PROTOCOL
*PreFullPath
;
344 EFI_DEVICE_PATH_PROTOCOL
*FsFullPath
;
349 // Try every full device Path generated from bootoption
352 PreFullPath
= CurFullPath
;
353 CurFullPath
= EfiBootManagerGetNextFullDevicePath (DevicePath
, CurFullPath
);
355 if (PreFullPath
!= NULL
) {
356 FreePool (PreFullPath
);
359 if (CurFullPath
== NULL
) {
361 // No Active EFI system partition is found in BootOption device path
363 Status
= EFI_NOT_FOUND
;
368 CHAR16
*DevicePathStr
;
370 DevicePathStr
= ConvertDevicePathToText (CurFullPath
, TRUE
, TRUE
);
371 if (DevicePathStr
!= NULL
){
372 DEBUG ((DEBUG_INFO
, "Full device path %s\n", DevicePathStr
));
373 FreePool (DevicePathStr
);
377 Status
= GetEfiSysPartitionFromDevPath (CurFullPath
, &FsFullPath
, Fs
);
378 } while (EFI_ERROR (Status
));
381 *FullPath
= FsFullPath
;
384 return EFI_NOT_FOUND
;
389 Get a valid SimpleFileSystem within EFI system partition.
391 @param[in] Map The FS mapping capsule write to
392 @param[out] BootNext The value of BootNext Variable
393 @param[out] Fs The file system within EfiSysPartition
394 @param[out] UpdateBootNext The flag to indicate whether update BootNext Variable
396 @retval EFI_SUCCESS Get FS successfully
397 @retval EFI_NOT_FOUND No valid FS found
398 @retval others Get FS failed
403 GetUpdateFileSystem (
405 OUT UINT16
*BootNext
,
406 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
,
407 OUT BOOLEAN
*UpdateBootNext
411 CHAR16 BootOptionName
[20];
413 CONST EFI_DEVICE_PATH_PROTOCOL
*MappedDevicePath
;
414 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
415 EFI_DEVICE_PATH_PROTOCOL
*FullPath
;
416 UINT16
*BootNextData
;
417 EFI_BOOT_MANAGER_LOAD_OPTION BootNextOption
;
418 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOptionBuffer
;
419 UINTN BootOptionCount
;
420 EFI_SHELL_PROTOCOL
*ShellProtocol
;
421 EFI_BOOT_MANAGER_LOAD_OPTION NewOption
;
423 MappedDevicePath
= NULL
;
424 ShellProtocol
= GetShellProtocol ();
427 // 1. If Fs is not assigned and there are capsule provisioned before,
428 // Get EFI system partition from BootNext.
430 if (IsCapsuleProvisioned () && Map
== NULL
) {
431 Status
= GetVariable2 (
433 &gEfiGlobalVariableGuid
,
434 (VOID
**)&BootNextData
,
437 if (!EFI_ERROR (Status
)) {
438 UnicodeSPrint (BootOptionName
, sizeof (BootOptionName
), L
"Boot%04x", *BootNextData
);
439 Status
= EfiBootManagerVariableToLoadOption (BootOptionName
, &BootNextOption
);
440 if (!EFI_ERROR (Status
)) {
441 DevicePath
= BootNextOption
.FilePath
;
442 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
443 if (!EFI_ERROR (Status
)) {
444 *UpdateBootNext
= FALSE
;
445 Print(L
"Get EFI system partition from BootNext : %s\n", BootNextOption
.Description
);
446 Print(L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
454 // Check if Map is valid.
457 MappedDevicePath
= ShellProtocol
->GetDevicePathFromMap (Map
);
458 if (MappedDevicePath
== NULL
) {
459 Print(L
"'%s' is not a valid mapping.\n", Map
);
460 return EFI_INVALID_PARAMETER
;
461 } else if (!IsEfiSysPartitionDevicePath (DuplicateDevicePath (MappedDevicePath
))) {
462 Print(L
"'%s' is not a EFI System Partition.\n", Map
);
463 return EFI_INVALID_PARAMETER
;
468 // 2. Get EFI system partition form boot options.
470 BootOptionBuffer
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
471 if (BootOptionCount
== 0 && Map
== NULL
) {
472 return EFI_NOT_FOUND
;
475 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
477 // Get the boot option from the link list
479 DevicePath
= BootOptionBuffer
[Index
].FilePath
;
482 // Skip inactive or legacy boot options
484 if ((BootOptionBuffer
[Index
].Attributes
& LOAD_OPTION_ACTIVE
) == 0 ||
485 DevicePathType (DevicePath
) == BBS_DEVICE_PATH
) {
490 CHAR16
*DevicePathStr
;
492 DevicePathStr
= ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
);
493 if (DevicePathStr
!= NULL
){
494 DEBUG ((DEBUG_INFO
, "Try BootOption %s\n", DevicePathStr
));
495 FreePool (DevicePathStr
);
497 DEBUG ((DEBUG_INFO
, "DevicePathToStr failed\n"));
501 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
502 if (!EFI_ERROR (Status
)) {
504 *BootNext
= (UINT16
) BootOptionBuffer
[Index
].OptionNumber
;
505 *UpdateBootNext
= TRUE
;
506 Print (L
"Found EFI system partition on Boot%04x: %s\n", *BootNext
, BootOptionBuffer
[Index
].Description
);
507 Print (L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
511 if (StrnCmp (Map
, ShellProtocol
->GetMapFromDevicePath (&FullPath
), StrLen (Map
)) == 0) {
512 *BootNext
= (UINT16
) BootOptionBuffer
[Index
].OptionNumber
;
513 *UpdateBootNext
= TRUE
;
514 Print (L
"Found Boot Option on %s : %s\n", Map
, BootOptionBuffer
[Index
].Description
);
521 // 3. If no ESP is found on boot option, try to find a ESP and create boot option for it.
525 // If map is assigned, try to get ESP from mapped Fs.
527 DevicePath
= DuplicateDevicePath (MappedDevicePath
);
528 Status
= GetEfiSysPartitionFromDevPath (DevicePath
, &FullPath
, Fs
);
529 if (EFI_ERROR (Status
)) {
530 Print (L
"Error: Cannot get EFI system partiion from '%s' - %r\n", Map
, Status
);
531 return EFI_NOT_FOUND
;
533 Print (L
"Warning: Cannot find Boot Option on '%s'!\n", Map
);
535 Status
= GetEfiSysPartition (&DevicePath
, Fs
);
536 if (EFI_ERROR (Status
)) {
537 Print (L
"Error: Cannot find a EFI system partition!\n");
538 return EFI_NOT_FOUND
;
542 Print (L
"Create Boot option for capsule on disk:\n");
543 Status
= EfiBootManagerInitializeLoadOption (
545 LoadOptionNumberUnassigned
,
548 L
"UEFI Capsule On Disk",
550 (UINT8
*) &mCapsuleOnDiskBootOptionGuid
,
553 if (!EFI_ERROR (Status
)) {
554 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, (UINTN
) -1); {
555 if (!EFI_ERROR (Status
)) {
556 *UpdateBootNext
= TRUE
;
557 *BootNext
= (UINT16
) NewOption
.OptionNumber
;
558 Print (L
" Boot%04x: %s\n", *BootNext
, ConvertDevicePathToText(DevicePath
, TRUE
, TRUE
));
564 Print (L
"ERROR: Cannot create boot option! - %r\n", Status
);
566 return EFI_NOT_FOUND
;
570 Write files to a given SimpleFileSystem.
572 @param[in] Buffer The buffer array
573 @param[in] BufferSize The buffer size array
574 @param[in] FileName The file name array
575 @param[in] BufferNum The buffer number
576 @param[in] Fs The SimpleFileSystem handle to be written
578 @retval EFI_SUCCESS Write file successfully
579 @retval EFI_NOT_FOUND SFS protocol not found
580 @retval others Write file failed
586 IN UINTN
*BufferSize
,
587 IN CHAR16
**FileName
,
589 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
594 EFI_FILE
*FileHandle
;
595 EFI_FILE_PROTOCOL
*DirHandle
;
606 // Open Root from SFS
608 Status
= Fs
->OpenVolume (Fs
, &Root
);
609 if (EFI_ERROR (Status
)) {
610 Print (L
"Cannot open volume. Status = %r\n", Status
);
611 return EFI_NOT_FOUND
;
615 // Ensure that efi and updatecapsule directories exist
617 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
618 if (EFI_ERROR (Status
)) {
619 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
620 if (EFI_ERROR (Status
)) {
621 Print(L
"Unable to create %s directory\n", L
"\\EFI");
622 return EFI_NOT_FOUND
;
625 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
626 if (EFI_ERROR (Status
)) {
627 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
628 if (EFI_ERROR (Status
)) {
629 Print(L
"Unable to create %s directory\n", EFI_CAPSULE_FILE_DIRECTORY
);
630 return EFI_NOT_FOUND
;
634 for (Index
= 0; Index
< BufferNum
; Index
++) {
638 // Open UpdateCapsule file
640 Status
= DirHandle
->Open (DirHandle
, &FileHandle
, FileName
[Index
], EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
, 0);
641 if (EFI_ERROR (Status
)) {
642 Print (L
"Unable to create %s file\n", FileName
[Index
]);
643 return EFI_NOT_FOUND
;
647 // Empty the file contents
649 Status
= FileHandleGetSize (FileHandle
, &FileInfo
);
650 if (EFI_ERROR (Status
)) {
651 FileHandleClose (FileHandle
);
652 Print (L
"Error Reading %s\n", FileName
[Index
]);
653 return EFI_DEVICE_ERROR
;
657 // If the file size is already 0, then it has been empty.
661 // Set the file size to 0.
664 Status
= FileHandleSetSize (FileHandle
, FileInfo
);
665 if (EFI_ERROR (Status
)) {
666 Print (L
"Error Deleting %s\n", FileName
[Index
]);
667 FileHandleClose (FileHandle
);
673 // Write Filebuffer to file
675 Filebuffer
= Buffer
[Index
];
676 FileSize
= BufferSize
[Index
];
677 Status
= FileHandleWrite (FileHandle
, &FileSize
, Filebuffer
);
678 if (EFI_ERROR (Status
)) {
679 Print (L
"Unable to write Capsule Update to %s, Status = %r\n", FileName
[Index
], Status
);
680 return EFI_NOT_FOUND
;
683 Print (L
"Succeed to write %s\n", FileName
[Index
]);
684 FileHandleClose (FileHandle
);
691 Set capsule status variable.
693 @param[in] SetCap Set or clear the capsule flag.
695 @retval EFI_SUCCESS Succeed to set SetCap variable.
696 @retval others Fail to set the variable.
700 SetCapsuleStatusVariable (
709 DataSize
= sizeof(UINT64
);
710 Status
= gRT
->GetVariable (
712 &gEfiGlobalVariableGuid
,
717 if (EFI_ERROR (Status
)) {
721 OsIndication
|= ((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
724 OsIndication
&= ~((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
726 Status
= gRT
->SetVariable (
728 &gEfiGlobalVariableGuid
,
729 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
738 Process Capsule On Disk.
740 @param[in] CapsuleBuffer An array of pointer to capsule images
741 @param[in] CapsuleBufferSize An array of UINTN to capsule images size
742 @param[in] FilePath An array of capsule images file path
743 @param[in] Map File system mapping string
744 @param[in] CapsuleNum The count of capsule images
746 @retval EFI_SUCCESS Capsule on disk success.
747 @retval others Capsule on disk fail.
751 ProcessCapsuleOnDisk (
752 IN VOID
**CapsuleBuffer
,
753 IN UINTN
*CapsuleBufferSize
,
754 IN CHAR16
**FilePath
,
761 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
;
762 BOOLEAN UpdateBootNext
;
765 // Get a valid file system from boot path
769 Status
= GetUpdateFileSystem (Map
, &BootNext
, &Fs
, &UpdateBootNext
);
770 if (EFI_ERROR (Status
)) {
771 Print (L
"CapsuleApp: cannot find a valid file system on boot devies. Status = %r\n", Status
);
776 // Copy capsule image to '\efi\UpdateCapsule\'
778 Status
= WriteUpdateFile (CapsuleBuffer
, CapsuleBufferSize
, FilePath
, CapsuleNum
, Fs
);
779 if (EFI_ERROR (Status
)) {
780 Print (L
"CapsuleApp: capsule image could not be copied for update.\n");
785 // Set variable then reset
787 Status
= SetCapsuleStatusVariable (TRUE
);
788 if (EFI_ERROR (Status
)) {
789 Print (L
"CapsuleApp: unable to set OSIndication variable.\n");
793 if (UpdateBootNext
) {
794 Status
= gRT
->SetVariable (
796 &gEfiGlobalVariableGuid
,
797 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
801 if (EFI_ERROR (Status
)){
802 Print (L
"CapsuleApp: unable to set BootNext variable.\n");