示例#1
0
/**
  Update the component name for the Tcp4 child handle.

  @param  Tcp4[in]                   A pointer to the EFI_TCP4_PROTOCOL.


  @retval EFI_SUCCESS                Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER      The input parameter is invalid.

**/
EFI_STATUS
UpdateTcp4Name (
  IN    EFI_TCP4_PROTOCOL             *Tcp4
  )
{
  EFI_STATUS                       Status;
  CHAR16                           HandleName[80];
  EFI_TCP4_CONFIG_DATA             Tcp4ConfigData;

  if (Tcp4 == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Format the child name into the string buffer as:
  // TCPv4 (SrcPort=59, DestPort=60, ActiveFlag=TRUE)
  //
  ZeroMem (&Tcp4ConfigData, sizeof (Tcp4ConfigData));
  Status = Tcp4->GetModeData (Tcp4, NULL, &Tcp4ConfigData, NULL, NULL, NULL);
  if (!EFI_ERROR (Status)) {
    UnicodeSPrint (HandleName, sizeof (HandleName),
      L"TCPv4 (SrcPort=%d, DestPort=%d, ActiveFlag=%s)",
      Tcp4ConfigData.AccessPoint.StationPort,
      Tcp4ConfigData.AccessPoint.RemotePort,
      (Tcp4ConfigData.AccessPoint.ActiveFlag ? L"TRUE" : L"FALSE")
      );
  } else if (Status == EFI_NOT_STARTED) {
    UnicodeSPrint (
      HandleName,
      sizeof (HandleName),
      L"TCPv4 (Not started)"
      );
  } else {
    return Status;
  }

  if (gTcpControllerNameTable != NULL) {
    FreeUnicodeStringTable (gTcpControllerNameTable);
    gTcpControllerNameTable = NULL;
  }

  Status = AddUnicodeString2 (
             "eng",
             gTcpComponentName.SupportedLanguages,
             &gTcpControllerNameTable,
             HandleName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return AddUnicodeString2 (
           "en",
           gTcpComponentName2.SupportedLanguages,
           &gTcpControllerNameTable,
           HandleName,
           FALSE
           );
}
示例#2
0
/**
  DevicePathNode must be IPv6 type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
**/
VOID
EFIAPI
DevPathSerialIPv6 (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
  )
{
  IPv6_DEVICE_PATH  *Ip;
  UINTN             Index;
  CHAR16            Buffer[64];
  CHAR16            *PBuffer;

  ASSERT(DevicePathNode != NULL);
  ASSERT(MappingItem != NULL);

  Ip = (IPv6_DEVICE_PATH *) DevicePathNode;
  for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
    UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Ip->LocalIpAddress.Addr[Index]);
  }

  AppendCSDStr (MappingItem, Buffer);
  AppendCSDNum (MappingItem, Ip->LocalPort);
  for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
    UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Ip->RemoteIpAddress.Addr[Index]);
  }

  AppendCSDStr (MappingItem, Buffer);
  AppendCSDNum (MappingItem, Ip->RemotePort);
}
示例#3
0
EFI_STATUS
BdsLoadOptionPxeList (
  IN OUT LIST_ENTRY* BdsLoadOptionList
  )
{
  EFI_STATUS                        Status;
  UINTN                             HandleCount;
  EFI_HANDLE                        *HandleBuffer;
  UINTN                             Index;
  BDS_SUPPORTED_DEVICE              *SupportedDevice;
  EFI_DEVICE_PATH_PROTOCOL*         DevicePathProtocol;
  EFI_SIMPLE_NETWORK_PROTOCOL*      SimpleNet;
  CHAR16                            DeviceDescription[BOOT_DEVICE_DESCRIPTION_MAX];
  EFI_MAC_ADDRESS                   *Mac;
  EFI_DEVICE_PATH_PROTOCOL          *DevicePathNode;

  
  // List all the PXE Protocols
  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiPxeBaseCodeProtocolGuid, NULL, &HandleCount, &HandleBuffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  for (Index = 0; Index < HandleCount; Index++) {
    // We only select the handle WITH a Device Path AND the PXE Protocol
    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);
    if (!EFI_ERROR(Status)) {
      // Allocate BDS Supported Device structure
      SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));

      //Status = gBS->LocateProtocol (&gEfiSimpleNetworkProtocolGuid, NULL, (VOID **)&SimpleNet);
       Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleNetworkProtocolGuid, (VOID **)&SimpleNet);   
      if (!EFI_ERROR(Status)) {
        Mac = &SimpleNet->Mode->CurrentAddress;
        UnicodeSPrint (DeviceDescription,BOOT_DEVICE_DESCRIPTION_MAX,L"MAC Address: %02x:%02x:%02x:%02x:%02x:%02x", Mac->Addr[0],  Mac->Addr[1],  Mac->Addr[2],  Mac->Addr[3],  Mac->Addr[4],  Mac->Addr[5]);
      } else {
        Status = GenerateDeviceDescriptionName (HandleBuffer[Index], DeviceDescription);
        ASSERT_EFI_ERROR (Status);
      }
      UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"PXE on %s",DeviceDescription);
      if(NULL != SupportedDevice) {
        SupportedDevice->DevicePathProtocol = DevicePathProtocol;

        DevicePathNode = DevicePathProtocol;
        while (!IsDevicePathEnd (DevicePathNode)) {
          if ((DevicePathType (DevicePathNode) == MESSAGING_DEVICE_PATH) &&
                ( DevicePathSubType (DevicePathNode) == MSG_MAC_ADDR_DP) ) {
            SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_PXE];
            InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);
            break;
          }
          DevicePathNode = NextDevicePathNode (DevicePathNode);
        }
    }
    }
  }

  return EFI_SUCCESS;
}
示例#4
0
/**
  Update the component name for the Udp4 child handle.

  @param  Udp4[in]                   A pointer to the EFI_UDP4_PROTOCOL.


  @retval EFI_SUCCESS                Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER      The input parameter is invalid.

**/
EFI_STATUS
UpdateName (
  EFI_UDP4_PROTOCOL             *Udp4
  )
{
  EFI_STATUS                       Status;
  CHAR16                           HandleName[64];
  EFI_UDP4_CONFIG_DATA             Udp4ConfigData;

  if (Udp4 == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Format the child name into the string buffer as:
  // UDPv4 (SrcPort=59, DestPort=60)
  //
  Status = Udp4->GetModeData (Udp4, &Udp4ConfigData, NULL, NULL, NULL);
  if (!EFI_ERROR (Status)) {
    UnicodeSPrint (HandleName, sizeof (HandleName),
      L"UDPv4 (SrcPort=%d, DestPort=%d)",
      Udp4ConfigData.StationPort,
      Udp4ConfigData.RemotePort
      );
  } else if (Status == EFI_NOT_STARTED) {
    UnicodeSPrint (
      HandleName,
      sizeof (HandleName),
      L"UDPv4 (Not started)"
      );
  } else {
    return Status;
  }

  if (gUdpControllerNameTable != NULL) {
    FreeUnicodeStringTable (gUdpControllerNameTable);
    gUdpControllerNameTable = NULL;
  }

  Status = AddUnicodeString2 (
             "eng",
             gUdp4ComponentName.SupportedLanguages,
             &gUdpControllerNameTable,
             HandleName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return AddUnicodeString2 (
           "en",
           gUdp4ComponentName2.SupportedLanguages,
           &gUdpControllerNameTable,
           HandleName,
           FALSE
           );
}
示例#5
0
/**
  Update the component name for the IP4 child handle.

  @param  Ip4[in]                 A pointer to the EFI_IP4_PROTOCOL.

  
  @retval EFI_SUCCESS             Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER   The input parameter is invalid.
  
**/
EFI_STATUS
UpdateName (
  IN     EFI_IP4_PROTOCOL         *Ip4
  )
{
  EFI_STATUS                       Status;
  CHAR16                           HandleName[80];
  EFI_IP4_MODE_DATA                Ip4ModeData;

  if (Ip4 == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Format the child name into the string buffer as:
  // IPv4 (SrcIP=127.0.0.1, DestIP=127.0.0.1)
  //
  Status = Ip4->GetModeData (Ip4, &Ip4ModeData, NULL, NULL);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (!Ip4ModeData.IsStarted || !Ip4ModeData.IsConfigured) {
    UnicodeSPrint (HandleName, sizeof (HandleName), L"IPv4 (Not started)");
  } else {
    UnicodeSPrint (HandleName, sizeof (HandleName),
      L"IPv4 (SrcIP=%d.%d.%d.%d)",
      Ip4ModeData.ConfigData.StationAddress.Addr[0],
      Ip4ModeData.ConfigData.StationAddress.Addr[1],
      Ip4ModeData.ConfigData.StationAddress.Addr[2],
      Ip4ModeData.ConfigData.StationAddress.Addr[3]
      );
  }

  if (gIp4ControllerNameTable != NULL) {
    FreeUnicodeStringTable (gIp4ControllerNameTable);
    gIp4ControllerNameTable = NULL;
  }
  Status = AddUnicodeString2 (
             "eng",
             gIp4ComponentName.SupportedLanguages,
             &gIp4ControllerNameTable,
             HandleName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  return AddUnicodeString2 (
           "en",
           gIp4ComponentName2.SupportedLanguages,
           &gIp4ControllerNameTable,
           HandleName,
           FALSE
           );
}
示例#6
0
/**
  Process BootOrder, or DriverOrder variables, by calling
  BdsLibVariableToOption () for each UINT16 in the variables.

  @param  BdsCommonOptionList   The header of the option list base on variable
                                VariableName
  @param  VariableName          EFI Variable name indicate the BootOrder or
                                DriverOrder

  @retval EFI_SUCCESS           Success create the boot option or driver option
                                list
  @retval EFI_OUT_OF_RESOURCES  Failed to get the boot option or driver option list

**/
EFI_STATUS
EFIAPI
BdsLibBuildOptionFromVar (
  IN  LIST_ENTRY                      *BdsCommonOptionList,
  IN  CHAR16                          *VariableName
  )
{
  UINT16            *OptionOrder;
  UINTN             OptionOrderSize;
  UINTN             Index;
  BDS_COMMON_OPTION *Option;
  CHAR16            OptionName[20];

  //
  // Zero Buffer in order to get all BOOT#### variables
  //
  ZeroMem (OptionName, sizeof (OptionName));

  //
  // Read the BootOrder, or DriverOrder variable.
  //
  OptionOrder = BdsLibGetVariableAndSize (
                  VariableName,
                  &gEfiGlobalVariableGuid,
                  &OptionOrderSize
                  );
  if (OptionOrder == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) {
    if (*VariableName == 'B') {
      UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionOrder[Index]);
    } else {
      UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", OptionOrder[Index]);
    }

    Option              = BdsLibVariableToOption (BdsCommonOptionList, OptionName);
    //ASSERT (Option != NULL);
    if (!Option)
    {
        DEBUG((DEBUG_INFO, "%a:%d Option %s wasn't found \n", __FILE__, __LINE__, Option));
        continue;
    }
    Option->BootCurrent = OptionOrder[Index];

  }

  FreePool (OptionOrder);

  return EFI_SUCCESS;
}
示例#7
0
/**

  Get the Option Number that has not been allocated for use.

  @param Type  The type of Option.

  @return The available Option Number.

**/
UINT16
BOpt_GetOptionNumber (
  CHAR16        *Type
  )
{
  UINT16        *OrderList;
  UINTN         OrderListSize;
  UINTN         Index;
  CHAR16        StrTemp[20];
  UINT16        *OptionBuffer;
  UINT16        OptionNumber;
  UINTN         OptionSize;

  OrderListSize = 0;
  OrderList     = NULL;
  OptionNumber  = 0;
  Index         = 0;

  UnicodeSPrint (StrTemp, sizeof (StrTemp), L"%sOrder", Type);

  GetEfiGlobalVariable2 (StrTemp, (VOID **) &OrderList, &OrderListSize);
  for (OptionNumber = 0; ; OptionNumber++) {
    if (OrderList != NULL) {
      for (Index = 0; Index < OrderListSize / sizeof (UINT16); Index++) {
        if (OptionNumber == OrderList[Index]) {
          break;
        }
      }
    }

    if (Index < OrderListSize / sizeof (UINT16)) {
      //
      // The OptionNumber occurs in the OrderList, continue to use next one
      //
      continue;
    }
    UnicodeSPrint (StrTemp, sizeof (StrTemp), L"%s%04x", Type, (UINTN) OptionNumber);
    DEBUG((EFI_D_ERROR,"Option = %s\n", StrTemp));
    GetEfiGlobalVariable2 (StrTemp, (VOID **) &OptionBuffer, &OptionSize);
    if (NULL == OptionBuffer) {
      //
      // The Boot[OptionNumber] / Driver[OptionNumber] NOT occurs, we found it
      //
      break;
    }
  }

  return OptionNumber;
}
示例#8
0
/**
  DevicePathNode must be Mac Address type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
**/
VOID
EFIAPI
DevPathSerialMacAddr (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
  )
{
  MAC_ADDR_DEVICE_PATH  *Mac;
  UINTN                 HwAddressSize;
  UINTN                 Index;
  CHAR16                Buffer[64];
  CHAR16                *PBuffer;

  ASSERT(DevicePathNode != NULL);
  ASSERT(MappingItem != NULL);

  Mac           = (MAC_ADDR_DEVICE_PATH *) DevicePathNode;

  HwAddressSize = sizeof (EFI_MAC_ADDRESS);
  if (Mac->IfType == 0x01 || Mac->IfType == 0x00) {
    HwAddressSize = 6;
  }

  for (Index = 0, PBuffer = Buffer; Index < HwAddressSize; Index++, PBuffer += 2) {
    UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) Mac->MacAddress.Addr[Index]);
  }

  AppendCSDStr (MappingItem, Buffer);
}
示例#9
0
文件: BdsHelper.c 项目: hzhuang1/uefi
/**
  Edit an IPv4 address

  The function displays as a string following the "%d.%d.%d.%d" format the
  IPv4 address that is passed in and asks the user to modify it. If the
  resulting string defines a valid IPv4 address, the four bytes of the
  corresponding IPv4 address are extracted from the string and returned by
  the function. As long as the user does not define a valid IP
  address, he is asked for one. He can always escape by
  pressing ESC.

  @param[in ]  EFI_IP_ADDRESS  InIpAddr   Input IPv4 address
  @param[out]  EFI_IP_ADDRESS  OutIpAddr  Returned IPv4 address. Valid if
                                          and only if the returned value
                                          is equal to EFI_SUCCESS

  @retval  EFI_SUCCESS            Update completed
  @retval  EFI_ABORTED            Editing aborted by the user
  @retval  EFI_INVALID_PARAMETER  The string returned by the user is
                                  mal-formated
  @retval  EFI_OUT_OF_RESOURCES   Fail to perform the operation due to
                                  lack of resource
**/
EFI_STATUS
EditHIInputIP (
  IN   EFI_IP_ADDRESS  *InIpAddr,
  OUT  EFI_IP_ADDRESS  *OutIpAddr
  )
{
  EFI_STATUS  Status;
  CHAR16      CmdLine[48];

  while (TRUE) {
    UnicodeSPrint (
      CmdLine, 48, L"%d.%d.%d.%d",
      InIpAddr->v4.Addr[0], InIpAddr->v4.Addr[1],
      InIpAddr->v4.Addr[2], InIpAddr->v4.Addr[3]
      );

    Status = EditHIInputStr (CmdLine, 48);
    if (EFI_ERROR (Status)) {
      return EFI_ABORTED;
    }
    Status = NetLibStrToIp4 (CmdLine, &OutIpAddr->v4);
    if (Status == EFI_INVALID_PARAMETER) {
      Print (L"Invalid address\n");
    } else {
      return Status;
    }
  }
}
示例#10
0
/**
  Add the ISO639-2 and RFC4646 component name both for the Serial IO device

  @param SerialDevice     A pointer to the SERIAL_DEV instance.
  @param Instance         Instance ID for the serial device.
**/
VOID
AddName (
  IN  SERIAL_DEV                               *SerialDevice,
  IN  UINT32                                   Instance
  )
{
  CHAR16                                       SerialPortName[SERIAL_PORT_NAME_LEN];
  UnicodeSPrint (
    SerialPortName,
    sizeof (SerialPortName),
    (SerialDevice->PciDeviceInfo != NULL) ? PCI_SERIAL_PORT_NAME : SIO_SERIAL_PORT_NAME,
    Instance
    );
  AddUnicodeString2 (
    "eng",
    gPciSioSerialComponentName.SupportedLanguages,
    &SerialDevice->ControllerNameTable,
    SerialPortName,
    TRUE
    );
  AddUnicodeString2 (
    "en",
    gPciSioSerialComponentName2.SupportedLanguages,
    &SerialDevice->ControllerNameTable,
    SerialPortName,
    FALSE
    );

}
示例#11
0
/**
  DevicePathNode must be InfiniBand type and this will populate the MappingItem.

  @param[in] DevicePathNode   The node to get info on.
  @param[in] MappingItem      The info item to populate.
**/
VOID
EFIAPI
DevPathSerialInfiniBand (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePathNode,
  IN DEVICE_CONSIST_MAPPING_INFO  *MappingItem
  )
{
  INFINIBAND_DEVICE_PATH  *InfiniBand;
  UINTN                   Index;
  CHAR16                  Buffer[64];
  CHAR16                  *PBuffer;

  ASSERT(DevicePathNode != NULL);
  ASSERT(MappingItem != NULL);

  InfiniBand = (INFINIBAND_DEVICE_PATH *) DevicePathNode;
  for (Index = 0, PBuffer = Buffer; Index < 16; Index++, PBuffer += 2) {
    UnicodeSPrint (PBuffer, 0, L"%02x", (UINTN) InfiniBand->PortGid[Index]);
  }

  AppendCSDStr (MappingItem, Buffer);
  AppendCSDNum (MappingItem, InfiniBand->ServiceId);
  AppendCSDNum (MappingItem, InfiniBand->TargetPortId);
  AppendCSDNum (MappingItem, InfiniBand->DeviceId);
}
示例#12
0
文件: DmpStore.c 项目: b-man/edk2
/**
  Convert binary to hex format string.

  @param[in]  Buffer            The binary data.
  @param[in]  BufferSize        The size in bytes of the binary data.
  @param[in, out] HexString     Hex format string.
  @param[in]      HexStringSize The size in bytes of the string.

  @return The hex format string.
**/
CHAR16*
BinaryToHexString (
  IN     VOID    *Buffer,
  IN     UINTN   BufferSize,
  IN OUT CHAR16  *HexString,
  IN     UINTN   HexStringSize
  )
{
  UINTN Index;
  UINTN StringIndex;

  ASSERT (Buffer != NULL);
  ASSERT ((BufferSize * 2 + 1) * sizeof (CHAR16) <= HexStringSize);

  for (Index = 0, StringIndex = 0; Index < BufferSize; Index += 1) {
    StringIndex +=
      UnicodeSPrint (
        &HexString[StringIndex],
        HexStringSize - StringIndex * sizeof (CHAR16),
        L"%02x",
        ((UINT8 *) Buffer)[Index]
        );
  }
  return HexString;
}
示例#13
0
/**
  Worker function that prints an EFI_GUID into specified Buffer.

  @param[in]     Guid          Pointer to GUID to print.
  @param[in]     Buffer        Buffer to print Guid into.
  @param[in]     BufferSize    Size of Buffer.
  
  @retval    Number of characters printed.

**/
UINTN
GuidToString (
  IN  EFI_GUID  *Guid,
  IN  CHAR16    *Buffer,
  IN  UINTN     BufferSize
  )
{
  UINTN Size;

  Size = UnicodeSPrint (
            Buffer,
            BufferSize, 
            L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
            (UINTN)Guid->Data1,                    
            (UINTN)Guid->Data2,
            (UINTN)Guid->Data3,
            (UINTN)Guid->Data4[0],
            (UINTN)Guid->Data4[1],
            (UINTN)Guid->Data4[2],
            (UINTN)Guid->Data4[3],
            (UINTN)Guid->Data4[4],
            (UINTN)Guid->Data4[5],
            (UINTN)Guid->Data4[6],
            (UINTN)Guid->Data4[7]
            );

  //
  // SPrint will null terminate the string. The -1 skips the null
  //
  return Size - 1;
}
示例#14
0
/**
  Initialize CapsuleMax variables.
**/
VOID
InitCapsuleMaxVariable (
  VOID
  )
{
  EFI_STATUS                       Status;
  UINTN                            Size;
  CHAR16                           CapsuleMaxStr[sizeof("Capsule####")];
  EDKII_VARIABLE_LOCK_PROTOCOL     *VariableLock;

  UnicodeSPrint(
    CapsuleMaxStr,
    sizeof(CapsuleMaxStr),
    L"Capsule%04x",
    PcdGet16(PcdCapsuleMax)
    );

  Size = sizeof(L"Capsule####") - sizeof(CHAR16); // no zero terminator
  Status = gRT->SetVariable(
                  L"CapsuleMax",
                  &gEfiCapsuleReportGuid,
                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                  Size,
                  CapsuleMaxStr
                  );
  if (!EFI_ERROR(Status)) {
    // Lock it per UEFI spec.
    Status = gBS->LocateProtocol(&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLock);
    if (!EFI_ERROR(Status)) {
      Status = VariableLock->RequestToLock(VariableLock, L"CapsuleMax", &gEfiCapsuleReportGuid);
      ASSERT_EFI_ERROR(Status);
    }
  }
}
示例#15
0
文件: BootOption.c 项目: vchong/edk2
EFI_STATUS
BootOptionUpdate (
  IN  BDS_LOAD_OPTION*          BdsLoadOption,
  IN  UINT32                    Attributes,
  IN  CHAR16*                   BootDescription,
  IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,
  IN  ARM_BDS_LOADER_TYPE       BootType,
  IN UINT8*                     OptionalData,
  IN UINTN                      OptionalDataSize
  )
{
  EFI_STATUS      Status;
  CHAR16          BootVariableName[9];

  // Update the BDS Load Option structure
  BootOptionSetFields (BdsLoadOption, Attributes, BootDescription, DevicePath, BootType, OptionalData, OptionalDataSize);

  // Update the related environment variables
  UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BdsLoadOption->LoadOptionIndex);

  Status = gRT->SetVariable (
      BootVariableName,
      &gEfiGlobalVariableGuid,
      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
      BdsLoadOption->LoadOptionSize,
      BdsLoadOption->LoadOption
      );

  return Status;
}
示例#16
0
/**
  Check if the Key Option is valid or not.

  @param KeyOption       The Hot Key Option to be checked.

  @retval  TRUE          The Hot Key Option is valid.
  @retval  FALSE         The Hot Key Option is invalid.

**/
BOOLEAN
IsKeyOptionValid (
  IN EFI_KEY_OPTION     *KeyOption
)
{
  UINT16   BootOptionName[10];
  UINT8    *BootOptionVar;
  UINTN    BootOptionSize;
  UINT32   Crc;

  //
  // Check whether corresponding Boot Option exist
  //
  UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04x", KeyOption->BootOption);
  BootOptionVar = BdsLibGetVariableAndSize (
                    BootOptionName,
                    &gEfiGlobalVariableGuid,
                    &BootOptionSize
                    );

  if (BootOptionVar == NULL || BootOptionSize == 0) {
    return FALSE;
  }

  //
  // Check CRC for Boot Option
  //
  gBS->CalculateCrc32 (BootOptionVar, BootOptionSize, &Crc);
  FreePool (BootOptionVar);

  return (BOOLEAN) ((KeyOption->BootOptionCrc == Crc) ? TRUE : FALSE);
}
示例#17
0
BOOLEAN
EFIAPI
IsKeyOptionValid (
  IN EFI_BOOT_MANAGER_KEY_OPTION     *KeyOption
)
{
  UINT16   OptionName[sizeof (L"Boot####")];
  UINT8    *BootOption;
  UINTN    BootOptionSize;
  UINT32   Crc;

  //
  // Check whether corresponding Boot Option exist
  //
  UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", KeyOption->BootOption);
  BootOption = EfiBootManagerGetVariableAndSize (
                    OptionName,
                    &gEfiGlobalVariableGuid,
                    &BootOptionSize
                    );

  if (BootOption == NULL) {
    return FALSE;
  }

  //
  // Check CRC for Boot Option
  //
  gBS->CalculateCrc32 (BootOption, BootOptionSize, &Crc);
  FreePool (BootOption);

  return (BOOLEAN) (KeyOption->BootOptionCrc == Crc);
}
示例#18
0
EFI_STATUS
GetDriverName(
    EFI_HANDLE   Handle,
    CHAR16         *GopVersion
)
{
    EFI_DRIVER_BINDING_PROTOCOL           *BindHandle = NULL;
    EFI_STATUS                            Status;
    UINT32                                Version;
    UINT16                                *Ptr;

    Status = gBS->OpenProtocol(
                 Handle,
                 &gEfiDriverBindingProtocolGuid,
                 (VOID**)&BindHandle,
                 NULL,
                 NULL,
                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
             );
    if (EFI_ERROR(Status)) {
        return EFI_NOT_FOUND;
    }

    Version = BindHandle->Version;
    Ptr = (UINT16*)&Version;
    UnicodeSPrint(GopVersion, 40, L"7.0.%04d", *(Ptr));
    return EFI_SUCCESS;
}
示例#19
0
/**
  Add the specified device path by DriverIndex to the forbid device path 
  list (mAccessInfo.LoadForbid).

  @param[in]  DriverIndex   The index of driver saved in driver options.
  
**/
VOID
AddToForbidLoad (
  IN  UINT16                                    DriverIndex
  )
{
  UINTN       DevicePathLen;
  UINT8       *Var;
  UINT8       *VarPtr;
  UINTN       NewLen;
  UINT8       *NewFL;
  CHAR16      VarName[13];

  //
  // Get loadable driver device path.
  //
  UnicodeSPrint  (VarName, sizeof (VarName), L"Driver%04x", DriverIndex);
  Var = GetEfiGlobalVariable (VarName);
  if (Var == NULL) {
    return;
  }
  
  //
  // Save forbid load driver.
  //
  
  VarPtr = Var;
  //
  // Skip attribute.
  //
  VarPtr += sizeof (UINT32);

  DevicePathLen = *(UINT16 *) VarPtr;
  //
  // Skip device path length.
  //
  VarPtr += sizeof (UINT16);

  //
  // Skip description string.
  //
  VarPtr += StrSize ((UINT16 *) VarPtr);

  NewLen  = mAccessInfo.LoadForbidLen + DevicePathLen;
  NewFL   = AllocateZeroPool (NewLen);
  if (NewFL == NULL) {
    FreePool (Var);
    return ;
  }

  if (mAccessInfo.LoadForbidLen > 0) {
    CopyMem (NewFL, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen);
    FreePool (mAccessInfo.LoadForbid);
  }

  CopyMem (NewFL + mAccessInfo.LoadForbidLen, VarPtr, DevicePathLen);
  mAccessInfo.LoadForbidLen = NewLen;
  mAccessInfo.LoadForbid    = NewFL;
  FreePool (Var);
}
示例#20
0
/**
  Convert the IPv4 address into a dotted string.

  @param[in]   Ip   The IPv4 address.
  @param[out]  Str  The dotted IP string.
**/
VOID
Ip4ConfigIpToStr (
  IN  EFI_IPv4_ADDRESS  *Ip,
  OUT CHAR16            *Str
  )
{
  UnicodeSPrint (Str, 2 * IP4_STR_MAX_SIZE, L"%d.%d.%d.%d", Ip->Addr[0], Ip->Addr[1], Ip->Addr[2], Ip->Addr[3]);
}
/**
  Convert the IPv4 address list into string consists of several decimal
  dotted IPv4 addresses separated by space.

  @param[in]   Ip        The IPv4 address list.
  @param[in]   IpCount   The size of IPv4 address list.
  @param[out]  Str       The string contains several decimal dotted
                         IPv4 addresses separated by space.

  @retval EFI_SUCCESS           Operation is success.
  @retval EFI_OUT_OF_RESOURCES  Error occurs in allocating memory.

**/
EFI_STATUS
Ip4Config2IpListToStr (
  IN  EFI_IPv4_ADDRESS  *Ip,
  IN  UINTN             IpCount,
  OUT CHAR16            *Str
  )
{
  UINTN            Index;
  UINTN            TemIndex;
  UINTN            StrIndex;
  CHAR16           *TempStr;
  EFI_IPv4_ADDRESS *TempIp;

  Index    = 0;
  TemIndex = 0;
  StrIndex = 0;
  TempStr  = NULL;
  TempIp   = NULL;

  for (Index = 0; Index < IpCount; Index ++) {
    TempIp = Ip + Index;
    if (TempStr == NULL) {
      TempStr = AllocateZeroPool(2 * IP4_STR_MAX_SIZE);
      if (TempStr == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
    }

    UnicodeSPrint (
      TempStr,
      2 * IP4_STR_MAX_SIZE,
      L"%d.%d.%d.%d",
      TempIp->Addr[0],
      TempIp->Addr[1],
      TempIp->Addr[2],
      TempIp->Addr[3]
      );

    for (TemIndex = 0; TemIndex < IP4_STR_MAX_SIZE; TemIndex ++) {
      if (*(TempStr + TemIndex) == L'\0') {
        if (Index == IpCount - 1) {
          Str[StrIndex++] = L'\0';
        } else {
          Str[StrIndex++] = L' ';
        }
        break;
      } else {
        Str[StrIndex++] = *(TempStr + TemIndex);
      }
    }
  }

  if (TempStr != NULL) {
    FreePool(TempStr);
  }

  return EFI_SUCCESS;
}
示例#22
0
EFI_STATUS
BdsLoadOptionMemMapUpdateDevicePath (
  IN EFI_DEVICE_PATH            *OldDevicePath,
  IN CHAR16*                    FileName,
  OUT EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath
  )
{
  EFI_STATUS          Status;
  CHAR16              StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX];
  CHAR16              StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX];
  MEMMAP_DEVICE_PATH* EndingDevicePath;
  EFI_DEVICE_PATH*    DevicePath;

  DevicePath = DuplicateDevicePath (OldDevicePath);
  EndingDevicePath = (MEMMAP_DEVICE_PATH*)GetLastDevicePathNode (DevicePath);

  Print(L"Starting Address of the %s: ", FileName);
  UnicodeSPrint (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX, L"0x%X", (UINTN)EndingDevicePath->StartingAddress);
  Status = EditHIInputStr (StrStartingAddress, BOOT_DEVICE_ADDRESS_MAX);
  if (EFI_ERROR(Status)) {
    //return EFI_ABORTED;
    goto Exit;
  }

  Print(L"Ending Address of the %s: ", FileName);
  UnicodeSPrint (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX, L"0x%X", (UINTN)EndingDevicePath->EndingAddress);
  Status = EditHIInputStr (StrEndingAddress, BOOT_DEVICE_ADDRESS_MAX);
  if (EFI_ERROR(Status)) {
    goto Exit;
    //return EFI_ABORTED;
  }

  EndingDevicePath->StartingAddress = StrHexToUint64 (StrStartingAddress);
  EndingDevicePath->EndingAddress = StrHexToUint64 (StrEndingAddress);

