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
= { 0x4CC29BB7, 0x2413, 0x40A2, { 0xB0, 0x6D, 0x25, 0x3E, 0x37, 0x10, 0xF5, 0x32 } };
14 Get file name from file path.
16 @param FilePath File path.
18 @return Pointer to file name.
27 EFI_SHELL_PROTOCOL
*ShellProtocol
;
28 SHELL_FILE_HANDLE Handle
;
29 EFI_FILE_INFO
*FileInfo
;
31 ShellProtocol
= GetShellProtocol ();
32 if (ShellProtocol
== NULL
) {
37 // Open file by FileName.
39 Status
= ShellProtocol
->OpenFileByName (
44 if (EFI_ERROR (Status
)) {
49 // Get file name from EFI_FILE_INFO.
51 FileInfo
= ShellProtocol
->GetFileInfo (Handle
);
52 ShellProtocol
->CloseFile (Handle
);
53 if (FileInfo
== NULL
) {
57 return FileInfo
->FileName
;
61 Check if the device path is EFI system Partition.
63 @param DevicePath The ESP device path.
65 @retval TRUE DevicePath is a device path for ESP.
66 @retval FALSE DevicePath is not a device path for ESP.
70 IsEfiSysPartitionDevicePath (
71 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
75 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
76 HARDDRIVE_DEVICE_PATH
*Hd
;
80 // Check if the device path contains GPT node
82 TempDevicePath
= DevicePath
;
84 while (!IsDevicePathEnd (TempDevicePath
)) {
85 if ((DevicePathType (TempDevicePath
) == MEDIA_DEVICE_PATH
) &&
86 (DevicePathSubType (TempDevicePath
) == MEDIA_HARDDRIVE_DP
)) {
87 Hd
= (HARDDRIVE_DEVICE_PATH
*)TempDevicePath
;
88 if (Hd
->MBRType
== MBR_TYPE_EFI_PARTITION_TABLE_HEADER
) {
92 TempDevicePath
= NextDevicePathNode (TempDevicePath
);
95 if (!IsDevicePathEnd (TempDevicePath
)) {
97 // Search for EFI system partition protocol on full device path in Boot Option
99 Status
= gBS
->LocateDevicePath (&gEfiPartTypeSystemPartGuid
, &DevicePath
, &Handle
);
100 return EFI_ERROR (Status
) ? FALSE
: TRUE
;
107 Dump all EFI System Partition.
111 DumpAllEfiSysPartition (
115 EFI_HANDLE
*SimpleFileSystemHandles
;
116 UINTN NumberSimpleFileSystemHandles
;
118 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
119 UINTN NumberEfiSystemPartitions
;
120 EFI_SHELL_PROTOCOL
*ShellProtocol
;
122 NumberEfiSystemPartitions
= 0;
124 ShellProtocol
= GetShellProtocol ();
125 if (ShellProtocol
== NULL
) {
126 Print (L
"Get Shell Protocol Fail\n");;
130 Print (L
"EFI System Partition list:\n");
132 gBS
->LocateHandleBuffer (
134 &gEfiSimpleFileSystemProtocolGuid
,
136 &NumberSimpleFileSystemHandles
,
137 &SimpleFileSystemHandles
140 for (Index
= 0; Index
< NumberSimpleFileSystemHandles
; Index
++) {
141 DevicePath
= DevicePathFromHandle (SimpleFileSystemHandles
[Index
]);
142 if (IsEfiSysPartitionDevicePath (DevicePath
)) {
143 NumberEfiSystemPartitions
++;
144 Print(L
" %s\n %s\n", ShellProtocol
->GetMapFromDevicePath (&DevicePath
), ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
));
148 if (NumberEfiSystemPartitions
== 0) {
149 Print(L
" No ESP found.\n");
154 Check if capsule is provisioned.
156 @retval TRUE Capsule is provisioned previously.
157 @retval FALSE No capsule is provisioned.
161 IsCapsuleProvisioned (
170 DataSize
= sizeof(UINT64
);
171 Status
= gRT
->GetVariable (
173 &gEfiGlobalVariableGuid
,
178 if (!EFI_ERROR (Status
) &&
179 (OsIndication
& EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
) != 0) {
187 Get one active Efi System Partition.
189 @param[out] FsDevicePath The device path of Fs
190 @param[out] Fs The file system within EfiSysPartition
192 @retval EFI_SUCCESS Get file system successfully
193 @retval EFI_NOT_FOUND No valid file system found
198 OUT EFI_DEVICE_PATH_PROTOCOL
**FsDevicePath
,
199 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
202 EFI_HANDLE
*SimpleFileSystemHandles
;
203 UINTN NumberSimpleFileSystemHandles
;
205 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
208 Status
= gBS
->LocateHandleBuffer (
210 &gEfiSimpleFileSystemProtocolGuid
,
212 &NumberSimpleFileSystemHandles
,
213 &SimpleFileSystemHandles
216 if (EFI_ERROR (Status
)) {
217 return EFI_NOT_FOUND
;
220 for (Index
= 0; Index
< NumberSimpleFileSystemHandles
; Index
++) {
221 DevicePath
= DevicePathFromHandle (SimpleFileSystemHandles
[Index
]);
222 if (IsEfiSysPartitionDevicePath (DevicePath
)) {
223 Status
= gBS
->HandleProtocol (SimpleFileSystemHandles
[Index
], &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)Fs
);
224 if (!EFI_ERROR (Status
)) {
225 *FsDevicePath
= DevicePath
;
231 return EFI_NOT_FOUND
;
235 Check if Active Efi System Partition within GPT is in the device path.
237 @param[in] DevicePath The device path
238 @param[out] FsDevicePath The device path of Fs
239 @param[out] Fs The file system within EfiSysPartition
241 @retval EFI_SUCCESS Get file system successfully
242 @retval EFI_NOT_FOUND No valid file system found
243 @retval others Get file system failed
247 GetEfiSysPartitionFromDevPath (
248 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
249 OUT EFI_DEVICE_PATH_PROTOCOL
**FsDevicePath
,
250 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
254 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
255 HARDDRIVE_DEVICE_PATH
*Hd
;
259 // Check if the device path contains GPT node
261 TempDevicePath
= DevicePath
;
262 while (!IsDevicePathEnd (TempDevicePath
)) {
263 if ((DevicePathType (TempDevicePath
) == MEDIA_DEVICE_PATH
) &&
264 (DevicePathSubType (TempDevicePath
) == MEDIA_HARDDRIVE_DP
)) {
265 Hd
= (HARDDRIVE_DEVICE_PATH
*)TempDevicePath
;
266 if (Hd
->MBRType
== MBR_TYPE_EFI_PARTITION_TABLE_HEADER
) {
270 TempDevicePath
= NextDevicePathNode (TempDevicePath
);
273 if (!IsDevicePathEnd (TempDevicePath
)) {
275 // Search for EFI system partition protocol on full device path in Boot Option
277 Status
= gBS
->LocateDevicePath (&gEfiPartTypeSystemPartGuid
, &DevicePath
, &Handle
);
280 // Search for simple file system on this handler
282 if (!EFI_ERROR (Status
)) {
283 Status
= gBS
->HandleProtocol (Handle
, &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)Fs
);
284 if (!EFI_ERROR (Status
)) {
285 *FsDevicePath
= DevicePathFromHandle (Handle
);
291 return EFI_NOT_FOUND
;
295 Get SimpleFileSystem from boot option file path.
297 @param[in] DevicePath The file path of boot option
298 @param[out] FullPath The full device path of boot device
299 @param[out] Fs The file system within EfiSysPartition
301 @retval EFI_SUCCESS Get file system successfully
302 @retval EFI_NOT_FOUND No valid file system found
303 @retval others Get file system failed
307 GetEfiSysPartitionFromBootOptionFilePath (
308 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
309 OUT EFI_DEVICE_PATH_PROTOCOL
**FullPath
,
310 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
314 EFI_DEVICE_PATH_PROTOCOL
*CurFullPath
;
315 EFI_DEVICE_PATH_PROTOCOL
*PreFullPath
;
316 EFI_DEVICE_PATH_PROTOCOL
*FsFullPath
;
321 // Try every full device Path generated from bootoption
324 PreFullPath
= CurFullPath
;
325 CurFullPath
= EfiBootManagerGetNextLoadOptionDevicePath (DevicePath
, CurFullPath
);
327 if (PreFullPath
!= NULL
) {
328 FreePool (PreFullPath
);
331 if (CurFullPath
== NULL
) {
333 // No Active EFI system partition is found in BootOption device path
335 Status
= EFI_NOT_FOUND
;
340 CHAR16
*DevicePathStr
;
342 DevicePathStr
= ConvertDevicePathToText (CurFullPath
, TRUE
, TRUE
);
343 if (DevicePathStr
!= NULL
){
344 DEBUG ((DEBUG_INFO
, "Full device path %s\n", DevicePathStr
));
345 FreePool (DevicePathStr
);
349 Status
= GetEfiSysPartitionFromDevPath (CurFullPath
, &FsFullPath
, Fs
);
350 } while (EFI_ERROR (Status
));
353 *FullPath
= FsFullPath
;
356 return EFI_NOT_FOUND
;
361 Get a valid SimpleFileSystem within EFI system partition.
363 @param[in] Map The FS mapping capsule write to
364 @param[out] BootNext The value of BootNext Variable
365 @param[out] Fs The file system within EfiSysPartition
366 @param[out] UpdateBootNext The flag to indicate whether update BootNext Variable
368 @retval EFI_SUCCESS Get FS successfully
369 @retval EFI_NOT_FOUND No valid FS found
370 @retval others Get FS failed
374 GetUpdateFileSystem (
376 OUT UINT16
*BootNext
,
377 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
,
378 OUT BOOLEAN
*UpdateBootNext
382 CHAR16 BootOptionName
[20];
384 CONST EFI_DEVICE_PATH_PROTOCOL
*MappedDevicePath
;
385 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
386 EFI_DEVICE_PATH_PROTOCOL
*FullPath
;
387 UINT16
*BootNextData
;
388 EFI_BOOT_MANAGER_LOAD_OPTION BootNextOption
;
389 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOptionBuffer
;
390 UINTN BootOptionCount
;
391 EFI_SHELL_PROTOCOL
*ShellProtocol
;
392 EFI_BOOT_MANAGER_LOAD_OPTION NewOption
;
394 MappedDevicePath
= NULL
;
395 BootOptionBuffer
= NULL
;
397 ShellProtocol
= GetShellProtocol ();
398 if (ShellProtocol
== NULL
) {
399 Print (L
"Get Shell Protocol Fail\n");;
400 return EFI_NOT_FOUND
;
404 // 1. If Fs is not assigned and there are capsule provisioned before,
405 // Get EFI system partition from BootNext.
407 if (IsCapsuleProvisioned () && Map
== NULL
) {
408 Status
= GetVariable2 (
410 &gEfiGlobalVariableGuid
,
411 (VOID
**)&BootNextData
,
414 if (EFI_ERROR (Status
) || BootNextData
== NULL
) {
415 Print (L
"Get Boot Next Data Fail. Status = %r\n", Status
);
416 return EFI_NOT_FOUND
;
418 UnicodeSPrint (BootOptionName
, sizeof (BootOptionName
), L
"Boot%04x", *BootNextData
);
419 Status
= EfiBootManagerVariableToLoadOption (BootOptionName
, &BootNextOption
);
420 if (!EFI_ERROR (Status
)) {
421 DevicePath
= BootNextOption
.FilePath
;
422 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
423 if (!EFI_ERROR (Status
)) {
424 *UpdateBootNext
= FALSE
;
425 Print(L
"Get EFI system partition from BootNext : %s\n", BootNextOption
.Description
);
426 Print(L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
434 // Check if Map is valid.
437 MappedDevicePath
= ShellProtocol
->GetDevicePathFromMap (Map
);
438 if (MappedDevicePath
== NULL
) {
439 Print(L
"'%s' is not a valid mapping.\n", Map
);
440 return EFI_INVALID_PARAMETER
;
441 } else if (!IsEfiSysPartitionDevicePath (DuplicateDevicePath (MappedDevicePath
))) {
442 Print(L
"'%s' is not a EFI System Partition.\n", Map
);
443 return EFI_INVALID_PARAMETER
;
448 // 2. Get EFI system partition form boot options.
450 BootOptionBuffer
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
451 if ( (BootOptionBuffer
== NULL
) ||
452 (BootOptionCount
== 0 && Map
== NULL
)
454 return EFI_NOT_FOUND
;
457 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
459 // Get the boot option from the link list
461 DevicePath
= BootOptionBuffer
[Index
].FilePath
;
464 // Skip inactive or legacy boot options
466 if ((BootOptionBuffer
[Index
].Attributes
& LOAD_OPTION_ACTIVE
) == 0 ||
467 DevicePathType (DevicePath
) == BBS_DEVICE_PATH
) {
472 CHAR16
*DevicePathStr
;
474 DevicePathStr
= ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
);
475 if (DevicePathStr
!= NULL
){
476 DEBUG ((DEBUG_INFO
, "Try BootOption %s\n", DevicePathStr
));
477 FreePool (DevicePathStr
);
479 DEBUG ((DEBUG_INFO
, "DevicePathToStr failed\n"));
483 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
484 if (!EFI_ERROR (Status
)) {
486 *BootNext
= (UINT16
) BootOptionBuffer
[Index
].OptionNumber
;
487 *UpdateBootNext
= TRUE
;
488 Print (L
"Found EFI system partition on Boot%04x: %s\n", *BootNext
, BootOptionBuffer
[Index
].Description
);
489 Print (L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
493 if (StrnCmp (Map
, ShellProtocol
->GetMapFromDevicePath (&FullPath
), StrLen (Map
)) == 0) {
494 *BootNext
= (UINT16
) BootOptionBuffer
[Index
].OptionNumber
;
495 *UpdateBootNext
= TRUE
;
496 Print (L
"Found Boot Option on %s : %s\n", Map
, BootOptionBuffer
[Index
].Description
);
503 // 3. If no ESP is found on boot option, try to find a ESP and create boot option for it.
507 // If map is assigned, try to get ESP from mapped Fs.
509 DevicePath
= DuplicateDevicePath (MappedDevicePath
);
510 Status
= GetEfiSysPartitionFromDevPath (DevicePath
, &FullPath
, Fs
);
511 if (EFI_ERROR (Status
)) {
512 Print (L
"Error: Cannot get EFI system partiion from '%s' - %r\n", Map
, Status
);
513 return EFI_NOT_FOUND
;
515 Print (L
"Warning: Cannot find Boot Option on '%s'!\n", Map
);
517 Status
= GetEfiSysPartition (&DevicePath
, Fs
);
518 if (EFI_ERROR (Status
)) {
519 Print (L
"Error: Cannot find a EFI system partition!\n");
520 return EFI_NOT_FOUND
;
524 Print (L
"Create Boot option for capsule on disk:\n");
525 Status
= EfiBootManagerInitializeLoadOption (
527 LoadOptionNumberUnassigned
,
530 L
"UEFI Capsule On Disk",
532 (UINT8
*) &mCapsuleOnDiskBootOptionGuid
,
535 if (!EFI_ERROR (Status
)) {
536 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, (UINTN
) -1); {
537 if (!EFI_ERROR (Status
)) {
538 *UpdateBootNext
= TRUE
;
539 *BootNext
= (UINT16
) NewOption
.OptionNumber
;
540 Print (L
" Boot%04x: %s\n", *BootNext
, ConvertDevicePathToText(DevicePath
, TRUE
, TRUE
));
546 Print (L
"ERROR: Cannot create boot option! - %r\n", Status
);
548 return EFI_NOT_FOUND
;
552 Write files to a given SimpleFileSystem.
554 @param[in] Buffer The buffer array
555 @param[in] BufferSize The buffer size array
556 @param[in] FileName The file name array
557 @param[in] BufferNum The buffer number
558 @param[in] Fs The SimpleFileSystem handle to be written
560 @retval EFI_SUCCESS Write file successfully
561 @retval EFI_NOT_FOUND SFS protocol not found
562 @retval others Write file failed
568 IN UINTN
*BufferSize
,
569 IN CHAR16
**FileName
,
571 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
576 EFI_FILE
*FileHandle
;
577 EFI_FILE_PROTOCOL
*DirHandle
;
588 // Open Root from SFS
590 Status
= Fs
->OpenVolume (Fs
, &Root
);
591 if (EFI_ERROR (Status
)) {
592 Print (L
"Cannot open volume. Status = %r\n", Status
);
593 return EFI_NOT_FOUND
;
597 // Ensure that efi and updatecapsule directories exist
599 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
600 if (EFI_ERROR (Status
)) {
601 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
602 if (EFI_ERROR (Status
)) {
603 Print(L
"Unable to create %s directory\n", L
"\\EFI");
604 return EFI_NOT_FOUND
;
607 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
608 if (EFI_ERROR (Status
)) {
609 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
610 if (EFI_ERROR (Status
)) {
611 Print(L
"Unable to create %s directory\n", EFI_CAPSULE_FILE_DIRECTORY
);
612 return EFI_NOT_FOUND
;
616 for (Index
= 0; Index
< BufferNum
; Index
++) {
620 // Open UpdateCapsule file
622 Status
= DirHandle
->Open (DirHandle
, &FileHandle
, FileName
[Index
], EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
, 0);
623 if (EFI_ERROR (Status
)) {
624 Print (L
"Unable to create %s file\n", FileName
[Index
]);
625 return EFI_NOT_FOUND
;
629 // Empty the file contents
631 Status
= FileHandleGetSize (FileHandle
, &FileInfo
);
632 if (EFI_ERROR (Status
)) {
633 FileHandleClose (FileHandle
);
634 Print (L
"Error Reading %s\n", FileName
[Index
]);
635 return EFI_DEVICE_ERROR
;
639 // If the file size is already 0, then it has been empty.
643 // Set the file size to 0.
646 Status
= FileHandleSetSize (FileHandle
, FileInfo
);
647 if (EFI_ERROR (Status
)) {
648 Print (L
"Error Deleting %s\n", FileName
[Index
]);
649 FileHandleClose (FileHandle
);
655 // Write Filebuffer to file
657 Filebuffer
= Buffer
[Index
];
658 FileSize
= BufferSize
[Index
];
659 Status
= FileHandleWrite (FileHandle
, &FileSize
, Filebuffer
);
660 if (EFI_ERROR (Status
)) {
661 Print (L
"Unable to write Capsule Update to %s, Status = %r\n", FileName
[Index
], Status
);
662 return EFI_NOT_FOUND
;
665 Print (L
"Succeed to write %s\n", FileName
[Index
]);
666 FileHandleClose (FileHandle
);
673 Set capsule status variable.
675 @param[in] SetCap Set or clear the capsule flag.
677 @retval EFI_SUCCESS Succeed to set SetCap variable.
678 @retval others Fail to set the variable.
682 SetCapsuleStatusVariable (
691 DataSize
= sizeof(UINT64
);
692 Status
= gRT
->GetVariable (
694 &gEfiGlobalVariableGuid
,
699 if (EFI_ERROR (Status
)) {
703 OsIndication
|= ((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
706 OsIndication
&= ~((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
708 Status
= gRT
->SetVariable (
710 &gEfiGlobalVariableGuid
,
711 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
720 Check if Capsule On Disk is supported.
722 @retval TRUE Capsule On Disk is supported.
723 @retval FALSE Capsule On Disk is not supported.
727 IsCapsuleOnDiskSupported (
732 UINT64 OsIndicationsSupported
;
735 DataSize
= sizeof(UINT64
);
736 Status
= gRT
->GetVariable (
737 L
"OsIndicationsSupported",
738 &gEfiGlobalVariableGuid
,
741 &OsIndicationsSupported
743 if (EFI_ERROR (Status
)) {
747 if ((OsIndicationsSupported
& EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
) != 0) {
755 Process Capsule On Disk.
757 @param[in] CapsuleBuffer An array of pointer to capsule images
758 @param[in] CapsuleBufferSize An array of UINTN to capsule images size
759 @param[in] FilePath An array of capsule images file path
760 @param[in] Map File system mapping string
761 @param[in] CapsuleNum The count of capsule images
763 @retval EFI_SUCCESS Capsule on disk success.
764 @retval others Capsule on disk fail.
768 ProcessCapsuleOnDisk (
769 IN VOID
**CapsuleBuffer
,
770 IN UINTN
*CapsuleBufferSize
,
771 IN CHAR16
**FilePath
,
778 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
;
779 BOOLEAN UpdateBootNext
;
780 CHAR16
*FileName
[MAX_CAPSULE_NUM
];
784 // Check if Capsule On Disk is supported
786 if (!IsCapsuleOnDiskSupported ()) {
787 Print (L
"CapsuleApp: Capsule On Disk is not supported.\n");
788 return EFI_UNSUPPORTED
;
792 // Get a valid file system from boot path
796 Status
= GetUpdateFileSystem (Map
, &BootNext
, &Fs
, &UpdateBootNext
);
797 if (EFI_ERROR (Status
)) {
798 Print (L
"CapsuleApp: cannot find a valid file system on boot devices. Status = %r\n", Status
);
803 // Get file name from file path
805 for (Index
= 0; Index
< CapsuleNum
; Index
++) {
806 FileName
[Index
] = GetFileNameFromPath (FilePath
[Index
]);
810 // Copy capsule image to '\efi\UpdateCapsule\'
812 Status
= WriteUpdateFile (CapsuleBuffer
, CapsuleBufferSize
, FileName
, CapsuleNum
, Fs
);
813 if (EFI_ERROR (Status
)) {
814 Print (L
"CapsuleApp: capsule image could not be copied for update.\n");
819 // Set variable then reset
821 Status
= SetCapsuleStatusVariable (TRUE
);
822 if (EFI_ERROR (Status
)) {
823 Print (L
"CapsuleApp: unable to set OSIndication variable.\n");
827 if (UpdateBootNext
) {
828 Status
= gRT
->SetVariable (
830 &gEfiGlobalVariableGuid
,
831 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
835 if (EFI_ERROR (Status
)){
836 Print (L
"CapsuleApp: unable to set BootNext variable.\n");