Ejemplo n.º 1
0
/**

  Acquire the string associated with the Index from smbios structure and return it.
  The caller is responsible for free the string buffer.

  @param    OptionalStrStart  The start position to search the string
  @param    Index             The index of the string to extract
  @param    String            The string that is extracted

  @retval   EFI_SUCCESS       The function returns EFI_SUCCESS always.

**/
EFI_STATUS
GetOptionalStringByIndex (
  IN      CHAR8                   *OptionalStrStart,
  IN      UINT8                   Index,
  OUT     CHAR16                  **String
  )
{
  UINTN          StrSize;

  if (Index == 0) {
    *String = AllocateZeroPool (sizeof (CHAR16));
    return EFI_SUCCESS;
  }

  StrSize = 0;
  do {
    Index--;
    OptionalStrStart += StrSize;
    StrSize           = AsciiStrSize (OptionalStrStart);
  } while (OptionalStrStart[StrSize] != 0 && Index != 0);

  if ((Index != 0) || (StrSize == 1)) {
    //
    // Meet the end of strings set but Index is non-zero, or
    // Find an empty string
    //
    *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));
  } else {
    *String = AllocatePool (StrSize * sizeof (CHAR16));
    AsciiStrToUnicodeStr (OptionalStrStart, *String);
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 2
0
Archivo: Path.c Proyecto: etiago/vbox
/*  Normalize a narrow-character path and produce a wide-character path
    that has forward slashes replaced with backslashes.
    Backslashes are directory separators in UEFI File Paths.

    It is the caller's responsibility to eventually free() the returned buffer.

    @param[in]    path    A pointer to the narrow-character path to be normalized.

    @return     A pointer to a buffer containing the normalized, wide-character, path.
*/
wchar_t *
NormalizePath( const char *path)
{
  wchar_t  *temp;
  wchar_t  *OldPath;
  wchar_t  *NewPath;
  size_t    Length;

  OldPath = AsciiStrToUnicodeStr(path, gMD->UString);
  Length  = wcslen(OldPath) + 1;

  NewPath = calloc(Length, sizeof(wchar_t));
  if(NewPath != NULL) {
    temp = NewPath;
    for( ; *OldPath; ++OldPath) {
      if(*OldPath == L'/') {
        *temp = L'\\';
      }
      else {
        *temp = *OldPath;
      }
      ++temp;
    }
  }
  else {
    errno     = ENOMEM;
    EFIerrno  = RETURN_OUT_OF_RESOURCES;
  }
  return NewPath;
}
Ejemplo n.º 3
0
/**
  Allows a program to determine the primary languages that are supported on a given handle.

  This routine is intended to be used by drivers to query the interface database for supported languages. 
  This routine returns a string of concatenated 3-byte language identifiers, one per string package associated with the handle.

  @param This           A pointer to the EFI_HII_PROTOCOL instance.
  @param Handle         The handle on which the strings reside. Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack() 
                        in the Packages section.
  @param LanguageString A string allocated by GetPrimaryLanguages() that contains a list of all primary languages 
                        registered on the handle. The routine will not return the three-spaces language identifier used in 
                        other functions to indicate non-language-specific strings.

  @retval EFI_SUCCESS            LanguageString was correctly returned.
 
  @retval EFI_INVALID_PARAMETER  The Handle was unknown.
**/
EFI_STATUS
EFIAPI
HiiGetPrimaryLanguages (
  IN  EFI_HII_PROTOCOL            *This,
  IN  FRAMEWORK_EFI_HII_HANDLE    Handle,
  OUT EFI_STRING                  *LanguageString
  )
{
  HII_THUNK_PRIVATE_DATA     *Private;
  EFI_HII_HANDLE             UefiHiiHandle;
  CHAR8                      *LangCodes4646;
  CHAR16                     *UnicodeLangCodes639;
  CHAR8                      *LangCodes639;
  EFI_STATUS                 Status;

  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);

  UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);
  if (UefiHiiHandle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  LangCodes4646 = HiiGetSupportedLanguages (UefiHiiHandle);

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

  LangCodes639 = ConvertLanguagesRfc4646ToIso639 (LangCodes4646);
  if (LangCodes639 == NULL) {
    Status = EFI_INVALID_PARAMETER;
    goto Done;
  }
  
  UnicodeLangCodes639 = AllocateZeroPool (AsciiStrSize (LangCodes639) * sizeof (CHAR16));
  if (UnicodeLangCodes639 == NULL) {
    Status =  EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  //
  // The language returned is in RFC 639-2 format.
  //
  AsciiStrToUnicodeStr (LangCodes639, UnicodeLangCodes639);
  *LanguageString = UnicodeLangCodes639;
  Status = EFI_SUCCESS;

Done:
  FreePool (LangCodes4646);
  if (LangCodes639 != NULL) {
    FreePool (LangCodes639);
  }

  return Status;
}
Ejemplo n.º 4
0
VOID Ext2DebugDirent (struct dirent *dir) {

  CHAR16 Name[dir->d_namlen];

  AsciiStrToUnicodeStr(dir->d_name, Name);

  DEBUG ((EFI_D_INFO, "\n============Ext2 direct===================\n"));
  DEBUG ((EFI_D_INFO, "d_fileno             : %d\n", dir->d_fileno));
  DEBUG ((EFI_D_INFO, "d_reclen             : %d\n", dir->d_reclen));
  DEBUG ((EFI_D_INFO, "d_namelen            : %d\n", dir->d_namlen));
  DEBUG ((EFI_D_INFO, "d_name               : %s\n", Name));

}
Ejemplo n.º 5
0
/** The getenv function searches an environment list, provided by the host
    environment, for a string that matches the string pointed to by name.  The
    set of environment names and the method for altering the environment list
    are determined by the underlying UEFI Shell implementation.

    @return   The getenv function returns a pointer to a string associated with
              the matched list member.  The string pointed to shall not be
              modified by the program, but may be overwritten by a subsequent
              call to the getenv function.  If the specified name cannot be
              found, a null pointer is returned.
**/
char   *getenv(const char *name)
{
  const CHAR16  *EfiEnv;
  char          *retval = NULL;

  (void)AsciiStrToUnicodeStr( name, gMD->UString);
  EfiEnv = ShellGetEnvironmentVariable(gMD->UString);
  if(EfiEnv != NULL) {
    retval = UnicodeStrToAsciiStr( EfiEnv, gMD->ASgetenv);
  }

  return retval;
}
Ejemplo n.º 6
0
VOID Ext2DebugDirect (struct ext2fs_direct *dir) {

  CHAR16 Name[dir->e2d_namlen+1];

  AsciiStrToUnicodeStr(dir->e2d_name, Name);

  DEBUG ((EFI_D_INFO, "\n============Ext2 direct===================\n"));
  DEBUG ((EFI_D_INFO, "e2d_ino              : %d\n", dir->e2d_ino));
  DEBUG ((EFI_D_INFO, "e2d_reclen           : %d\n", dir->e2d_reclen));
  DEBUG ((EFI_D_INFO, "e2d_namelen          : %d\n", dir->e2d_namlen));
  DEBUG ((EFI_D_INFO, "e2d_type             : %d\n", dir->e2d_type));
  DEBUG ((EFI_D_INFO, "e2d_name             : %s\n", Name));

}
Ejemplo n.º 7
0
CHAR16*
Ascii2Unicode (
  CONST CHAR8* AsciiStr
)
{
  CHAR16* UnicodeStr = AllocatePool((AsciiStrLen (AsciiStr) + 1) * sizeof (CHAR16));
  if (UnicodeStr == NULL) {
    return NULL;
  }

  AsciiStrToUnicodeStr(AsciiStr, UnicodeStr);

  return UnicodeStr;
}
Ejemplo n.º 8
0
/**
  Get EMMC device model name.

  @param[in, out] Device   The pointer to the EMMC_DEVICE data structure.
  @param[in]      Cid      Pointer to EMMC_CID data structure.

  @retval EFI_SUCCESS      The function completed successfully

**/
EFI_STATUS
GetEmmcModelName (
  IN OUT EMMC_DEVICE         *Device,
  IN     EMMC_CID            *Cid
  )
{
  CHAR8  String[EMMC_MODEL_NAME_MAX_LEN];

  ZeroMem (String, sizeof (String));
  CopyMem (String, &Cid->OemId, sizeof (Cid->OemId));
  String[sizeof (Cid->OemId)] = ' ';
  CopyMem (String + sizeof (Cid->OemId) + 1, Cid->ProductName, sizeof (Cid->ProductName));
  String[sizeof (Cid->OemId) + sizeof (Cid->ProductName)] = ' ';
  CopyMem (String + sizeof (Cid->OemId) + sizeof (Cid->ProductName) + 1, Cid->ProductSerialNumber, sizeof (Cid->ProductSerialNumber));

  AsciiStrToUnicodeStr (String, Device->ModelName);

  return EFI_SUCCESS;
}
Ejemplo n.º 9
0
/** If string is a null pointer, the system function determines whether the
    host environment has a command processor. If string is not a null pointer,
    the system function passes the string pointed to by string to that command
    processor to be executed in a manner which the implementation shall
    document; this might then cause the program calling system to behave in a
    non-conforming manner or to terminate.

    @retval   EXIT_FAILURE    EFIerrno will contain the EFI status code
                              indicating the cause of failure.

    @retval   EXIT_SUCCESS    EFIerrno will contain the EFI status returned
                              by the executed command string.
    @retval   0               If string is NULL, 0 means a command processor
                              is not available.
    @retval   1               If string is NULL, 1 means a command processor
                              is available.
**/
int
system(const char *string)
{
  EFI_STATUS  CmdStat;
  EFI_STATUS  OpStat;
  EFI_HANDLE  MyHandle = gImageHandle;

  if( string == NULL) {
    return 1;
  }
  (void)AsciiStrToUnicodeStr( string, gMD->UString);
  OpStat = ShellExecute( &MyHandle, gMD->UString, FALSE, NULL, &CmdStat);
  if(OpStat == RETURN_SUCCESS) {
    EFIerrno = CmdStat;
    return EXIT_SUCCESS;
  }
  EFIerrno = OpStat;
  return EXIT_FAILURE;
}
Ejemplo n.º 10
0
EFI_STATUS
ArmFastbootPlatformOemCommand (
  IN  CHAR8   *Command
  )
{
  CHAR16 CommandUnicode[65];

  AsciiStrToUnicodeStr (Command, CommandUnicode);

  if (AsciiStrCmp (Command, "Demonstrate") == 0) {
    DEBUG ((EFI_D_ERROR, "ARM OEM Fastboot command 'Demonstrate' received.\n"));
    return EFI_SUCCESS;
  } else {
    DEBUG ((EFI_D_ERROR,
      "VExpress: Unrecognised Fastboot OEM command: %s\n",
      CommandUnicode
      ));
    return EFI_NOT_FOUND;
  }
}
Ejemplo n.º 11
0
EFI_STATUS
EditHIInputAscii (
  IN OUT CHAR8   *CmdLine,
  IN     UINTN   MaxCmdLine
  )
{
  CHAR16*     Str;
  EFI_STATUS  Status;

  Str = (CHAR16*)AllocatePool (MaxCmdLine * sizeof(CHAR16));
  AsciiStrToUnicodeStr (CmdLine, Str);

  Status = EditHIInputStr (Str, MaxCmdLine);
  if (!EFI_ERROR(Status)) {
    UnicodeStrToAsciiStr (Str, CmdLine);
  }
  FreePool (Str);

  return Status;
}
Ejemplo n.º 12
0
VOID
InstallProcessorSmbios (
  IN VOID                  *Smbios
  )
{
  SMBIOS_STRUCTURE_POINTER          SmbiosTable;
  CHAR8                             *AString;
  CHAR16                            *UString;
  STRING_REF                        Token;

  //
  // Processor info (TYPE 4)
  // 
  SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 4, 0);
  if (SmbiosTable.Raw == NULL) {
    DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 4 (Processor Info) not found!\n"));
    return ;
  }

  //
  // Log Smbios Record Type4
  //
  LogSmbiosData(gSmbios,(UINT8*)SmbiosTable.Type4);

  //
  // Set ProcessorVersion string
  //
  AString = GetSmbiosString (SmbiosTable, SmbiosTable.Type4->ProcessorVersion);
  UString = AllocateZeroPool ((AsciiStrLen(AString) + 1) * sizeof(CHAR16));
  ASSERT (UString != NULL);
  AsciiStrToUnicodeStr (AString, UString);

  Token = HiiSetString (gStringHandle, 0, UString, NULL);
  if (Token == 0) {
    gBS->FreePool (UString);
    return ;
  }
  gBS->FreePool (UString);
  return ;
}
Ejemplo n.º 13
0
VOID
InstallMiscSmbios (
  IN VOID                  *Smbios
  )
{
  SMBIOS_STRUCTURE_POINTER          SmbiosTable;
  CHAR8                             *AString;
  CHAR16                            *UString;
  STRING_REF                        Token;

  //
  // BIOS information (TYPE 0)
  // 
  SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 0, 0);
  if (SmbiosTable.Raw == NULL) {
    DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 0 (BIOS Information) not found!\n"));
    return ;
  }

  //
  // Record Type 2
  //
  AString = GetSmbiosString (SmbiosTable, SmbiosTable.Type0->BiosVersion);
  UString = AllocateZeroPool ((AsciiStrLen(AString) + 1) * sizeof(CHAR16) + sizeof(FIRMWARE_BIOS_VERSIONE));
  ASSERT (UString != NULL);
  CopyMem (UString, FIRMWARE_BIOS_VERSIONE, sizeof(FIRMWARE_BIOS_VERSIONE));
  AsciiStrToUnicodeStr (AString, UString + sizeof(FIRMWARE_BIOS_VERSIONE) / sizeof(CHAR16) - 1);

  Token = HiiSetString (gStringHandle, 0, UString, NULL);
  if (Token == 0) {
    gBS->FreePool (UString);
    return ;
  }
  gBS->FreePool (UString);

  //
  // Log Smios Type 0
  //
  LogSmbiosData(gSmbios, (UINT8*)SmbiosTable.Type0);
  
  //
  // System information (TYPE 1)
  // 
  SmbiosTable = GetSmbiosTableFromType ((SMBIOS_TABLE_ENTRY_POINT *)Smbios, 1, 0);
  if (SmbiosTable.Raw == NULL) {
    DEBUG ((EFI_D_ERROR, "SmbiosTable: Type 1 (System Information) not found!\n"));
    return ;
  }

  //
  // Record Type 3
  //
  AString = GetSmbiosString (SmbiosTable, SmbiosTable.Type1->ProductName);
  UString = AllocateZeroPool ((AsciiStrLen(AString) + 1) * sizeof(CHAR16) + sizeof(FIRMWARE_PRODUCT_NAME));
  ASSERT (UString != NULL);
  CopyMem (UString, FIRMWARE_PRODUCT_NAME, sizeof(FIRMWARE_PRODUCT_NAME));
  AsciiStrToUnicodeStr (AString, UString + sizeof(FIRMWARE_PRODUCT_NAME) / sizeof(CHAR16) - 1);

  Token = HiiSetString (gStringHandle, 0, UString, NULL);
  if (Token == 0) {
    gBS->FreePool (UString);
    return ;
  }
  gBS->FreePool (UString);

  //
  // Log Smbios Type 1
  //
  LogSmbiosData(gSmbios, (UINT8*)SmbiosTable.Type1);
  
  return ;
}
Ejemplo n.º 14
0
EFI_STATUS
DefineDefaultBootEntries (
  VOID
  )
{
  BDS_LOAD_OPTION*                    BdsLoadOption;
  UINTN                               Size;
  EFI_STATUS                          Status;
  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol;
  EFI_DEVICE_PATH*                    BootDevicePath;
  UINTN                               CmdLineSize;
  UINTN                               CmdLineAsciiSize;
  CHAR16*                             DefaultBootArgument;
  CHAR8*                              AsciiDefaultBootArgument;

  //
  // If Boot Order does not exist then create a default entry
  //
  Size = 0;
  Status = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &Size, NULL);
  if (Status == EFI_NOT_FOUND) {
    if ((PcdGetPtr(PcdDefaultBootDevicePath) == NULL) || (StrLen ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)) == 0)) {
      return EFI_UNSUPPORTED;
    }

    Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
    if (EFI_ERROR(Status)) {
      // You must provide an implementation of DevicePathFromTextProtocol in your firmware (eg: DevicePathDxe)
      DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathFromTextProtocol\n"));
      return Status;
    }
    BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath));

    DEBUG_CODE_BEGIN();
      // We convert back to the text representation of the device Path to see if the initial text is correct
      EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
      CHAR16* DevicePathTxt;

      Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
      ASSERT_EFI_ERROR(Status);
      DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootDevicePath, TRUE, TRUE);

      if (StrCmp ((CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath), DevicePathTxt) != 0) {
        DEBUG ((EFI_D_ERROR, "Device Path given: '%s' Device Path expected: '%s'\n",
            (CHAR16*)PcdGetPtr (PcdDefaultBootDevicePath), DevicePathTxt));
        ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
      }

      FreePool (DevicePathTxt);
    DEBUG_CODE_END();

    // Create the entry is the Default values are correct
    if (BootDevicePath != NULL) {
      // We do not support NULL pointer
      ASSERT (PcdGetPtr (PcdDefaultBootArgument) != NULL);

      //
      // Logic to handle ASCII or Unicode default parameters
      //
      if (*(CHAR8*)PcdGetPtr (PcdDefaultBootArgument) == '\0') {
        CmdLineSize = 0;
        CmdLineAsciiSize = 0;
        DefaultBootArgument = NULL;
        AsciiDefaultBootArgument = NULL;
      } else if (IsUnicodeString ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument))) {
        // The command line is a Unicode string
        DefaultBootArgument = (CHAR16*)PcdGetPtr (PcdDefaultBootArgument);
        CmdLineSize = StrSize (DefaultBootArgument);

        // Initialize ASCII variables
        CmdLineAsciiSize = CmdLineSize / 2;
        AsciiDefaultBootArgument = AllocatePool (CmdLineAsciiSize);
        if (AsciiDefaultBootArgument == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }
        UnicodeStrToAsciiStr ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument), AsciiDefaultBootArgument);
      } else {
        // The command line is a ASCII string
        AsciiDefaultBootArgument = (CHAR8*)PcdGetPtr (PcdDefaultBootArgument);
        CmdLineAsciiSize = AsciiStrSize (AsciiDefaultBootArgument);

        // Initialize ASCII variables
        CmdLineSize = CmdLineAsciiSize * 2;
        DefaultBootArgument = AllocatePool (CmdLineSize);
        if (DefaultBootArgument == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }
        AsciiStrToUnicodeStr (AsciiDefaultBootArgument, DefaultBootArgument);
      }

      BootOptionCreate (LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT,
        (CHAR16*)PcdGetPtr (PcdDefaultBootDescription),
        BootDevicePath,
        (UINT8 *)DefaultBootArgument, // OptionalData
        CmdLineSize,                  // OptionalDataSize
        &BdsLoadOption
        );
      FreePool (BdsLoadOption);

      if (DefaultBootArgument == (CHAR16*)PcdGetPtr (PcdDefaultBootArgument)) {
        FreePool (AsciiDefaultBootArgument);
      } else if (DefaultBootArgument != NULL) {
        FreePool (DefaultBootArgument);
      }
    } else {
      Status = EFI_UNSUPPORTED;
    }
  }

  return Status;
}
Ejemplo n.º 15
0
/**
  The Request() function queues an HTTP request to this HTTP instance.

  Similar to Transmit() function in the EFI TCP driver. When the HTTP request is sent
  successfully, or if there is an error, Status in token will be updated and Event will
  be signaled.

  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
  @param[in]  Token               Pointer to storage containing HTTP request token.

  @retval EFI_SUCCESS             Outgoing data was processed.
  @retval EFI_NOT_STARTED         This EFI HTTP Protocol instance has not been started.
  @retval EFI_DEVICE_ERROR        An unexpected system or network error occurred.
  @retval EFI_TIMEOUT             Data was dropped out of the transmit or receive queue.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate enough system resources.
  @retval EFI_UNSUPPORTED         The HTTP method is not supported in current
                                  implementation.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  Token->Message is NULL.
                                  Token->Message->Body is not NULL,
                                  Token->Message->BodyLength is non-zero, and
                                  Token->Message->Data is NULL, but a previous call to
                                  Request()has not been completed successfully.
**/
EFI_STATUS
EFIAPI
EfiHttpRequest (
  IN  EFI_HTTP_PROTOCOL         *This,
  IN  EFI_HTTP_TOKEN            *Token
  )
{
  EFI_HTTP_MESSAGE              *HttpMsg;
  EFI_HTTP_REQUEST_DATA         *Request;
  VOID                          *UrlParser;
  EFI_STATUS                    Status;
  CHAR8                         *HostName;
  UINT16                        RemotePort;
  HTTP_PROTOCOL                 *HttpInstance;
  BOOLEAN                       Configure;
  BOOLEAN                       ReConfigure;
  CHAR8                         *RequestStr;
  CHAR8                         *Url;
  CHAR16                        *HostNameStr;
  HTTP_TOKEN_WRAP               *Wrap;
  HTTP_TCP_TOKEN_WRAP           *TcpWrap;

  if ((This == NULL) || (Token == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  HttpMsg = Token->Message;
  if ((HttpMsg == NULL) || (HttpMsg->Headers == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Current implementation does not support POST/PUT method.
  // If future version supports these two methods, Request could be NULL for a special case that to send large amounts
  // of data. For this case, the implementation need check whether previous call to Request() has been completed or not.
  // 
  //
  Request = HttpMsg->Data.Request;
  if ((Request == NULL) || (Request->Url == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Only support GET and HEAD method in current implementation.
  //
  if ((Request->Method != HttpMethodGet) && (Request->Method != HttpMethodHead)) {
    return EFI_UNSUPPORTED;
  }

  HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);
  ASSERT (HttpInstance != NULL);

  if (HttpInstance->State < HTTP_STATE_HTTP_CONFIGED) {
    return EFI_NOT_STARTED;
  }

  if (HttpInstance->LocalAddressIsIPv6) {
    return EFI_UNSUPPORTED;
  }

  //
  // Check whether the token already existed.
  //
  if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTokenExist, Token))) {
    return EFI_ACCESS_DENIED;   
  }  

  Url         = NULL;
  HostName    = NULL;
  Wrap        = NULL;
  HostNameStr = NULL;
  TcpWrap     = NULL;

  //
  // Parse the URI of the remote host.
  //
  Url = AllocatePool (StrLen (Request->Url) + 1);
  if (Url == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  UnicodeStrToAsciiStr (Request->Url, Url);
  UrlParser = NULL;
  Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser);
  if (EFI_ERROR (Status)) {
    goto Error1;
  }

  RequestStr = NULL;
  HostName   = NULL;
  Status     = HttpUrlGetHostName (Url, UrlParser, &HostName);
  if (EFI_ERROR (Status)) {
    goto Error1;
  }

  Status = HttpUrlGetPort (Url, UrlParser, &RemotePort);
  if (EFI_ERROR (Status)) {
    RemotePort = HTTP_DEFAULT_PORT;
  }

  Configure   = TRUE;
  ReConfigure = TRUE;  

  if (HttpInstance->RemoteHost == NULL && HttpInstance->RemotePort == 0) {
    //
    // Request() is called the first time. 
    //
    ReConfigure = FALSE;
  } else {
    if ((HttpInstance->RemotePort == RemotePort) &&
        (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0)) {
      //
      // Host Name and port number of the request URL are the same with previous call to Request().
      // Check whether previous TCP packet sent out.
      //
      if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTcpNotReady, NULL))) {
        //
        // Wrap the HTTP token in HTTP_TOKEN_WRAP
        //
        Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP));
        if (Wrap == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          goto Error1;
        }

        Wrap->HttpToken    = Token;
        Wrap->HttpInstance = HttpInstance;

        Status = HttpCreateTcp4TxEvent (Wrap);
        if (EFI_ERROR (Status)) {
          goto Error1;
        }

        Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap);
        if (EFI_ERROR (Status)) {
          goto Error1;
        }

        Wrap->TcpWrap.Method = Request->Method;

        FreePool (Url);
        FreePool (HostName);
        
        //
        // Queue the HTTP token and return.
        //
        return EFI_SUCCESS;
      } else {
        //
        // Use existing TCP instance to transmit the packet.
        //
        Configure   = FALSE;
        ReConfigure = FALSE;
      }
    } else {
      //
      // Need close existing TCP instance and create a new TCP instance for data transmit.
      //
      if (HttpInstance->RemoteHost != NULL) {
        FreePool (HttpInstance->RemoteHost);
        HttpInstance->RemoteHost = NULL;
      }
    }
  } 

  if (Configure) {
    //
    // Parse Url for IPv4 address, if failed, perform DNS resolution.
    //
    Status = NetLibAsciiStrToIp4 (HostName, &HttpInstance->RemoteAddr);
    if (EFI_ERROR (Status)) {
      HostNameStr = AllocateZeroPool ((AsciiStrLen (HostName) + 1) * sizeof (UINT16));
      if (HostNameStr == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Error1;
      }

      AsciiStrToUnicodeStr (HostName, HostNameStr);
      Status = HttpDns4 (HttpInstance, HostNameStr, &HttpInstance->RemoteAddr);
      FreePool (HostNameStr);
      if (EFI_ERROR (Status)) {
        goto Error1;
      }
    }

    //
    // Save the RemotePort and RemoteHost.
    //
    ASSERT (HttpInstance->RemoteHost == NULL);
    HttpInstance->RemotePort = RemotePort;
    HttpInstance->RemoteHost = HostName;
    HostName = NULL;
  }

  if (ReConfigure) {
    //
    // The request URL is different from previous calls to Request(), close existing TCP instance.
    //
    ASSERT (HttpInstance->Tcp4 != NULL);
    HttpCloseConnection (HttpInstance);
    EfiHttpCancel (This, NULL);
  }

  //
  // Wrap the HTTP token in HTTP_TOKEN_WRAP
  //
  Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP));
  if (Wrap == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error1;
  }

  Wrap->HttpToken      = Token;
  Wrap->HttpInstance   = HttpInstance;
  Wrap->TcpWrap.Method = Request->Method;

  if (Configure) {
    //
    // Configure TCP instance.
    //
    Status = HttpConfigureTcp4 (HttpInstance, Wrap);
    if (EFI_ERROR (Status)) {
      goto Error1;
    }
    //
    // Connect TCP.
    //
    Status = HttpConnectTcp4 (HttpInstance);
    if (EFI_ERROR (Status)) {
      goto Error2;
    }
  } else {
    //
    // For the new HTTP token, create TX TCP token events.    
    //
    Status = HttpCreateTcp4TxEvent (Wrap);
    if (EFI_ERROR (Status)) {
      goto Error1;
    }
  }

  //
  // Create request message.
  //
  RequestStr = HttpGenRequestString (HttpInstance, HttpMsg, Url);
  if (RequestStr == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error3;
  }

  Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap);
  if (EFI_ERROR (Status)) {
    goto Error4;
  }

  FreePool (Url);
  if (HostName != NULL) {
    FreePool (HostName);
  }

  //
  // Transmit the request message.
  //
  Status = HttpTransmitTcp4 (
             HttpInstance,
             Wrap,
             (UINT8*) RequestStr,
             AsciiStrLen (RequestStr)
             );
  if (EFI_ERROR (Status)) {
    goto Error5;    
  }

  return EFI_SUCCESS;