Exit:  
  if (EFI_ERROR(Status)) {
    FreePool(DevicePath);
  } else {
    *NewDevicePath = DevicePath;
  }

  return Status;
}
示例#23
0
文件: BootOption.c 项目: vchong/edk2
EFI_STATUS
BootOptionDelete (
  IN  BDS_LOAD_OPTION *BootOption
  )
{
  UINTN         Index;
  UINTN         BootOrderSize;
  UINT16*       BootOrder;
  UINTN         BootOrderCount;
  CHAR16        BootVariableName[9];
  EFI_STATUS    Status;

  // Remove the entry from the BootOrder environment variable
  Status = GetGlobalEnvironmentVariable (L"BootOrder", NULL, &BootOrderSize, (VOID**)&BootOrder);
  if (!EFI_ERROR(Status)) {
    BootOrderCount = BootOrderSize / sizeof(UINT16);

    // Find the index of the removed entry
    for (Index = 0; Index < BootOrderCount; Index++) {
      if (BootOrder[Index] == BootOption->LoadOptionIndex) {
        // If it the last entry we do not need to rearrange the BootOrder list
        if (Index + 1 != BootOrderCount) {
          CopyMem (
            &BootOrder[Index],
            &BootOrder[Index + 1],
            (BootOrderCount - (Index + 1)) * sizeof(UINT16)
            );
        }
        break;
      }
    }

    // Update the BootOrder environment variable
    Status = gRT->SetVariable (
        L"BootOrder",
        &gEfiGlobalVariableGuid,
        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
        BootOrderSize - sizeof(UINT16),
        BootOrder
        );
  }

  // Delete Boot#### environment variable
  UnicodeSPrint (BootVariableName, 9 * sizeof(CHAR16), L"Boot%04X", BootOption->LoadOptionIndex);
  Status = gRT->SetVariable (
      BootVariableName,
      &gEfiGlobalVariableGuid,
      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
      0,
      NULL
      );

  FreePool (BootOrder);

  return Status;
}
示例#24
0
/**
  Update the component name for the Mtftp4 child handle.

  @param  Mtftp4[in]                A pointer to the EFI_MTFTP4_PROTOCOL.


  @retval EFI_SUCCESS               Update the ControllerNameTable of this instance successfully.
  @retval EFI_INVALID_PARAMETER     The input parameter is invalid.

**/
EFI_STATUS
UpdateName (
  IN   EFI_MTFTP4_PROTOCOL             *Mtftp4
  )
{
  EFI_STATUS                       Status;
  CHAR16                           HandleName[80];
  EFI_MTFTP4_MODE_DATA             ModeData;

  if (Mtftp4 == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Format the child name into the string buffer as:
  // MTFTPv4 (ServerIp=192.168.1.10, ServerPort=69)
  //
  Status = Mtftp4->GetModeData (Mtftp4, &ModeData);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  UnicodeSPrint (HandleName, sizeof (HandleName),
    L"MTFTPv4 (ServerIp=%d.%d.%d.%d, ServerPort=%d)",
    ModeData.ConfigData.ServerIp.Addr[0],
    ModeData.ConfigData.ServerIp.Addr[1],
    ModeData.ConfigData.ServerIp.Addr[2],
    ModeData.ConfigData.ServerIp.Addr[3],
    ModeData.ConfigData.InitialServerPort
    );

  if (gMtftp4ControllerNameTable != NULL) {
    FreeUnicodeStringTable (gMtftp4ControllerNameTable);
    gMtftp4ControllerNameTable = NULL;
  }

  Status = AddUnicodeString2 (
             "eng",
             gMtftp4ComponentName.SupportedLanguages,
             &gMtftp4ControllerNameTable,
             HandleName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return AddUnicodeString2 (
           "en",
           gMtftp4ComponentName2.SupportedLanguages,
           &gMtftp4ControllerNameTable,
           HandleName,
           FALSE
           );
}
示例#25
0
/**
  Delete the load option.

  @param  OptionNumber        Indicate the option number of load option
  @param  OptionType          Indicate the type of load option

  @retval EFI_INVALID_PARAMETER OptionType or OptionNumber is invalid.
  @retval EFI_NOT_FOUND         The load option cannot be found
  @retval EFI_SUCCESS           The load option was deleted
  @retval others                Status of RT->SetVariable()
**/
EFI_STATUS
EFIAPI
EfiBootManagerDeleteLoadOptionVariable (
  IN UINTN                              OptionNumber,
  IN EFI_BOOT_MANAGER_LOAD_OPTION_TYPE  OptionType
  )
{
  UINT16                            *OptionOrder;
  UINTN                             OptionOrderSize;
  UINTN                             Index;
  CHAR16                            OptionName[BM_OPTION_NAME_LEN];

  if (((UINT32) OptionType >= LoadOptionTypeMax) || (OptionNumber >= LoadOptionNumberMax)) {
    return EFI_INVALID_PARAMETER;
  }

  if (OptionType == LoadOptionTypeDriver || OptionType == LoadOptionTypeSysPrep || OptionType == LoadOptionTypeBoot) {
    //
    // If the associated *Order exists, firstly remove the reference in *Order for
    //  Driver####, SysPrep#### and Boot####.
    //
    GetEfiGlobalVariable2 (mBmLoadOptionOrderName[OptionType], (VOID **) &OptionOrder, &OptionOrderSize);
    ASSERT ((OptionOrder != NULL && OptionOrderSize != 0) || (OptionOrder == NULL && OptionOrderSize == 0));

    for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) {
      if (OptionOrder[Index] == OptionNumber) {
        OptionOrderSize -= sizeof (UINT16);
        CopyMem (&OptionOrder[Index], &OptionOrder[Index + 1], OptionOrderSize - Index * sizeof (UINT16));
        gRT->SetVariable (
               mBmLoadOptionOrderName[OptionType],
               &gEfiGlobalVariableGuid,
               EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
               OptionOrderSize,
               OptionOrder
               );
        break;
      }
    }
    if (OptionOrder != NULL) {
      FreePool (OptionOrder);
    }
  }

  //
  // Remove the Driver####, SysPrep####, Boot#### or PlatformRecovery#### itself.
  //
  UnicodeSPrint (OptionName, sizeof (OptionName), L"%s%04x", mBmLoadOptionName[OptionType], OptionNumber);
  return gRT->SetVariable (
                OptionName,
                &gEfiGlobalVariableGuid,
                0,
                0,
                NULL
                );
}
示例#26
0
EFI_STATUS
BdsLoadOptionFileSystemList (
  IN OUT LIST_ENTRY* BdsLoadOptionList
  )
{
  EFI_STATUS                        Status;
  UINTN                             HandleCount;
  EFI_HANDLE                        *HandleBuffer;
  UINTN                             Index;
  BDS_SUPPORTED_DEVICE              *SupportedDevice;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL*  FileProtocol;
  EFI_FILE_HANDLE                   Fs;
  UINTN                             Size;
  EFI_FILE_SYSTEM_INFO*             FsInfo;
  EFI_DEVICE_PATH_PROTOCOL*         DevicePathProtocol;

  // List all the Simple File System Protocols
  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &HandleBuffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);
    if (!EFI_ERROR(Status)) {
      // Allocate BDS Supported Device structure
      SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool (sizeof(BDS_SUPPORTED_DEVICE));

      FileProtocol = NULL;
      Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&FileProtocol);
      ASSERT_EFI_ERROR(Status);

      FileProtocol->OpenVolume (FileProtocol, &Fs);

      // Generate a Description from the file system
      Size = 0;
      FsInfo = NULL;
      Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo);
      if (Status == EFI_BUFFER_TOO_SMALL) {
        FsInfo = AllocatePool (Size);
        Status = Fs->GetInfo (Fs, &gEfiFileSystemInfoGuid, &Size, FsInfo);
      }
      UnicodeSPrint (SupportedDevice->Description,BOOT_DEVICE_DESCRIPTION_MAX,L"%s (%d MB)",FsInfo->VolumeLabel,(UINT32)(FsInfo->VolumeSize / (1024 * 1024)));
      FreePool(FsInfo);
      Fs->Close (Fs);

      SupportedDevice->DevicePathProtocol = DevicePathProtocol;
      SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_FILESYSTEM];

      InsertTailList (BdsLoadOptionList,&SupportedDevice->Link);
    }
  }

  return EFI_SUCCESS;
}
EFI_STATUS
TGetTouchFirmwareVersion(
 CHAR16 *TouchVerString
)
{
  CHAR16     Buffer[40];

  UnicodeSPrint (Buffer, sizeof (Buffer), L"NA");
  StrCpy (TouchVerString, Buffer);

  return EFI_SUCCESS;
}
示例#28
0
文件: Tftp.c 项目: rsalveti/edk2
/**
  Get the name of the NIC.

  @param[in]   ControllerHandle  The network physical device handle.
  @param[in]   NicNumber         The network physical device number.
  @param[out]  NicName           Address where to store the NIC name.
                                 The memory area has to be at least
                                 IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH 
                                 double byte wide.

  @return  EFI_SUCCESS  The name of the NIC was returned.
  @return  Others       The creation of the child for the Managed
                        Network Service failed or the opening of
                        the Managed Network Protocol failed or
                        the operational parameters for the
                        Managed Network Protocol could not be
                        read.
**/
STATIC
EFI_STATUS
GetNicName (
  IN   EFI_HANDLE  ControllerHandle,
  IN   UINTN       NicNumber,
  OUT  CHAR16      *NicName
  )
{
  EFI_STATUS                    Status;
  EFI_HANDLE                    MnpHandle;
  EFI_MANAGED_NETWORK_PROTOCOL  *Mnp;
  EFI_SIMPLE_NETWORK_MODE       SnpMode;

  Status = CreateServiceChildAndOpenProtocol (
             ControllerHandle,
             &gEfiManagedNetworkServiceBindingProtocolGuid,
             &gEfiManagedNetworkProtocolGuid,
             &MnpHandle,
             (VOID**)&Mnp
             );
  if (EFI_ERROR (Status)) {
    goto Error;
  }

  Status = Mnp->GetModeData (Mnp, NULL, &SnpMode);
  if (EFI_ERROR (Status) && (Status != EFI_NOT_STARTED)) {
    goto Error;
  }

  UnicodeSPrint (
    NicName,
    IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH,
    SnpMode.IfType == NET_IFTYPE_ETHERNET ?
    L"eth%d" :
    L"unk%d" ,
    NicNumber
    );

  Status = EFI_SUCCESS;

Error:

  if (MnpHandle != NULL) {
    CloseProtocolAndDestroyServiceChild (
      ControllerHandle,
      &gEfiManagedNetworkServiceBindingProtocolGuid,
      &gEfiManagedNetworkProtocolGuid,
      MnpHandle
      );
  }

  return Status;
}
示例#29
0
/**
  Delete Boot Option that represent a Deleted state in BootOptionMenu.
  After deleting this boot option, call Var_ChangeBootOrder to
  make sure BootOrder is in valid state.

  @retval EFI_SUCCESS   If all boot load option EFI Variables corresponding to  
                        BM_LOAD_CONTEXT marked for deletion is deleted.
  @retval EFI_NOT_FOUND If can not find the boot option want to be deleted.
  @return Others        If failed to update the "BootOrder" variable after deletion. 

**/
EFI_STATUS
Var_DelBootOption (
  VOID
  )
{
  BM_MENU_ENTRY   *NewMenuEntry;
  BM_LOAD_CONTEXT *NewLoadContext;
  UINT16          BootString[10];
  EFI_STATUS      Status;
  UINTN           Index;
  UINTN           Index2;

  Status  = EFI_SUCCESS;
  Index2  = 0;
  for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
    NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2));
    if (NULL == NewMenuEntry) {
      return EFI_NOT_FOUND;
    }

    NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
    if (!NewLoadContext->Deleted) {
      continue;
    }

    UnicodeSPrint (
      BootString,
      sizeof (BootString),
      L"Boot%04x",
      NewMenuEntry->OptionNumber
      );

    EfiLibDeleteVariable (BootString, &gEfiGlobalVariableGuid);
    Index2++;
    //
    // If current Load Option is the same as BootNext,
    // must delete BootNext in order to make sure
    // there will be no panic on next boot
    //
    if (NewLoadContext->IsBootNext) {
      EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
    }

    RemoveEntryList (&NewMenuEntry->Link);
    BOpt_DestroyMenuEntry (NewMenuEntry);
    NewMenuEntry = NULL;
  }

  BootOptionMenu.MenuNumber -= Index2;

  Status = Var_ChangeBootOrder ();
  return Status;
}
示例#30
0
/**
  Enumerate all boot option descriptions and append " 2"/" 3"/... to make
  unique description.

  @param BootOptions            Array of boot options.
  @param BootOptionCount        Count of boot options.
**/
VOID
BmMakeBootOptionDescriptionUnique (
  EFI_BOOT_MANAGER_LOAD_OPTION         *BootOptions,
  UINTN                                BootOptionCount
  )
{
  UINTN                                Base;
  UINTN                                Index;
  UINTN                                DescriptionSize;
  UINTN                                MaxSuffixSize;
  BOOLEAN                              *Visited;
  UINTN                                MatchCount;

  if (BootOptionCount == 0) {
    return;
  }

  //
  // Calculate the maximum buffer size for the number suffix.
  // The initial sizeof (CHAR16) is for the blank space before the number.
  //
  MaxSuffixSize = sizeof (CHAR16);
  for (Index = BootOptionCount; Index != 0; Index = Index / 10) {
    MaxSuffixSize += sizeof (CHAR16);
  }

  Visited = AllocateZeroPool (sizeof (BOOLEAN) * BootOptionCount);
  ASSERT (Visited != NULL);

  for (Base = 0; Base < BootOptionCount; Base++) {
    if (!Visited[Base]) {
      MatchCount      = 1;
      Visited[Base]   = TRUE;
      DescriptionSize = StrSize (BootOptions[Base].Description);
      for (Index = Base + 1; Index < BootOptionCount; Index++) {
        if (!Visited[Index] && StrCmp (BootOptions[Base].Description, BootOptions[Index].Description) == 0) {
          Visited[Index] = TRUE;
          MatchCount++;
          FreePool (BootOptions[Index].Description);
          BootOptions[Index].Description = AllocatePool (DescriptionSize + MaxSuffixSize);
          UnicodeSPrint (
            BootOptions[Index].Description, DescriptionSize + MaxSuffixSize,
            L"%s %d",
            BootOptions[Base].Description, MatchCount
            );
        }
      }
    }
  }

  FreePool (Visited);
}