11EFI_GUID mCapsuleOnDiskBootOptionGuid = {
12 0x4CC29BB7, 0x2413, 0x40A2, { 0xB0, 0x6D, 0x25, 0x3E, 0x37, 0x10, 0xF5, 0x32 }
30 SHELL_FILE_HANDLE Handle;
34 if (ShellProtocol ==
NULL) {
41 Status = ShellProtocol->OpenFileByName (
46 if (EFI_ERROR (Status)) {
53 FileInfo = ShellProtocol->GetFileInfo (Handle);
54 ShellProtocol->CloseFile (Handle);
84 TempDevicePath = DevicePath;
91 if (Hd->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER) {
103 Status =
gBS->LocateDevicePath (&gEfiPartTypeSystemPartGuid, &DevicePath, &Handle);
104 return EFI_ERROR (Status) ?
FALSE :
TRUE;
120 UINTN NumberSimpleFileSystemHandles;
123 UINTN NumberEfiSystemPartitions;
126 NumberEfiSystemPartitions = 0;
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++) {
147 NumberEfiSystemPartitions++;
152 if (NumberEfiSystemPartitions == 0) {
153 Print (L
" No ESP found.\n");
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))
208 UINTN NumberSimpleFileSystemHandles;
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++) {
228 Status =
gBS->HandleProtocol (SimpleFileSystemHandles[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)Fs);
229 if (!EFI_ERROR (Status)) {
230 *FsDevicePath = DevicePath;
236 return EFI_NOT_FOUND;
266 TempDevicePath = DevicePath;
272 if (Hd->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER) {
284 Status =
gBS->LocateDevicePath (&gEfiPartTypeSystemPartGuid, &DevicePath, &Handle);
289 if (!EFI_ERROR (Status)) {
290 Status =
gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)Fs);
291 if (!EFI_ERROR (Status)) {
298 return EFI_NOT_FOUND;
331 PreFullPath = CurFullPath;
334 if (PreFullPath !=
NULL) {
338 if (CurFullPath ==
NULL) {
342 Status = EFI_NOT_FOUND;
347 CHAR16 *DevicePathStr;
350 if (DevicePathStr !=
NULL) {
351 DEBUG ((DEBUG_INFO,
"Full device path %s\n", DevicePathStr));
358 }
while (EFI_ERROR (Status));
361 *FullPath = FsFullPath;
364 return EFI_NOT_FOUND;
384 OUT UINT16 *BootNext,
386 OUT BOOLEAN *UpdateBootNext
390 CHAR16 BootOptionName[20];
395 UINT16 *BootNextData;
398 UINTN BootOptionCount;
402 MappedDevicePath =
NULL;
403 BootOptionBuffer =
NULL;
406 if (ShellProtocol ==
NULL) {
407 Print (L
"Get Shell Protocol Fail\n");
408 return EFI_NOT_FOUND;
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);
428 if (!EFI_ERROR (Status)) {
429 DevicePath = BootNextOption.FilePath;
431 if (!EFI_ERROR (Status)) {
432 *UpdateBootNext =
FALSE;
433 Print (L
"Get EFI system partition from BootNext : %s\n", BootNextOption.Description);
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;
450 Print (L
"'%s' is not a EFI System Partition.\n", Map);
451 return EFI_INVALID_PARAMETER;
459 if ((BootOptionBuffer ==
NULL) ||
460 ((BootOptionCount == 0) && (Map ==
NULL))
463 return EFI_NOT_FOUND;
466 for (Index = 0; Index < BootOptionCount; Index++) {
470 DevicePath = BootOptionBuffer[Index].FilePath;
475 if (((BootOptionBuffer[Index].Attributes & LOAD_OPTION_ACTIVE) == 0) ||
482 CHAR16 *DevicePathStr;
485 if (DevicePathStr !=
NULL) {
486 DEBUG ((DEBUG_INFO,
"Try BootOption %s\n", DevicePathStr));
489 DEBUG ((DEBUG_INFO,
"DevicePathToStr failed\n"));
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);
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);
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);
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");
539 LoadOptionNumberUnassigned,
542 L
"UEFI Capsule On Disk",
544 (UINT8 *)&mCapsuleOnDiskBootOptionGuid,
547 if (!EFI_ERROR (Status)) {
550 if (!EFI_ERROR (Status)) {
551 *UpdateBootNext =
TRUE;
552 *BootNext = (UINT16)NewOption.OptionNumber;
559 Print (L
"ERROR: Cannot create boot option! - %r\n", Status);
561 return EFI_NOT_FOUND;
582 IN CHAR16 **FileName,
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;
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++) {
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;
646 if (EFI_ERROR (Status)) {
648 Print (L
"Error Reading %s\n", FileName[Index]);
649 return EFI_DEVICE_ERROR;
661 if (EFI_ERROR (Status)) {
662 Print (L
"Error Deleting %s\n", FileName[Index]);
671 Filebuffer = Buffer[Index];
672 FileSize = BufferSize[Index];
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]);
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,
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) {
784 IN VOID **CapsuleBuffer,
786 IN CHAR16 **FilePath,
794 BOOLEAN UpdateBootNext;
795 CHAR16 *FileName[MAX_CAPSULE_NUM];
802 Print (L
"CapsuleApp: Capsule On Disk is not supported.\n");
803 return EFI_UNSUPPORTED;
812 if (EFI_ERROR (Status)) {
813 Print (L
"CapsuleApp: cannot find a valid file system on boot devices. Status = %r\n", Status);
820 for (Index = 0; Index < CapsuleNum; Index++) {
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");
837 if (EFI_ERROR (Status)) {
838 Print (L
"CapsuleApp: unable to set OSIndication variable.\n");
842 if (UpdateBootNext) {
843 Status =
gRT->SetVariable (
845 &gEfiGlobalVariableGuid,
850 if (EFI_ERROR (Status)) {
851 Print (L
"CapsuleApp: unable to set BootNext variable.\n");
EFI_SHELL_PROTOCOL * GetShellProtocol(VOID)
EFI_STATUS SetCapsuleStatusVariable(BOOLEAN SetCap)
BOOLEAN IsCapsuleOnDiskSupported(VOID)
EFI_STATUS GetUpdateFileSystem(IN CHAR16 *Map, OUT UINT16 *BootNext, OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **Fs, OUT BOOLEAN *UpdateBootNext)
EFI_STATUS WriteUpdateFile(IN VOID **Buffer, IN UINTN *BufferSize, IN CHAR16 **FileName, IN UINTN BufferNum, IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs)
BOOLEAN IsCapsuleProvisioned(VOID)
EFI_STATUS GetEfiSysPartitionFromBootOptionFilePath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT EFI_DEVICE_PATH_PROTOCOL **FullPath, OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **Fs)
VOID DumpAllEfiSysPartition(VOID)
BOOLEAN IsEfiSysPartitionDevicePath(EFI_DEVICE_PATH_PROTOCOL *DevicePath)
CHAR16 * GetFileNameFromPath(CHAR16 *FilePath)
EFI_STATUS GetEfiSysPartitionFromDevPath(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, OUT EFI_DEVICE_PATH_PROTOCOL **FsDevicePath, OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **Fs)
EFI_STATUS GetEfiSysPartition(OUT EFI_DEVICE_PATH_PROTOCOL **FsDevicePath, OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **Fs)
EFI_STATUS ProcessCapsuleOnDisk(IN VOID **CapsuleBuffer, IN UINTN *CapsuleBufferSize, IN CHAR16 **FilePath, IN CHAR16 *Map, IN UINTN CapsuleNum)
INTN EFIAPI StrnCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString, IN UINTN Length)
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
#define MEDIA_HARDDRIVE_DP
UINT8 EFIAPI DevicePathType(IN CONST VOID *Node)
UINT8 EFIAPI DevicePathSubType(IN CONST VOID *Node)
BOOLEAN EFIAPI IsDevicePathEnd(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI NextDevicePathNode(IN CONST VOID *Node)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DevicePathFromHandle(IN EFI_HANDLE Handle)
CHAR16 *EFIAPI ConvertDevicePathToText(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN BOOLEAN DisplayOnly, IN BOOLEAN AllowShortcuts)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI DuplicateDevicePath(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
VOID EFIAPI FreePool(IN VOID *Buffer)
EFI_STATUS EFIAPI FileHandleSetSize(IN EFI_FILE_HANDLE FileHandle, IN UINT64 Size)
EFI_STATUS EFIAPI FileHandleClose(IN EFI_FILE_HANDLE FileHandle)
EFI_STATUS EFIAPI FileHandleGetSize(IN EFI_FILE_HANDLE FileHandle, OUT UINT64 *Size)
EFI_STATUS EFIAPI FileHandleWrite(IN EFI_FILE_HANDLE FileHandle, IN OUT UINTN *BufferSize, IN VOID *Buffer)
UINTN EFIAPI UnicodeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
EFI_RUNTIME_SERVICES * gRT
#define DEBUG_CODE_BEGIN()
#define DEBUG(Expression)
EFI_FILE_INFO * FileInfo(IN EFI_FILE_HANDLE FHand)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI EfiBootManagerGetNextLoadOptionDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN EFI_DEVICE_PATH_PROTOCOL *FullPath)
EFI_BOOT_MANAGER_LOAD_OPTION *EFIAPI EfiBootManagerGetLoadOptions(OUT UINTN *LoadOptionCount, IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE LoadOptionType)
EFI_STATUS EFIAPI EfiBootManagerAddLoadOptionVariable(IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *Option, IN UINTN Position)
EFI_STATUS EFIAPI EfiBootManagerVariableToLoadOption(IN CHAR16 *VariableName, IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *LoadOption)
EFI_STATUS EFIAPI EfiBootManagerInitializeLoadOption(IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *Option, IN UINTN OptionNumber, IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType, IN UINT32 Attributes, IN CHAR16 *Description, IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN UINT8 *OptionalData, IN UINT32 OptionalDataSize)
EFI_STATUS EFIAPI GetVariable2(IN CONST CHAR16 *Name, IN CONST EFI_GUID *Guid, OUT VOID **Value, OUT UINTN *Size OPTIONAL)
UINTN EFIAPI Print(IN CONST CHAR16 *Format,...)
#define EFI_VARIABLE_NON_VOLATILE