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 EFI_GUID mCapsuleOnDiskBootOptionGuid
= { 0x4CC29BB7, 0x2413, 0x40A2, { 0xB0, 0x6D, 0x25, 0x3E, 0x37, 0x10, 0xF5, 0x32 } };
31 @return Pointer to shell protocol.
40 Get file name from file path.
42 @param FilePath File path.
44 @return Pointer to file name.
53 EFI_SHELL_PROTOCOL
*ShellProtocol
;
54 SHELL_FILE_HANDLE Handle
;
55 EFI_FILE_INFO
*FileInfo
;
57 ShellProtocol
= GetShellProtocol ();
58 if (ShellProtocol
== NULL
) {
63 // Open file by FileName.
65 Status
= ShellProtocol
->OpenFileByName (
70 if (EFI_ERROR (Status
)) {
75 // Get file name from EFI_FILE_INFO.
77 FileInfo
= ShellProtocol
->GetFileInfo (Handle
);
78 ShellProtocol
->CloseFile (Handle
);
79 if (FileInfo
== NULL
) {
83 return FileInfo
->FileName
;
87 Check if the device path is EFI system Partition.
89 @param DevicePath The ESP device path.
91 @retval TRUE DevicePath is a device path for ESP.
92 @retval FALSE DevicePath is not a device path for ESP.
96 IsEfiSysPartitionDevicePath (
97 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
101 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
102 HARDDRIVE_DEVICE_PATH
*Hd
;
106 // Check if the device path contains GPT node
108 TempDevicePath
= DevicePath
;
110 while (!IsDevicePathEnd (TempDevicePath
)) {
111 if ((DevicePathType (TempDevicePath
) == MEDIA_DEVICE_PATH
) &&
112 (DevicePathSubType (TempDevicePath
) == MEDIA_HARDDRIVE_DP
)) {
113 Hd
= (HARDDRIVE_DEVICE_PATH
*)TempDevicePath
;
114 if (Hd
->MBRType
== MBR_TYPE_EFI_PARTITION_TABLE_HEADER
) {
118 TempDevicePath
= NextDevicePathNode (TempDevicePath
);
121 if (!IsDevicePathEnd (TempDevicePath
)) {
123 // Search for EFI system partition protocol on full device path in Boot Option
125 Status
= gBS
->LocateDevicePath (&gEfiPartTypeSystemPartGuid
, &DevicePath
, &Handle
);
126 return EFI_ERROR (Status
) ? FALSE
: TRUE
;
133 Dump all EFI System Partition.
137 DumpAllEfiSysPartition (
141 EFI_HANDLE
*SimpleFileSystemHandles
;
142 UINTN NumberSimpleFileSystemHandles
;
144 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
145 UINTN NumberEfiSystemPartitions
;
146 EFI_SHELL_PROTOCOL
*ShellProtocol
;
148 NumberEfiSystemPartitions
= 0;
150 ShellProtocol
= GetShellProtocol ();
151 if (ShellProtocol
== NULL
) {
152 Print (L
"Get Shell Protocol Fail\n");;
156 Print (L
"EFI System Partition list:\n");
158 gBS
->LocateHandleBuffer (
160 &gEfiSimpleFileSystemProtocolGuid
,
162 &NumberSimpleFileSystemHandles
,
163 &SimpleFileSystemHandles
166 for (Index
= 0; Index
< NumberSimpleFileSystemHandles
; Index
++) {
167 DevicePath
= DevicePathFromHandle (SimpleFileSystemHandles
[Index
]);
168 if (IsEfiSysPartitionDevicePath (DevicePath
)) {
169 NumberEfiSystemPartitions
++;
170 Print(L
" %s\n %s\n", ShellProtocol
->GetMapFromDevicePath (&DevicePath
), ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
));
174 if (NumberEfiSystemPartitions
== 0) {
175 Print(L
" No ESP found.\n");
180 Check if capsule is provisioned.
182 @retval TRUE Capsule is provisioned previously.
183 @retval FALSE No capsule is provisioned.
187 IsCapsuleProvisioned (
196 DataSize
= sizeof(UINT64
);
197 Status
= gRT
->GetVariable (
199 &gEfiGlobalVariableGuid
,
204 if (!EFI_ERROR (Status
) &&
205 (OsIndication
& EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
) != 0) {
213 Get one active Efi System Partition.
215 @param[out] FsDevicePath The device path of Fs
216 @param[out] Fs The file system within EfiSysPartition
218 @retval EFI_SUCCESS Get file system successfully
219 @retval EFI_NOT_FOUND No valid file system found
224 OUT EFI_DEVICE_PATH_PROTOCOL
**FsDevicePath
,
225 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
228 EFI_HANDLE
*SimpleFileSystemHandles
;
229 UINTN NumberSimpleFileSystemHandles
;
231 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
234 Status
= gBS
->LocateHandleBuffer (
236 &gEfiSimpleFileSystemProtocolGuid
,
238 &NumberSimpleFileSystemHandles
,
239 &SimpleFileSystemHandles
242 if (EFI_ERROR (Status
)) {
243 return EFI_NOT_FOUND
;
246 for (Index
= 0; Index
< NumberSimpleFileSystemHandles
; Index
++) {
247 DevicePath
= DevicePathFromHandle (SimpleFileSystemHandles
[Index
]);
248 if (IsEfiSysPartitionDevicePath (DevicePath
)) {
249 Status
= gBS
->HandleProtocol (SimpleFileSystemHandles
[Index
], &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)Fs
);
250 if (!EFI_ERROR (Status
)) {
251 *FsDevicePath
= DevicePath
;
257 return EFI_NOT_FOUND
;
261 Check if Active Efi System Partition within GPT is in the device path.
263 @param[in] DevicePath The device path
264 @param[out] FsDevicePath The device path of Fs
265 @param[out] Fs The file system within EfiSysPartition
267 @retval EFI_SUCCESS Get file system successfully
268 @retval EFI_NOT_FOUND No valid file system found
269 @retval others Get file system failed
273 GetEfiSysPartitionFromDevPath (
274 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
275 OUT EFI_DEVICE_PATH_PROTOCOL
**FsDevicePath
,
276 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
280 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
281 HARDDRIVE_DEVICE_PATH
*Hd
;
285 // Check if the device path contains GPT node
287 TempDevicePath
= DevicePath
;
288 while (!IsDevicePathEnd (TempDevicePath
)) {
289 if ((DevicePathType (TempDevicePath
) == MEDIA_DEVICE_PATH
) &&
290 (DevicePathSubType (TempDevicePath
) == MEDIA_HARDDRIVE_DP
)) {
291 Hd
= (HARDDRIVE_DEVICE_PATH
*)TempDevicePath
;
292 if (Hd
->MBRType
== MBR_TYPE_EFI_PARTITION_TABLE_HEADER
) {
296 TempDevicePath
= NextDevicePathNode (TempDevicePath
);
299 if (!IsDevicePathEnd (TempDevicePath
)) {
301 // Search for EFI system partition protocol on full device path in Boot Option
303 Status
= gBS
->LocateDevicePath (&gEfiPartTypeSystemPartGuid
, &DevicePath
, &Handle
);
306 // Search for simple file system on this handler
308 if (!EFI_ERROR (Status
)) {
309 Status
= gBS
->HandleProtocol (Handle
, &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)Fs
);
310 if (!EFI_ERROR (Status
)) {
311 *FsDevicePath
= DevicePathFromHandle (Handle
);
317 return EFI_NOT_FOUND
;
321 Get SimpleFileSystem from boot option file path.
323 @param[in] DevicePath The file path of boot option
324 @param[out] FullPath The full device path of boot device
325 @param[out] Fs The file system within EfiSysPartition
327 @retval EFI_SUCCESS Get file system successfully
328 @retval EFI_NOT_FOUND No valid file system found
329 @retval others Get file system failed
334 GetEfiSysPartitionFromBootOptionFilePath (
335 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
336 OUT EFI_DEVICE_PATH_PROTOCOL
**FullPath
,
337 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
341 EFI_DEVICE_PATH_PROTOCOL
*CurFullPath
;
342 EFI_DEVICE_PATH_PROTOCOL
*PreFullPath
;
343 EFI_DEVICE_PATH_PROTOCOL
*FsFullPath
;
348 // Try every full device Path generated from bootoption
351 PreFullPath
= CurFullPath
;
352 CurFullPath
= EfiBootManagerGetNextLoadOptionDevicePath (DevicePath
, CurFullPath
);
354 if (PreFullPath
!= NULL
) {
355 FreePool (PreFullPath
);
358 if (CurFullPath
== NULL
) {
360 // No Active EFI system partition is found in BootOption device path
362 Status
= EFI_NOT_FOUND
;
367 CHAR16
*DevicePathStr
;
369 DevicePathStr
= ConvertDevicePathToText (CurFullPath
, TRUE
, TRUE
);
370 if (DevicePathStr
!= NULL
){
371 DEBUG ((DEBUG_INFO
, "Full device path %s\n", DevicePathStr
));
372 FreePool (DevicePathStr
);
376 Status
= GetEfiSysPartitionFromDevPath (CurFullPath
, &FsFullPath
, Fs
);
377 } while (EFI_ERROR (Status
));
380 *FullPath
= FsFullPath
;
383 return EFI_NOT_FOUND
;
388 Get a valid SimpleFileSystem within EFI system partition.
390 @param[in] Map The FS mapping capsule write to
391 @param[out] BootNext The value of BootNext Variable
392 @param[out] Fs The file system within EfiSysPartition
393 @param[out] UpdateBootNext The flag to indicate whether update BootNext Variable
395 @retval EFI_SUCCESS Get FS successfully
396 @retval EFI_NOT_FOUND No valid FS found
397 @retval others Get FS failed
402 GetUpdateFileSystem (
404 OUT UINT16
*BootNext
,
405 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
,
406 OUT BOOLEAN
*UpdateBootNext
410 CHAR16 BootOptionName
[20];
412 CONST EFI_DEVICE_PATH_PROTOCOL
*MappedDevicePath
;
413 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
414 EFI_DEVICE_PATH_PROTOCOL
*FullPath
;
415 UINT16
*BootNextData
;
416 EFI_BOOT_MANAGER_LOAD_OPTION BootNextOption
;
417 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOptionBuffer
;
418 UINTN BootOptionCount
;
419 EFI_SHELL_PROTOCOL
*ShellProtocol
;
420 EFI_BOOT_MANAGER_LOAD_OPTION NewOption
;
422 MappedDevicePath
= NULL
;
423 BootOptionBuffer
= NULL
;
425 ShellProtocol
= GetShellProtocol ();
426 if (ShellProtocol
== NULL
) {
427 Print (L
"Get Shell Protocol Fail\n");;
428 return EFI_NOT_FOUND
;
432 // 1. If Fs is not assigned and there are capsule provisioned before,
433 // Get EFI system partition from BootNext.
435 if (IsCapsuleProvisioned () && Map
== NULL
) {
436 Status
= GetVariable2 (
438 &gEfiGlobalVariableGuid
,
439 (VOID
**)&BootNextData
,
442 if (EFI_ERROR (Status
) || BootNextData
== NULL
) {
443 Print (L
"Get Boot Next Data Fail. Status = %r\n", Status
);
444 return EFI_NOT_FOUND
;
446 UnicodeSPrint (BootOptionName
, sizeof (BootOptionName
), L
"Boot%04x", *BootNextData
);
447 Status
= EfiBootManagerVariableToLoadOption (BootOptionName
, &BootNextOption
);
448 if (!EFI_ERROR (Status
)) {
449 DevicePath
= BootNextOption
.FilePath
;
450 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
451 if (!EFI_ERROR (Status
)) {
452 *UpdateBootNext
= FALSE
;
453 Print(L
"Get EFI system partition from BootNext : %s\n", BootNextOption
.Description
);
454 Print(L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
462 // Check if Map is valid.
465 MappedDevicePath
= ShellProtocol
->GetDevicePathFromMap (Map
);
466 if (MappedDevicePath
== NULL
) {
467 Print(L
"'%s' is not a valid mapping.\n", Map
);
468 return EFI_INVALID_PARAMETER
;
469 } else if (!IsEfiSysPartitionDevicePath (DuplicateDevicePath (MappedDevicePath
))) {
470 Print(L
"'%s' is not a EFI System Partition.\n", Map
);
471 return EFI_INVALID_PARAMETER
;
476 // 2. Get EFI system partition form boot options.
478 BootOptionBuffer
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
479 if ( (BootOptionBuffer
== NULL
) ||
480 (BootOptionCount
== 0 && Map
== NULL
)
482 return EFI_NOT_FOUND
;
485 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
487 // Get the boot option from the link list
489 DevicePath
= BootOptionBuffer
[Index
].FilePath
;
492 // Skip inactive or legacy boot options
494 if ((BootOptionBuffer
[Index
].Attributes
& LOAD_OPTION_ACTIVE
) == 0 ||
495 DevicePathType (DevicePath
) == BBS_DEVICE_PATH
) {
500 CHAR16
*DevicePathStr
;
502 DevicePathStr
= ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
);
503 if (DevicePathStr
!= NULL
){
504 DEBUG ((DEBUG_INFO
, "Try BootOption %s\n", DevicePathStr
));
505 FreePool (DevicePathStr
);
507 DEBUG ((DEBUG_INFO
, "DevicePathToStr failed\n"));
511 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
512 if (!EFI_ERROR (Status
)) {
514 *BootNext
= (UINT16
) BootOptionBuffer
[Index
].OptionNumber
;
515 *UpdateBootNext
= TRUE
;
516 Print (L
"Found EFI system partition on Boot%04x: %s\n", *BootNext
, BootOptionBuffer
[Index
].Description
);
517 Print (L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
521 if (StrnCmp (Map
, ShellProtocol
->GetMapFromDevicePath (&FullPath
), StrLen (Map
)) == 0) {
522 *BootNext
= (UINT16
) BootOptionBuffer
[Index
].OptionNumber
;
523 *UpdateBootNext
= TRUE
;
524 Print (L
"Found Boot Option on %s : %s\n", Map
, BootOptionBuffer
[Index
].Description
);
531 // 3. If no ESP is found on boot option, try to find a ESP and create boot option for it.
535 // If map is assigned, try to get ESP from mapped Fs.
537 DevicePath
= DuplicateDevicePath (MappedDevicePath
);
538 Status
= GetEfiSysPartitionFromDevPath (DevicePath
, &FullPath
, Fs
);
539 if (EFI_ERROR (Status
)) {
540 Print (L
"Error: Cannot get EFI system partiion from '%s' - %r\n", Map
, Status
);
541 return EFI_NOT_FOUND
;
543 Print (L
"Warning: Cannot find Boot Option on '%s'!\n", Map
);
545 Status
= GetEfiSysPartition (&DevicePath
, Fs
);
546 if (EFI_ERROR (Status
)) {
547 Print (L
"Error: Cannot find a EFI system partition!\n");
548 return EFI_NOT_FOUND
;
552 Print (L
"Create Boot option for capsule on disk:\n");
553 Status
= EfiBootManagerInitializeLoadOption (
555 LoadOptionNumberUnassigned
,
558 L
"UEFI Capsule On Disk",
560 (UINT8
*) &mCapsuleOnDiskBootOptionGuid
,
563 if (!EFI_ERROR (Status
)) {
564 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, (UINTN
) -1); {
565 if (!EFI_ERROR (Status
)) {
566 *UpdateBootNext
= TRUE
;
567 *BootNext
= (UINT16
) NewOption
.OptionNumber
;
568 Print (L
" Boot%04x: %s\n", *BootNext
, ConvertDevicePathToText(DevicePath
, TRUE
, TRUE
));
574 Print (L
"ERROR: Cannot create boot option! - %r\n", Status
);
576 return EFI_NOT_FOUND
;
580 Write files to a given SimpleFileSystem.
582 @param[in] Buffer The buffer array
583 @param[in] BufferSize The buffer size array
584 @param[in] FileName The file name array
585 @param[in] BufferNum The buffer number
586 @param[in] Fs The SimpleFileSystem handle to be written
588 @retval EFI_SUCCESS Write file successfully
589 @retval EFI_NOT_FOUND SFS protocol not found
590 @retval others Write file failed
596 IN UINTN
*BufferSize
,
597 IN CHAR16
**FileName
,
599 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
604 EFI_FILE
*FileHandle
;
605 EFI_FILE_PROTOCOL
*DirHandle
;
616 // Open Root from SFS
618 Status
= Fs
->OpenVolume (Fs
, &Root
);
619 if (EFI_ERROR (Status
)) {
620 Print (L
"Cannot open volume. Status = %r\n", Status
);
621 return EFI_NOT_FOUND
;
625 // Ensure that efi and updatecapsule directories exist
627 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
628 if (EFI_ERROR (Status
)) {
629 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
630 if (EFI_ERROR (Status
)) {
631 Print(L
"Unable to create %s directory\n", L
"\\EFI");
632 return EFI_NOT_FOUND
;
635 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
636 if (EFI_ERROR (Status
)) {
637 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
638 if (EFI_ERROR (Status
)) {
639 Print(L
"Unable to create %s directory\n", EFI_CAPSULE_FILE_DIRECTORY
);
640 return EFI_NOT_FOUND
;
644 for (Index
= 0; Index
< BufferNum
; Index
++) {
648 // Open UpdateCapsule file
650 Status
= DirHandle
->Open (DirHandle
, &FileHandle
, FileName
[Index
], EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
, 0);
651 if (EFI_ERROR (Status
)) {
652 Print (L
"Unable to create %s file\n", FileName
[Index
]);
653 return EFI_NOT_FOUND
;
657 // Empty the file contents
659 Status
= FileHandleGetSize (FileHandle
, &FileInfo
);
660 if (EFI_ERROR (Status
)) {
661 FileHandleClose (FileHandle
);
662 Print (L
"Error Reading %s\n", FileName
[Index
]);
663 return EFI_DEVICE_ERROR
;
667 // If the file size is already 0, then it has been empty.
671 // Set the file size to 0.
674 Status
= FileHandleSetSize (FileHandle
, FileInfo
);
675 if (EFI_ERROR (Status
)) {
676 Print (L
"Error Deleting %s\n", FileName
[Index
]);
677 FileHandleClose (FileHandle
);
683 // Write Filebuffer to file
685 Filebuffer
= Buffer
[Index
];
686 FileSize
= BufferSize
[Index
];
687 Status
= FileHandleWrite (FileHandle
, &FileSize
, Filebuffer
);
688 if (EFI_ERROR (Status
)) {
689 Print (L
"Unable to write Capsule Update to %s, Status = %r\n", FileName
[Index
], Status
);
690 return EFI_NOT_FOUND
;
693 Print (L
"Succeed to write %s\n", FileName
[Index
]);
694 FileHandleClose (FileHandle
);
701 Set capsule status variable.
703 @param[in] SetCap Set or clear the capsule flag.
705 @retval EFI_SUCCESS Succeed to set SetCap variable.
706 @retval others Fail to set the variable.
710 SetCapsuleStatusVariable (
719 DataSize
= sizeof(UINT64
);
720 Status
= gRT
->GetVariable (
722 &gEfiGlobalVariableGuid
,
727 if (EFI_ERROR (Status
)) {
731 OsIndication
|= ((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
734 OsIndication
&= ~((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
736 Status
= gRT
->SetVariable (
738 &gEfiGlobalVariableGuid
,
739 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
748 Process Capsule On Disk.
750 @param[in] CapsuleBuffer An array of pointer to capsule images
751 @param[in] CapsuleBufferSize An array of UINTN to capsule images size
752 @param[in] FilePath An array of capsule images file path
753 @param[in] Map File system mapping string
754 @param[in] CapsuleNum The count of capsule images
756 @retval EFI_SUCCESS Capsule on disk success.
757 @retval others Capsule on disk fail.
761 ProcessCapsuleOnDisk (
762 IN VOID
**CapsuleBuffer
,
763 IN UINTN
*CapsuleBufferSize
,
764 IN CHAR16
**FilePath
,
771 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
;
772 BOOLEAN UpdateBootNext
;
775 // Get a valid file system from boot path
779 Status
= GetUpdateFileSystem (Map
, &BootNext
, &Fs
, &UpdateBootNext
);
780 if (EFI_ERROR (Status
)) {
781 Print (L
"CapsuleApp: cannot find a valid file system on boot devies. Status = %r\n", Status
);
786 // Copy capsule image to '\efi\UpdateCapsule\'
788 Status
= WriteUpdateFile (CapsuleBuffer
, CapsuleBufferSize
, FilePath
, CapsuleNum
, Fs
);
789 if (EFI_ERROR (Status
)) {
790 Print (L
"CapsuleApp: capsule image could not be copied for update.\n");
795 // Set variable then reset
797 Status
= SetCapsuleStatusVariable (TRUE
);
798 if (EFI_ERROR (Status
)) {
799 Print (L
"CapsuleApp: unable to set OSIndication variable.\n");
803 if (UpdateBootNext
) {
804 Status
= gRT
->SetVariable (
806 &gEfiGlobalVariableGuid
,
807 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
811 if (EFI_ERROR (Status
)){
812 Print (L
"CapsuleApp: unable to set BootNext variable.\n");