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 NumberEfiSystemPartitions
= 0;
156 ShellProtocol
= GetShellProtocol ();
157 if (ShellProtocol
== NULL
) {
158 Print (L
"Get Shell Protocol Fail\n");;
162 Print (L
"EFI System Partition list:\n");
164 gBS
->LocateHandleBuffer (
166 &gEfiSimpleFileSystemProtocolGuid
,
168 &NumberSimpleFileSystemHandles
,
169 &SimpleFileSystemHandles
172 for (Index
= 0; Index
< NumberSimpleFileSystemHandles
; Index
++) {
173 DevicePath
= DevicePathFromHandle (SimpleFileSystemHandles
[Index
]);
174 if (IsEfiSysPartitionDevicePath (DevicePath
)) {
175 NumberEfiSystemPartitions
++;
176 Print(L
" %s\n %s\n", ShellProtocol
->GetMapFromDevicePath (&DevicePath
), ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
));
180 if (NumberEfiSystemPartitions
== 0) {
181 Print(L
" No ESP found.\n");
186 Check if capsule is provisioned.
188 @retval TRUE Capsule is provisioned previously.
189 @retval FALSE No capsule is provisioned.
193 IsCapsuleProvisioned (
202 DataSize
= sizeof(UINT64
);
203 Status
= gRT
->GetVariable (
205 &gEfiGlobalVariableGuid
,
210 if (!EFI_ERROR (Status
) &&
211 (OsIndication
& EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
) != 0) {
219 Get one active Efi System Partition.
221 @param[out] FsDevicePath The device path of Fs
222 @param[out] Fs The file system within EfiSysPartition
224 @retval EFI_SUCCESS Get file system successfully
225 @retval EFI_NOT_FOUND No valid file system found
230 OUT EFI_DEVICE_PATH_PROTOCOL
**FsDevicePath
,
231 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
234 EFI_HANDLE
*SimpleFileSystemHandles
;
235 UINTN NumberSimpleFileSystemHandles
;
237 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
240 Status
= gBS
->LocateHandleBuffer (
242 &gEfiSimpleFileSystemProtocolGuid
,
244 &NumberSimpleFileSystemHandles
,
245 &SimpleFileSystemHandles
248 if (EFI_ERROR (Status
)) {
249 return EFI_NOT_FOUND
;
252 for (Index
= 0; Index
< NumberSimpleFileSystemHandles
; Index
++) {
253 DevicePath
= DevicePathFromHandle (SimpleFileSystemHandles
[Index
]);
254 if (IsEfiSysPartitionDevicePath (DevicePath
)) {
255 Status
= gBS
->HandleProtocol (SimpleFileSystemHandles
[Index
], &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)Fs
);
256 if (!EFI_ERROR (Status
)) {
257 *FsDevicePath
= DevicePath
;
263 return EFI_NOT_FOUND
;
267 Check if Active Efi System Partition within GPT is in the device path.
269 @param[in] DevicePath The device path
270 @param[out] FsDevicePath The device path of Fs
271 @param[out] Fs The file system within EfiSysPartition
273 @retval EFI_SUCCESS Get file system successfully
274 @retval EFI_NOT_FOUND No valid file system found
275 @retval others Get file system failed
279 GetEfiSysPartitionFromDevPath (
280 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
281 OUT EFI_DEVICE_PATH_PROTOCOL
**FsDevicePath
,
282 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
286 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
287 HARDDRIVE_DEVICE_PATH
*Hd
;
291 // Check if the device path contains GPT node
293 TempDevicePath
= DevicePath
;
294 while (!IsDevicePathEnd (TempDevicePath
)) {
295 if ((DevicePathType (TempDevicePath
) == MEDIA_DEVICE_PATH
) &&
296 (DevicePathSubType (TempDevicePath
) == MEDIA_HARDDRIVE_DP
)) {
297 Hd
= (HARDDRIVE_DEVICE_PATH
*)TempDevicePath
;
298 if (Hd
->MBRType
== MBR_TYPE_EFI_PARTITION_TABLE_HEADER
) {
302 TempDevicePath
= NextDevicePathNode (TempDevicePath
);
305 if (!IsDevicePathEnd (TempDevicePath
)) {
307 // Search for EFI system partition protocol on full device path in Boot Option
309 Status
= gBS
->LocateDevicePath (&gEfiPartTypeSystemPartGuid
, &DevicePath
, &Handle
);
312 // Search for simple file system on this handler
314 if (!EFI_ERROR (Status
)) {
315 Status
= gBS
->HandleProtocol (Handle
, &gEfiSimpleFileSystemProtocolGuid
, (VOID
**)Fs
);
316 if (!EFI_ERROR (Status
)) {
317 *FsDevicePath
= DevicePathFromHandle (Handle
);
323 return EFI_NOT_FOUND
;
327 Get SimpleFileSystem from boot option file path.
329 @param[in] DevicePath The file path of boot option
330 @param[out] FullPath The full device path of boot device
331 @param[out] Fs The file system within EfiSysPartition
333 @retval EFI_SUCCESS Get file system successfully
334 @retval EFI_NOT_FOUND No valid file system found
335 @retval others Get file system failed
340 GetEfiSysPartitionFromBootOptionFilePath (
341 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
342 OUT EFI_DEVICE_PATH_PROTOCOL
**FullPath
,
343 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
347 EFI_DEVICE_PATH_PROTOCOL
*CurFullPath
;
348 EFI_DEVICE_PATH_PROTOCOL
*PreFullPath
;
349 EFI_DEVICE_PATH_PROTOCOL
*FsFullPath
;
354 // Try every full device Path generated from bootoption
357 PreFullPath
= CurFullPath
;
358 CurFullPath
= EfiBootManagerGetNextLoadOptionDevicePath (DevicePath
, CurFullPath
);
360 if (PreFullPath
!= NULL
) {
361 FreePool (PreFullPath
);
364 if (CurFullPath
== NULL
) {
366 // No Active EFI system partition is found in BootOption device path
368 Status
= EFI_NOT_FOUND
;
373 CHAR16
*DevicePathStr
;
375 DevicePathStr
= ConvertDevicePathToText (CurFullPath
, TRUE
, TRUE
);
376 if (DevicePathStr
!= NULL
){
377 DEBUG ((DEBUG_INFO
, "Full device path %s\n", DevicePathStr
));
378 FreePool (DevicePathStr
);
382 Status
= GetEfiSysPartitionFromDevPath (CurFullPath
, &FsFullPath
, Fs
);
383 } while (EFI_ERROR (Status
));
386 *FullPath
= FsFullPath
;
389 return EFI_NOT_FOUND
;
394 Get a valid SimpleFileSystem within EFI system partition.
396 @param[in] Map The FS mapping capsule write to
397 @param[out] BootNext The value of BootNext Variable
398 @param[out] Fs The file system within EfiSysPartition
399 @param[out] UpdateBootNext The flag to indicate whether update BootNext Variable
401 @retval EFI_SUCCESS Get FS successfully
402 @retval EFI_NOT_FOUND No valid FS found
403 @retval others Get FS failed
408 GetUpdateFileSystem (
410 OUT UINT16
*BootNext
,
411 OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
**Fs
,
412 OUT BOOLEAN
*UpdateBootNext
416 CHAR16 BootOptionName
[20];
418 CONST EFI_DEVICE_PATH_PROTOCOL
*MappedDevicePath
;
419 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
420 EFI_DEVICE_PATH_PROTOCOL
*FullPath
;
421 UINT16
*BootNextData
;
422 EFI_BOOT_MANAGER_LOAD_OPTION BootNextOption
;
423 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOptionBuffer
;
424 UINTN BootOptionCount
;
425 EFI_SHELL_PROTOCOL
*ShellProtocol
;
426 EFI_BOOT_MANAGER_LOAD_OPTION NewOption
;
428 MappedDevicePath
= NULL
;
429 BootOptionBuffer
= NULL
;
431 ShellProtocol
= GetShellProtocol ();
432 if (ShellProtocol
== NULL
) {
433 Print (L
"Get Shell Protocol Fail\n");;
434 return EFI_NOT_FOUND
;
438 // 1. If Fs is not assigned and there are capsule provisioned before,
439 // Get EFI system partition from BootNext.
441 if (IsCapsuleProvisioned () && Map
== NULL
) {
442 Status
= GetVariable2 (
444 &gEfiGlobalVariableGuid
,
445 (VOID
**)&BootNextData
,
448 if (EFI_ERROR (Status
) || BootNextData
== NULL
) {
449 Print (L
"Get Boot Next Data Fail. Status = %r\n", Status
);
450 return EFI_NOT_FOUND
;
452 UnicodeSPrint (BootOptionName
, sizeof (BootOptionName
), L
"Boot%04x", *BootNextData
);
453 Status
= EfiBootManagerVariableToLoadOption (BootOptionName
, &BootNextOption
);
454 if (!EFI_ERROR (Status
)) {
455 DevicePath
= BootNextOption
.FilePath
;
456 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
457 if (!EFI_ERROR (Status
)) {
458 *UpdateBootNext
= FALSE
;
459 Print(L
"Get EFI system partition from BootNext : %s\n", BootNextOption
.Description
);
460 Print(L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
468 // Check if Map is valid.
471 MappedDevicePath
= ShellProtocol
->GetDevicePathFromMap (Map
);
472 if (MappedDevicePath
== NULL
) {
473 Print(L
"'%s' is not a valid mapping.\n", Map
);
474 return EFI_INVALID_PARAMETER
;
475 } else if (!IsEfiSysPartitionDevicePath (DuplicateDevicePath (MappedDevicePath
))) {
476 Print(L
"'%s' is not a EFI System Partition.\n", Map
);
477 return EFI_INVALID_PARAMETER
;
482 // 2. Get EFI system partition form boot options.
484 BootOptionBuffer
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
485 if ( (BootOptionBuffer
== NULL
) ||
486 (BootOptionCount
== 0 && Map
== NULL
)
488 return EFI_NOT_FOUND
;
491 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
493 // Get the boot option from the link list
495 DevicePath
= BootOptionBuffer
[Index
].FilePath
;
498 // Skip inactive or legacy boot options
500 if ((BootOptionBuffer
[Index
].Attributes
& LOAD_OPTION_ACTIVE
) == 0 ||
501 DevicePathType (DevicePath
) == BBS_DEVICE_PATH
) {
506 CHAR16
*DevicePathStr
;
508 DevicePathStr
= ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
);
509 if (DevicePathStr
!= NULL
){
510 DEBUG ((DEBUG_INFO
, "Try BootOption %s\n", DevicePathStr
));
511 FreePool (DevicePathStr
);
513 DEBUG ((DEBUG_INFO
, "DevicePathToStr failed\n"));
517 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
518 if (!EFI_ERROR (Status
)) {
520 *BootNext
= (UINT16
) BootOptionBuffer
[Index
].OptionNumber
;
521 *UpdateBootNext
= TRUE
;
522 Print (L
"Found EFI system partition on Boot%04x: %s\n", *BootNext
, BootOptionBuffer
[Index
].Description
);
523 Print (L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
527 if (StrnCmp (Map
, ShellProtocol
->GetMapFromDevicePath (&FullPath
), StrLen (Map
)) == 0) {
528 *BootNext
= (UINT16
) BootOptionBuffer
[Index
].OptionNumber
;
529 *UpdateBootNext
= TRUE
;
530 Print (L
"Found Boot Option on %s : %s\n", Map
, BootOptionBuffer
[Index
].Description
);
537 // 3. If no ESP is found on boot option, try to find a ESP and create boot option for it.
541 // If map is assigned, try to get ESP from mapped Fs.
543 DevicePath
= DuplicateDevicePath (MappedDevicePath
);
544 Status
= GetEfiSysPartitionFromDevPath (DevicePath
, &FullPath
, Fs
);
545 if (EFI_ERROR (Status
)) {
546 Print (L
"Error: Cannot get EFI system partiion from '%s' - %r\n", Map
, Status
);
547 return EFI_NOT_FOUND
;
549 Print (L
"Warning: Cannot find Boot Option on '%s'!\n", Map
);
551 Status
= GetEfiSysPartition (&DevicePath
, Fs
);
552 if (EFI_ERROR (Status
)) {
553 Print (L
"Error: Cannot find a EFI system partition!\n");
554 return EFI_NOT_FOUND
;
558 Print (L
"Create Boot option for capsule on disk:\n");
559 Status
= EfiBootManagerInitializeLoadOption (
561 LoadOptionNumberUnassigned
,
564 L
"UEFI Capsule On Disk",
566 (UINT8
*) &mCapsuleOnDiskBootOptionGuid
,
569 if (!EFI_ERROR (Status
)) {
570 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, (UINTN
) -1); {
571 if (!EFI_ERROR (Status
)) {
572 *UpdateBootNext
= TRUE
;
573 *BootNext
= (UINT16
) NewOption
.OptionNumber
;
574 Print (L
" Boot%04x: %s\n", *BootNext
, ConvertDevicePathToText(DevicePath
, TRUE
, TRUE
));
580 Print (L
"ERROR: Cannot create boot option! - %r\n", Status
);
582 return EFI_NOT_FOUND
;
586 Write files to a given SimpleFileSystem.
588 @param[in] Buffer The buffer array
589 @param[in] BufferSize The buffer size array
590 @param[in] FileName The file name array
591 @param[in] BufferNum The buffer number
592 @param[in] Fs The SimpleFileSystem handle to be written
594 @retval EFI_SUCCESS Write file successfully
595 @retval EFI_NOT_FOUND SFS protocol not found
596 @retval others Write file failed
602 IN UINTN
*BufferSize
,
603 IN CHAR16
**FileName
,
605 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
610 EFI_FILE
*FileHandle
;
611 EFI_FILE_PROTOCOL
*DirHandle
;
622 // Open Root from SFS
624 Status
= Fs
->OpenVolume (Fs
, &Root
);
625 if (EFI_ERROR (Status
)) {
626 Print (L
"Cannot open volume. Status = %r\n", Status
);
627 return EFI_NOT_FOUND
;
631 // Ensure that efi and updatecapsule directories exist
633 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
634 if (EFI_ERROR (Status
)) {
635 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
636 if (EFI_ERROR (Status
)) {
637 Print(L
"Unable to create %s directory\n", L
"\\EFI");
638 return EFI_NOT_FOUND
;
641 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
642 if (EFI_ERROR (Status
)) {
643 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
644 if (EFI_ERROR (Status
)) {
645 Print(L
"Unable to create %s directory\n", EFI_CAPSULE_FILE_DIRECTORY
);
646 return EFI_NOT_FOUND
;
650 for (Index
= 0; Index
< BufferNum
; Index
++) {
654 // Open UpdateCapsule file
656 Status
= DirHandle
->Open (DirHandle
, &FileHandle
, FileName
[Index
], EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
, 0);
657 if (EFI_ERROR (Status
)) {
658 Print (L
"Unable to create %s file\n", FileName
[Index
]);
659 return EFI_NOT_FOUND
;
663 // Empty the file contents
665 Status
= FileHandleGetSize (FileHandle
, &FileInfo
);
666 if (EFI_ERROR (Status
)) {
667 FileHandleClose (FileHandle
);
668 Print (L
"Error Reading %s\n", FileName
[Index
]);
669 return EFI_DEVICE_ERROR
;
673 // If the file size is already 0, then it has been empty.
677 // Set the file size to 0.
680 Status
= FileHandleSetSize (FileHandle
, FileInfo
);
681 if (EFI_ERROR (Status
)) {
682 Print (L
"Error Deleting %s\n", FileName
[Index
]);
683 FileHandleClose (FileHandle
);
689 // Write Filebuffer to file
691 Filebuffer
= Buffer
[Index
];
692 FileSize
= BufferSize
[Index
];
693 Status
= FileHandleWrite (FileHandle
, &FileSize
, Filebuffer
);
694 if (EFI_ERROR (Status
)) {
695 Print (L
"Unable to write Capsule Update to %s, Status = %r\n", FileName
[Index
], Status
);
696 return EFI_NOT_FOUND
;
699 Print (L
"Succeed to write %s\n", FileName
[Index
]);
700 FileHandleClose (FileHandle
);
707 Set capsule status variable.
709 @param[in] SetCap Set or clear the capsule flag.
711 @retval EFI_SUCCESS Succeed to set SetCap variable.
712 @retval others Fail to set the variable.
716 SetCapsuleStatusVariable (
725 DataSize
= sizeof(UINT64
);
726 Status
= gRT
->GetVariable (
728 &gEfiGlobalVariableGuid
,
733 if (EFI_ERROR (Status
)) {
737 OsIndication
|= ((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
740 OsIndication
&= ~((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
742 Status
= gRT
->SetVariable (
744 &gEfiGlobalVariableGuid
,
745 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
754 Process Capsule On Disk.
756 @param[in] CapsuleBuffer An array of pointer to capsule images
757 @param[in] CapsuleBufferSize An array of UINTN to capsule images size
758 @param[in] FilePath An array of capsule images file path
759 @param[in] Map File system mapping string
760 @param[in] CapsuleNum The count of capsule images
762 @retval EFI_SUCCESS Capsule on disk success.
763 @retval others Capsule on disk fail.
767 ProcessCapsuleOnDisk (
768 IN VOID
**CapsuleBuffer
,
769 IN UINTN
*CapsuleBufferSize
,
770 IN CHAR16
**FilePath
,
777 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
;
778 BOOLEAN UpdateBootNext
;
781 // Get a valid file system from boot path
785 Status
= GetUpdateFileSystem (Map
, &BootNext
, &Fs
, &UpdateBootNext
);
786 if (EFI_ERROR (Status
)) {
787 Print (L
"CapsuleApp: cannot find a valid file system on boot devies. Status = %r\n", Status
);
792 // Copy capsule image to '\efi\UpdateCapsule\'
794 Status
= WriteUpdateFile (CapsuleBuffer
, CapsuleBufferSize
, FilePath
, CapsuleNum
, Fs
);
795 if (EFI_ERROR (Status
)) {
796 Print (L
"CapsuleApp: capsule image could not be copied for update.\n");
801 // Set variable then reset
803 Status
= SetCapsuleStatusVariable (TRUE
);
804 if (EFI_ERROR (Status
)) {
805 Print (L
"CapsuleApp: unable to set OSIndication variable.\n");
809 if (UpdateBootNext
) {
810 Status
= gRT
->SetVariable (
812 &gEfiGlobalVariableGuid
,
813 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
817 if (EFI_ERROR (Status
)){
818 Print (L
"CapsuleApp: unable to set BootNext variable.\n");