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
= EfiBootManagerGetNextFullDevicePath (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
)) {
449 UnicodeSPrint (BootOptionName
, sizeof (BootOptionName
), L
"Boot%04x", *BootNextData
);
450 Status
= EfiBootManagerVariableToLoadOption (BootOptionName
, &BootNextOption
);
451 if (!EFI_ERROR (Status
)) {
452 DevicePath
= BootNextOption
.FilePath
;
453 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
454 if (!EFI_ERROR (Status
)) {
455 *UpdateBootNext
= FALSE
;
456 Print(L
"Get EFI system partition from BootNext : %s\n", BootNextOption
.Description
);
457 Print(L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
465 // Check if Map is valid.
468 MappedDevicePath
= ShellProtocol
->GetDevicePathFromMap (Map
);
469 if (MappedDevicePath
== NULL
) {
470 Print(L
"'%s' is not a valid mapping.\n", Map
);
471 return EFI_INVALID_PARAMETER
;
472 } else if (!IsEfiSysPartitionDevicePath (DuplicateDevicePath (MappedDevicePath
))) {
473 Print(L
"'%s' is not a EFI System Partition.\n", Map
);
474 return EFI_INVALID_PARAMETER
;
479 // 2. Get EFI system partition form boot options.
481 BootOptionBuffer
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
482 if ( (BootOptionBuffer
== NULL
) ||
483 (BootOptionCount
== 0 && Map
== NULL
)
485 return EFI_NOT_FOUND
;
488 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
490 // Get the boot option from the link list
492 DevicePath
= BootOptionBuffer
[Index
].FilePath
;
495 // Skip inactive or legacy boot options
497 if ((BootOptionBuffer
[Index
].Attributes
& LOAD_OPTION_ACTIVE
) == 0 ||
498 DevicePathType (DevicePath
) == BBS_DEVICE_PATH
) {
503 CHAR16
*DevicePathStr
;
505 DevicePathStr
= ConvertDevicePathToText (DevicePath
, TRUE
, TRUE
);
506 if (DevicePathStr
!= NULL
){
507 DEBUG ((DEBUG_INFO
, "Try BootOption %s\n", DevicePathStr
));
508 FreePool (DevicePathStr
);
510 DEBUG ((DEBUG_INFO
, "DevicePathToStr failed\n"));
514 Status
= GetEfiSysPartitionFromBootOptionFilePath (DevicePath
, &FullPath
, Fs
);
515 if (!EFI_ERROR (Status
)) {
517 *BootNext
= (UINT16
) BootOptionBuffer
[Index
].OptionNumber
;
518 *UpdateBootNext
= TRUE
;
519 Print (L
"Found EFI system partition on Boot%04x: %s\n", *BootNext
, BootOptionBuffer
[Index
].Description
);
520 Print (L
"%s %s\n", ShellProtocol
->GetMapFromDevicePath (&FullPath
), ConvertDevicePathToText (FullPath
, TRUE
, TRUE
));
524 if (StrnCmp (Map
, ShellProtocol
->GetMapFromDevicePath (&FullPath
), StrLen (Map
)) == 0) {
525 *BootNext
= (UINT16
) BootOptionBuffer
[Index
].OptionNumber
;
526 *UpdateBootNext
= TRUE
;
527 Print (L
"Found Boot Option on %s : %s\n", Map
, BootOptionBuffer
[Index
].Description
);
534 // 3. If no ESP is found on boot option, try to find a ESP and create boot option for it.
538 // If map is assigned, try to get ESP from mapped Fs.
540 DevicePath
= DuplicateDevicePath (MappedDevicePath
);
541 Status
= GetEfiSysPartitionFromDevPath (DevicePath
, &FullPath
, Fs
);
542 if (EFI_ERROR (Status
)) {
543 Print (L
"Error: Cannot get EFI system partiion from '%s' - %r\n", Map
, Status
);
544 return EFI_NOT_FOUND
;
546 Print (L
"Warning: Cannot find Boot Option on '%s'!\n", Map
);
548 Status
= GetEfiSysPartition (&DevicePath
, Fs
);
549 if (EFI_ERROR (Status
)) {
550 Print (L
"Error: Cannot find a EFI system partition!\n");
551 return EFI_NOT_FOUND
;
555 Print (L
"Create Boot option for capsule on disk:\n");
556 Status
= EfiBootManagerInitializeLoadOption (
558 LoadOptionNumberUnassigned
,
561 L
"UEFI Capsule On Disk",
563 (UINT8
*) &mCapsuleOnDiskBootOptionGuid
,
566 if (!EFI_ERROR (Status
)) {
567 Status
= EfiBootManagerAddLoadOptionVariable (&NewOption
, (UINTN
) -1); {
568 if (!EFI_ERROR (Status
)) {
569 *UpdateBootNext
= TRUE
;
570 *BootNext
= (UINT16
) NewOption
.OptionNumber
;
571 Print (L
" Boot%04x: %s\n", *BootNext
, ConvertDevicePathToText(DevicePath
, TRUE
, TRUE
));
577 Print (L
"ERROR: Cannot create boot option! - %r\n", Status
);
579 return EFI_NOT_FOUND
;
583 Write files to a given SimpleFileSystem.
585 @param[in] Buffer The buffer array
586 @param[in] BufferSize The buffer size array
587 @param[in] FileName The file name array
588 @param[in] BufferNum The buffer number
589 @param[in] Fs The SimpleFileSystem handle to be written
591 @retval EFI_SUCCESS Write file successfully
592 @retval EFI_NOT_FOUND SFS protocol not found
593 @retval others Write file failed
599 IN UINTN
*BufferSize
,
600 IN CHAR16
**FileName
,
602 IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
607 EFI_FILE
*FileHandle
;
608 EFI_FILE_PROTOCOL
*DirHandle
;
619 // Open Root from SFS
621 Status
= Fs
->OpenVolume (Fs
, &Root
);
622 if (EFI_ERROR (Status
)) {
623 Print (L
"Cannot open volume. Status = %r\n", Status
);
624 return EFI_NOT_FOUND
;
628 // Ensure that efi and updatecapsule directories exist
630 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
631 if (EFI_ERROR (Status
)) {
632 Status
= Root
->Open (Root
, &DirHandle
, L
"\\EFI", EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
633 if (EFI_ERROR (Status
)) {
634 Print(L
"Unable to create %s directory\n", L
"\\EFI");
635 return EFI_NOT_FOUND
;
638 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
, 0);
639 if (EFI_ERROR (Status
)) {
640 Status
= Root
->Open (Root
, &DirHandle
, EFI_CAPSULE_FILE_DIRECTORY
, EFI_FILE_MODE_READ
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_CREATE
, EFI_FILE_DIRECTORY
);
641 if (EFI_ERROR (Status
)) {
642 Print(L
"Unable to create %s directory\n", EFI_CAPSULE_FILE_DIRECTORY
);
643 return EFI_NOT_FOUND
;
647 for (Index
= 0; Index
< BufferNum
; Index
++) {
651 // Open UpdateCapsule file
653 Status
= DirHandle
->Open (DirHandle
, &FileHandle
, FileName
[Index
], EFI_FILE_MODE_CREATE
| EFI_FILE_MODE_WRITE
| EFI_FILE_MODE_READ
, 0);
654 if (EFI_ERROR (Status
)) {
655 Print (L
"Unable to create %s file\n", FileName
[Index
]);
656 return EFI_NOT_FOUND
;
660 // Empty the file contents
662 Status
= FileHandleGetSize (FileHandle
, &FileInfo
);
663 if (EFI_ERROR (Status
)) {
664 FileHandleClose (FileHandle
);
665 Print (L
"Error Reading %s\n", FileName
[Index
]);
666 return EFI_DEVICE_ERROR
;
670 // If the file size is already 0, then it has been empty.
674 // Set the file size to 0.
677 Status
= FileHandleSetSize (FileHandle
, FileInfo
);
678 if (EFI_ERROR (Status
)) {
679 Print (L
"Error Deleting %s\n", FileName
[Index
]);
680 FileHandleClose (FileHandle
);
686 // Write Filebuffer to file
688 Filebuffer
= Buffer
[Index
];
689 FileSize
= BufferSize
[Index
];
690 Status
= FileHandleWrite (FileHandle
, &FileSize
, Filebuffer
);
691 if (EFI_ERROR (Status
)) {
692 Print (L
"Unable to write Capsule Update to %s, Status = %r\n", FileName
[Index
], Status
);
693 return EFI_NOT_FOUND
;
696 Print (L
"Succeed to write %s\n", FileName
[Index
]);
697 FileHandleClose (FileHandle
);
704 Set capsule status variable.
706 @param[in] SetCap Set or clear the capsule flag.
708 @retval EFI_SUCCESS Succeed to set SetCap variable.
709 @retval others Fail to set the variable.
713 SetCapsuleStatusVariable (
722 DataSize
= sizeof(UINT64
);
723 Status
= gRT
->GetVariable (
725 &gEfiGlobalVariableGuid
,
730 if (EFI_ERROR (Status
)) {
734 OsIndication
|= ((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
737 OsIndication
&= ~((UINT64
)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
);
739 Status
= gRT
->SetVariable (
741 &gEfiGlobalVariableGuid
,
742 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
751 Process Capsule On Disk.
753 @param[in] CapsuleBuffer An array of pointer to capsule images
754 @param[in] CapsuleBufferSize An array of UINTN to capsule images size
755 @param[in] FilePath An array of capsule images file path
756 @param[in] Map File system mapping string
757 @param[in] CapsuleNum The count of capsule images
759 @retval EFI_SUCCESS Capsule on disk success.
760 @retval others Capsule on disk fail.
764 ProcessCapsuleOnDisk (
765 IN VOID
**CapsuleBuffer
,
766 IN UINTN
*CapsuleBufferSize
,
767 IN CHAR16
**FilePath
,
774 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
*Fs
;
775 BOOLEAN UpdateBootNext
;
778 // Get a valid file system from boot path
782 Status
= GetUpdateFileSystem (Map
, &BootNext
, &Fs
, &UpdateBootNext
);
783 if (EFI_ERROR (Status
)) {
784 Print (L
"CapsuleApp: cannot find a valid file system on boot devies. Status = %r\n", Status
);
789 // Copy capsule image to '\efi\UpdateCapsule\'
791 Status
= WriteUpdateFile (CapsuleBuffer
, CapsuleBufferSize
, FilePath
, CapsuleNum
, Fs
);
792 if (EFI_ERROR (Status
)) {
793 Print (L
"CapsuleApp: capsule image could not be copied for update.\n");
798 // Set variable then reset
800 Status
= SetCapsuleStatusVariable (TRUE
);
801 if (EFI_ERROR (Status
)) {
802 Print (L
"CapsuleApp: unable to set OSIndication variable.\n");
806 if (UpdateBootNext
) {
807 Status
= gRT
->SetVariable (
809 &gEfiGlobalVariableGuid
,
810 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE
,
814 if (EFI_ERROR (Status
)){
815 Print (L
"CapsuleApp: unable to set BootNext variable.\n");