Error5:
    NetMapRemoveTail (&HttpInstance->TxTokens, NULL);

Error4:
  if (RequestStr != NULL) {
    FreePool (RequestStr);
  }  

Error3:
  HttpCloseConnection (HttpInstance);


Error2:
  HttpCloseTcp4ConnCloseEvent (HttpInstance);
  if (NULL != Wrap->TcpWrap.TxToken.CompletionToken.Event) {
    gBS->CloseEvent (Wrap->TcpWrap.TxToken.CompletionToken.Event);
  }

Error1:
  if (Url != NULL) {
    FreePool (Url);
  }
  if (HostName != NULL) {
    FreePool (HostName);
  }
  if (Wrap != NULL) {
    FreePool (Wrap);
  }
  if (UrlParser!= NULL) {
    HttpUrlFreeParser (UrlParser);
  }

  return Status;
  
}
Ejemplo n.º 16
0
/*
  Set up TCP Fastboot transport: Configure the network device via DHCP then
  start waiting for a TCP connection on the Fastboot port.
*/
EFI_STATUS
TcpFastbootTransportStart (
  EFI_EVENT ReceiveEvent
  )
{
  EFI_STATUS                    Status;
  EFI_HANDLE                    NetDeviceHandle;
  EFI_HANDLE                   *HandleBuffer;
  EFI_IP4_MODE_DATA             Ip4ModeData;
  UINTN                         NumHandles;
  UINTN                         HostnameSize = 256;
  CHAR8                         Hostname[256];
  CHAR16                        HostnameUnicode[256] = L"<no hostname>";
  CHAR16                        IpAddrString[16];
  UINTN                         Index;

  EFI_TCP4_CONFIG_DATA TcpConfigData = {
    0x00,                                           // IPv4 Type of Service
    255,                                            // IPv4 Time to Live
    {                                               // AccessPoint:
      TRUE,                                         // Use default address
      { {0, 0, 0, 0} },                             // IP Address  (ignored - use default)
      { {0, 0, 0, 0} },                             // Subnet mask (ignored - use default)
      FixedPcdGet32 (PcdAndroidFastbootTcpPort),    // Station port
      { {0, 0, 0, 0} },                             // Remote address: accept any
      0,                                            // Remote Port: accept any
      FALSE                                         // ActiveFlag: be a "server"
    },
    NULL                                            // Default advanced TCP options
  };

  mReceiveEvent = ReceiveEvent;
  InitializeListHead (&mPacketListHead);

  mTextOut->OutputString (mTextOut, L"Initialising TCP Fastboot transport...\r\n");

  //
  // Open a passive TCP instance
  //

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiTcp4ServiceBindingProtocolGuid,
                  NULL,
                  &NumHandles,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Find TCP Service Binding: %r\n", Status));
    return Status;
  }

  // We just use the first network device
  NetDeviceHandle = HandleBuffer[0];

  Status =  gBS->OpenProtocol (
                    NetDeviceHandle,
                    &gEfiTcp4ServiceBindingProtocolGuid,
                    (VOID **) &mTcpServiceBinding,
                    gImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Open TCP Service Binding: %r\n", Status));
    return Status;
  }

  Status = mTcpServiceBinding->CreateChild (mTcpServiceBinding, &mTcpHandle);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "TCP ServiceBinding Create: %r\n", Status));
    return Status;
  }

  Status =  gBS->OpenProtocol (
                    mTcpHandle,
                    &gEfiTcp4ProtocolGuid,
                    (VOID **) &mTcpListener,
                    gImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Open TCP Protocol: %r\n", Status));
  }

  //
  // Set up re-usable tokens
  //

  for (Index = 0; Index < NUM_RX_TOKENS; Index++) {
    mRxData[Index].UrgentFlag = FALSE;
    mRxData[Index].FragmentCount = 1;
    mReceiveToken[Index].Packet.RxData = &mRxData[Index];
  }

  mTxData.Push = TRUE;
  mTxData.Urgent = FALSE;
  mTxData.FragmentCount = 1;
  mTransmitToken.Packet.TxData = &mTxData;

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  ConnectionAccepted,
                  &mAcceptToken,
                  &mAcceptToken.CompletionToken.Event
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->CreateEvent (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  ConnectionClosed,
                  &mCloseToken,
                  &mCloseToken.CompletionToken.Event
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Configure the TCP instance
  //

  Status = mTcpListener->Configure (mTcpListener, &TcpConfigData);
  if (Status == EFI_NO_MAPPING) {
    // Wait until the IP configuration process (probably DHCP) has finished
    do {
      Status = mTcpListener->GetModeData (mTcpListener,
                               NULL, NULL,
                               &Ip4ModeData,
                               NULL, NULL
                               );
      ASSERT_EFI_ERROR (Status);
    } while (!Ip4ModeData.IsConfigured);
    Status = mTcpListener->Configure (mTcpListener, &TcpConfigData);
  } else if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "TCP Configure: %r\n", Status));
    return Status;
  }

  //
  // Tell the user our address and hostname
  //
  IP4_ADDR_TO_STRING (Ip4ModeData.ConfigData.StationAddress, IpAddrString);

  // Look up hostname
  Status = gRT->GetVariable (
                  L"Hostname",
                  &gEfiHostnameVariableGuid,
                  NULL,
                  &HostnameSize,
                  &Hostname
                  );
  if (!EFI_ERROR (Status) && HostnameSize != 0) {
    AsciiStrToUnicodeStr (Hostname, HostnameUnicode);
  }

  // Hostname variable is not null-terminated.
  Hostname[HostnameSize] = L'\0';

  mTextOut->OutputString (mTextOut, L"TCP Fastboot transport configured.");
  mTextOut->OutputString (mTextOut, L"\r\nIP address: ");
  mTextOut->OutputString (mTextOut ,IpAddrString);
  mTextOut->OutputString (mTextOut, L"\r\n");
  mTextOut->OutputString (mTextOut, L"\r\nhostname: ");
  mTextOut->OutputString (mTextOut, HostnameUnicode);
  mTextOut->OutputString (mTextOut, L"\r\n");

  //
  // Start listening for a connection
  //

  Status = mTcpListener->Accept (mTcpListener, &mAcceptToken);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "TCP Accept: %r\n", Status));
    return Status;
  }

  mTextOut->OutputString (mTextOut, L"TCP Fastboot transport initialised.\r\n");

  FreePool (HandleBuffer);

  return EFI_SUCCESS;
}
Ejemplo n.º 17
0
/**
  Gather and print Handle data.

  @param[in]    ExcludeFlag   TRUE to exclude individual Cumulative items from display.

  @return       Status from a call to gBS->LocateHandle().
**/
EFI_STATUS
ProcessHandles(
  IN BOOLEAN      ExcludeFlag
  )
{
  MEASUREMENT_RECORD        Measurement;
  UINT64                    ElapsedTime;
  UINT64                    Duration;
  EFI_HANDLE                *HandleBuffer;
  EFI_STRING                StringPtr;
  UINTN                     Index;
  UINTN                     LogEntryKey;
  UINTN                     Count;
  UINTN                     Size;
  EFI_HANDLE                TempHandle;
  EFI_STATUS                Status;
  EFI_STRING                StringPtrUnknown;

  StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
  StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL);
  PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
              (StringPtr == NULL) ? StringPtrUnknown : StringPtr);
  FreePool (StringPtr);
  FreePool (StringPtrUnknown);

  Size = 0;
  HandleBuffer = &TempHandle;
  Status  = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    HandleBuffer = AllocatePool (Size);
    ASSERT (HandleBuffer != NULL);
    if (HandleBuffer == NULL) {
      return Status;
    }
    Status  = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);
  }
  if (EFI_ERROR (Status)) {
    PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status);
  }
  else {
#if DP_DEBUG == 2
    Print (L"There are %,d Handles defined.\n", (Size / sizeof(HandleBuffer[0])));
#endif

    if (mShowId) {
      PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION2) );
    } else {
      PrintToken (STRING_TOKEN (STR_DP_HANDLE_SECTION) );
    }
    PrintToken (STRING_TOKEN (STR_DP_DASHES) );

    LogEntryKey = 0;
    Count   = 0;
    while ((LogEntryKey = GetPerformanceMeasurementEx (
                            LogEntryKey,
                            &Measurement.Handle,
                            &Measurement.Token,
                            &Measurement.Module,
                            &Measurement.StartTimeStamp,
                            &Measurement.EndTimeStamp,
                            &Measurement.Identifier)) != 0)
    {
      Count++;
      Duration = GetDuration (&Measurement);
      ElapsedTime = DurationInMicroSeconds ( Duration );
      if ((ElapsedTime < mInterestThreshold)                 ||
          (Measurement.EndTimeStamp == 0)                    ||
          (Measurement.Handle == NULL)                       ||
          ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
         ) { // Ignore "uninteresting" or excluded records
        continue;
      }
      mGaugeString[0] = 0;    // Empty driver name by default
      AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
      // See if the Handle is in the HandleBuffer
      for (Index = 0; Index < (Size / sizeof(HandleBuffer[0])); Index++) {
        if (Measurement.Handle == HandleBuffer[Index]) {
          GetNameFromHandle (HandleBuffer[Index]); // Name is put into mGaugeString
          break;
        }
      }
      // Ensure that the argument strings are not too long.
      mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
      mUnicodeToken[11] = 0;
      if (mGaugeString[0] != 0) {
        // Display the record if it has a valid handle.
        if (mShowId) {
          PrintToken (
            STRING_TOKEN (STR_DP_HANDLE_VARS2),
            Count,      // 1 based, Which measurement record is being printed
            Index + 1,  // 1 based, Which handle is being printed
            mGaugeString,
            mUnicodeToken,
            ElapsedTime,
            Measurement.Identifier
          );
        } else {
          PrintToken (
            STRING_TOKEN (STR_DP_HANDLE_VARS),
            Count,      // 1 based, Which measurement record is being printed
            Index + 1,  // 1 based, Which handle is being printed
            mGaugeString,
            mUnicodeToken,
            ElapsedTime
          );
        }
      }
    }
  }
  if (HandleBuffer != &TempHandle) {
    FreePool (HandleBuffer);
  }
  return Status;
}
Ejemplo n.º 18
0
/**
  Add or update a variable in the environment list

  @param name     Address of a zero terminated name string
  @param value    Address of a zero terminated value string
  @param rewrite  TRUE allows overwriting existing values

  @retval Returns 0 upon success
  @retval Returns -1 upon failure, sets errno with more information

  Errors

  EINVAL - name is NULL or points to a zero length string
  EALREADY - name already set and rewrite set to FALSE
  ENODEV - Unable to set non-volatile version of environment variable
  ENOMEM - Unable to set volatile version of environment variable
  ENOTSUP - Variable storage not supported

**/
int
setenv (
  register const char * name,
  register const char * value,
  int rewrite
  )
{
  CONST CHAR16 * HostName;
  int retval;
  EFI_STATUS Status;
  CHAR16 * UName;
  CHAR16 * UValue;

  //
  //  Assume failure
  //
  retval = -1;

  //
  //  Validate the inputs
  //
  errno = EINVAL;
  if (( NULL != name ) && ( 0 != *name )) {
    //
    //  Get the storage locations for the unicode strings
    //
    UName = &gMD->UString[0];
    UValue = &gMD->UString2[0];

    //
    //  Convert the strings
    //
    AsciiStrToUnicodeStr ( name, UName );
    AsciiStrToUnicodeStr ( value, UValue );

    //
    //  Determine if the string is already present
    //
    errno = EALREADY;
    HostName = ShellGetEnvironmentVariable ( UName );
    if ( rewrite || ( NULL == HostName )) {
      //
      //  Support systems that don't have non-volatile memory
      //
      errno = ENOMEM;
      Status = ShellSetEnvironmentVariable ( UName, UValue, TRUE );
      if ( EFI_ERROR ( Status )) {
        if ( EFI_UNSUPPORTED == Status ) {
          errno = ENOTSUP;
        }
      }
      else {
        //
        //  Permanently set the environment variable
        //
        errno = ENODEV;
        Status = ShellSetEnvironmentVariable ( UName, UValue, FALSE );
        if ( !EFI_ERROR ( Status )) {
          //
          //  Success
          //
          errno = 0;
          retval = 0;
        }
      }
    }
  }

  //
  //  Return the operation status
  //
  return retval;
}
Ejemplo n.º 19
0
/**
  Gather and print ALL Trace Records.

  Displays all "interesting" Trace measurements in order.<BR>
  The number of records displayed is controlled by:
     - records with a duration less than mInterestThreshold microseconds are not displayed.
     - No more than Limit records are displayed.  A Limit of zero will not limit the output.
     - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not
       displayed.

  @pre    The mInterestThreshold global variable is set to the shortest duration to be printed.
           The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.
           They must not be in use by a calling function.

  @param[in]    Limit       The number of records to print.  Zero is ALL.
  @param[in]    ExcludeFlag TRUE to exclude individual Cumulative items from display.

**/
VOID
DumpAllTrace(
  IN UINTN             Limit,
  IN BOOLEAN           ExcludeFlag
  )
{
  MEASUREMENT_RECORD        Measurement;
  UINT64                    ElapsedTime;
  UINT64                    Duration;
  const CHAR16              *IncFlag;
  UINTN                     LogEntryKey;
  UINTN                     Count;
  UINTN                     Index;
  UINTN                     TIndex;

  EFI_HANDLE                *HandleBuffer;
  UINTN                     Size;
  EFI_HANDLE                TempHandle;
  EFI_STATUS                Status;
  EFI_STRING                StringPtrUnknown;

  StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
  IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL);
  PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
              (IncFlag == NULL) ? StringPtrUnknown : IncFlag);
  FreePool (StringPtrUnknown);

  // Get Handle information
  //
  Size = 0;
  HandleBuffer = &TempHandle;
  Status  = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    HandleBuffer = AllocatePool (Size);
    ASSERT (HandleBuffer != NULL);
    if (HandleBuffer == NULL) {
      return;
    }
    Status  = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);
  }
  if (EFI_ERROR (Status)) {
    PrintToken (STRING_TOKEN (STR_DP_HANDLES_ERROR), Status);
  }
  else {
    // We have successfully populated the HandleBuffer
    // Display ALL Measurement Records
    //    Up to Limit lines displayed
    //    Display only records with Elapsed times >= mInterestThreshold
    //    Display driver names in Module field for records with Handles.
    //
    if (mShowId) {
      PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR2) );
      PrintToken (STRING_TOKEN (STR_DP_ALL_DASHES2) );
    } else {
      PrintToken (STRING_TOKEN (STR_DP_ALL_HEADR) );
      PrintToken (STRING_TOKEN (STR_DP_DASHES) );
    }

    LogEntryKey = 0;
    Count = 0;
    Index = 0;
    while ( WITHIN_LIMIT(Count, Limit) &&
            ((LogEntryKey = GetPerformanceMeasurementEx (
                            LogEntryKey,
                            &Measurement.Handle,
                            &Measurement.Token,
                            &Measurement.Module,
                            &Measurement.StartTimeStamp,
                            &Measurement.EndTimeStamp,
                            &Measurement.Identifier)) != 0)
          )
    {
      ++Index;    // Count every record.  First record is 1.
      ElapsedTime = 0;
      SafeFreePool ((VOID *) IncFlag);
      if (Measurement.EndTimeStamp != 0) {
        Duration = GetDuration (&Measurement);
        ElapsedTime = DurationInMicroSeconds ( Duration );
        IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_COMPLETE), NULL);
      }
      else {
        IncFlag = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_INCOMPLETE), NULL);  // Mark incomplete records
      }
      if (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) ||
          ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))
         ) {      // Ignore "uninteresting" or excluded records
        continue;
      }
      ++Count;    // Count the number of records printed

      // If Handle is non-zero, see if we can determine a name for the driver
      AsciiStrToUnicodeStr (Measurement.Module, mGaugeString); // Use Module by default
      AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
      if (Measurement.Handle != NULL) {
        // See if the Handle is in the HandleBuffer
        for (TIndex = 0; TIndex < (Size / sizeof(HandleBuffer[0])); TIndex++) {
          if (Measurement.Handle == HandleBuffer[TIndex]) {
            GetNameFromHandle (HandleBuffer[TIndex]);
            break;
          }
        }
      }

      if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {
        UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", Measurement.Handle);
      }

      // Ensure that the argument strings are not too long.
      mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
      mUnicodeToken[13] = 0;

      if (mShowId) {
        PrintToken( STRING_TOKEN (STR_DP_ALL_VARS2),
          Index,      // 1 based, Which measurement record is being printed
          IncFlag,
          Measurement.Handle,
          mGaugeString,
          mUnicodeToken,
          ElapsedTime,
          Measurement.Identifier
        );
      } else {
        PrintToken( STRING_TOKEN (STR_DP_ALL_VARS),
          Index,      // 1 based, Which measurement record is being printed
          IncFlag,
          Measurement.Handle,
          mGaugeString,
          mUnicodeToken,
          ElapsedTime
        );
      }
    }
  }
  if (HandleBuffer != &TempHandle) {
    FreePool (HandleBuffer);
  }
  SafeFreePool ((VOID *) IncFlag);
}
Ejemplo n.º 20
0
EFI_STATUS
ArmFastbootPlatformFlashPartition (
  IN CHAR8  *PartitionName,
  IN UINTN   Size,
  IN VOID   *Image
  )
{
  EFI_STATUS               Status;
  EFI_BLOCK_IO_PROTOCOL   *BlockIo;
  EFI_DISK_IO_PROTOCOL    *DiskIo;
  UINT32                   MediaId;
  UINTN                    PartitionSize;
  FASTBOOT_PARTITION_LIST *Entry;
  CHAR16                   PartitionNameUnicode[60];
  BOOLEAN                  PartitionFound;

  AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode);

  PartitionFound = FALSE;
  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
    // Search the partition list for the partition named by PartitionName
    if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
      PartitionFound = TRUE;
      break;
    }

   Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link);
  }
  if (!PartitionFound) {
    return EFI_NOT_FOUND;
  }

  Status = gBS->OpenProtocol (
                  Entry->PartitionHandle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **) &BlockIo,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Fastboot platform: couldn't open Block IO for flash: %r\n", Status));
    return EFI_NOT_FOUND;
  }

  // Check image will fit on device
  PartitionSize = (BlockIo->Media->LastBlock + 1) * BlockIo->Media->BlockSize;
  if (PartitionSize < Size) {
    DEBUG ((EFI_D_ERROR, "Partition not big enough.\n"));
    DEBUG ((EFI_D_ERROR, "Partition Size:\t%d\nImage Size:\t%d\n", PartitionSize, Size));

    return EFI_VOLUME_FULL;
  }

  MediaId = BlockIo->Media->MediaId;

  Status = gBS->OpenProtocol (
                  Entry->PartitionHandle,
                  &gEfiDiskIoProtocolGuid,
                  (VOID **) &DiskIo,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  ASSERT_EFI_ERROR (Status);

  Status = DiskIo->WriteDisk (DiskIo, MediaId, 0, Size, Image);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  BlockIo->FlushBlocks(BlockIo);

  return Status;
}
Ejemplo n.º 21
0
EFI_STATUS
EFIAPI
EblGetCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS        Status = EFI_INVALID_PARAMETER;
  UINTN       Size;
  VOID*       Value;
  CHAR8*      AsciiVariableName = NULL;
  CHAR16*     VariableName;
  UINT32      Index;

  if (Argc == 1) {
    AsciiPrint("Variable name is missing.\n");
    return Status;
  }

  for (Index = 1; Index < Argc; Index++) {
    if (Argv[Index][0] == '-') {
      AsciiPrint("Warning: '%a' not recognized.\n",Argv[Index]);
    } else {
      AsciiVariableName = Argv[Index];
    }
  }

  if (AsciiVariableName == NULL) {
    AsciiPrint("Variable name is missing.\n");
    return Status;
  } else {
    VariableName = AllocatePool((AsciiStrLen (AsciiVariableName) + 1) * sizeof (CHAR16));
    AsciiStrToUnicodeStr (AsciiVariableName,VariableName);
  }

  // Try to get the variable size.
  Value = NULL;
  Size = 0;
  Status = gRT->GetVariable (VariableName, &gEfiGlobalVariableGuid, NULL, &Size, Value);
  if (Status == EFI_NOT_FOUND) {
    AsciiPrint("Variable name '%s' not found.\n",VariableName);
  } else if (Status == EFI_BUFFER_TOO_SMALL) {
    // Get the environment variable value
    Value = AllocatePool (Size);
    if (Value == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = gRT->GetVariable ((CHAR16 *)VariableName, &gEfiGlobalVariableGuid, NULL, &Size, Value);
    if (EFI_ERROR (Status)) {
      AsciiPrint("Error: '%r'\n",Status);
    } else {
      AsciiPrint("%a=%a\n",AsciiVariableName,Value);
    }
    FreePool(Value);
  } else {
    AsciiPrint("Error: '%r'\n",Status);
  }

  FreePool(VariableName);
  return Status;
}
Ejemplo n.º 22
0
/**
  Allows a program to determine which secondary languages are supported on a given handle for a given primary language

  This routine is intended to be used by drivers to query the interface database for supported languages. 
  This routine returns a string of concatenated 3-byte language identifiers, one per string package associated with the handle.

  @param This           A pointer to the EFI_HII_PROTOCOL instance.
  @param Handle         The handle on which the strings reside. Type EFI_HII_HANDLE is defined in EFI_HII_PROTOCOL.NewPack() 
                        in the Packages section.
  @param PrimaryLanguage Pointer to a NULL-terminated string containing a single ISO 639-2 language identifier, indicating 
                         the primary language.
  @param LanguageString  A string allocated by GetSecondaryLanguages() containing a list of all secondary languages registered 
                         on the handle. The routine will not return the three-spaces language identifier used in other functions 
                         to indicate non-language-specific strings, nor will it return the primary language. This function succeeds 
                         but returns a NULL LanguageString if there are no secondary languages associated with the input Handle and 
                         PrimaryLanguage pair. Type EFI_STRING is defined in String.
  
  @retval EFI_SUCCESS            LanguageString was correctly returned.
  @retval EFI_INVALID_PARAMETER  The Handle was unknown.
**/
EFI_STATUS
EFIAPI
HiiGetSecondaryLanguages (
  IN  EFI_HII_PROTOCOL              *This,
  IN  FRAMEWORK_EFI_HII_HANDLE      Handle,
  IN  CHAR16                        *PrimaryLanguage,
  OUT EFI_STRING                    *LanguageString
  )
{
  HII_THUNK_PRIVATE_DATA     *Private;
  EFI_HII_HANDLE             UefiHiiHandle;
  CHAR8                      *PrimaryLang4646;
  CHAR8                      *PrimaryLang639;
  CHAR8                      *SecLangCodes4646;
  CHAR8                      *SecLangCodes639;
  CHAR16                     *UnicodeSecLangCodes639;
  EFI_STATUS                 Status;

  Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);

  SecLangCodes639        = NULL;
  SecLangCodes4646       = NULL;
  PrimaryLang4646        = NULL;
  UnicodeSecLangCodes639 = NULL;

  UefiHiiHandle = FwHiiHandleToUefiHiiHandle (Private, Handle);
  if (UefiHiiHandle == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  PrimaryLang639 = AllocateZeroPool (StrLen (PrimaryLanguage) + 1);
  if (PrimaryLang639 == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  UnicodeStrToAsciiStr (PrimaryLanguage, PrimaryLang639);

  PrimaryLang4646 = ConvertLanguagesIso639ToRfc4646 (PrimaryLang639);
  ASSERT_EFI_ERROR (PrimaryLang4646 != NULL);

  SecLangCodes4646 = HiiGetSupportedSecondaryLanguages (UefiHiiHandle, PrimaryLang4646);

  if (SecLangCodes4646 == NULL) {
    Status =  EFI_INVALID_PARAMETER;
    goto Done;
  }

  SecLangCodes639 = ConvertLanguagesIso639ToRfc4646 (SecLangCodes4646);
  if (SecLangCodes639 == NULL) {
    Status =  EFI_INVALID_PARAMETER;
    goto Done;
  }

  UnicodeSecLangCodes639 = AllocateZeroPool (AsciiStrSize (SecLangCodes639) * sizeof (CHAR16));
  if (UnicodeSecLangCodes639 == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  //
  // The language returned is in RFC 4646 format.
  //
  *LanguageString = AsciiStrToUnicodeStr (SecLangCodes639, UnicodeSecLangCodes639);
  Status = EFI_SUCCESS;

Done:
  if (PrimaryLang639 != NULL) {
    FreePool (PrimaryLang639);
  }

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

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

  if (SecLangCodes4646 != NULL) {
    FreePool (SecLangCodes4646);
  }
  if (UnicodeSecLangCodes639 != NULL) {
    FreePool (UnicodeSecLangCodes639);
  }
  
  return Status;
}
Ejemplo n.º 23
0
EFI_STATUS
DefineDefaultBootEntries (
  VOID
  )
{
  BDS_LOAD_OPTION*                    BdsLoadOption;
  UINTN                               Size;
  EFI_STATUS                          Status;
  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol;
  EFI_DEVICE_PATH*                    BootDevicePath;
  UINT8*                              OptionalData;
  UINTN                               OptionalDataSize;
  ARM_BDS_LOADER_ARGUMENTS*           BootArguments;
  ARM_BDS_LOADER_TYPE                 BootType;
  EFI_DEVICE_PATH*                    InitrdPath;
  UINTN                               InitrdSize;
  UINTN                               CmdLineSize;
  UINTN                               CmdLineAsciiSize;
  CHAR16*                             DefaultBootArgument;
  CHAR8*                              AsciiDefaultBootArgument;

  //
  // If Boot Order does not exist then create a default entry
  //
  Size = 0;
  Status = gRT->GetVariable (L"BootOrder", &gEfiGlobalVariableGuid, NULL, &Size, NULL);
  if (Status == EFI_NOT_FOUND) {
    if ((PcdGetPtr(PcdDefaultBootDevicePath) == NULL) || (StrLen ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath)) == 0)) {
      return EFI_UNSUPPORTED;
    }

    Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
    if (EFI_ERROR(Status)) {
      // You must provide an implementation of DevicePathFromTextProtocol in your firmware (eg: DevicePathDxe)
      DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathFromTextProtocol\n"));
      return Status;
    }
    BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath));

    DEBUG_CODE_BEGIN();
      // We convert back to the text representation of the device Path to see if the initial text is correct
      EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
      CHAR16* DevicePathTxt;

      Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
      ASSERT_EFI_ERROR(Status);
      DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootDevicePath, TRUE, TRUE);

      ASSERT (StrCmp ((CHAR16*)PcdGetPtr(PcdDefaultBootDevicePath), DevicePathTxt) == 0);

      FreePool (DevicePathTxt);
    DEBUG_CODE_END();

    // Create the entry is the Default values are correct
    if (BootDevicePath != NULL) {
      BootType = (ARM_BDS_LOADER_TYPE)PcdGet32 (PcdDefaultBootType);

      // We do not support NULL pointer
      ASSERT (PcdGetPtr (PcdDefaultBootArgument) != NULL);

      //
      // Logic to handle ASCII or Unicode default parameters
      //
      if (*(CHAR8*)PcdGetPtr (PcdDefaultBootArgument) == '\0') {
        CmdLineSize = 0;
        CmdLineAsciiSize = 0;
        DefaultBootArgument = NULL;
        AsciiDefaultBootArgument = NULL;
      } else if (IsUnicodeString ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument))) {
        // The command line is a Unicode string
        DefaultBootArgument = (CHAR16*)PcdGetPtr (PcdDefaultBootArgument);
        CmdLineSize = StrSize (DefaultBootArgument);

        // Initialize ASCII variables
        CmdLineAsciiSize = CmdLineSize / 2;
        AsciiDefaultBootArgument = AllocatePool (CmdLineAsciiSize);
        if (AsciiDefaultBootArgument == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }
        UnicodeStrToAsciiStr ((CHAR16*)PcdGetPtr (PcdDefaultBootArgument), AsciiDefaultBootArgument);
      } else {
        // The command line is a ASCII string
        AsciiDefaultBootArgument = (CHAR8*)PcdGetPtr (PcdDefaultBootArgument);
        CmdLineAsciiSize = AsciiStrSize (AsciiDefaultBootArgument);

        // Initialize ASCII variables
        CmdLineSize = CmdLineAsciiSize * 2;
        DefaultBootArgument = AllocatePool (CmdLineSize);
        if (DefaultBootArgument == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }
        AsciiStrToUnicodeStr (AsciiDefaultBootArgument, DefaultBootArgument);
      }

      if ((BootType == BDS_LOADER_KERNEL_LINUX_ATAG) || (BootType == BDS_LOADER_KERNEL_LINUX_FDT)) {
        InitrdPath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdDefaultBootInitrdPath));
        InitrdSize = GetDevicePathSize (InitrdPath);

        OptionalDataSize = sizeof(ARM_BDS_LOADER_ARGUMENTS) + CmdLineAsciiSize + InitrdSize;
        BootArguments = (ARM_BDS_LOADER_ARGUMENTS*)AllocatePool (OptionalDataSize);
        if (BootArguments == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }
        BootArguments->LinuxArguments.CmdLineSize = CmdLineAsciiSize;
        BootArguments->LinuxArguments.InitrdSize = InitrdSize;

        CopyMem ((VOID*)(BootArguments + 1), AsciiDefaultBootArgument, CmdLineAsciiSize);
        CopyMem ((VOID*)((UINTN)(BootArguments + 1) + CmdLineAsciiSize), InitrdPath, InitrdSize);

        OptionalData = (UINT8*)BootArguments;
      } else {
        OptionalData = (UINT8*)DefaultBootArgument;
        OptionalDataSize = CmdLineSize;
      }

      BootOptionCreate (LOAD_OPTION_ACTIVE | LOAD_OPTION_CATEGORY_BOOT,
        (CHAR16*)PcdGetPtr(PcdDefaultBootDescription),
        BootDevicePath,
        BootType,
        OptionalData,
        OptionalDataSize,
        &BdsLoadOption
        );
      FreePool (BdsLoadOption);

      if (DefaultBootArgument == (CHAR16*)PcdGetPtr (PcdDefaultBootArgument)) {
        FreePool (AsciiDefaultBootArgument);
      } else if (DefaultBootArgument != NULL) {
        FreePool (DefaultBootArgument);
      }
    } else {
      Status = EFI_UNSUPPORTED;
    }
  }

  return Status;
}
Ejemplo n.º 24
0
/**
  Gather and print global data.

  Strips out incomplete or "Execution Phase" records
  Only prints records where Handle is NULL
  Increment TIndex for every record, even skipped ones, so that we have an
  indication of every measurement record taken.

**/
VOID
ProcessGlobal(
  VOID
)
{
  MEASUREMENT_RECORD        Measurement;
  UINT64                    Duration;
  UINT64                    ElapsedTime;
  EFI_STRING                StringPtr;
  UINTN                     LogEntryKey;
  UINTN                     Index;        // Index, or number, of the measurement record being processed
  EFI_STRING                StringPtrUnknown;

  StringPtrUnknown = HiiGetString (gHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);
  StringPtr = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);
  PrintToken( STRING_TOKEN (STR_DP_SECTION_HEADER),
              (StringPtr == NULL) ? StringPtrUnknown: StringPtr);
  FreePool (StringPtr);
  FreePool (StringPtrUnknown);

  if (mShowId) {
    PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION2));
  } else {
    PrintToken (STRING_TOKEN (STR_DP_GLOBAL_SECTION));
  }
  PrintToken (STRING_TOKEN (STR_DP_DASHES));

  Index = 1;
  LogEntryKey = 0;

  while ((LogEntryKey = GetPerformanceMeasurementEx (
                          LogEntryKey,
                          &Measurement.Handle,
                          &Measurement.Token,
                          &Measurement.Module,
                          &Measurement.StartTimeStamp,
                          &Measurement.EndTimeStamp,
                          &Measurement.Identifier)) != 0)
  {
    AsciiStrToUnicodeStr (Measurement.Module, mGaugeString);
    AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);
    mGaugeString[25] = 0;
    mUnicodeToken[31] = 0;
    if ( ! ( IsPhase( &Measurement)  ||
        (Measurement.Handle != NULL)      ||
        (Measurement.EndTimeStamp == 0)
        ))
    {
      Duration = GetDuration (&Measurement);
      ElapsedTime = DurationInMicroSeconds ( Duration );
      if (ElapsedTime >= mInterestThreshold) {
        if (mShowId) {
          PrintToken (
            STRING_TOKEN (STR_DP_GLOBAL_VARS2),
            Index,
            mGaugeString,
            mUnicodeToken,
            ElapsedTime,
            Measurement.Identifier
            );
        } else {
           PrintToken (
            STRING_TOKEN (STR_DP_GLOBAL_VARS),
            Index,
            mGaugeString,
            mUnicodeToken,
            ElapsedTime
            );
        }
      }
    }
    Index++;
  }
}
Ejemplo n.º 25
0
/**
  Initialize HII information for the FrontPage


  @param InitializeHiiData    TRUE if HII elements need to be initialized.

  @retval  EFI_SUCCESS        The operation is successful.
  @retval  EFI_DEVICE_ERROR   If the dynamic opcode creation failed.

**/
EFI_STATUS
InitializeFrontPage (
  IN BOOLEAN                         InitializeHiiData
  )
{
  EFI_STATUS                  Status;
  CHAR8                       *LangCode;
  CHAR8                       *Lang;
  CHAR8                       *CurrentLang;
  UINTN                       OptionCount;
  CHAR16                      *StringBuffer;
  EFI_HII_HANDLE              HiiHandle;
  VOID                        *OptionsOpCodeHandle;
  VOID                        *StartOpCodeHandle;
  VOID                        *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL          *StartLabel;
  EFI_IFR_GUID_LABEL          *EndLabel;
  EFI_HII_STRING_PROTOCOL     *HiiString;
  UINTN                       StringSize;

  Lang         = NULL;
  StringBuffer = NULL;

  if (InitializeHiiData) {
    //
    // Initialize the Device Manager
    //
    InitializeDeviceManager ();

    //
    // Initialize the Device Manager
    //
    InitializeBootManager ();

    gCallbackKey  = 0;

    //
    // Locate Hii relative protocols
    //
    Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Install Device Path Protocol and Config Access protocol to driver handle
    //
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &gFrontPagePrivate.DriverHandle,
                    &gEfiDevicePathProtocolGuid,
                    &mFrontPageHiiVendorDevicePath,
                    &gEfiHiiConfigAccessProtocolGuid,
                    &gFrontPagePrivate.ConfigAccess,
                    NULL
                    );
    ASSERT_EFI_ERROR (Status);

    //
    // Publish our HII data
    //
    gFrontPagePrivate.HiiHandle = HiiAddPackages (
                                    &gFrontPageFormSetGuid,
                                    gFrontPagePrivate.DriverHandle,
                                    FrontPageVfrBin,
                                    BdsDxeStrings,
                                    NULL
                                    );
    if (gFrontPagePrivate.HiiHandle == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
  }


  //
  // Init OpCode Handle and Allocate space for creation of UpdateData Buffer
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (OptionsOpCodeHandle != 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_SELECT_LANGUAGE;

  //
  // 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;

  //
  // Collect the languages from what our current Language support is based on our VFR
  //
  HiiHandle = gFrontPagePrivate.HiiHandle;

  GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLang, NULL);

  //
  // Get Support language list from variable.
  //
  if (mLanguageString == NULL){
    GetEfiGlobalVariable2 (L"PlatformLangCodes", (VOID**)&mLanguageString, NULL);
    if (mLanguageString == NULL) {
      mLanguageString = AllocateCopyPool (
                                 AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)),
                                 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)
                                 );
      ASSERT (mLanguageString != NULL);
    }
  }

  if (gFrontPagePrivate.LanguageToken == NULL) {
    //
    // Count the language list number.
    //  
    LangCode      = mLanguageString;
    Lang          = AllocatePool (AsciiStrSize (mLanguageString));
    ASSERT (Lang != NULL);
    OptionCount = 0;
    while (*LangCode != 0) {
      GetNextLanguage (&LangCode, Lang);
      OptionCount ++;
    }

    //
    // Allocate extra 1 as the end tag.
    //
    gFrontPagePrivate.LanguageToken = AllocateZeroPool ((OptionCount + 1) * sizeof (EFI_STRING_ID));
    ASSERT (gFrontPagePrivate.LanguageToken != NULL);

    Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
    ASSERT_EFI_ERROR (Status);

    LangCode     = mLanguageString;
    OptionCount  = 0;
    while (*LangCode != 0) {
      GetNextLanguage (&LangCode, Lang);

      StringSize = 0;
      Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);
      if (Status == EFI_BUFFER_TOO_SMALL) {
        StringBuffer = AllocateZeroPool (StringSize);
        ASSERT (StringBuffer != NULL);
        Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL);
        ASSERT_EFI_ERROR (Status);
      }

      if (EFI_ERROR (Status)) {
        StringBuffer = AllocatePool (AsciiStrSize (Lang) * sizeof (CHAR16));
        ASSERT (StringBuffer != NULL);
        AsciiStrToUnicodeStr (Lang, StringBuffer);
      }

      ASSERT (StringBuffer != NULL);
      gFrontPagePrivate.LanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL);
      FreePool (StringBuffer);

      OptionCount++;
    }
  }

  ASSERT (gFrontPagePrivate.LanguageToken != NULL);
  LangCode     = mLanguageString;
  OptionCount  = 0;
  if (Lang == NULL) {
    Lang = AllocatePool (AsciiStrSize (mLanguageString));
    ASSERT (Lang != NULL);
  }
  while (*LangCode != 0) {
    GetNextLanguage (&LangCode, Lang);

    if (CurrentLang != NULL && AsciiStrCmp (Lang, CurrentLang) == 0) {
      HiiCreateOneOfOptionOpCode (
        OptionsOpCodeHandle,
        gFrontPagePrivate.LanguageToken[OptionCount],
        EFI_IFR_OPTION_DEFAULT,
        EFI_IFR_NUMERIC_SIZE_1,
        (UINT8) OptionCount
        );
    } else {
      HiiCreateOneOfOptionOpCode (
        OptionsOpCodeHandle,
        gFrontPagePrivate.LanguageToken[OptionCount],
        0,
        EFI_IFR_NUMERIC_SIZE_1,
        (UINT8) OptionCount
        );
    }

    OptionCount++;
  }

  if (CurrentLang != NULL) {
    FreePool (CurrentLang);
  }
  FreePool (Lang);

  HiiCreateOneOfOpCode (
    StartOpCodeHandle,
    FRONT_PAGE_KEY_LANGUAGE,
    0,
    0,
    STRING_TOKEN (STR_LANGUAGE_SELECT),
    STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),
    EFI_IFR_FLAG_CALLBACK,
    EFI_IFR_NUMERIC_SIZE_1,
    OptionsOpCodeHandle,
    NULL
    );

  Status = HiiUpdateForm (
             HiiHandle,
             &gFrontPageFormSetGuid,
             FRONT_PAGE_FORM_ID,
             StartOpCodeHandle, // LABEL_SELECT_LANGUAGE
             EndOpCodeHandle    // LABEL_END
             );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
  return Status;
}
Ejemplo n.º 26
0
/**
  Perform a dir on a device. The device must support Simple File System Protocol
  or the FV protocol.

  Argv[0] - "dir"
  Argv[1] - Device Name:path. Path is optional
  Argv[2] - Optional filename to match on. A leading * means match substring
  Argv[3] - Optional FV file type

  dir fs1:\efi      ; perform a dir on fs1: device in the efi directory
  dir fs1:\efi *.efi; perform a dir on fs1: device in the efi directory but
                      only print out files that contain the string *.efi
  dir fv1:\         ; perform a dir on fv1: device in the efi directory
                    NOTE: fv devices do not contain subdirs
  dir fv1:\ * PEIM  ; will match all files of type PEIM

  @param  Argc   Number of command arguments in Argv
  @param  Argv   Array of strings that represent the parsed command line.
                 Argv[0] is the command name

  @return EFI_SUCCESS

**/
EFI_STATUS
EblDirCmd (
    IN UINTN  Argc,
    IN CHAR8  **Argv
)
{
    EFI_STATUS                    Status;
    EFI_OPEN_FILE                 *File;
    EFI_FILE_INFO                 *DirInfo;
    UINTN                         ReadSize;
    UINTN                         CurrentRow;
    CHAR16                        *MatchSubString;
    EFI_STATUS                    GetNextFileStatus;
    UINTN                         Key;
    EFI_FV_FILETYPE               SearchType;
    EFI_FV_FILETYPE               Type;
    EFI_FV_FILE_ATTRIBUTES        Attributes;
    UINTN                         Size;
    EFI_GUID                      NameGuid;
    EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
    UINT32                        AuthenticationStatus;
    VOID                          *Section;
    UINTN                         SectionSize;
    EFI_FV_FILETYPE               Index;
    UINTN                         Length;
    UINTN                         BestMatchCount;
    CHAR16                        UnicodeFileName[MAX_CMD_LINE];
    CHAR8                         *Path;
    CHAR8                         *TypeStr;
    UINTN                         TotalSize;


    if (Argc <= 1) {
        Path = EfiGetCwd ();
        if (Path == NULL) {
            return EFI_SUCCESS;
        }
    } else {
        Path = Argv[1];
    }

    File = EfiOpen (Path, EFI_FILE_MODE_READ, 0);
    if (File == NULL) {
        return EFI_SUCCESS;
    }

    if (File->Type == EfiOpenFirmwareVolume) {
        // FV Dir

        SearchType = EFI_FV_FILETYPE_ALL;
        UnicodeFileName[0] = '\0';
        MatchSubString = &UnicodeFileName[0];
        if (Argc > 2) {
            AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);
            if (UnicodeFileName[0] == '*') {
                // Handle *Name substring matching
                MatchSubString = &UnicodeFileName[1];
            }

            // Handle file type matchs
            if (Argc > 3) {
                // match a specific file type, always last argument
                Length = AsciiStrLen (Argv[3]);
                for (Index = 1, BestMatchCount = 0; Index < sizeof (gFvFileType)/sizeof (CHAR8 *); Index++) {
                    if (AsciiStriCmp (gFvFileType[Index], Argv[3]) == 0) {
                        // exact match
                        SearchType = Index;
                        break;
                    }

                    if (AsciiStrniCmp (Argv[3], gFvFileType[Index], Length) == 0) {
                        // partial match, so keep looking to make sure there is only one partial match
                        BestMatchCount++;
                        SearchType = Index;
                    }
                }

                if (BestMatchCount > 1) {
                    SearchType = EFI_FV_FILETYPE_ALL;
                }
            }
        }

        TotalSize = 0;
        Fv = File->Fv;
        Key = 0;
        CurrentRow = 0;
        do {
            Type = SearchType;
            GetNextFileStatus = Fv->GetNextFile (
                                    Fv,
                                    &Key,
                                    &Type,
                                    &NameGuid,
                                    &Attributes,
                                    &Size
                                );
            if (!EFI_ERROR (GetNextFileStatus)) {
                TotalSize += Size;
                // Calculate size of entire file
                Section = NULL;
                Size = 0;
                Status = Fv->ReadFile (
                             Fv,
                             &NameGuid,
                             Section,
                             &Size,
                             &Type,
                             &Attributes,
                             &AuthenticationStatus
                         );
                if (!((Status == EFI_BUFFER_TOO_SMALL) || !EFI_ERROR (Status))) {
                    // EFI_SUCCESS or EFI_BUFFER_TOO_SMALL mean size is valid
                    Size = 0;
                }

                TypeStr = (Type <= EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) ? gFvFileType[Type] : "UNKNOWN";

                // read the UI seciton to do a name match.
                Section = NULL;
                Status = Fv->ReadSection (
                             Fv,
                             &NameGuid,
                             EFI_SECTION_USER_INTERFACE,
                             0,
                             &Section,
                             &SectionSize,
                             &AuthenticationStatus
                         );
                if (!EFI_ERROR (Status)) {
                    if (StrStr (Section, MatchSubString) != NULL) {
                        AsciiPrint ("%,9d %7a %g %s\n", Size, TypeStr, &NameGuid, Section);
                        if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
                            break;
                        }
                    }
                    FreePool (Section);
                } else {
                    if (*MatchSubString == '\0') {
                        AsciiPrint ("%,9d %7a %g\n", Size, TypeStr, &NameGuid);
                        if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
                            break;
                        }
                    }
                }
            }
        } while (!EFI_ERROR (GetNextFileStatus));

        if (SearchType == EFI_FV_FILETYPE_ALL) {
            AsciiPrint ("%,20d bytes in files %,d bytes free\n", TotalSize, File->FvSize - File->FvHeaderSize - TotalSize);
        }


    } else if ((File->Type == EfiOpenFileSystem) || (File->Type == EfiOpenBlockIo)) {
        // Simple File System DIR

        if (File->FsFileInfo ==  NULL) {
            return EFI_SUCCESS;
        }

        if (!(File->FsFileInfo->Attribute & EFI_FILE_DIRECTORY)) {
            return EFI_SUCCESS;
        }

        // Handle *Name substring matching
        MatchSubString = NULL;
        UnicodeFileName[0] = '\0';
        if (Argc > 2) {
            AsciiStrToUnicodeStr (Argv[2], UnicodeFileName);
            if (UnicodeFileName[0] == '*') {
                MatchSubString = &UnicodeFileName[1];
            }
        }

        File->FsFileHandle->SetPosition (File->FsFileHandle, 0);
        for (CurrentRow = 0;;) {
            // First read gets the size
            DirInfo = NULL;
            ReadSize = 0;
            Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);
            if (Status == EFI_BUFFER_TOO_SMALL) {
                // Allocate the buffer for the real read
                DirInfo = AllocatePool (ReadSize);
                if (DirInfo == NULL) {
                    goto Done;
                }

                // Read the data
                Status = File->FsFileHandle->Read (File->FsFileHandle, &ReadSize, DirInfo);
                if ((EFI_ERROR (Status)) || (ReadSize == 0)) {
                    break;
                }
            } else {
                break;
            }

            if (MatchSubString != NULL) {
                if (StrStr (&DirInfo->FileName[0], MatchSubString) == NULL) {
                    // does not match *name argument, so skip
                    continue;
                }
            } else if (UnicodeFileName[0] != '\0') {
                // is not an exact match for name argument, so skip
                if (StrCmp (&DirInfo->FileName[0], UnicodeFileName) != 0) {
                    continue;
                }
            }

            if (DirInfo->Attribute & EFI_FILE_DIRECTORY) {
                AsciiPrint ("         <DIR> %s\n", &DirInfo->FileName[0]);
            } else {
                AsciiPrint ("%,14ld %s\n", DirInfo->FileSize, &DirInfo->FileName[0]);
            }

            if (EblAnyKeyToContinueQtoQuit (&CurrentRow, FALSE)) {
                break;
            }

            FreePool (DirInfo);
        }

