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 "CapsuleApp.h"
11 EFI_GUID mCapsuleOnDiskBootOptionGuid
= {
12 0x4CC29BB7, 0x2413, 0x40A2, { 0xB0, 0x6D, 0x25, 0x3E, 0x37, 0x10, 0xF5, 0x32 }
16 Get file name from file path.
18 @param FilePath File path.
20 @return Pointer to file name.
29 EFI_SHELL_PROTOCOL
*ShellProtocol
;
30 SHELL_FILE_HANDLE Handle
;
31 EFI_FILE_INFO
*FileInfo
;
33 ShellProtocol
= GetShellProtocol ();
34 if (ShellProtocol
== NULL
) {
39 // Open file by FileName.
41 Status
= ShellProtocol
->OpenFileByName (
46 if (EFI_ERROR (Status
)) {
51 // Get file name from EFI_FILE_INFO.
53 FileInfo
= ShellProtocol
->GetFileInfo (Handle
);
54 ShellProtocol
->CloseFile (Handle
);
55 if (FileInfo
== NULL
) {
59 return FileInfo
->FileName
;
63 Check if the device path is EFI system Partition.
65 @param DevicePath The ESP device path.
67 @retval TRUE DevicePath is a device path for ESP.
68 @retval FALSE DevicePath is not a device path for ESP.
72 IsEfiSysPartitionDevicePath (
73 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
77 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
78 HARDDRIVE_DEVICE_PATH
*Hd
;
82 // Check if the device path contains GPT node
84 TempDevicePath
= DevicePath
;
86 while (!IsDevicePathEnd (TempDevicePath
)) {
87 if ((DevicePathType (TempDevicePath
) == MEDIA_DEVICE_PATH
) &&
88 (DevicePathSubType (TempDevicePath
) == MEDIA_HARDDRIVE_DP
))
90 Hd
= (HARDDRIVE_DEVICE_PATH
*)TempDevicePath
;
91 if (Hd
->MBRType
== MBR_TYPE_EFI_PARTITION_TABLE_HEADER
) {
96 TempDevicePath
= NextDevicePathNode (TempDevicePath
);
99 if (!IsDevicePathEnd (TempDevicePath
)) {
101 // Search for EFI system partition protocol on full device path in Boot Option
103 Status
= gBS
->LocateDevicePath (&gEfiPartTypeSystemPartGuid
, &DevicePath
, &Handle
);
104 return EFI_ERROR (Status
) ? FALSE
: TRUE
;
111 Dump all EFI System Partition.
115 DumpAllEfiSysPartition (
119 EFI_HANDLE
*SimpleFileSystemHandles
;
120 UINTN NumberSimpleFileSystemHandles
;
122 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
123 UINTN NumberEfiSystemPartitions
;
124 EFI_SHELL_PROTOCOL
*ShellProtocol
;
126 NumberEfiSystemPartitions
= 0;
128 ShellProtocol
= GetShellProtocol ();
129 if (ShellProtocol
== NULL
) {
130 Print (L
"Get Shell Protocol Fail\n");
134 Print (L
"EFI System Partition list:\n");
136 gBS
->LocateHandleBuffer (
138 &gEfiSimpleFileSystemProtocolGuid
,
140 &NumberSimpleFileSystemHandles
,
141 &SimpleFileSystemHandles
144 for (Index
= 0; Index
< NumberSimpleFileSystemHandles
; Index
++) {
145 DevicePath
= DevicePathFromHandle (SimpleFileSystemHandles
[Index
]);
146 if (IsEfiSysPartitionDevicePath (DevicePath
)) {
147 NumberEfiSystemPartitions
++;
148 Print (L
" %s\n %s\n", ShellProtocol
->GetMapFromDevicePath (&DevicePath
), ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
));
152 if (NumberEfiSystemPartitions
== 0) {
153 Print (L
" No ESP found.\n");
158 Check if capsule is provisioned.
160 @retval TRUE Capsule is provisioned previously.
161 @retval FALSE No capsule is provisioned.
165 IsCapsuleProvisioned (
174 DataSize
= sizeof (UINT64
);
175 Status
= gRT
->GetVariable (
177 &gEfiGlobalVariableGuid
,
182 if (!EFI_ERROR (Status
) &&
183 ((OsIndication
& EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
) != 0))
192 Get one active Efi System Partition.
194 @param[out] FsDevicePath The device path of Fs
195 @param[out] Fs The file system within EfiSysPartition
197 @retval EFI_SUCCESS Get file system successfully
198 @retval EFI_NOT_FOUND No valid file system found
203 OUT EFI_DEVICE_PATH_PROTOCOL
**FsDevicePath
,
204 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
207 EFI_HANDLE
*SimpleFileSystemHandles
;
208 UINTN NumberSimpleFileSystemHandles
;
210 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
213 Status
= gBS
->LocateHandleBuffer (
215 &gEfiSimpleFileSystemProtocolGuid
,
217 &NumberSimpleFileSystemHandles
,
218 &SimpleFileSystemHandles
221 if (EFI_ERROR (Status
)) {
222 return EFI_NOT_FOUND
;
225 for (Index
= 0; Index
< NumberSimpleFileSystemHandles
; Index
++) {
226 DevicePath
= DevicePathFromHandle (SimpleFileSystemHandles
[Index
]);
227 if (IsEfiSysPartitionDevicePath (DevicePath
)) {
228 Status
= gBS
->HandleProtocol (SimpleFileSystemHandles
[Index
], &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)Fs
);
229 if (!EFI_ERROR (Status
)) {
230 *FsDevicePath
= DevicePath
;
236 return EFI_NOT_FOUND
;
240 Check if Active Efi System Partition within GPT is in the device path.
242 @param[in] DevicePath The device path
243 @param[out] FsDevicePath The device path of Fs
244 @param[out] Fs The file system within EfiSysPartition
246 @retval EFI_SUCCESS Get file system successfully
247 @retval EFI_NOT_FOUND No valid file system found
248 @retval others Get file system failed
252 GetEfiSysPartitionFromDevPath (
253 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
254 OUT EFI_DEVICE_PATH_PROTOCOL
**FsDevicePath
,
255 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
259 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
260 HARDDRIVE_DEVICE_PATH
*Hd
;
264 // Check if the device path contains GPT node
266 TempDevicePath
= DevicePath
;
267 while (!IsDevicePathEnd (TempDevicePath
)) {
268 if ((DevicePathType (TempDevicePath
) == MEDIA_DEVICE_PATH
) &&
269 (DevicePathSubType (TempDevicePath
) == MEDIA_HARDDRIVE_DP
))
271 Hd
= (HARDDRIVE_DEVICE_PATH
*)TempDevicePath
;
272 if (Hd
->MBRType
== MBR_TYPE_EFI_PARTITION_TABLE_HEADER
) {
277 TempDevicePath
= NextDevicePathNode (TempDevicePath
);
280 if (!IsDevicePathEnd (TempDevicePath
)) {
282 // Search for EFI system partition protocol on full device path in Boot Option
284 Status
= gBS
->LocateDevicePath (&gEfiPartTypeSystemPartGuid
, &DevicePath
, &Handle
);
287 // Search for simple file system on this handler
289 if (!EFI_ERROR (Status
)) {
290 Status
= gBS
->HandleProtocol (Handle
, &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)Fs
);
291 if (!EFI_ERROR (Status
)) {
292 *FsDevicePath
= DevicePathFromHandle (Handle
);
298 return EFI_NOT_FOUND
;
302 Get SimpleFileSystem from boot option file path.
304 @param[in] DevicePath The file path of boot option
305 @param[out] FullPath The full device path of boot device
306 @param[out] Fs The file system within EfiSysPartition
308 @retval EFI_SUCCESS Get file system successfully
309 @retval EFI_NOT_FOUND No valid file system found
310 @retval others Get file system failed
314 GetEfiSysPartitionFromBootOptionFilePath (
315 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
316 OUT EFI_DEVICE_PATH_PROTOCOL
**FullPath
,
317 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
321 EFI_DEVICE_PATH_PROTOCOL
*CurFullPath
;
322 EFI_DEVICE_PATH_PROTOCOL
*PreFullPath
;
323 EFI_DEVICE_PATH_PROTOCOL
*FsFullPath
;
328 // Try every full device Path generated from bootoption
331 PreFullPath
= CurFullPath
;
332 CurFullPath
= EfiBootManagerGetNextLoadOptionDevicePath (DevicePath
, CurFullPath
);
334 if (PreFullPath
!= NULL
) {
335 FreePool (PreFullPath
);
338 if (CurFullPath
== NULL
) {
340 // No Active EFI system partition is found in BootOption device path
342 Status
= EFI_NOT_FOUND
;
347 CHAR16
*DevicePathStr
;
349 DevicePathStr
= ConvertDevicePathToText (CurFullPath
, TRUE
, TRUE
);
350 if (DevicePathStr
!= NULL
) {
351 DEBUG ((DEBUG_INFO
, "Full device path %s\n", DevicePathStr
));
352 FreePool (DevicePathStr
);
357 Status
= GetEfiSysPartitionFromDevPath (CurFullPath
, &FsFullPath
, Fs
);
358 } while (EFI_ERROR (Status
));
361 *FullPath
= FsFullPath
;
364 return EFI_NOT_FOUND
;
369 Get a valid SimpleFileSystem within EFI system partition.
371 @param[in] Map The FS mapping capsule write to
372 @param[out] BootNext The value of BootNext Variable
373 @param[out] Fs The file system within EfiSysPartition
374 @param[out] UpdateBootNext The flag to indicate whether update BootNext Variable
376 @retval EFI_SUCCESS Get FS successfully
377 @retval EFI_NOT_FOUND No valid FS found
378 @retval others Get FS failed
382 GetUpdateFileSystem (
384 OUT UINT16
*BootNext
,
385 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
,
386 OUT BOOLEAN
*UpdateBootNext
390 CHAR16 BootOptionName
[20];
392 CONST EFI_DEVICE_PATH_PROTOCOL
*MappedDevicePath
;
393 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
394 EFI_DEVICE_PATH_PROTOCOL
*FullPath
;
395 UINT16
*BootNextData
;
396 EFI_BOOT_MANAGER_LOAD_OPTION BootNextOption
;
397 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOptionBuffer
;
398 UINTN BootOptionCount
;
399 EFI_SHELL_PROTOCOL
*ShellProtocol
;
400 EFI_BOOT_MANAGER_LOAD_OPTION NewOption
;
402 MappedDevicePath
= NULL
;
403 BootOptionBuffer
= NULL
;
405 ShellProtocol
= GetShellProtocol ();
406 if (ShellProtocol
== NULL
) {
407 Print (L
"Get Shell Protocol Fail\n");
408 return EFI_NOT_FOUND
;
412 // 1. If Fs is not assigned and there are capsule provisioned before,
413 // Get EFI system partition from BootNext.
415 if (IsCapsuleProvisioned () && (Map
== NULL
)) {
416 Status
= GetVariable2 (
418 &gEfiGlobalVariableGuid
,
419 (VOID
**)&BootNextData
,
422 if (EFI_ERROR (Status
) || (BootNextData
== NULL
)) {
423 Print (L
"Get Boot Next Data Fail. Status = %r\n", Status
);
424 return EFI_NOT_FOUND
;
426 UnicodeSPrint (BootOptionName
, sizeof (BootOptionName
), L
"Boot%04x", *BootNextData
);
427 Status
= EfiBootManagerVariableToLoadOption (BootOptionName
, &BootNextOption
);
428 if (!EFI_ERROR (Status
)) {
429 DevicePath
= BootNextOption
.FilePath
;
430 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
431 if (!EFI_ERROR (Status
)) {
432 *UpdateBootNext
= FALSE
;
433 Print (L
"Get EFI system partition from BootNext : %s\n", BootNextOption
.Description
);
434 Print (L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
442 // Check if Map is valid.
445 MappedDevicePath
= ShellProtocol
->GetDevicePathFromMap (Map
);
446 if (MappedDevicePath
== NULL
) {
447 Print (L
"'%s' is not a valid mapping.\n", Map
);
448 return EFI_INVALID_PARAMETER
;
449 } else if (!IsEfiSysPartitionDevicePath (DuplicateDevicePath (MappedDevicePath
))) {
450 Print (L
"'%s' is not a EFI System Partition.\n", Map
);
451 return EFI_INVALID_PARAMETER
;
456 // 2. Get EFI system partition form boot options.
458 BootOptionBuffer
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
459 if ((BootOptionBuffer
== NULL
) ||
460 ((BootOptionCount
== 0) && (Map
== NULL
))
463 return EFI_NOT_FOUND
;
466 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
468 // Get the boot option from the link list
470 DevicePath
= BootOptionBuffer
[Index
].FilePath
;
473 // Skip inactive or legacy boot options
475 if (((BootOptionBuffer
[Index
].Attributes
& LOAD_OPTION_ACTIVE
) == 0) ||
476 (DevicePathType (DevicePath
) == BBS_DEVICE_PATH
))
482 CHAR16
*DevicePathStr
;
484 DevicePathStr
= ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
);
485 if (DevicePathStr
!= NULL
) {
486 DEBUG ((DEBUG_INFO
, "Try BootOption %s\n", DevicePathStr
));
487 FreePool (DevicePathStr
);
489 DEBUG ((DEBUG_INFO
, "DevicePathToStr failed\n"));
494 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
495 if (!EFI_ERROR (Status
)) {
497 *BootNext
= (UINT16
)BootOptionBuffer
[Index
].OptionNumber
;
498 *UpdateBootNext
= TRUE
;
499 Print (L
"Found EFI system partition on Boot%04x: %s\n", *BootNext
, BootOptionBuffer
[Index
].Description
);
500 Print (L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
504 if (StrnCmp (Map
, ShellProtocol
->GetMapFromDevicePath (&FullPath
), StrLen (Map
)) == 0) {
505 *BootNext
= (UINT16
)BootOptionBuffer
[Index
].OptionNumber
;
506 *UpdateBootNext
= TRUE
;
507 Print (L
"Found Boot Option on %s : %s\n", Map
, BootOptionBuffer
[Index
].Description
);
514 // 3. If no ESP is found on boot option, try to find a ESP and create boot option for it.
518 // If map is assigned, try to get ESP from mapped Fs.
520 DevicePath
= DuplicateDevicePath (MappedDevicePath
);
521 Status
= GetEfiSysPartitionFromDevPath (DevicePath
, &FullPath
, Fs
);
522 if (EFI_ERROR (Status
)) {
523 Print (L
"Error: Cannot get EFI system partition from '%s' - %r\n", Map
, Status
);
524 return EFI_NOT_FOUND
;
527 Print (L
"Warning: Cannot find Boot Option on '%s'!\n", Map
);
529 Status
= GetEfiSysPartition (&DevicePath
, Fs
);
530 if (EFI_ERROR (Status
)) {
531 Print (L
"Error: Cannot find a EFI system partition!\n");
532 return EFI_NOT_FOUND
;
536 Print (L
"Create Boot option for capsule on disk:\n");
537 Status
= EfiBootManagerInitializeLoadOption (
539 LoadOptionNumberUnassigned
,
542 L
"UEFI Capsule On Disk",
544 (UINT8
*)&mCapsuleOnDiskBootOptionGuid
,
547 if (!EFI_ERROR (Status
)) {
548 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, (UINTN
)-1);
550 if (!EFI_ERROR (Status
)) {
551 *UpdateBootNext
= TRUE
;
552 *BootNext
= (UINT16
)NewOption
.OptionNumber
;
553 Print (L
" Boot%04x: %s\n", *BootNext
, ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
));
559 Print (L
"ERROR: Cannot create boot option! - %r\n", Status
);
561 return EFI_NOT_FOUND
;
565 Write files to a given SimpleFileSystem.
567 @param[in] Buffer The buffer array
568 @param[in] BufferSize The buffer size array
569 @param[in] FileName The file name array
570 @param[in] BufferNum The buffer number
571 @param[in] Fs The SimpleFileSystem handle to be written
573 @retval EFI_SUCCESS Write file successfully
574 @retval EFI_NOT_FOUND SFS protocol not found
575 @retval others Write file failed
581 IN UINTN
*BufferSize
,
582 IN CHAR16
**FileName
,
584 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
589 EFI_FILE
*FileHandle
;
590 EFI_FILE_PROTOCOL
*DirHandle
;
601 // Open Root from SFS
603 Status
= Fs
->OpenVolume (Fs
, &Root
);
604 if (EFI_ERROR (Status
)) {
605 Print (L
"Cannot open volume. Status = %r\n", Status
);
606 return EFI_NOT_FOUND
;
610 // Ensure that efi and updatecapsule directories exist
612 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
613 if (EFI_ERROR (Status
)) {
614 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
615 if (EFI_ERROR (Status
)) {
616 Print (L
"Unable to create %s directory\n", L
"\\EFI");
617 return EFI_NOT_FOUND
;
621 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
622 if (EFI_ERROR (Status
)) {
623 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
624 if (EFI_ERROR (Status
)) {
625 Print (L
"Unable to create %s directory\n", EFI_CAPSULE_FILE_DIRECTORY
);
626 return EFI_NOT_FOUND
;
630 for (Index
= 0; Index
< BufferNum
; Index
++) {
634 // Open UpdateCapsule file
636 Status
= DirHandle
->Open (DirHandle
, &FileHandle
, FileName
[Index
], EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
, 0);
637 if (EFI_ERROR (Status
)) {
638 Print (L
"Unable to create %s file\n", FileName
[Index
]);
639 return EFI_NOT_FOUND
;
643 // Empty the file contents
645 Status
= FileHandleGetSize (FileHandle
, &FileInfo
);
646 if (EFI_ERROR (Status
)) {
647 FileHandleClose (FileHandle
);
648 Print (L
"Error Reading %s\n", FileName
[Index
]);
649 return EFI_DEVICE_ERROR
;
653 // If the file size is already 0, then it has been empty.
657 // Set the file size to 0.
660 Status
= FileHandleSetSize (FileHandle
, FileInfo
);
661 if (EFI_ERROR (Status
)) {
662 Print (L
"Error Deleting %s\n", FileName
[Index
]);
663 FileHandleClose (FileHandle
);
669 // Write Filebuffer to file
671 Filebuffer
= Buffer
[Index
];
672 FileSize
= BufferSize
[Index
];
673 Status
= FileHandleWrite (FileHandle
, &FileSize
, Filebuffer
);
674 if (EFI_ERROR (Status
)) {
675 Print (L
"Unable to write Capsule Update to %s, Status = %r\n", FileName
[Index
], Status
);
676 return EFI_NOT_FOUND
;
679 Print (L
"Succeed to write %s\n", FileName
[Index
]);
680 FileHandleClose (FileHandle
);
687 Set capsule status variable.
689 @param[in] SetCap Set or clear the capsule flag.
691 @retval EFI_SUCCESS Succeed to set SetCap variable.
692 @retval others Fail to set the variable.
696 SetCapsuleStatusVariable (
705 DataSize
= sizeof (UINT64
);
706 Status
= gRT
->GetVariable (
708 &gEfiGlobalVariableGuid
,
713 if (EFI_ERROR (Status
)) {
718 OsIndication
|= ((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
720 OsIndication
&= ~((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
723 Status
= gRT
->SetVariable (
725 &gEfiGlobalVariableGuid
,
726 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
735 Check if Capsule On Disk is supported.
737 @retval TRUE Capsule On Disk is supported.
738 @retval FALSE Capsule On Disk is not supported.
742 IsCapsuleOnDiskSupported (
747 UINT64 OsIndicationsSupported
;
750 DataSize
= sizeof (UINT64
);
751 Status
= gRT
->GetVariable (
752 L
"OsIndicationsSupported",
753 &gEfiGlobalVariableGuid
,
756 &OsIndicationsSupported
758 if (EFI_ERROR (Status
)) {
762 if ((OsIndicationsSupported
& EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
) != 0) {
770 Process Capsule On Disk.
772 @param[in] CapsuleBuffer An array of pointer to capsule images
773 @param[in] CapsuleBufferSize An array of UINTN to capsule images size
774 @param[in] FilePath An array of capsule images file path
775 @param[in] Map File system mapping string
776 @param[in] CapsuleNum The count of capsule images
778 @retval EFI_SUCCESS Capsule on disk success.
779 @retval others Capsule on disk fail.
783 ProcessCapsuleOnDisk (
784 IN VOID
**CapsuleBuffer
,
785 IN UINTN
*CapsuleBufferSize
,
786 IN CHAR16
**FilePath
,
793 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
;
794 BOOLEAN UpdateBootNext
;
795 CHAR16
*FileName
[MAX_CAPSULE_NUM
];
799 // Check if Capsule On Disk is supported
801 if (!IsCapsuleOnDiskSupported ()) {
802 Print (L
"CapsuleApp: Capsule On Disk is not supported.\n");
803 return EFI_UNSUPPORTED
;
807 // Get a valid file system from boot path
811 Status
= GetUpdateFileSystem (Map
, &BootNext
, &Fs
, &UpdateBootNext
);
812 if (EFI_ERROR (Status
)) {
813 Print (L
"CapsuleApp: cannot find a valid file system on boot devices. Status = %r\n", Status
);
818 // Get file name from file path
820 for (Index
= 0; Index
< CapsuleNum
; Index
++) {
821 FileName
[Index
] = GetFileNameFromPath (FilePath
[Index
]);
825 // Copy capsule image to '\efi\UpdateCapsule\'
827 Status
= WriteUpdateFile (CapsuleBuffer
, CapsuleBufferSize
, FileName
, CapsuleNum
, Fs
);
828 if (EFI_ERROR (Status
)) {
829 Print (L
"CapsuleApp: capsule image could not be copied for update.\n");
834 // Set variable then reset
836 Status
= SetCapsuleStatusVariable (TRUE
);
837 if (EFI_ERROR (Status
)) {
838 Print (L
"CapsuleApp: unable to set OSIndication variable.\n");
842 if (UpdateBootNext
) {
843 Status
= gRT
->SetVariable (
845 &gEfiGlobalVariableGuid
,
846 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
850 if (EFI_ERROR (Status
)) {
851 Print (L
"CapsuleApp: unable to set BootNext variable.\n");