EFI_STATUS CheckStore ( IN EFI_HANDLE SimpleFileSystemHandle, OUT EFI_DEVICE_PATH_PROTOCOL **Device ) { EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlkIo; EFI_FILE_PROTOCOL *File; *Device = NULL; Status = gBS->HandleProtocol ( SimpleFileSystemHandle, &gEfiBlockIoProtocolGuid, (VOID*)&BlkIo ); if (EFI_ERROR (Status)) { goto ErrHandle; } if (!BlkIo->Media->MediaPresent) { DEBUG ((DEBUG_ERROR, "FwhMappedFile: Media not present!\n")); Status = EFI_NO_MEDIA; goto ErrHandle; } if (BlkIo->Media->ReadOnly) { DEBUG ((DEBUG_ERROR, "FwhMappedFile: Media is read-only!\n")); Status = EFI_ACCESS_DENIED; goto ErrHandle; } Status = FileOpen (DevicePathFromHandle (SimpleFileSystemHandle), mFvInstance->MappedFile, &File, EFI_FILE_MODE_READ); if (EFI_ERROR (Status)) { goto ErrHandle; } /* We found it! Maybe do more checks...? */ FileClose (File); *Device = DuplicateDevicePath (DevicePathFromHandle (SimpleFileSystemHandle)); ASSERT (*Device != NULL); ErrHandle: return Status; }
/* * Some UEFI firmwares (like HPQ EFI from HP notebooks) have DiskIo protocols * opened BY_DRIVER (by Partition driver in HP case) even when no file system * is produced from this DiskIo. This then blocks our FS driver from connecting * and producing file systems. * To fix it we disconnect drivers that connected to DiskIo BY_DRIVER if this * is a partition volume and if those drivers did not produce file system. */ static VOID DisconnectBlockingDrivers(VOID) { EFI_STATUS Status; UINTN HandleCount = 0, Index, OpenInfoIndex, OpenInfoCount; EFI_HANDLE *Handles = NULL; CHAR16 *DevicePathString; EFI_FILE_IO_INTERFACE *Volume; EFI_BLOCK_IO *BlockIo; EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo; // Get all DiskIo handles Status = BS->LocateHandleBuffer(ByProtocol, &DiskIoProtocol, NULL, &HandleCount, &Handles); if (EFI_ERROR(Status) || (HandleCount == 0)) return; // Check every DiskIo handle for (Index = 0; Index < HandleCount; Index++) { // If this is not partition - skip it. // This is then whole disk and DiskIo // should be opened here BY_DRIVER by Partition driver // to produce partition volumes. Status = BS->HandleProtocol(Handles[Index], &BlockIoProtocol, (VOID **)&BlockIo); if (EFI_ERROR(Status)) continue; if ((BlockIo->Media == NULL) || (!BlockIo->Media->LogicalPartition)) continue; // If SimpleFileSystem is already produced - skip it, this is ok Status = BS->HandleProtocol(Handles[Index], &FileSystemProtocol, (VOID **)&Volume); if (Status == EFI_SUCCESS) continue; DevicePathString = DevicePathToStr(DevicePathFromHandle(Handles[Index])); Print(L"%N\r[ INFO ] Probing %d devices... [%d] %s", HandleCount, Index + 1, DevicePathString); FreePool(DevicePathString); // If no SimpleFileSystem on this handle but DiskIo is opened BY_DRIVER // then disconnect this connection Status = BS->OpenProtocolInformation(Handles[Index], &DiskIoProtocol, &OpenInfo, &OpenInfoCount); if (EFI_ERROR(Status)) { Print(L"%H\n[ WARN ] Could not get DiskIo protocol: %r\n", Status); FreePool(DevicePathString); continue; } if (OpenInfoCount > 0) Print(L"%N\n[ INFO ] Disconnecting %d drivers...", OpenInfoCount); for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) { if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) { Print(L"%N\r[ INFO ] Disconnecting %d drivers... [%d] %s", OpenInfoCount, OpenInfoIndex+1, GetDriverName(OpenInfo[OpenInfoIndex].AgentHandle)); Status = BS->DisconnectController(Handles[Index], OpenInfo[OpenInfoIndex].AgentHandle, NULL); if (EFI_ERROR(Status)) { Print(L"%H\n[ WARN ] Could not disconnect driver: %r\n", Status); } } } FreePool(OpenInfo); } FreePool(Handles); }
EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, CHAR16 uuid[37]) { EFI_DEVICE_PATH *device_path; EFI_STATUS r = EFI_NOT_FOUND; /* export the device path this image is started from */ device_path = DevicePathFromHandle(handle); if (device_path) { EFI_DEVICE_PATH *path, *paths; paths = UnpackDevicePath(device_path); for (path = paths; !IsDevicePathEnd(path); path = NextDevicePathNode(path)) { HARDDRIVE_DEVICE_PATH *drive; if (DevicePathType(path) != MEDIA_DEVICE_PATH) continue; if (DevicePathSubType(path) != MEDIA_HARDDRIVE_DP) continue; drive = (HARDDRIVE_DEVICE_PATH *)path; if (drive->SignatureType != SIGNATURE_TYPE_GUID) continue; GuidToString(uuid, (EFI_GUID *)&drive->Signature); r = EFI_SUCCESS; break; } FreePool(paths); } return r; }
/** This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from the handle, and adds it to ConOut and ErrOut. **/ STATIC VOID EFIAPI AddOutput ( IN EFI_HANDLE Handle, IN CONST CHAR16 *ReportText ) { EFI_STATUS Status; EFI_DEVICE_PATH_PROTOCOL *DevicePath; DevicePath = DevicePathFromHandle (Handle); if (DevicePath == NULL) { DEBUG ((EFI_D_ERROR, "%a: %s: handle %p: device path not found\n", __FUNCTION__, ReportText, Handle)); return; } Status = BdsLibUpdateConsoleVariable (L"ConOut", DevicePath, NULL); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "%a: %s: adding to ConOut: %r\n", __FUNCTION__, ReportText, Status)); return; } Status = BdsLibUpdateConsoleVariable (L"ErrOut", DevicePath, NULL); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "%a: %s: adding to ErrOut: %r\n", __FUNCTION__, ReportText, Status)); return; } DEBUG ((EFI_D_VERBOSE, "%a: %s: added to ConOut and ErrOut\n", __FUNCTION__, ReportText)); }
/** This function gets driver name from Component Name 2 protocol interface and Component Name protocol interface in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the driver name. If the attempt fails, it then gets the driver name from EFI 1.1 Component Name protocol for backward compatibility support. @param DriverBindingHandle The handle on which the Component Name (2) protocol instance is retrieved. @return A pointer to the Unicode string to return. This Unicode string is the name of the controller specified by ControllerHandle and ChildHandle. **/ CHAR16 * DriverHealthManagerGetDriverName ( IN EFI_HANDLE DriverBindingHandle ) { EFI_STATUS Status; CHAR16 *DriverName; // // Get driver name from UEFI 2.0 Component Name 2 protocol interface. // Status = DriverHealthManagerGetDriverNameWorker (&gEfiComponentName2ProtocolGuid, DriverBindingHandle, &DriverName); if (EFI_ERROR (Status)) { // // If it fails to get the driver name from Component Name protocol interface, we should fall back on // EFI 1.1 Component Name protocol interface. // Status = DriverHealthManagerGetDriverNameWorker (&gEfiComponentNameProtocolGuid, DriverBindingHandle, &DriverName); } if (!EFI_ERROR (Status)) { return AllocateCopyPool (StrSize (DriverName), DriverName); } else { return ConvertDevicePathToText (DevicePathFromHandle (DriverBindingHandle), FALSE, TRUE); } }
/** Extract device path for given HII handle and class guid. @param Handle The HII handle. @retval NULL Fail to get the device path string. @return PathString Get the device path string. **/ CHAR16 * BmmExtractDevicePathFromHiiHandle ( IN EFI_HII_HANDLE Handle ) { EFI_STATUS Status; EFI_HANDLE DriverHandle; ASSERT (Handle != NULL); if (Handle == NULL) { return NULL; } Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle); if (EFI_ERROR (Status)) { return NULL; } // // Get device path string. // return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE); }
EFI_DEVICE_PATH_PROTOCOL * FileDevicePath ( IN EFI_HANDLE Device OPTIONAL, IN CHAR16 *FileName ) /*++ Routine Description: Function allocates a device path for a file and appends it to an existing device path. Arguments: Device - A pointer to a device handle. FileName - A pointer to a Null-terminated Unicode string. Returns: If Device is not a valid device handle, then a device path for the file specified by FileName is allocated and returned. Results are allocated from pool. The caller must FreePool the resulting device path structure --*/ { UINTN Size; FILEPATH_DEVICE_PATH *FilePath; EFI_DEVICE_PATH_PROTOCOL *Eop, *DevicePath; Size = StrSize(FileName); FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH_PROTOCOL)); DevicePath = NULL; if (FilePath) { // // Build a file path // FilePath->Header.Type = MEDIA_DEVICE_PATH; FilePath->Header.SubType = MEDIA_FILEPATH_DP; SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); CopyMem (FilePath->PathName, FileName, Size); Eop = NextDevicePathNode(&FilePath->Header); SetDevicePathEndNode(Eop); // // Append file path to device's device path // DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) FilePath; if (Device) { DevicePath = AppendDevicePath ( DevicePathFromHandle(Device), DevicePath ); FreePool(FilePath); } } return DevicePath; }
static EFI_STATUS nvme_erase_blocks( EFI_HANDLE handle, ATTR_UNUSED EFI_BLOCK_IO *bio, EFI_LBA start, EFI_LBA end ) { EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *NvmePassthru; NVME_NAMESPACE_DEVICE_PATH *nvme_dp; EFI_DEVICE_PATH *dp; EFI_STATUS ret; UINT32 NamespaceId = 0; UINT32 num; EFI_LBA blk; debug(L"nvme_erase_blocks: 0x%X blocks", end - start + 1); dp = DevicePathFromHandle(handle); if (!dp) { error(L"Failed to get device path from handle"); return EFI_INVALID_PARAMETER; } ret = get_nvme_passthru(dp, (VOID **) &NvmePassthru); if (EFI_ERROR(ret)) return ret; if (!is_nvme_supported_write_zeros(NvmePassthru)) return EFI_UNSUPPORTED; nvme_dp = get_nvme_device_path(dp); ret = NvmePassthru->GetNamespace(NvmePassthru, (EFI_DEVICE_PATH_PROTOCOL *)nvme_dp, &NamespaceId); debug(L"GetNamespace() ret=%d, NamespaceId=%d", ret, NamespaceId); for (blk = start; blk < end; ) { if (end - blk >= NVME_MAX_WRITE_ZEROS_BLOCKS) num = NVME_MAX_WRITE_ZEROS_BLOCKS; else num = end - blk; ret = nvme_erase_blocks_impl(NvmePassthru, NamespaceId, blk, num); if (EFI_ERROR(ret)) { /* Workround: * if NVME driver do not support NVME_CMD_WRITE_ZEROS, erase large partition will take a long time * return EFI_SUCCESS and skip erasing large partition */ if (end - start > 0x04000000) { error(L"Warning: skip erasing 0x%X blocks this time !!!", end - start + 1); return EFI_SUCCESS; } return EFI_UNSUPPORTED; } blk += num; } return ret; }
EFI_STATUS CheckStore ( IN EFI_HANDLE SimpleFileSystemHandle, IN UINT32 VolumeId, OUT EFI_DEVICE_PATH_PROTOCOL **Device ) { #define BLOCK_SIZE 0x200 #define FAT16_VOLUME_ID_OFFSET 39 #define FAT32_VOLUME_ID_OFFSET 67 EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlkIo; UINT8 BootSector[BLOCK_SIZE]; *Device = NULL; Status = gBS->HandleProtocol ( SimpleFileSystemHandle, &gEfiBlockIoProtocolGuid, // BlockIo should be supported if it supports SimpleFileSystem (VOID*)&BlkIo ); if (EFI_ERROR (Status)) { goto ErrHandle; } if (!BlkIo->Media->MediaPresent) { DEBUG ((EFI_D_ERROR, "FwhMappedFile: Media not present!\n")); Status = EFI_NO_MEDIA; goto ErrHandle; } if (BlkIo->Media->ReadOnly) { DEBUG ((EFI_D_ERROR, "FwhMappedFile: Media is read-only!\n")); Status = EFI_ACCESS_DENIED; goto ErrHandle; } Status = BlkIo->ReadBlocks( BlkIo, BlkIo->Media->MediaId, 0, BLOCK_SIZE, BootSector ); ASSERT_EFI_ERROR (Status); if ((*(UINT32 *) &BootSector[FAT16_VOLUME_ID_OFFSET] != VolumeId) && (*(UINT32 *) &BootSector[FAT32_VOLUME_ID_OFFSET] != VolumeId) ) { Status = EFI_NOT_FOUND; goto ErrHandle; } *Device = DuplicateDevicePath (DevicePathFromHandle (SimpleFileSystemHandle)); ASSERT (*Device != NULL); ErrHandle: return Status; }
/** Return the boot description for the controller based on the type. @param Handle Controller handle. @return The description string. **/ CHAR16 * BmGetMiscDescription ( IN EFI_HANDLE Handle ) { EFI_STATUS Status; CHAR16 *Description; EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs; switch (BmDevicePathType (DevicePathFromHandle (Handle))) { case BmAcpiFloppyBoot: Description = L"Floppy"; break; case BmMessageAtapiBoot: case BmMessageSataBoot: Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo); ASSERT_EFI_ERROR (Status); // // Assume a removable SATA device should be the DVD/CD device // Description = BlockIo->Media->RemovableMedia ? L"DVD/CDROM" : L"Hard Drive"; break; case BmMessageUsbBoot: Description = L"USB Device"; break; case BmMessageScsiBoot: Description = L"SCSI Device"; break; case BmHardwareDeviceBoot: Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo); if (!EFI_ERROR (Status)) { Description = BlockIo->Media->RemovableMedia ? L"Removable Disk" : L"Hard Drive"; } else { Description = L"Misc Device"; } break; default: Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **) &Fs); if (!EFI_ERROR (Status)) { Description = L"Non-Block Boot Device"; } else { Description = L"Misc Device"; } break; } return AllocateCopyPool (StrSize (Description), Description); }
/** Locate all handles that carry the specified protocol, filter them with a callback function, and pass each handle that passes the filter to another callback. @param[in] ProtocolGuid The protocol to look for. @param[in] Filter The filter function to pass each handle to. If this parameter is NULL, then all handles are processed. @param[in] Process The callback function to pass each handle to that clears the filter. **/ STATIC VOID FilterAndProcess ( IN EFI_GUID *ProtocolGuid, IN FILTER_FUNCTION Filter OPTIONAL, IN CALLBACK_FUNCTION Process ) { EFI_STATUS Status; EFI_HANDLE *Handles; UINTN NoHandles; UINTN Idx; Status = gBS->LocateHandleBuffer (ByProtocol, ProtocolGuid, NULL /* SearchKey */, &NoHandles, &Handles); if (EFI_ERROR (Status)) { // // This is not an error, just an informative condition. // DEBUG ((EFI_D_VERBOSE, "%a: %g: %r\n", __FUNCTION__, ProtocolGuid, Status)); return; } ASSERT (NoHandles > 0); for (Idx = 0; Idx < NoHandles; ++Idx) { CHAR16 *DevicePathText; STATIC CHAR16 Fallback[] = L"<device path unavailable>"; // // The ConvertDevicePathToText() function handles NULL input transparently. // DevicePathText = ConvertDevicePathToText ( DevicePathFromHandle (Handles[Idx]), FALSE, // DisplayOnly FALSE // AllowShortcuts ); if (DevicePathText == NULL) { DevicePathText = Fallback; } if (Filter == NULL || Filter (Handles[Idx], DevicePathText)) { Process (Handles[Idx], DevicePathText); } if (DevicePathText != Fallback) { FreePool (DevicePathText); } } gBS->FreePool (Handles); }
EFI_DEVICE_PATH * FileDevicePath ( IN EFI_HANDLE Device OPTIONAL, IN CHAR16 *FileName ) /*++ N.B. Results are allocated from pool. The caller must FreePool the resulting device path structure --*/ { UINTN Size; FILEPATH_DEVICE_PATH *FilePath; EFI_DEVICE_PATH *Eop, *DevicePath; Size = StrSize(FileName); FilePath = (FILEPATH_DEVICE_PATH *) AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH)); DevicePath = (EFI_DEVICE_PATH *) NULL; if (FilePath) { // // Build a file path // FilePath->Header.Type = MEDIA_DEVICE_PATH; FilePath->Header.SubType = MEDIA_FILEPATH_DP; SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH); BS->CopyMem (FilePath->PathName, FileName, Size); Eop = NextDevicePathNode(&FilePath->Header); SetDevicePathEndNode(Eop); // // Append file path to device's device path // DevicePath = (EFI_DEVICE_PATH *) FilePath; if (Device) { DevicePath = AppendDevicePath ( DevicePathFromHandle(Device), DevicePath ); BS->FreePool(FilePath); } } return DevicePath; }
CHAR16 * LibGetUiString ( IN EFI_HANDLE Handle, IN UI_STRING_TYPE StringType, IN ISO_639_2 *LangCode, IN BOOLEAN ReturnDevicePathStrOnMismatch ) { UI_INTERFACE *Ui; UI_STRING_TYPE Index; UI_STRING_ENTRY *Array; EFI_STATUS Status; Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &UiProtocol, (VOID *)&Ui); if (EFI_ERROR(Status)) { return (ReturnDevicePathStrOnMismatch) ? DevicePathToStr(DevicePathFromHandle(Handle)) : NULL; } // // Skip the first strings // for (Index = UiDeviceString, Array = Ui->Entry; Index < StringType; Index++, Array++) { while (Array->LangCode) { Array++; } } // // Search for the match // while (Array->LangCode) { if (strcmpa (Array->LangCode, LangCode) == 0) { return Array->UiString; } } return (ReturnDevicePathStrOnMismatch) ? DevicePathToStr(DevicePathFromHandle(Handle)) : NULL; }
EFI_DEVICE_PATH * FvFileDevicePath ( IN EFI_HANDLE FvHandle, IN EFI_GUID *NameGuid ) { EFI_DEVICE_PATH_PROTOCOL *DevicePath; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH NewNode; DevicePath = DevicePathFromHandle (FvHandle); EfiInitializeFwVolDevicepathNode (&NewNode, NameGuid); return AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&NewNode); }
VOID PlatformRegisterFvBootOption ( EFI_GUID *FileGuid, CHAR16 *Description, UINT32 Attributes ) { EFI_STATUS Status; UINTN OptionIndex; EFI_BOOT_MANAGER_LOAD_OPTION NewOption; EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; UINTN BootOptionCount; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; EFI_DEVICE_PATH_PROTOCOL *DevicePath; Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage); ASSERT_EFI_ERROR (Status); EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); DevicePath = AppendDevicePathNode ( DevicePathFromHandle (LoadedImage->DeviceHandle), (EFI_DEVICE_PATH_PROTOCOL *) &FileNode ); Status = EfiBootManagerInitializeLoadOption ( &NewOption, LoadOptionNumberUnassigned, LoadOptionTypeBoot, Attributes, Description, DevicePath, NULL, 0 ); if (!EFI_ERROR (Status)) { BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot); OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount); if (OptionIndex == -1) { Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1); ASSERT_EFI_ERROR (Status); } EfiBootManagerFreeLoadOption (&NewOption); EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); } }
CHAR8 *get_pci_dev_path(pci_dt_t *PciDt) { // DBG("get_pci_dev_path"); CHAR8* tmp; CHAR16* devpathstr = NULL; EFI_DEVICE_PATH_PROTOCOL* DevicePath = NULL; DevicePath = DevicePathFromHandle (PciDt->DeviceHandle); if (!DevicePath) return NULL; devpathstr = FileDevicePathToStr(DevicePath); tmp = AllocateZeroPool((StrLen(devpathstr)+1)*sizeof(CHAR16)); UnicodeStrToAsciiStr(devpathstr, tmp); return tmp; }
static INTN simple_scheme(device_t *tab, UINTN n) { EFI_DEVICE_PATH *dp1, *dp; devices_types_t *p; UINTN i; /* * note that this test is necessary but not sufficient to guarantee that this scheme * will work because, we have no way of detecting that the machine got actually * rebooted if the EDD30 variable was forced. this comes from the fact, that elilo * can be invoked once, aborted and then restarted with no machine reboot. * * XXX: there may be a way to detect this with the another variable which would * be in volatile memory only */ if (elilo_opt.edd30_on == 0) { VERB_PRT(4, Print(L"%s device naming scheme only works with EDD3.0 enabled\n", NAMING_SCHEME)); return -1; } for(i=0; i < n; i++) { dp = DevicePathFromHandle(tab[i].dev); if (dp == NULL) { ERR_PRT((L"cannot get device path for device %d", i)); continue; } dp1 = dp = UnpackDevicePath(dp); while (!IsDevicePathEnd(dp)) { p = dev_types; while (p->type) { if ( p->type == DevicePathType(dp) && p->subtype == DevicePathSubType(dp)) { (*p->device_func)(tab+i, dp); goto done; } p++; } dp = NextDevicePathNode(dp); } done: FreePool(dp1); } return 0; }
/** Find the platform active active video controller and connect it. @retval EFI_NOT_FOUND There is no active video controller. @retval EFI_SUCCESS The video controller is connected. **/ EFI_STATUS ConnectVideoController ( VOID ) { EFI_HANDLE VideoController; EFI_DEVICE_PATH_PROTOCOL *Gop; // // Get the platform vga device // VideoController = GetVideoController (); if (VideoController == NULL) { return EFI_NOT_FOUND; } // // Try to connect the PCI device path, so that GOP dirver could start on this // device and create child handles with GraphicsOutput Protocol installed // on them, then we get device paths of these child handles and select // them as possible console device. // gBS->ConnectController (VideoController, NULL, NULL, FALSE); Gop = EfiBootManagerGetGopDevicePath (VideoController); if (Gop == NULL) { // // Last chance - just try VGA controller // Don't assume all VGA controller support GOP operation // DEBUG ((EFI_D_ERROR, "[Bds] GOP not found, try VGA device path!\n")); Gop = DuplicateDevicePath (DevicePathFromHandle (VideoController)); if (Gop == NULL) { return EFI_NOT_FOUND; } } EfiBootManagerUpdateConsoleVariable (ConOut, Gop, NULL); FreePool (Gop); // // Necessary for ConPlatform and ConSplitter driver to start up again after ConOut is updated. // return gBS->ConnectController (VideoController, NULL, NULL, TRUE); }
STATIC EFI_STATUS CreatePlatformBootOptionFromGuid ( IN EFI_GUID *FileGuid, IN CHAR16 *Description, IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *BootOption ) { EFI_STATUS Status; EFI_DEVICE_PATH *DevicePath; EFI_DEVICE_PATH *TempDevicePath; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; Status = gBS->HandleProtocol ( gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage ); ASSERT_EFI_ERROR (Status); EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); TempDevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle); ASSERT (TempDevicePath != NULL); DevicePath = AppendDevicePathNode ( TempDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &FileNode ); ASSERT (DevicePath != NULL); Status = EfiBootManagerInitializeLoadOption ( BootOption, LoadOptionNumberUnassigned, LoadOptionTypeBoot, LOAD_OPTION_ACTIVE, Description, DevicePath, NULL, 0 ); FreePool (DevicePath); return Status; }
/** Generate device path include the input file guid info. @param FileGuid Input file guid for the BootManagerMenuApp. @retval DevicePath for BootManagerMenuApp. **/ EFI_DEVICE_PATH * FvFilePath ( EFI_GUID *FileGuid ) { EFI_STATUS Status; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); Status = gBS->HandleProtocol ( gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage ); ASSERT_EFI_ERROR (Status); return AppendDevicePathNode ( DevicePathFromHandle (LoadedImage->DeviceHandle), (EFI_DEVICE_PATH_PROTOCOL *) &FileNode ); }
/** Binds exclusively to serial io on the controller handle, Produces DebugPort protocol and DevicePath on new handle. @param This Protocol instance pointer. @param ControllerHandle Handle of device to bind driver to. @param RemainingDevicePath Optional parameter use to pick a specific child device to start. @retval EFI_SUCCESS This driver is added to ControllerHandle. @retval EFI_OUT_OF_RESOURCES Fails to allocate memory for device. @retval others Some error occurs. **/ EFI_STATUS EFIAPI DebugPortStart ( IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) { EFI_STATUS Status; DEBUGPORT_DEVICE_PATH DebugPortDP; EFI_DEVICE_PATH_PROTOCOL EndDP; EFI_DEVICE_PATH_PROTOCOL *Dp1; Status = gBS->OpenProtocol ( ControllerHandle, &gEfiSerialIoProtocolGuid, (VOID **) &mDebugPortDevice.SerialIoBinding, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE ); if (EFI_ERROR (Status)) { return Status; } mDebugPortDevice.SerialIoDeviceHandle = ControllerHandle; // // Initialize the Serial Io interface... // Status = mDebugPortDevice.SerialIoBinding->SetAttributes ( mDebugPortDevice.SerialIoBinding, mDebugPortDevice.BaudRate, mDebugPortDevice.ReceiveFifoDepth, mDebugPortDevice.Timeout, mDebugPortDevice.Parity, mDebugPortDevice.DataBits, mDebugPortDevice.StopBits ); if (EFI_ERROR (Status)) { mDebugPortDevice.BaudRate = 0; mDebugPortDevice.Parity = DefaultParity; mDebugPortDevice.DataBits = 0; mDebugPortDevice.StopBits = DefaultStopBits; mDebugPortDevice.ReceiveFifoDepth = 0; Status = mDebugPortDevice.SerialIoBinding->SetAttributes ( mDebugPortDevice.SerialIoBinding, mDebugPortDevice.BaudRate, mDebugPortDevice.ReceiveFifoDepth, mDebugPortDevice.Timeout, mDebugPortDevice.Parity, mDebugPortDevice.DataBits, mDebugPortDevice.StopBits ); if (EFI_ERROR (Status)) { gBS->CloseProtocol ( ControllerHandle, &gEfiSerialIoProtocolGuid, This->DriverBindingHandle, ControllerHandle ); return Status; } } mDebugPortDevice.SerialIoBinding->Reset (mDebugPortDevice.SerialIoBinding); // // Create device path instance for DebugPort // DebugPortDP.Header.Type = MESSAGING_DEVICE_PATH; DebugPortDP.Header.SubType = MSG_VENDOR_DP; SetDevicePathNodeLength (&(DebugPortDP.Header), sizeof (DebugPortDP)); CopyGuid (&DebugPortDP.Guid, &gEfiDebugPortDevicePathGuid); Dp1 = DevicePathFromHandle (ControllerHandle); if (Dp1 == NULL) { Dp1 = &EndDP; SetDevicePathEndNode (Dp1); } mDebugPortDevice.DebugPortDevicePath = AppendDevicePathNode (Dp1, (EFI_DEVICE_PATH_PROTOCOL *) &DebugPortDP); if (mDebugPortDevice.DebugPortDevicePath == NULL) { return EFI_OUT_OF_RESOURCES; } // // Publish DebugPort and Device Path protocols // Status = gBS->InstallMultipleProtocolInterfaces ( &mDebugPortDevice.DebugPortDeviceHandle, &gEfiDevicePathProtocolGuid, mDebugPortDevice.DebugPortDevicePath, &gEfiDebugPortProtocolGuid, &mDebugPortDevice.DebugPortInterface, NULL ); if (EFI_ERROR (Status)) { gBS->CloseProtocol ( ControllerHandle, &gEfiSerialIoProtocolGuid, This->DriverBindingHandle, ControllerHandle ); return Status; } // // Connect debugport child to serial io // Status = gBS->OpenProtocol ( ControllerHandle, &gEfiSerialIoProtocolGuid, (VOID **) &mDebugPortDevice.SerialIoBinding, This->DriverBindingHandle, mDebugPortDevice.DebugPortDeviceHandle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ); if (EFI_ERROR (Status)) { gBS->CloseProtocol ( ControllerHandle, &gEfiSerialIoProtocolGuid, This->DriverBindingHandle, ControllerHandle ); return Status; } return EFI_SUCCESS; }
/** This function build the FsOptionMenu list which records all available file system in the system. They includes all instances of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM. @retval EFI_SUCCESS Success find the file system @retval EFI_OUT_OF_RESOURCES Can not create menu entry **/ EFI_STATUS LibFindFileSystem ( VOID ) { UINTN NoSimpleFsHandles; EFI_HANDLE *SimpleFsHandle; UINT16 *VolumeLabel; UINTN Index; EFI_STATUS Status; MENU_ENTRY *MenuEntry; FILE_CONTEXT *FileContext; UINTN OptionNumber; EFI_FILE_SYSTEM_VOLUME_LABEL *Info; NoSimpleFsHandles = 0; OptionNumber = 0; // // Locate Handles that support Simple File System protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &NoSimpleFsHandles, &SimpleFsHandle ); if (!EFI_ERROR (Status)) { // // Find all the instances of the File System prototocol // for (Index = 0; Index < NoSimpleFsHandles; Index++) { // // Allocate pool for this load option // MenuEntry = LibCreateMenuEntry (); if (NULL == MenuEntry) { FreePool (SimpleFsHandle); return EFI_OUT_OF_RESOURCES; } FileContext = (FILE_CONTEXT *) MenuEntry->VariableContext; FileContext->DeviceHandle = SimpleFsHandle[Index]; FileContext->FileHandle = LibOpenRoot (FileContext->DeviceHandle); if (FileContext->FileHandle == NULL) { LibDestroyMenuEntry (MenuEntry); continue; } MenuEntry->HelpString = LibDevicePathToStr (DevicePathFromHandle (FileContext->DeviceHandle)); FileContext->FileName = LibStrDuplicate (L"\\"); FileContext->DevicePath = FileDevicePath (FileContext->DeviceHandle, FileContext->FileName); FileContext->IsDir = TRUE; FileContext->IsRoot = TRUE; // // Get current file system's Volume Label // Info = (EFI_FILE_SYSTEM_VOLUME_LABEL *) LibFileInfo (FileContext->FileHandle, &gEfiFileSystemVolumeLabelInfoIdGuid); if (Info == NULL) { VolumeLabel = L"NO FILE SYSTEM INFO"; } else { if (Info->VolumeLabel == NULL) { VolumeLabel = L"NULL VOLUME LABEL"; } else { VolumeLabel = Info->VolumeLabel; if (*VolumeLabel == 0x0000) { VolumeLabel = L"NO VOLUME LABEL"; } } } MenuEntry->DisplayString = AllocateZeroPool (MAX_CHAR); ASSERT (MenuEntry->DisplayString != NULL); UnicodeSPrint ( MenuEntry->DisplayString, MAX_CHAR, L"%s, [%s]", VolumeLabel, MenuEntry->HelpString ); MenuEntry->DisplayStringToken = HiiSetString ( gFileExplorerPrivate.FeHiiHandle, 0, MenuEntry->DisplayString, NULL ); if (Info != NULL) FreePool (Info); OptionNumber++; InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &MenuEntry->Link); } } if (NoSimpleFsHandles != 0) { FreePool (SimpleFsHandle); } gFileExplorerPrivate.FsOptionMenu->MenuNumber = OptionNumber; return EFI_SUCCESS; }
EFI_STATUS add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *label, CHAR16 *arguments) { CHAR16 *fullpath = NULL; UINT64 pathlen = 0; EFI_STATUS rc = EFI_SUCCESS; rc = make_full_path(dirname, filename, &fullpath, &pathlen); if (EFI_ERROR(rc)) return rc; EFI_DEVICE_PATH *dph = NULL; EFI_DEVICE_PATH *file = NULL; EFI_DEVICE_PATH *full_device_path = NULL; EFI_DEVICE_PATH *dp = NULL; dph = DevicePathFromHandle(this_image->DeviceHandle); if (!dph) { rc = EFI_OUT_OF_RESOURCES; goto err; } file = FileDevicePath(fh, fullpath); if (!file) { rc = EFI_OUT_OF_RESOURCES; goto err; } full_device_path = AppendDevicePath(dph, file); if (!full_device_path) { rc = EFI_OUT_OF_RESOURCES; goto err; } rc = FindSubDevicePath(full_device_path, MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, &dp); if (EFI_ERROR(rc)) { if (rc == EFI_NOT_FOUND) { dp = full_device_path; } else { rc = EFI_OUT_OF_RESOURCES; goto err; } } #ifdef DEBUG_FALLBACK { UINTN s = DevicePathSize(dp); UINTN i; UINT8 *dpv = (void *)dp; for (i = 0; i < s; i++) { if (i > 0 && i % 16 == 0) Print(L"\n"); Print(L"%02x ", dpv[i]); } Print(L"\n"); CHAR16 *dps = DevicePathToStr(dp); Print(L"device path: \"%s\"\n", dps); } #endif UINT16 option; rc = find_boot_option(dp, full_device_path, fullpath, label, arguments, &option); if (EFI_ERROR(rc)) { add_boot_option(dp, full_device_path, fullpath, label, arguments); } else if (option != 0) { CHAR16 *newbootorder; newbootorder = AllocateZeroPool(sizeof (CHAR16) * nbootorder); if (!newbootorder) return EFI_OUT_OF_RESOURCES; newbootorder[0] = bootorder[option]; CopyMem(newbootorder + 1, bootorder, sizeof (CHAR16) * option); CopyMem(newbootorder + option + 1, bootorder + option + 1, sizeof (CHAR16) * (nbootorder - option - 1)); FreePool(bootorder); bootorder = newbootorder; } err: if (file) FreePool(file); if (full_device_path) FreePool(full_device_path); if (dp) FreePool(dp); if (fullpath) FreePool(fullpath); return rc; }
EFI_DEVICE_PATH * FvFilePath ( UINTN FvBaseAddress, UINTN FvSize, EFI_GUID *FileGuid ) { EFI_STATUS Status; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; EFI_HANDLE FvProtocolHandle; EFI_HANDLE *FvHandleBuffer; UINTN FvHandleCount; EFI_FV_FILETYPE Type; UINTN Size; EFI_FV_FILE_ATTRIBUTES Attributes; UINT32 AuthenticationStatus; EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; UINTN Index; EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); if (FvBaseAddress == 0) { Status = gBS->HandleProtocol ( gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage ); ASSERT_EFI_ERROR (Status); return AppendDevicePathNode ( DevicePathFromHandle (LoadedImage->DeviceHandle), (EFI_DEVICE_PATH_PROTOCOL *) &FileNode ); } else { // // Expose Payload file in FV // gDS->ProcessFirmwareVolume ( (VOID *)FvBaseAddress, (UINT32)FvSize, &FvProtocolHandle ); // // Find out the handle of FV containing the playload file // FvHandleBuffer = NULL; gBS->LocateHandleBuffer ( ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &FvHandleCount, &FvHandleBuffer ); for (Index = 0; Index < FvHandleCount; Index++) { gBS->HandleProtocol ( FvHandleBuffer[Index], &gEfiFirmwareVolume2ProtocolGuid, (VOID **) &Fv ); Status = Fv->ReadFile ( Fv, FileGuid, NULL, &Size, &Type, &Attributes, &AuthenticationStatus ); if (!EFI_ERROR (Status)) { break; } } if (Index < FvHandleCount) { return AppendDevicePathNode ( DevicePathFromHandle (FvHandleBuffer[Index]), ( EFI_DEVICE_PATH_PROTOCOL *) &FileNode ); } } return NULL; }
VOID UpdateConOut ( VOID ) { EFI_HANDLE VideoController; EFI_DEVICE_PATH_PROTOCOL *Gop; EFI_HANDLE OnboardVideoController = NULL; EFI_HANDLE AddinVideoController = NULL; UINTN VideoSelect; // // Get the platform vga device // VideoController = PlatformGetVideoController (&OnboardVideoController, &AddinVideoController); if (VideoController == NULL) { return ; } // Force to Auto VideoSelect = 0; // If device selected by SystemConfig is not present, force to Auto if (VideoSelect == 1 && OnboardVideoController == NULL) { VideoSelect = 0; } if (VideoSelect == 2 && AddinVideoController == NULL) { VideoSelect = 0; } switch(VideoSelect) { case 1: // Onboard selected VideoController = OnboardVideoController; DEBUG((EFI_D_INFO, "Video select: Onboard\n")); break; case 2: // Add-in selected VideoController = AddinVideoController; DEBUG((EFI_D_INFO, "Video select: Add-in\n")); break; case 0: default: // Use first VideoController found, which is what GetVideoController returns as VideoController DEBUG((EFI_D_INFO, "Video select: Auto\n")); break; } // // Try to connect the PCI device path, so that GOP dirver could start on this // device and create child handles with GraphicsOutput Protocol installed // on them, then we get device paths of these child handles and select // them as possible console device. // gBS->ConnectController (VideoController, NULL, NULL, FALSE); Gop = EfiBootManagerGetGopDevicePath (VideoController); if (Gop == NULL) { return ; } // // Update ConOut variable to remove device path of on-board/add-in video controller // and add the device path of the specified video controller // EfiBootManagerUpdateConsoleVariable (ConOut, NULL, DevicePathFromHandle (OnboardVideoController)); EfiBootManagerUpdateConsoleVariable (ConOut, Gop, DevicePathFromHandle (AddinVideoController)); FreePool (Gop); }
/** Execute registered handlers until one returns an error and that error is returned. If none of the handlers return an error, then EFI_SUCCESS is returned. Before exectue handler, get the image buffer by file device path if a handler requires the image file. And return the image buffer to each handler when exectue handler. The handlers are executed in same order to their registered order. @param[in] AuthenticationStatus This is the authentication type returned from the Section Extraction protocol. See the Section Extraction Protocol Specification for details on this type. @param[in] FilePath This is a pointer to the device path of the file that is being dispatched. This will optionally be used for logging. @retval EFI_SUCCESS The file specified by File did authenticate when more than one security handler services were registered, or the file did not authenticate when no security handler service was registered. And the platform policy dictates that the DXE Core may use File. @retval EFI_INVALID_PARAMETER File is NULL. @retval EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and the platform policy dictates that File should be placed in the untrusted state. A file may be promoted from the untrusted to the trusted state at a future time with a call to the Trust() DXE Service. @retval EFI_ACCESS_DENIED The file specified by File did not authenticate, and the platform policy dictates that File should not be used for any purpose. **/ EFI_STATUS EFIAPI ExecuteSecurityHandlers ( IN UINT32 AuthenticationStatus, IN CONST EFI_DEVICE_PATH_PROTOCOL *FilePath ) { UINT32 Index; EFI_STATUS Status; UINT32 HandlerAuthenticationStatus; VOID *FileBuffer; UINTN FileSize; EFI_HANDLE Handle; EFI_DEVICE_PATH_PROTOCOL *Node; EFI_DEVICE_PATH_PROTOCOL *FilePathToVerfiy; if (FilePath == NULL) { return EFI_INVALID_PARAMETER; } // // Directly return successfully when no handler is registered. // if (mNumberOfSecurityHandler == 0) { return EFI_SUCCESS; } Status = EFI_SUCCESS; FileBuffer = NULL; FileSize = 0; HandlerAuthenticationStatus = AuthenticationStatus; FilePathToVerfiy = (EFI_DEVICE_PATH_PROTOCOL *) FilePath; // // Run security handler in same order to their registered list // for (Index = 0; Index < mNumberOfSecurityHandler; Index ++) { if ((mSecurityTable[Index].SecurityOperation & EFI_AUTH_OPERATION_IMAGE_REQUIRED) == EFI_AUTH_OPERATION_IMAGE_REQUIRED) { // // Try get file buffer when the handler requires image buffer. // if (FileBuffer == NULL) { Node = FilePathToVerfiy; Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &Node, &Handle); // // Try to get image by FALSE boot policy for the exact boot file path. // FileBuffer = GetFileBufferByFilePath (FALSE, FilePath, &FileSize, &AuthenticationStatus); if (FileBuffer == NULL) { // // Try to get image by TRUE boot policy for the inexact boot file path. // FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, &FileSize, &AuthenticationStatus); } if ((FileBuffer != NULL) && (!EFI_ERROR (Status))) { // // LoadFile () may cause the device path of the Handle be updated. // FilePathToVerfiy = AppendDevicePath (DevicePathFromHandle (Handle), Node); } } } Status = mSecurityTable[Index].SecurityHandler ( HandlerAuthenticationStatus, FilePathToVerfiy, FileBuffer, FileSize ); if (EFI_ERROR (Status)) { break; } } if (FileBuffer != NULL) { FreePool (FileBuffer); } if (FilePathToVerfiy != FilePath) { FreePool (FilePathToVerfiy); } return Status; }
/** Update the form to include the driver health instances. @param ConfigureOnly Only include the configure required driver health instances when TRUE, include all the driver health instances otherwise. **/ VOID DriverHealthManagerUpdateForm ( BOOLEAN ConfigureOnly ) { EFI_STATUS Status; EFI_IFR_GUID_LABEL *StartLabel; EFI_IFR_GUID_LABEL *EndLabel; VOID *StartOpCodeHandle; VOID *EndOpCodeHandle; UINTN Index; EFI_STRING_ID Prompt; EFI_STRING_ID Help; CHAR16 String[512]; UINTN StringCount; EFI_STRING TmpString; EFI_STRING DriverName; EFI_STRING ControllerName; UINTN MessageIndex; EFI_HANDLE DriverHandle; EFI_STRING_ID DevicePath; EFI_GUID FormsetGuid; EfiBootManagerFreeDriverHealthInfo (mDriverHealthManagerHealthInfo, mDriverHealthManagerHealthInfoCount); mDriverHealthManagerHealthInfo = EfiBootManagerGetDriverHealthInfo (&mDriverHealthManagerHealthInfoCount); // // Allocate space for creation of UpdateData Buffer // StartOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (StartOpCodeHandle != NULL); EndOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (EndOpCodeHandle != NULL); // // Create Hii Extend Label OpCode as the start opcode // StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; StartLabel->Number = LABEL_BEGIN; // // Create Hii Extend Label OpCode as the end opcode // EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; EndLabel->Number = LABEL_END; for (Index = 0; Index < mDriverHealthManagerHealthInfoCount; Index++) { if (ConfigureOnly && mDriverHealthManagerHealthInfo[Index].HealthStatus != EfiDriverHealthStatusConfigurationRequired) { continue; } DriverName = DriverHealthManagerGetDriverName (mDriverHealthManagerHealthInfo[Index].DriverHealthHandle); ASSERT (DriverName != NULL); if (mDriverHealthManagerHealthInfo[Index].ControllerHandle == NULL) { // // The ControllerHandle is set to NULL and the HealthStatus is set to EfiDriverHealthStatusHealthy // if all the controllers managed by the driver are in healthy state. // ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy); UnicodeSPrint (String, sizeof (String), L"%s", DriverName); } else { ControllerName = DriverHealthManagerGetControllerName ( mDriverHealthManagerHealthInfo[Index].DriverHealthHandle, mDriverHealthManagerHealthInfo[Index].ControllerHandle, mDriverHealthManagerHealthInfo[Index].ChildHandle ); ASSERT (ControllerName != NULL); UnicodeSPrint (String, sizeof (String), L"%s %s", DriverName, ControllerName); FreePool (ControllerName); } FreePool (DriverName); Prompt = HiiSetString (mDriverHealthManagerHiiHandle, 0, String, NULL); switch(mDriverHealthManagerHealthInfo[Index].HealthStatus) { case EfiDriverHealthStatusRepairRequired: TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_REPAIR_REQUIRED), NULL); break; case EfiDriverHealthStatusConfigurationRequired: TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_CONFIGURATION_REQUIRED), NULL); break; case EfiDriverHealthStatusFailed: TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_FAILED), NULL); break; case EfiDriverHealthStatusReconnectRequired: TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_RECONNECT_REQUIRED), NULL); break; case EfiDriverHealthStatusRebootRequired: TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_REBOOT_REQUIRED), NULL); break; default: ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy); TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_HEALTHY), NULL); break; } StringCount = UnicodeSPrint (String, sizeof (String), L"%s\n", TmpString); FreePool (TmpString); // // Add the message of the Module itself provided as the help. // if (mDriverHealthManagerHealthInfo[Index].MessageList != NULL) { for (MessageIndex = 0; mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].HiiHandle != NULL; MessageIndex++) { TmpString = HiiGetString ( mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].HiiHandle, mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].StringId, NULL ); StringCount += UnicodeSPrint (String + StringCount, sizeof (String) - sizeof (String[0]) * StringCount, L"\n%s", TmpString); FreePool (TmpString); } } Help = HiiSetString (mDriverHealthManagerHiiHandle, 0, String, NULL); switch (mDriverHealthManagerHealthInfo[Index].HealthStatus) { case EfiDriverHealthStatusConfigurationRequired: Status = mDriverHealthManagerDatabase->GetPackageListHandle ( mDriverHealthManagerDatabase, mDriverHealthManagerHealthInfo[Index].HiiHandle, &DriverHandle ); ASSERT_EFI_ERROR (Status); TmpString = ConvertDevicePathToText (DevicePathFromHandle (DriverHandle), FALSE, TRUE); DevicePath = HiiSetString (mDriverHealthManagerHiiHandle, 0, TmpString, NULL); FreePool (TmpString); Status = DriverHealthManagerGetFormsetId (mDriverHealthManagerHealthInfo[Index].HiiHandle, &FormsetGuid); ASSERT_EFI_ERROR (Status); HiiCreateGotoExOpCode ( StartOpCodeHandle, 0, Prompt, Help, 0, 0, 0, &FormsetGuid, DevicePath ); break; case EfiDriverHealthStatusRepairRequired: case EfiDriverHealthStatusReconnectRequired: case EfiDriverHealthStatusRebootRequired: HiiCreateActionOpCode ( StartOpCodeHandle, (EFI_QUESTION_ID) (Index + QUESTION_ID_DRIVER_HEALTH_BASE), Prompt, Help, EFI_IFR_FLAG_CALLBACK, 0 ); break; default: ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy || mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusFailed); HiiCreateTextOpCode ( StartOpCodeHandle, Prompt, Help, 0 ); break; } } Status = HiiUpdateForm ( mDriverHealthManagerHiiHandle, ConfigureOnly ? PcdGetPtr (PcdDriverHealthConfigureForm) : &mDriverHealthManagerForm, DRIVER_HEALTH_FORM_ID, StartOpCodeHandle, EndOpCodeHandle ); ASSERT_EFI_ERROR (Status); HiiFreeOpCodeHandle (StartOpCodeHandle); HiiFreeOpCodeHandle (EndOpCodeHandle); }
static EFI_STATUS EFIAPI FSBindingStart(EFI_DRIVER_BINDING_PROTOCOL *This, EFI_HANDLE ControllerHandle, EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath) { EFI_STATUS Status; EFI_FS *Instance; EFI_DEVICE_PATH *DevicePath; PrintDebug(L"FSBindingStart\n"); /* Allocate a new instance of a filesystem */ Instance = AllocateZeroPool(sizeof(EFI_FS)); if (Instance == NULL) { Status = EFI_OUT_OF_RESOURCES; PrintStatusError(Status, L"Could not allocate a new file system instance"); return Status; } Instance->FileIoInterface.Revision = EFI_FILE_IO_INTERFACE_REVISION; Instance->FileIoInterface.OpenVolume = FileOpenVolume, /* Fill the device path for our instance */ DevicePath = DevicePathFromHandle(ControllerHandle); if (DevicePath == NULL) { Status = EFI_NO_MAPPING; PrintStatusError(Status, L"Could not get Device Path"); goto error; } Instance->DevicePathString = DevicePathToStr(DevicePath); if (Instance->DevicePathString == NULL) { Status = EFI_OUT_OF_RESOURCES; PrintStatusError(Status, L"Could not allocate Device Path string"); goto error; } /* Get access to the Block IO protocol for this controller */ Status = BS->OpenProtocol(ControllerHandle, &BlockIoProtocol, (VOID **) &Instance->BlockIo, This->DriverBindingHandle, ControllerHandle, /* http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES#OpenProtocol.28.29 * EFI_OPEN_PROTOCOL_BY_DRIVER returns Access Denied here, most likely * because the disk driver has that protocol already open. So we use * EFI_OPEN_PROTOCOL_GET_PROTOCOL (which doesn't require us to close it) */ EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(Status)) { PrintStatusError(Status, L"Could not access BlockIO protocol"); goto error; } /* Get exclusive access to the Disk IO protocol */ Status = BS->OpenProtocol(ControllerHandle, &DiskIoProtocol, (VOID**) &Instance->DiskIo, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); if (EFI_ERROR(Status)) { PrintStatusError(Status, L"Could not access the DiskIo protocol"); goto error; } /* Go through GRUB target init */ Status = GrubDeviceInit(Instance); if (EFI_ERROR(Status)) { PrintStatusError(Status, L"Could not init grub device"); goto error; } Status = FSInstall(Instance, ControllerHandle); /* Unless we close the DiskIO protocol in case of error, no other * FS driver will be able to access this partition. */ if (EFI_ERROR(Status)) { GrubDeviceExit(Instance); BS->CloseProtocol(ControllerHandle, &DiskIoProtocol, This->DriverBindingHandle, ControllerHandle); } error: if (EFI_ERROR(Status)) FreeFsInstance(Instance); return Status; }
/** Function to initialize the table for creating consistent map names. @param[out] Table The pointer to pointer to pointer to DevicePathProtocol object. @retval EFI_SUCCESS The table was created successfully. **/ EFI_STATUS EFIAPI ShellCommandConsistMappingInitialize ( OUT EFI_DEVICE_PATH_PROTOCOL ***Table ) { EFI_HANDLE *HandleBuffer; UINTN HandleNum; UINTN HandleLoop; EFI_DEVICE_PATH_PROTOCOL **TempTable; EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *HIDevicePath; UINTN Index; EFI_STATUS Status; HandleBuffer = NULL; Status = gBS->LocateHandleBuffer ( AllHandles, NULL, NULL, &HandleNum, &HandleBuffer ); ASSERT_EFI_ERROR(Status); TempTable = AllocateZeroPool ((HandleNum + 1) * sizeof (EFI_DEVICE_PATH_PROTOCOL *)); if (TempTable == NULL) { return EFI_OUT_OF_RESOURCES; } for (HandleLoop = 0 ; HandleLoop < HandleNum ; HandleLoop++) { DevicePath = DevicePathFromHandle (HandleBuffer[HandleLoop]); if (DevicePath == NULL) { continue; } HIDevicePath = GetHIDevicePath (DevicePath); if (HIDevicePath == NULL) { continue; } for (Index = 0; TempTable[Index] != NULL; Index++) { if (DevicePathCompare (&TempTable[Index], &HIDevicePath) == 0) { FreePool (HIDevicePath); break; } } if (TempTable[Index] == NULL) { TempTable[Index] = HIDevicePath; } } for (Index = 0; TempTable[Index] != NULL; Index++); PerformQuickSort(TempTable, Index, sizeof(EFI_DEVICE_PATH_PROTOCOL*), DevicePathCompare); *Table = TempTable; if (HandleBuffer != NULL) { FreePool (HandleBuffer); } return EFI_SUCCESS; }
/** Emuerate all possible bootable medias in the following order: 1. Removable BlockIo - The boot option only points to the removable media device, like USB key, DVD, Floppy etc. 2. Fixed BlockIo - The boot option only points to a Fixed blockIo device, like HardDisk. 3. Non-BlockIo SimpleFileSystem - The boot option points to a device supporting SimpleFileSystem Protocol, but not supporting BlockIo protocol. 4. LoadFile - The boot option points to the media supporting LoadFile protocol. Reference: UEFI Spec chapter 3.3 Boot Option Variables Default Boot Behavior @param BootOptionCount Return the boot option count which has been found. @retval Pointer to the boot option array. **/ EFI_BOOT_MANAGER_LOAD_OPTION * BdsEnumerateBootOptions ( UINTN *BootOptionCount ) { EFI_STATUS Status; EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; UINTN HandleCount; EFI_HANDLE *Handles; EFI_BLOCK_IO_PROTOCOL *BlkIo; UINTN Removable; UINTN Index; ASSERT (BootOptionCount != NULL); *BootOptionCount = 0; BootOptions = NULL; // // Parse removable block io followed by fixed block io // gBS->LocateHandleBuffer ( ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &HandleCount, &Handles ); for (Removable = 0; Removable < 2; Removable++) { for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol ( Handles[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlkIo ); if (EFI_ERROR (Status)) { continue; } // // Skip the logical partitions // if (BlkIo->Media->LogicalPartition) { continue; } // // Skip the fixed block io then the removable block io // if (BlkIo->Media->RemovableMedia == ((Removable == 0) ? FALSE : TRUE)) { continue; } BootOptions = ReallocatePool ( sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount), sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1), BootOptions ); ASSERT (BootOptions != NULL); Status = EfiBootManagerInitializeLoadOption ( &BootOptions[(*BootOptionCount)++], LoadOptionNumberUnassigned, LoadOptionTypeBoot, LOAD_OPTION_ACTIVE, mRecoveryBoot, DevicePathFromHandle (Handles[Index]), NULL, 0 ); ASSERT_EFI_ERROR (Status); } } if (HandleCount != 0) { FreePool (Handles); } // // Parse simple file system not based on block io // gBS->LocateHandleBuffer ( ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles ); for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol ( Handles[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlkIo ); if (!EFI_ERROR (Status)) { // // Skip if the file system handle supports a BlkIo protocol, which we've handled in above // continue; } BootOptions = ReallocatePool ( sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount), sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1), BootOptions ); ASSERT (BootOptions != NULL); Status = EfiBootManagerInitializeLoadOption ( &BootOptions[(*BootOptionCount)++], LoadOptionNumberUnassigned, LoadOptionTypeBoot, LOAD_OPTION_ACTIVE, mRecoveryBoot, DevicePathFromHandle (Handles[Index]), NULL, 0 ); ASSERT_EFI_ERROR (Status); } if (HandleCount != 0) { FreePool (Handles); } // // Parse load file, assuming UEFI Network boot option // gBS->LocateHandleBuffer ( ByProtocol, &gEfiLoadFileProtocolGuid, NULL, &HandleCount, &Handles ); for (Index = 0; Index < HandleCount; Index++) { BootOptions = ReallocatePool ( sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount), sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (*BootOptionCount + 1), BootOptions ); ASSERT (BootOptions != NULL); Status = EfiBootManagerInitializeLoadOption ( &BootOptions[(*BootOptionCount)++], LoadOptionNumberUnassigned, LoadOptionTypeBoot, LOAD_OPTION_ACTIVE, mRecoveryBoot, DevicePathFromHandle (Handles[Index]), NULL, 0 ); ASSERT_EFI_ERROR (Status); } if (HandleCount != 0) { FreePool (Handles); } return BootOptions; }