Done:
        if (DirInfo != NULL) {
            FreePool (DirInfo);
        }
    }

    EfiClose (File);

    return EFI_SUCCESS;
}
Ejemplo n.º 27
0
EFI_STATUS
EFIAPI
EblSetCmd (
  IN UINTN  Argc,
  IN CHAR8  **Argv
  )
{
  EFI_STATUS    Status = EFI_INVALID_PARAMETER;
  CHAR8*        AsciiVariableSetting = NULL;
  CHAR8*        AsciiVariableName;
  CHAR8*        AsciiValue;
  UINT32        AsciiValueLength;
  CHAR16*       VariableName;
  UINT32        Index;
  UINT32        EscapedQuotes = 0;
  BOOLEAN       Volatile = FALSE;

  if (Argc == 1) {
    AsciiPrint("Variable name is missing.\n");
    return Status;
  }

  for (Index = 1; Index < Argc; Index++) {
    if (AsciiStrCmp(Argv[Index],"-v") == 0) {
      Volatile = 0;
    } else if (Argv[Index][0] == '-') {
      AsciiPrint("Warning: '%a' not recognized.\n",Argv[Index]);
    } else {
      AsciiVariableSetting = Argv[Index];
    }
  }

  if (AsciiVariableSetting == NULL) {
    AsciiPrint("Variable name is missing.\n");
    return Status;
  }

  // Check if it is a valid variable setting
  AsciiValue = AsciiStrStr (AsciiVariableSetting,"=");
  if (AsciiValue == NULL) {
    //
    // There is no value. It means this variable will be deleted
    //

    // Convert VariableName into Unicode
    VariableName = AllocatePool((AsciiStrLen (AsciiVariableSetting) + 1) * sizeof (CHAR16));
    AsciiStrToUnicodeStr (AsciiVariableSetting,VariableName);

    Status = gRT->SetVariable (
                          VariableName,
                          &gEfiGlobalVariableGuid,
                          ( !Volatile ? EFI_VARIABLE_NON_VOLATILE : 0) |
                          EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                          0,
                          NULL
                          );
    if (!EFI_ERROR(Status)) {
      AsciiPrint("Variable '%s' deleted\n",VariableName);
    } else {
      AsciiPrint("Variable setting is incorrect. It should be VariableName=Value\n");
    }
    return Status;
  }

  AsciiValue[0] = '\0';
  AsciiVariableName = AsciiVariableSetting;
  AsciiValue++;

  // Clean AsciiValue from quote
  if (AsciiValue[0] == '"') {
    AsciiValue++;
  }
  AsciiValueLength = AsciiStrLen (AsciiValue);
  if ((AsciiValue[AsciiValueLength-2] != '\\') && (AsciiValue[AsciiValueLength-1] == '"')) {
    AsciiValue[AsciiValueLength-1] = '\0';
  }

  // Clean AsciiValue from escaped quotes
  for (Index = 0; Index < AsciiValueLength; Index++) {
    if ((Index > 0) && (AsciiValue[Index-1] == '\\') && (AsciiValue[Index] == '"')) {
      EscapedQuotes++;
    }
    AsciiValue[Index-EscapedQuotes] = AsciiValue[Index];
  }
  // Fill the end of the value with '\0'
  for (Index = 0; Index < EscapedQuotes; Index++) {
    AsciiValue[AsciiValueLength-1-Index] = '\0';
  }

  // Convert VariableName into Unicode
  VariableName = AllocatePool((AsciiStrLen (AsciiVariableName) + 1) * sizeof (CHAR16));
  AsciiStrToUnicodeStr (AsciiVariableName,VariableName);

  Status = gRT->SetVariable (
                      VariableName,
                      &gEfiGlobalVariableGuid,
                      ( !Volatile ? EFI_VARIABLE_NON_VOLATILE : 0) |
                      EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                      AsciiStrLen (AsciiValue)+1,
                      AsciiValue
                      );
  if (!EFI_ERROR(Status)) {
    AsciiPrint("'%a'='%a'\n",AsciiVariableName,AsciiValue);
  }

  return Status;
}
Ejemplo n.º 28
0
/**
Internal work function to fill in EFI_OPEN_FILE information for the Fs and BlkIo

@param  File        Open file handle
@param  FileName    Name of file after device stripped off


**/
EFI_STATUS
EblFileDevicePath (
  IN OUT EFI_OPEN_FILE  *File,
  IN  CHAR8             *FileName,
  IN  CONST UINT64      OpenMode
  )
{
  EFI_STATUS                        Status;
  UINTN                             Size;
  FILEPATH_DEVICE_PATH              *FilePath;
  EFI_DEVICE_PATH_PROTOCOL          *FileDevicePath;
  CHAR16                            UnicodeFileName[MAX_PATHNAME];
  EFI_BLOCK_IO_PROTOCOL             *BlkIo;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Fs;
  EFI_FILE_HANDLE                   Root;


  if ( *FileName != 0 ) {
    AsciiStrToUnicodeStr (FileName, UnicodeFileName);
  } else {
    AsciiStrToUnicodeStr ("\\", UnicodeFileName);
  }

  Size = StrSize (UnicodeFileName);
  FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof (EFI_DEVICE_PATH_PROTOCOL));
  if (FileDevicePath != NULL) {
    FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;
    FilePath->Header.Type    = MEDIA_DEVICE_PATH;
    FilePath->Header.SubType = MEDIA_FILEPATH_DP;
    CopyMem (&FilePath->PathName, UnicodeFileName, Size);
    SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
    SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));

    if (File->EfiHandle != NULL) {
      File->DevicePath = DevicePathFromHandle (File->EfiHandle);
    }

    File->DevicePath = AppendDevicePath (File->DevicePath, FileDevicePath);
    FreePool (FileDevicePath);
  }

  Status = gBS->HandleProtocol (File->EfiHandle, &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo);
  if (!EFI_ERROR (Status)) {
    File->FsBlockIoMedia = BlkIo->Media;
    File->FsBlockIo = BlkIo;

    // If we are not opening the device this will get over written with file info
    File->MaxPosition = MultU64x32 (BlkIo->Media->LastBlock + 1, BlkIo->Media->BlockSize);
  }

  if (File->Type == EfiOpenFileSystem) {
    Status = gBS->HandleProtocol (File->EfiHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
    if (!EFI_ERROR (Status)) {
      Status = Fs->OpenVolume (Fs, &Root);
      if (!EFI_ERROR (Status)) {
        // Get information about the volume
        Size = 0;
        Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo);
        if (Status == EFI_BUFFER_TOO_SMALL) {
          File->FsInfo = AllocatePool (Size);
          Status = Root->GetInfo (Root, &gEfiFileSystemInfoGuid, &Size, File->FsInfo);
        }

        // Get information about the file
        Status = Root->Open (Root, &File->FsFileHandle, UnicodeFileName, OpenMode, 0);
        if (!EFI_ERROR (Status)) {
          Size = 0;
          Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, NULL);
          if (Status == EFI_BUFFER_TOO_SMALL) {
            File->FsFileInfo = AllocatePool (Size);
            Status = File->FsFileHandle->GetInfo (File->FsFileHandle, &gEfiFileInfoGuid, &Size, File->FsFileInfo);
            if (!EFI_ERROR (Status)) {
              File->Size = (UINTN)File->FsFileInfo->FileSize;
              File->MaxPosition = (UINT64)File->Size;
            }
          }
        }

        Root->Close (Root);
      }
    }
  } else if (File->Type == EfiOpenBlockIo) {
    File->Size = (UINTN)File->MaxPosition;
  }

  return Status;
}
Ejemplo n.º 29
0
/**
  Try to get the controller's ATA/ATAPI description.

  @param Handle                Controller handle.

  @return  The description string.
**/
CHAR16 *
BmGetDescriptionFromDiskInfo (
  IN EFI_HANDLE                Handle
  )
{
  UINTN                        Index;
  EFI_STATUS                   Status;
  EFI_DISK_INFO_PROTOCOL       *DiskInfo;
  UINT32                       BufferSize;
  EFI_ATAPI_IDENTIFY_DATA      IdentifyData;
  EFI_SCSI_INQUIRY_DATA        InquiryData;
  CHAR16                       *Description;
  UINTN                        Length;
  CONST UINTN                  ModelNameLength    = 40;
  CONST UINTN                  SerialNumberLength = 20;
  CHAR8                        *StrPtr;
  UINT8                        Temp;

  Description  = NULL;

  Status = gBS->HandleProtocol (
                  Handle,
                  &gEfiDiskInfoProtocolGuid,
                  (VOID **) &DiskInfo
                  );
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoAhciInterfaceGuid) ||
      CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoIdeInterfaceGuid)) {
    BufferSize   = sizeof (EFI_ATAPI_IDENTIFY_DATA);
    Status = DiskInfo->Identify (
                         DiskInfo,
                         &IdentifyData,
                         &BufferSize
                         );
    if (!EFI_ERROR (Status)) {
      Description = AllocateZeroPool ((ModelNameLength + SerialNumberLength + 2) * sizeof (CHAR16));
      ASSERT (Description != NULL);
      for (Index = 0; Index + 1 < ModelNameLength; Index += 2) {
        Description[Index]     = (CHAR16) IdentifyData.ModelName[Index + 1];
        Description[Index + 1] = (CHAR16) IdentifyData.ModelName[Index];
      }

      Length = Index;
      Description[Length++] = L' ';

      for (Index = 0; Index + 1 < SerialNumberLength; Index += 2) {
        Description[Length + Index]     = (CHAR16) IdentifyData.SerialNo[Index + 1];
        Description[Length + Index + 1] = (CHAR16) IdentifyData.SerialNo[Index];
      }
      Length += Index;
      Description[Length++] = L'\0';
      ASSERT (Length == ModelNameLength + SerialNumberLength + 2);

      BmEliminateExtraSpaces (Description);
    }
  } else if (CompareGuid (&DiskInfo->Interface, &gEfiDiskInfoScsiInterfaceGuid)) {
    BufferSize   = sizeof (EFI_SCSI_INQUIRY_DATA);
    Status = DiskInfo->Inquiry (
                         DiskInfo,
                         &InquiryData,
                         &BufferSize
                         );
    if (!EFI_ERROR (Status)) {
      Description = AllocateZeroPool ((VENDOR_IDENTIFICATION_LENGTH + PRODUCT_IDENTIFICATION_LENGTH + 2) * sizeof (CHAR16));
      ASSERT (Description != NULL);

      //
      // Per SCSI spec, EFI_SCSI_INQUIRY_DATA.Reserved_5_95[3 - 10] save the Verdor identification
      // EFI_SCSI_INQUIRY_DATA.Reserved_5_95[11 - 26] save the product identification,
      // Here combine the vendor identification and product identification to the description.
      //
      StrPtr = (CHAR8 *) (&InquiryData.Reserved_5_95[VENDOR_IDENTIFICATION_OFFSET]);
      Temp = StrPtr[VENDOR_IDENTIFICATION_LENGTH];
      StrPtr[VENDOR_IDENTIFICATION_LENGTH] = '\0';
      AsciiStrToUnicodeStr (StrPtr, Description);
      StrPtr[VENDOR_IDENTIFICATION_LENGTH] = Temp;

      //
      // Add one space at the middle of vendor information and product information.
      //
      Description[VENDOR_IDENTIFICATION_LENGTH] = L' ';

      StrPtr = (CHAR8 *) (&InquiryData.Reserved_5_95[PRODUCT_IDENTIFICATION_OFFSET]);
      StrPtr[PRODUCT_IDENTIFICATION_LENGTH] = '\0';
      AsciiStrToUnicodeStr (StrPtr, Description + VENDOR_IDENTIFICATION_LENGTH + 1);

      BmEliminateExtraSpaces (Description);
    }
  }

  return Description;
}
Ejemplo n.º 30
0
/**
  The Request() function queues an HTTP request to this HTTP instance.

  Similar to Transmit() function in the EFI TCP driver. When the HTTP request is sent
  successfully, or if there is an error, Status in token will be updated and Event will
  be signaled.

  @param[in]  This                Pointer to EFI_HTTP_PROTOCOL instance.
  @param[in]  Token               Pointer to storage containing HTTP request token.

  @retval EFI_SUCCESS             Outgoing data was processed.
  @retval EFI_NOT_STARTED         This EFI HTTP Protocol instance has not been started.
  @retval EFI_DEVICE_ERROR        An unexpected system or network error occurred.
  @retval EFI_TIMEOUT             Data was dropped out of the transmit or receive queue.
  @retval EFI_OUT_OF_RESOURCES    Could not allocate enough system resources.
  @retval EFI_UNSUPPORTED         The HTTP method is not supported in current
                                  implementation.
  @retval EFI_INVALID_PARAMETER   One or more of the following conditions is TRUE:
                                  This is NULL.
                                  Token is NULL.
                                  Token->Message is NULL.
                                  Token->Message->Body is not NULL,
                                  Token->Message->BodyLength is non-zero, and
                                  Token->Message->Data is NULL, but a previous call to
                                  Request()has not been completed successfully.
**/
EFI_STATUS
EFIAPI
EfiHttpRequest (
  IN  EFI_HTTP_PROTOCOL         *This,
  IN  EFI_HTTP_TOKEN            *Token
  )
{
  EFI_HTTP_MESSAGE              *HttpMsg;
  EFI_HTTP_REQUEST_DATA         *Request;
  VOID                          *UrlParser;
  EFI_STATUS                    Status;
  CHAR8                         *HostName;
  UINT16                        RemotePort;
  HTTP_PROTOCOL                 *HttpInstance;
  BOOLEAN                       Configure;
  BOOLEAN                       ReConfigure;
  CHAR8                         *RequestMsg;
  CHAR8                         *Url;
  UINTN                         UrlLen;
  CHAR16                        *HostNameStr;
  HTTP_TOKEN_WRAP               *Wrap;
  CHAR8                         *FileUrl;
  UINTN                         RequestMsgSize;

  //
  // Initializations
  //
  Url = NULL;
  HostName = NULL;
  RequestMsg = NULL;
  HostNameStr = NULL;
  Wrap = NULL;
  FileUrl = NULL;

  if ((This == NULL) || (Token == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  HttpMsg = Token->Message;
  if (HttpMsg == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Request = HttpMsg->Data.Request;

  //
  // Only support GET, HEAD, PUT and POST method in current implementation.
  //
  if ((Request != NULL) && (Request->Method != HttpMethodGet) &&
      (Request->Method != HttpMethodHead) && (Request->Method != HttpMethodPut) && (Request->Method != HttpMethodPost)) {
    return EFI_UNSUPPORTED;
  }

  HttpInstance = HTTP_INSTANCE_FROM_PROTOCOL (This);
  ASSERT (HttpInstance != NULL);

  //
  // Capture the method into HttpInstance.
  //
  if (Request != NULL) {
    HttpInstance->Method = Request->Method;
  }

  if (HttpInstance->State < HTTP_STATE_HTTP_CONFIGED) {
    return EFI_NOT_STARTED;
  }

  if (Request == NULL) {
    //
    // Request would be NULL only for PUT/POST operation (in the current implementation)
    //
    if ((HttpInstance->Method != HttpMethodPut) && (HttpInstance->Method != HttpMethodPost)) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // For PUT/POST, we need to have the TCP already configured. Bail out if it is not!
    //
    if (HttpInstance->State < HTTP_STATE_TCP_CONFIGED) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // We need to have the Message Body for sending the HTTP message across in these cases.
    //
    if (HttpMsg->Body == NULL || HttpMsg->BodyLength == 0) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Use existing TCP instance to transmit the packet.
    //
    Configure   = FALSE;
    ReConfigure = FALSE;
  } else {
    //
    // Check whether the token already existed.
    //
    if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTokenExist, Token))) {
      return EFI_ACCESS_DENIED;
    }

    //
    // Parse the URI of the remote host.
    //
    Url = HttpInstance->Url;
    UrlLen = StrLen (Request->Url) + 1;
    if (UrlLen > HTTP_URL_BUFFER_LEN) {
      Url = AllocateZeroPool (UrlLen);
      if (Url == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
      FreePool (HttpInstance->Url);
      HttpInstance->Url = Url;
    }


    UnicodeStrToAsciiStr (Request->Url, Url);
    UrlParser = NULL;
    Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser);
    if (EFI_ERROR (Status)) {
      goto Error1;
    }

    HostName   = NULL;
    Status     = HttpUrlGetHostName (Url, UrlParser, &HostName);
    if (EFI_ERROR (Status)) {
     goto Error1;
    }

    Status = HttpUrlGetPort (Url, UrlParser, &RemotePort);
    if (EFI_ERROR (Status)) {
      RemotePort = HTTP_DEFAULT_PORT;
    }
    //
    // If Configure is TRUE, it indicates the first time to call Request();
    // If ReConfigure is TRUE, it indicates the request URL is not same
    // with the previous call to Request();
    //
    Configure   = TRUE;
    ReConfigure = TRUE;

    if (HttpInstance->RemoteHost == NULL) {
      //
      // Request() is called the first time.
      //
      ReConfigure = FALSE;
    } else {
      if ((HttpInstance->RemotePort == RemotePort) &&
        (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0)) {
        //
        // Host Name and port number of the request URL are the same with previous call to Request().
        // Check whether previous TCP packet sent out.
        //

        if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTcpNotReady, NULL))) {
          //
          // Wrap the HTTP token in HTTP_TOKEN_WRAP
          //
          Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP));
          if (Wrap == NULL) {
            Status = EFI_OUT_OF_RESOURCES;
            goto Error1;
          }

          Wrap->HttpToken    = Token;
          Wrap->HttpInstance = HttpInstance;

          Status = HttpCreateTcpTxEvent (Wrap);
          if (EFI_ERROR (Status)) {
            goto Error1;
          }

          Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap);
          if (EFI_ERROR (Status)) {
            goto Error1;
          }

          Wrap->TcpWrap.Method = Request->Method;

          FreePool (HostName);

          //
          // Queue the HTTP token and return.
          //
          return EFI_SUCCESS;
        } else {
          //
          // Use existing TCP instance to transmit the packet.
          //
          Configure   = FALSE;
          ReConfigure = FALSE;
        }
      } else {
        //
        // Need close existing TCP instance and create a new TCP instance for data transmit.
        //
        if (HttpInstance->RemoteHost != NULL) {
          FreePool (HttpInstance->RemoteHost);
          HttpInstance->RemoteHost = NULL;
          HttpInstance->RemotePort = 0;
        }
      }
    }
  } 

  if (Configure) {
    //
    // Parse Url for IPv4 or IPv6 address, if failed, perform DNS resolution.
    //
    if (!HttpInstance->LocalAddressIsIPv6) {
      Status = NetLibAsciiStrToIp4 (HostName, &HttpInstance->RemoteAddr);
    } else {
      Status = HttpUrlGetIp6 (Url, UrlParser, &HttpInstance->RemoteIpv6Addr);
    }

    if (EFI_ERROR (Status)) {
      HostNameStr = AllocateZeroPool ((AsciiStrLen (HostName) + 1) * sizeof (CHAR16));
      if (HostNameStr == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Error1;
      }
      
      AsciiStrToUnicodeStr (HostName, HostNameStr);
      if (!HttpInstance->LocalAddressIsIPv6) {
        Status = HttpDns4 (HttpInstance, HostNameStr, &HttpInstance->RemoteAddr);
      } else {
        Status = HttpDns6 (HttpInstance, HostNameStr, &HttpInstance->RemoteIpv6Addr);
      }
      
      FreePool (HostNameStr);
      if (EFI_ERROR (Status)) {
        goto Error1;
      }
    }


    //
    // Save the RemotePort and RemoteHost.
    //
    ASSERT (HttpInstance->RemoteHost == NULL);
    HttpInstance->RemotePort = RemotePort;
    HttpInstance->RemoteHost = HostName;
    HostName = NULL;
  }

  if (ReConfigure) {
    //
    // The request URL is different from previous calls to Request(), close existing TCP instance.
    //
    if (!HttpInstance->LocalAddressIsIPv6) {
      ASSERT (HttpInstance->Tcp4 != NULL);
    } else {
      ASSERT (HttpInstance->Tcp6 != NULL);
    }
    HttpCloseConnection (HttpInstance);
    EfiHttpCancel (This, NULL);
  }

  //
  // Wrap the HTTP token in HTTP_TOKEN_WRAP
  //
  Wrap = AllocateZeroPool (sizeof (HTTP_TOKEN_WRAP));
  if (Wrap == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error1;
  }

  Wrap->HttpToken      = Token;
  Wrap->HttpInstance   = HttpInstance;
  if (Request != NULL) {
    Wrap->TcpWrap.Method = Request->Method;
  }

  Status = HttpInitTcp (HttpInstance, Wrap, Configure);
  if (EFI_ERROR (Status)) {
    goto Error2;
  }  

  if (!Configure) {
    //
    // For the new HTTP token, create TX TCP token events.    
    //
    Status = HttpCreateTcpTxEvent (Wrap);
    if (EFI_ERROR (Status)) {
      goto Error1;
    }
  }
  
  //
  // Create request message.
  //
  FileUrl = Url;
  if (Url != NULL && *FileUrl != '/') {
    //
    // Convert the absolute-URI to the absolute-path
    //
    while (*FileUrl != ':') {
      FileUrl++;
    }
    if ((*(FileUrl+1) == '/') && (*(FileUrl+2) == '/')) {
      FileUrl += 3;
      while (*FileUrl != '/') {
        FileUrl++;
      }
    } else {
      Status = EFI_INVALID_PARAMETER;
      goto Error3;
    }
  }

  Status = HttpGenRequestMessage (HttpMsg, FileUrl, &RequestMsg, &RequestMsgSize);

  if (EFI_ERROR (Status)) {
    goto Error3;
  }

  //
  // Every request we insert a TxToken and a response call would remove the TxToken.
  // In cases of PUT/POST, after an initial request-response pair, we would do a
  // continuous request without a response call. So, in such cases, where Request
  // structure is NULL, we would not insert a TxToken.
  //
  if (Request != NULL) {
    Status = NetMapInsertTail (&HttpInstance->TxTokens, Token, Wrap);
    if (EFI_ERROR (Status)) {
      goto Error4;
    }
  }

  //
  // Transmit the request message.
  //
  Status = HttpTransmitTcp (
             HttpInstance,
             Wrap,
             (UINT8*) RequestMsg,
             RequestMsgSize
             );
  if (EFI_ERROR (Status)) {
    goto Error5;    
  }

  DispatchDpc ();
  
  if (HostName != NULL) {
    FreePool (HostName);
  }
  
  return EFI_SUCCESS;

Error5:
    //
    // We would have inserted a TxToken only if Request structure is not NULL.
    // Hence check before we do a remove in this error case.
    //
    if (Request != NULL) {
      NetMapRemoveTail (&HttpInstance->TxTokens, NULL);
    }

Error4:
  if (RequestMsg != NULL) {
    FreePool (RequestMsg);
  }  

Error3:
  HttpCloseConnection (HttpInstance);

Error2:
  HttpCloseTcpConnCloseEvent (HttpInstance);
  if (NULL != Wrap->TcpWrap.Tx4Token.CompletionToken.Event) {
    gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);
    Wrap->TcpWrap.Tx4Token.CompletionToken.Event = NULL;
  }
  if (NULL != Wrap->TcpWrap.Tx6Token.CompletionToken.Event) {
    gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event);
    Wrap->TcpWrap.Tx6Token.CompletionToken.Event = NULL;
  }

Error1:

  if (HostName != NULL) {
    FreePool (HostName);
  }
  if (Wrap != NULL) {
    FreePool (Wrap);
  }
  if (UrlParser!= NULL) {
    HttpUrlFreeParser (UrlParser);
  }

  return Status;
  
}