Beispiel #1
0
/**
  The function is called by PerformQuickSort to sort file name in alphabet.

  @param[in] Left            The pointer to first buffer.
  @param[in] Right           The pointer to second buffer.

  @retval 0                  Buffer1 equal to Buffer2.
  @return <0                 Buffer1 is less than Buffer2.
  @return >0                 Buffer1 is greater than Buffer2.

**/
INTN
EFIAPI
CompareFileNameInAlphabet (
  IN VOID                         *Left,
  IN VOID                         *Right
  )
{
  EFI_FILE_INFO  *FileInfo1;
  EFI_FILE_INFO  *FileInfo2;
  CHAR16         FileName1[MAX_FILE_NAME_SIZE];
  CHAR16         FileExtension1[MAX_FILE_NAME_SIZE];
  CHAR16         FileName2[MAX_FILE_NAME_SIZE];
  CHAR16         FileExtension2[MAX_FILE_NAME_SIZE];
  CHAR16         TempSubStr1[MAX_FILE_NAME_SIZE];
  CHAR16         TempSubStr2[MAX_FILE_NAME_SIZE];
  UINTN          SubStrLen1;
  UINTN          SubStrLen2;
  INTN           SubStrCmpResult;

  FileInfo1 = (EFI_FILE_INFO *) (*(UINTN *)Left);
  FileInfo2 = (EFI_FILE_INFO *) (*(UINTN *)Right);

  SplitFileNameExtension (FileInfo1->FileName, FileName1, FileExtension1);
  SplitFileNameExtension (FileInfo2->FileName, FileName2, FileExtension2);

  UpperCaseString (FileName1);
  UpperCaseString (FileName2);

  GetSubStringBeforePeriod (FileName1, TempSubStr1, &SubStrLen1);
  GetSubStringBeforePeriod (FileName2, TempSubStr2, &SubStrLen2);

  if (SubStrLen1 > SubStrLen2) {
    //
    // Substr in NewFileName is longer.  Pad tail with SPACE
    //
    PadStrInTail (TempSubStr2, SubStrLen1 - SubStrLen2, L' ');
  } else if (SubStrLen1 < SubStrLen2){
    //
    // Substr in ListedFileName is longer. Pad tail with SPACE
    //
    PadStrInTail (TempSubStr1, SubStrLen2 - SubStrLen1, L' ');
  }

  SubStrCmpResult = StrnCmp (TempSubStr1, TempSubStr2, MAX_FILE_NAME_LEN);
  if (SubStrCmpResult != 0) {
    return SubStrCmpResult;
  }

  UpperCaseString (FileExtension1);
  UpperCaseString (FileExtension2);

  return StrnCmp (FileExtension1, FileExtension2, MAX_FILE_NAME_LEN);
}
Beispiel #2
0
/**

  Check whether the input variable is an key option variable.

  @param   Name               Input variable name.
  @param   Guid               Input variable guid.
  @param   OptionNumber       The option number of this key option variable.

  @retval  TRUE               Input variable is a key option variable.
  @retval  FALSE              Input variable is not a key option variable.
**/
BOOLEAN
BmIsKeyOptionVariable (
  CHAR16        *Name,
  EFI_GUID      *Guid,
  UINT16        *OptionNumber
  )
{
  UINTN         Index;
  UINTN         Uint;

  if (!CompareGuid (Guid, &gEfiGlobalVariableGuid) ||
      (StrSize (Name) != sizeof (L"Key####")) ||
      (StrnCmp (Name, L"Key", 3) != 0)
     ) {
    return FALSE;
  }

  *OptionNumber = 0;
  for (Index = 3; Index < 7; Index++) {
    Uint = BmCharToUint (Name[Index]);
    if (Uint == -1) {
      return FALSE;
    } else {
      *OptionNumber = (UINT16) Uint + *OptionNumber * 0x10;
    }
  }

  return TRUE;
}
Beispiel #3
0
/**
  Function to check the TYPE of Data.

  @param[in]    Data          The Data to be check.

  @retval       DATA_TYPE     The TYPE of Data.
**/
DATA_TYPE
TestDataType (
  IN CONST CHAR16  *Data
  )
{
  if (Data[0] == L'0' && (Data[1] == L'x' || Data[1] == L'X')) {
    if (IsStringOfHexNibbles (Data+2) && StrLen (Data + 2) <= 16) {
      return DataTypeHexNumber;
    } else {
      return DataTypeUnKnow;
    }
  } else if (Data[0] == L'H') {
    if (IsStringOfHexNibbles (Data + 1) && StrLen (Data + 1) % 2 == 0) {
      return DataTypeHexArray;
    } else {
      return DataTypeUnKnow;
    }
  } else if (Data[0] == L'S') {
    return DataTypeAscii;
  } else if (Data[0] == L'L') {
    return DataTypeUnicode;
  } else if (Data[0] == L'P' || StrnCmp (Data, L"--", 2) == 0) {
    return DataTypeDevicePath;
  }

  if (IsStringOfHexNibbles (Data) && StrLen (Data) % 2 == 0) {
    return DataTypeHexArray;
  }

  return DataTypeAscii;
}
Beispiel #4
0
EFIAPI
GetManFileName(
  IN CONST CHAR16 *ManFileName
  )
{
  CHAR16 *Buffer;
  if (ManFileName == NULL) {
    return (NULL);
  }
  //
  // Fix the file name
  //
  if (StrnCmp(ManFileName+StrLen(ManFileName)-4, L".man", 4)==0) {
    Buffer = AllocateCopyPool(StrSize(ManFileName), ManFileName);
  } else {
    Buffer = AllocateZeroPool(StrSize(ManFileName) + 4*sizeof(CHAR16));
    if (Buffer != NULL) {
      StrnCpyS( Buffer, 
                (StrSize(ManFileName) + 4*sizeof(CHAR16))/sizeof(CHAR16), 
                ManFileName, 
                StrLen(ManFileName)
                );
      StrnCatS( Buffer, 
                (StrSize(ManFileName) + 4*sizeof(CHAR16))/sizeof(CHAR16),
                L".man", 
                4
                );
    }
  }
  return (Buffer);
}
Beispiel #5
0
/**
  Variable property get with wildcard name.

  @param[in] VariableName       Pointer to variable name.
  @param[in] VendorGuid         Pointer to variable vendor GUID.
  @param[in] WildcardMatch      Try wildcard match or not.

  @return Pointer to variable property.

**/
VAR_CHECK_VARIABLE_PROPERTY *
VariablePropertyGetWithWildcardName (
  IN CHAR16                         *VariableName,
  IN EFI_GUID                       *VendorGuid,
  IN BOOLEAN                        WildcardMatch
  )
{
  UINTN     Index;
  UINTN     NameLength;

  NameLength = StrLen (VariableName) - 4;
  for (Index = 0; Index < sizeof (mVarCheckVariableWithWildcardName)/sizeof (mVarCheckVariableWithWildcardName[0]); Index++) {
    if (CompareGuid (mVarCheckVariableWithWildcardName[Index].Guid, VendorGuid)){
      if (WildcardMatch) {
        if ((StrLen (VariableName) == StrLen (mVarCheckVariableWithWildcardName[Index].Name)) &&
            (StrnCmp (VariableName, mVarCheckVariableWithWildcardName[Index].Name, NameLength) == 0) &&
            VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength]) &&
            VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&
            VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&
            VarCheckInternalIsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) {
          return &mVarCheckVariableWithWildcardName[Index].VariableProperty;
        }
      }
      if (StrCmp (mVarCheckVariableWithWildcardName[Index].Name, VariableName) == 0) {
        return  &mVarCheckVariableWithWildcardName[Index].VariableProperty;
      }
    }
  }

  return NULL;
}
Beispiel #6
0
BOOLEAN
IsKeyOptionVariable (
  CHAR16        *Name,
  EFI_GUID      *Guid,
  UINT16        *OptionNumber
  )
{
  UINTN         Index;
  
  if (!CompareGuid (Guid, &gEfiGlobalVariableGuid) ||
      (StrSize (Name) != sizeof (L"Key####")) ||
      (StrnCmp (Name, L"Key", 3) != 0)
     ) {
    return FALSE;
  }

  *OptionNumber = 0;
  for (Index = 3; Index < 7; Index++) {
    if ((Name[Index] >= L'0') && (Name[Index] <= L'9')) {
      *OptionNumber = *OptionNumber * 10 + Name[Index] - L'0';
    } else if ((Name[Index] >= L'A') && (Name[Index] <= L'F')) {
      *OptionNumber = *OptionNumber * 10 + Name[Index] - L'A';
    } else {
      return FALSE;
    }
  }

  return TRUE;
}
Beispiel #7
0
const CHAR16* StrStr(const CHAR16* haystack, const CHAR16* needle) {
	int len = StrLen(needle);
	while (haystack && haystack[0]) {
		if (StrnCmp(haystack, needle, len) == 0) {
			return haystack;
		}
		++haystack;
	}
	return 0;
}
Beispiel #8
0
EFIAPI
GetExecuatableFileName (
  IN CONST CHAR16    *NameString
  )
{
  CHAR16  *Buffer;
  CHAR16  *SuffixStr;
  if (NameString == NULL) {
    return (NULL);
  }

  //
  // Fix the file name
  //
  if (StrnCmp(NameString+StrLen(NameString)-StrLen(L".efi"), L".efi", StrLen(L".efi"))==0) {
    Buffer = AllocateCopyPool(StrSize(NameString), NameString);
  } else if (StrnCmp(NameString+StrLen(NameString)-StrLen(L".man"), L".man", StrLen(L".man"))==0) {
    Buffer = AllocateCopyPool(StrSize(NameString), NameString);
    if (Buffer != NULL) {
      SuffixStr = Buffer+StrLen(Buffer)-StrLen(L".man");
      StrnCpyS (SuffixStr, StrSize(L".man")/sizeof(CHAR16), L".efi", StrLen(L".efi"));
    }
  } else {
    Buffer = AllocateZeroPool(StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16));
    if (Buffer != NULL) {
      StrnCpyS( Buffer,
                (StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16))/sizeof(CHAR16),
                NameString,
                StrLen(NameString)
                );
      StrnCatS( Buffer,
                (StrSize(NameString) + StrLen(L".efi")*sizeof(CHAR16))/sizeof(CHAR16),
                L".efi",
                StrLen(L".efi")
                );
    }
  }
  return (Buffer);

}
EFI_STATUS flash(VOID *data, UINTN size, CHAR16 *label)
{
	UINTN i;

#ifndef USER
	/* special case for writing inside esp partition */
	CHAR16 esp[] = L"/ESP/";
	if (!StrnCmp(esp, label, StrLen(esp)))
		return flash_into_esp(data, size, &label[ARRAY_SIZE(esp) - 1]);
#endif
	/* special cases */
	for (i = 0; i < ARRAY_SIZE(LABEL_EXCEPTIONS); i++)
		if (!StrCmp(LABEL_EXCEPTIONS[i].name, label))
			return LABEL_EXCEPTIONS[i].flash_func(data, size);

	return flash_partition(data, size, label);
}
/**

  This code checks if variable is hardware error record variable or not.

  According to UEFI spec, hardware error record variable should use the EFI_HARDWARE_ERROR_VARIABLE VendorGuid
  and have the L"HwErrRec####" name convention, #### is a printed hex value and no 0x or h is included in the hex value.

  @param[in] VariableName   Pointer to variable name.
  @param[in] VendorGuid     Variable Vendor Guid.

  @retval TRUE              Variable is hardware error record variable.
  @retval FALSE             Variable is not hardware error record variable.

**/
BOOLEAN
EFIAPI
IsHwErrRecVariable (
  IN CHAR16             *VariableName,
  IN EFI_GUID           *VendorGuid
  )
{
  if (!CompareGuid (VendorGuid, &gEfiHardwareErrorVariableGuid) ||
      (StrLen (VariableName) != StrLen (L"HwErrRec####")) ||
      (StrnCmp(VariableName, L"HwErrRec", StrLen (L"HwErrRec")) != 0) ||
      !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0x8]) ||
      !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0x9]) ||
      !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0xA]) ||
      !VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[0xB])) {
    return FALSE;
  }

  return TRUE;
}
/**
  Check whether the VariableName is a valid load option variable name
  and return the load option type and option number.

  @param VariableName The name of the load option variable.
  @param OptionType   Return the load option type.
  @param OptionNumber Return the load option number.

  @retval TRUE  The variable name is valid; The load option type and
                load option number is returned.
  @retval FALSE The variable name is NOT valid.
**/
BOOLEAN
BmIsValidLoadOptionVariableName (
  IN CHAR16                             *VariableName,
  OUT EFI_BOOT_MANAGER_LOAD_OPTION_TYPE *OptionType,
  OUT UINT16                            *OptionNumber
  )
{
  UINTN                             VariableNameLen;
  UINTN                             Index;
  UINTN                             Uint;

  VariableNameLen = StrLen (VariableName);

  if (VariableNameLen <= 4) {
    return FALSE;
  }

  for (Index = 0; Index < sizeof (mBmLoadOptionName) / sizeof (mBmLoadOptionName[0]); Index++) {
    if ((VariableNameLen - 4 == StrLen (mBmLoadOptionName[Index])) &&
        (StrnCmp (VariableName, mBmLoadOptionName[Index], VariableNameLen - 4) == 0)
        ) {
      break;
    }
  }

  if (Index == sizeof (mBmLoadOptionName) / sizeof (mBmLoadOptionName[0])) {
    return FALSE;
  }

  *OptionType = (EFI_BOOT_MANAGER_LOAD_OPTION_TYPE) Index;
  *OptionNumber = 0;
  for (Index = VariableNameLen - 4; Index < VariableNameLen; Index++) {
    Uint = BmCharToUint (VariableName[Index]);
    if (Uint == -1) {
      break;
    } else {
      *OptionNumber = (UINT16) Uint + *OptionNumber * 0x10;
    }
  }

  return (BOOLEAN) (Index == VariableNameLen);
}
/**
  Get UEFI defined var check function.

  @param[in]  VariableName      Pointer to variable name.
  @param[in]  VendorGuid        Pointer to variable vendor GUID.
  @param[out] VariableProperty  Pointer to variable property.

  @return Internal var check function, NULL if no specific check function.

**/
INTERNAL_VAR_CHECK_FUNCTION
GetUefiDefinedVarCheckFunction (
  IN CHAR16                         *VariableName,
  IN EFI_GUID                       *VendorGuid,
  OUT VAR_CHECK_VARIABLE_PROPERTY   **VariableProperty
  )
{
  UINTN     Index;
  UINTN     NameLength;

  if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {
    //
    // Try list 1, exactly match.
    //
    for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {
      if (StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) {
        *VariableProperty = &(mGlobalVariableList[Index].VariableProperty);
        return mGlobalVariableList[Index].CheckFunction;
      }
    }

    //
    // Try list 2.
    //
    NameLength = StrLen (VariableName) - 4;
    for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {
      if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) &&
          (StrnCmp (VariableName, mGlobalVariableList2[Index].Name, NameLength) == 0) &&
          VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength]) &&
          VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&
          VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&
          VarCheckUefiIsHexaDecimalDigitCharacter (VariableName[NameLength + 3])) {
        *VariableProperty = &(mGlobalVariableList2[Index].VariableProperty);
        return mGlobalVariableList2[Index].CheckFunction;
      }
    }
  }

  return NULL;
}
Beispiel #13
0
/**
  Extract the decimal index from the network interface name.

  @param[in]  Name           Name of the network interface.

  @retval INVALID_NIC_INDEX  Failed to extract the network interface index.
  @return others             The network interface index.

**/
UINTN
NicNameToIndex (
  IN CHAR16                   *Name
  )
{
  CHAR16  *Str;

  Str = Name + 3;
  if ((StrnCmp (Name, L"eth", 3) != 0) || (*Str == 0)) {
    return INVALID_NIC_INDEX;
  }

  while (*Str != 0) {
    if ((*Str < L'0') || (*Str > L'9')) {
      return INVALID_NIC_INDEX;
    }

    Str++;
  }

  return (UINT16) StrDecimalToUintn (Name + 3);
}
Beispiel #14
0
/**
  Set information about a file.

  @param[in]  Instance  A pointer to the description of the volume
                        the file belongs to.
  @param[in]  File      A pointer to the description of the file.
  @param[in]  Info      A pointer to the file information to write.

  @retval  EFI_SUCCESS           The information was set.
  @retval  EFI_ACCESS_DENIED     An attempt is being made to change the
                                 EFI_FILE_DIRECTORY Attribute.
  @retval  EFI_ACCESS_DENIED     The file was opened in read-only mode and an
                                 attempt is being made to modify a field other
                                 than Attribute.
  @retval  EFI_ACCESS_DENIED     An attempt is made to change the name of a file
                                 to a file that is already present.
  @retval  EFI_WRITE_PROTECTED   An attempt is being made to modify a read-only
                                 attribute.
  @retval  EFI_OUT_OF_RESOURCES  An allocation needed to process the request
                                 failed.

**/
STATIC
EFI_STATUS
SetFileInfo (
  IN BOOTMON_FS_INSTANCE  *Instance,
  IN BOOTMON_FS_FILE      *File,
  IN EFI_FILE_INFO        *Info
  )
{
  EFI_STATUS  Status;
  BOOLEAN     FileSizeIsDifferent;
  BOOLEAN     FileNameIsDifferent;
  BOOLEAN     TimeIsDifferent;

  //
  // A directory can not be changed to a file and a file can
  // not be changed to a directory.
  //
  if ((Info->Attribute & EFI_FILE_DIRECTORY)      !=
      (File->Info->Attribute & EFI_FILE_DIRECTORY)  ) {
    return EFI_ACCESS_DENIED;
  }

  FileSizeIsDifferent = (Info->FileSize != File->Info->FileSize);
  FileNameIsDifferent = (StrnCmp (
                           Info->FileName,
                           File->Info->FileName,
                           MAX_NAME_LENGTH - 1
                           ) != 0);
  //
  // Check if the CreateTime, LastAccess or ModificationTime
  // have been changed. The file system does not support file
  // timestamps thus the three times in "File->Info" are
  // always equal to zero. The following comparison actually
  // checks if all three times are still equal to 0 or not.
  //
  TimeIsDifferent = CompareMem (
                      &Info->CreateTime,
                      &File->Info->CreateTime,
                      3 * sizeof (EFI_TIME)
                      ) != 0;

  //
  // For a file opened in read-only mode, only the Attribute field can be
  // modified. The root directory open mode is forced to read-only at opening
  // thus the following test protects the root directory to be somehow modified.
  //
  if (File->OpenMode == EFI_FILE_MODE_READ) {
    if (FileSizeIsDifferent || FileNameIsDifferent || TimeIsDifferent) {
      return EFI_ACCESS_DENIED;
    }
  }

  if (TimeIsDifferent) {
    return EFI_WRITE_PROTECTED;
  }

  if (FileSizeIsDifferent) {
    Status = SetFileSize (Instance, File, Info->FileSize);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Note down in RAM the Attribute field but we can not
  // ask to store it in flash for the time being.
  //
  File->Info->Attribute = Info->Attribute;

  if (FileNameIsDifferent) {
    Status = SetFileName (Instance, File, Info->FileName);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  return EFI_SUCCESS;
}
Beispiel #15
0
/**
  parses through the MAN file specified by SHELL_FILE_HANDLE and returns the
  detailed help for any sub section specified in the comma seperated list of
  sections provided.  If the end of the file or a .TH section is found then
  return.

  Upon a sucessful return the caller is responsible to free the memory in *HelpText

  @param[in] Handle             FileHandle to read from
  @param[in] Sections           name of command's sub sections to find
  @param[out] HelpText          pointer to pointer to string where text goes.
  @param[out] HelpSize          pointer to size of allocated HelpText (may be updated)
  @param[in] Ascii              TRUE if the file is ASCII, FALSE otherwise.

  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
  @retval EFI_SUCCESS           the section was found and its description sotred in
                                an alloceted buffer.
**/
EFI_STATUS
EFIAPI
ManFileFindSections(
  IN SHELL_FILE_HANDLE  Handle,
  IN CONST CHAR16       *Sections,
  OUT CHAR16            **HelpText,
  OUT UINTN             *HelpSize,
  IN BOOLEAN            Ascii
  )
{
  EFI_STATUS          Status;
  CHAR16              *ReadLine;
  UINTN               Size;
  BOOLEAN             CurrentlyReading;
  CHAR16              *SectionName;
  UINTN               SectionLen;
  BOOLEAN             Found;

  if ( Handle     == NULL
    || HelpText   == NULL
    || HelpSize   == NULL
   ){
    return (EFI_INVALID_PARAMETER);
  }

  Status            = EFI_SUCCESS;
  CurrentlyReading  = FALSE;
  Size              = 1024;
  Found             = FALSE;

  ReadLine          = AllocateZeroPool(Size);
  if (ReadLine == NULL) {
    return (EFI_OUT_OF_RESOURCES);
  }

  for (;!ShellFileHandleEof(Handle);Size = 1024) {
    Status = ShellFileHandleReadLine(Handle, ReadLine, &Size, TRUE, &Ascii);
    if (ReadLine[0] == L'#') {
      //
      // Skip comment lines
      //
      continue;
    }
    //
    // ignore too small of buffer...
    //
    if (Status == EFI_BUFFER_TOO_SMALL) {
      Status = EFI_SUCCESS;
    }
    if (EFI_ERROR(Status)) {
      break;
    } else if (StrnCmp(ReadLine, L".TH", 3) == 0) {
      //
      // we hit the end of this commands section so stop.
      //
      break;
    } else if (StrnCmp(ReadLine, L".SH", 3) == 0) {
      if (Sections == NULL) {
        CurrentlyReading = TRUE;
        continue;
      }
      //
      // we found a section
      //
      if (CurrentlyReading) {
        CurrentlyReading = FALSE;
      }
      //
      // is this a section we want to read in?
      //
      for ( SectionName = ReadLine + 3
          ; *SectionName == L' '
          ; SectionName++);
      SectionLen = StrLen(SectionName);
      SectionName = StrStr(Sections, SectionName);
      if (SectionName == NULL) {
        continue;
      }
      if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') {
        CurrentlyReading = TRUE;
      }
    } else if (CurrentlyReading) {
      Found = TRUE;
      //
      // copy and save the current line.
      //
      ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL));
      StrnCatGrow (HelpText, HelpSize, ReadLine, 0);
      StrnCatGrow (HelpText, HelpSize, L"\r\n", 0);
    }
  }
  FreePool(ReadLine);
  if (!Found && !EFI_ERROR(Status)) {
    return (EFI_NOT_FOUND);
  }
  return (Status);
}
Beispiel #16
0
/**
  parses through Buffer (which is MAN file formatted) and returns the
  detailed help for any sub section specified in the comma seperated list of
  sections provided.  If the end of the file or a .TH section is found then
  return.

  Upon a sucessful return the caller is responsible to free the memory in *HelpText

  @param[in] Buffer             Buffer to read from
  @param[in] Sections           name of command's sub sections to find
  @param[in] HelpText           pointer to pointer to string where text goes.
  @param[in] HelpSize           pointer to size of allocated HelpText (may be updated)

  @retval EFI_OUT_OF_RESOURCES  a memory allocation failed.
  @retval EFI_SUCCESS           the section was found and its description sotred in
                                an alloceted buffer.
**/
EFI_STATUS
EFIAPI
ManBufferFindSections(
  IN CONST CHAR16 *Buffer,
  IN CONST CHAR16 *Sections,
  IN CHAR16       **HelpText,
  IN UINTN        *HelpSize
  )
{
  EFI_STATUS          Status;
  CONST CHAR16        *CurrentLocation;
  BOOLEAN             CurrentlyReading;
  CHAR16              *SectionName;
  UINTN               SectionLen;
  BOOLEAN             Found;
  CHAR16              *TempString;
  CHAR16              *TempString2;

  if ( Buffer     == NULL
    || HelpText   == NULL
    || HelpSize   == NULL
   ){
    return (EFI_INVALID_PARAMETER);
  }

  Status            = EFI_SUCCESS;
  CurrentlyReading  = FALSE;
  Found             = FALSE;

  for (CurrentLocation = Buffer,TempString = NULL
    ;  CurrentLocation != NULL && *CurrentLocation != CHAR_NULL
    ;  CurrentLocation=StrStr(CurrentLocation, L"\r\n"),TempString = NULL
   ){
    while(CurrentLocation[0] == L'\r' || CurrentLocation[0] == L'\n') {
      CurrentLocation++;
    }
    if (CurrentLocation[0] == L'#') {
      //
      // Skip comment lines
      //
      continue;
    }
    if (StrnCmp(CurrentLocation, L".TH", 3) == 0) {
      //
      // we hit the end of this commands section so stop.
      //
      break;
    }
    if (StrnCmp(CurrentLocation, L".SH ", 4) == 0) {
      if (Sections == NULL) {
        CurrentlyReading = TRUE;
        continue;
      } else if (CurrentlyReading) {
        CurrentlyReading = FALSE;
      }
      CurrentLocation += 4;
      //
      // is this a section we want to read in?
      //
      if (StrLen(CurrentLocation)!=0) {
        TempString2 = StrStr(CurrentLocation, L" ");
        TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\r"));
        TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n"));
        ASSERT(TempString == NULL);
        TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation);
        if (TempString == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }
        SectionName = TempString;
        SectionLen = StrLen(SectionName);
        SectionName = StrStr(Sections, SectionName);
        if (SectionName == NULL) {
          continue;
        }
        if (*(SectionName + SectionLen) == CHAR_NULL || *(SectionName + SectionLen) == L',') {
          CurrentlyReading = TRUE;
        }
      }
    } else if (CurrentlyReading) {
      Found = TRUE;
      if (StrLen(CurrentLocation)!=0) {
        TempString2 = StrStr(CurrentLocation, L"\r");
        TempString2 = MIN(TempString2, StrStr(CurrentLocation, L"\n"));
        ASSERT(TempString == NULL);
        TempString = StrnCatGrow(&TempString, NULL, CurrentLocation, TempString2==NULL?0:TempString2 - CurrentLocation);
        if (TempString == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }
        //
        // copy and save the current line.
        //
        ASSERT((*HelpText == NULL && *HelpSize == 0) || (*HelpText != NULL));
        StrnCatGrow (HelpText, HelpSize, TempString, 0);
        if (HelpText == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }
        StrnCatGrow (HelpText, HelpSize, L"\r\n", 0);
        if (HelpText == NULL) {
          Status = EFI_OUT_OF_RESOURCES;
          break;
        }
      }
    }
    SHELL_FREE_NON_NULL(TempString);
  }
  if (!Found && !EFI_ERROR(Status)) {
    return (EFI_NOT_FOUND);
  }
  return (Status);
}
Beispiel #17
0
/**
  Function for 'setvar' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunSetVar (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS          Status;
  LIST_ENTRY          *Package;
  CHAR16              *ProblemParam;
  SHELL_STATUS        ShellStatus;
  CONST CHAR16        *VariableName;
  CONST CHAR16        *Data;
  EFI_GUID            Guid;
  CONST CHAR16        *StringGuid;
  UINT32              Attributes;
  UINT32              Attributes2;
  VOID                *Buffer;
  UINTN               Size;
  UINTN               LoopVar;
  EFI_DEVICE_PATH_PROTOCOL           *DevPath;

  ShellStatus         = SHELL_SUCCESS;
  Status              = EFI_SUCCESS;
  Buffer              = NULL;
  Size                = 0;
  Attributes          = 0;
  DevPath             = NULL;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize();
  ASSERT_EFI_ERROR(Status);

  Status = CommandInit();
  ASSERT_EFI_ERROR(Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR(Status)) {
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, ProblemParam);
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT(FALSE);
    }
  } else {
    if (ShellCommandLineGetCount(Package) < 2) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else if (ShellCommandLineGetCount(Package) > 3) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      VariableName  = ShellCommandLineGetRawValue(Package, 1);
      Data          = ShellCommandLineGetRawValue(Package, 2);
      if (!ShellCommandLineGetFlag(Package, L"-guid")){
        CopyGuid(&Guid, &gEfiGlobalVariableGuid);
      } else {
        StringGuid = ShellCommandLineGetValue(Package, L"-guid");
        Status = ConvertStringToGuid(StringGuid, &Guid);
        if (EFI_ERROR(Status)) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, StringGuid);
          ShellStatus = SHELL_INVALID_PARAMETER;
        }
      }
      if (Data == NULL) {
        //
        // Display what's there
        //
        Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
        if (Status == EFI_BUFFER_TOO_SMALL) {
          Buffer = AllocateZeroPool(Size);
          Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes, &Size, Buffer);
        }
        if (!EFI_ERROR(Status)&& Buffer != NULL) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_PRINT), gShellDebug1HiiHandle, &Guid, VariableName, Size);
          for (LoopVar = 0 ; LoopVar < Size ; LoopVar++) {
            ShellPrintEx(-1, -1, L"%02x ", ((UINT8*)Buffer)[LoopVar]);
          }
          ShellPrintEx(-1, -1, L"\r\n");
        } else {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_GET), gShellDebug1HiiHandle, &Guid, VariableName, Status);
          ShellStatus = SHELL_ACCESS_DENIED;
        }
      } else if (StrCmp(Data, L"=") == 0) {
        //
        // Delete what's there!
        //
        Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, 0, NULL);
        if (EFI_ERROR(Status)) {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);
          ShellStatus = SHELL_ACCESS_DENIED;
        } else {
          ASSERT(ShellStatus == SHELL_SUCCESS);
        }
      } else {
        if (Data[0] == L'=') {
          Data++;
        }
        //
        // Change what's there
        //
        if (ShellCommandLineGetFlag(Package, L"-bs")) {
          Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
        }
        if (ShellCommandLineGetFlag(Package, L"-rt")) {
          Attributes |= EFI_VARIABLE_RUNTIME_ACCESS |
                        EFI_VARIABLE_BOOTSERVICE_ACCESS;
        }
        if (ShellCommandLineGetFlag(Package, L"-nv")) {
          Attributes |= EFI_VARIABLE_NON_VOLATILE;
        }
        if (ShellIsHexOrDecimalNumber(Data, TRUE, FALSE)) {
          if (StrLen(Data) % 2 != 0) {
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM_VAL), gShellDebug1HiiHandle, Data);
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            //
            // arbitrary buffer
            //
            Buffer = AllocateZeroPool((StrLen(Data) / 2));
            if (Buffer == NULL) {
              Status = EFI_OUT_OF_RESOURCES;
            } else {
              for (LoopVar = 0 ; LoopVar < (StrLen(Data) / 2) ; LoopVar++) {
                ((UINT8*)Buffer)[LoopVar] = (UINT8)(HexCharToUintn(Data[LoopVar*2]) * 16);
                ((UINT8*)Buffer)[LoopVar] = (UINT8)(((UINT8*)Buffer)[LoopVar] + HexCharToUintn(Data[LoopVar*2+1]));
              }
              Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrLen(Data) / 2, Buffer);
            }
            if (EFI_ERROR(Status)) {
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);
              ShellStatus = SHELL_ACCESS_DENIED;
            } else {
              ASSERT(ShellStatus == SHELL_SUCCESS);
            }
          }
        } else if (StrnCmp(Data, L"\"", 1) == 0) {
          Size = 0;
          Attributes2 = 0;
          Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes2, &Size, Buffer);
          if (Status == EFI_BUFFER_TOO_SMALL) {
            Buffer = AllocateZeroPool(Size);
            Status = gRT->GetVariable((CHAR16*)VariableName, &Guid, &Attributes2, &Size, Buffer);
            if (Buffer != NULL) {
              FreePool(Buffer);
            }
            Attributes = Attributes2;
          }
          //
          // ascii text
          //
          Data++;
          Buffer = AllocateZeroPool(StrSize(Data) / 2);
          if (Buffer == NULL) {
            Status = EFI_OUT_OF_RESOURCES;
          } else {
            AsciiSPrint(Buffer, StrSize(Data) / 2, "%s", Data);
            ((CHAR8*)Buffer)[AsciiStrLen(Buffer)-1] = CHAR_NULL;
            Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, AsciiStrSize(Buffer)-sizeof(CHAR8), Buffer);
          }
          if (EFI_ERROR(Status)) {
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);
            ShellStatus = SHELL_ACCESS_DENIED;
          } else {
            ASSERT(ShellStatus == SHELL_SUCCESS);
          }
        } else if (StrnCmp(Data, L"L\"", 2) == 0) {
          //
          // ucs2 text
          //
          Data++;
          Data++;
          Buffer = AllocateZeroPool(StrSize(Data));
          if (Buffer == NULL) {
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle);
            ShellStatus = SHELL_OUT_OF_RESOURCES;
          } else {
            UnicodeSPrint(Buffer, StrSize(Data), L"%s", Data);
            ((CHAR16*)Buffer)[StrLen(Buffer)-1] = CHAR_NULL;

            Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, StrSize(Buffer)-sizeof(CHAR16), Buffer);
            if (EFI_ERROR(Status)) {
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);
              ShellStatus = SHELL_ACCESS_DENIED;
            } else {
              ASSERT(ShellStatus == SHELL_SUCCESS);
            }
          }
        } else if (StrnCmp(Data, L"--", 2) == 0) {
          //
          // device path in text format
          //
          Data++;
          Data++;
          DevPath = ConvertTextToDevicePath(Data);
          if (DevPath == NULL) {
            ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, Status);
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            Status = gRT->SetVariable((CHAR16*)VariableName, &Guid, Attributes, GetDevicePathSize(DevPath), DevPath);
            if (EFI_ERROR(Status)) {
              ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_SET), gShellDebug1HiiHandle, &Guid, VariableName, Status);
              ShellStatus = SHELL_ACCESS_DENIED;
            } else {
              ASSERT(ShellStatus == SHELL_SUCCESS);
            }
          }
        } else {
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, Data);
          ShellStatus = SHELL_INVALID_PARAMETER;
        }
      }
    }
    ShellCommandLineFreeVarList (Package);
  }

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

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

  return (ShellStatus);
}
Beispiel #18
0
/**
  Function to parse the Data by the type of Data, and save in the Buffer.

  @param[in]      Data                A pointer to a buffer to be parsed.
  @param[out]     Buffer              A pointer to a buffer to hold the return data.
  @param[in,out]  BufferSize          On input, indicates the size of Buffer in bytes.
                                      On output,indicates the size of data return in Buffer.
                                      Or the size in bytes of the buffer needed to obtain.

  @retval   EFI_INVALID_PARAMETER     The Buffer or BufferSize is NULL.
  @retval   EFI_BUFFER_TOO_SMALL      The Buffer is too small to hold the data.
  @retval   EFI_OUT_OF_RESOURCES      A memory allcation failed.
  @retval   EFI_SUCCESS               The Data parsed successful and save in the Buffer.
**/
EFI_STATUS
ParseParameterData (
  IN CONST CHAR16   *Data,
  OUT VOID          *Buffer,
  IN OUT UINTN      *BufferSize
  )
{
  UINT64                    HexNumber;
  UINTN                     HexNumberLen;
  UINTN                     Size;
  CHAR8                     *AsciiBuffer;
  DATA_TYPE                 DataType;
  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
  EFI_STATUS                Status;

  HexNumber                 = 0;
  HexNumberLen              = 0;
  Size                      = 0;
  AsciiBuffer               = NULL;
  DevPath                   = NULL;
  Status                    = EFI_SUCCESS;

  if (Data == NULL || BufferSize == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  DataType = TestDataType (Data);
  if (DataType == DataTypeHexNumber) {
    //
    // hex number
    //
    StrHexToUint64S (Data + 2, NULL, &HexNumber);
    HexNumberLen = StrLen (Data + 2);
    if (HexNumberLen >= 1 && HexNumberLen <= 2) {
      Size = 1;
    } else if (HexNumberLen >= 3 && HexNumberLen <= 4) {
      Size = 2;
    } else if (HexNumberLen >= 5 && HexNumberLen <= 8) {
      Size = 4;
    } else if (HexNumberLen >= 9 && HexNumberLen <= 16) {
      Size = 8;
    }
    if (Buffer != NULL && *BufferSize >= Size) {
      CopyMem(Buffer, (VOID *)&HexNumber, Size);
    } else {
      Status = EFI_BUFFER_TOO_SMALL;
    }
    *BufferSize = Size;
  } else if (DataType == DataTypeHexArray) {
    //
    // hex array
    //
    if (*Data == L'H') {
      Data = Data + 1;
    }

    Size = StrLen (Data) / 2;
    if (Buffer != NULL && *BufferSize >= Size) {
      StrHexToBytes(Data, StrLen  (Data), (UINT8 *)Buffer, Size);
    } else {
      Status = EFI_BUFFER_TOO_SMALL;
    }
    *BufferSize = Size;
  } else if (DataType == DataTypeAscii) {
    //
    // ascii text
    //
    if (*Data == L'S') {
      Data = Data + 1;
    }
    AsciiBuffer = AllocateZeroPool (StrSize (Data) / 2);
    if (AsciiBuffer == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
    } else {
      AsciiSPrint (AsciiBuffer, StrSize (Data) / 2, "%s", (CHAR8 *)Data);

      Size = StrSize (Data) / 2 - 1;
      if (Buffer != NULL && *BufferSize >= Size) {
        CopyMem (Buffer, AsciiBuffer, Size);
      } else {
        Status = EFI_BUFFER_TOO_SMALL;
      }
      *BufferSize = Size;
    }
    SHELL_FREE_NON_NULL (AsciiBuffer);
  } else if (DataType == DataTypeUnicode) {
    //
    // unicode text
    //
    if (*Data == L'L') {
      Data = Data + 1;
    }
    Size = StrSize (Data) - sizeof (CHAR16);
    if (Buffer != NULL && *BufferSize >= Size) {
      CopyMem (Buffer, Data, Size);
    } else {
      Status = EFI_BUFFER_TOO_SMALL;
    }
    *BufferSize = Size;
  } else if (DataType == DataTypeDevicePath) {
    if (*Data == L'P') {
      Data = Data + 1;
    } else if (StrnCmp (Data, L"--", 2) == 0) {
      Data = Data + 2;
    }
    DevPath = ConvertTextToDevicePath (Data);
    if (DevPath == NULL) {
      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_SETVAR_ERROR_DPFT), gShellDebug1HiiHandle, L"setvar");
      Status = EFI_INVALID_PARAMETER;
    } else {
      Size = GetDevicePathSize (DevPath);
      if (Buffer != NULL && *BufferSize >= Size) {
        CopyMem (Buffer, DevPath, Size);
      } else {
        Status = EFI_BUFFER_TOO_SMALL;
      }
      *BufferSize = Size;
    }
    SHELL_FREE_NON_NULL (DevPath);
  } else {
    Status = EFI_INVALID_PARAMETER;
  }

  return Status;
}
Beispiel #19
0
/**
  Add new boot option for HTTP boot.

  @param[in]  Private             Pointer to the driver private data.
  @param[in]  UsingIpv6           Set to TRUE if creating boot option for IPv6.
  @param[in]  Description         The description text of the boot option.
  @param[in]  Uri                 The URI string of the boot file.
  
  @retval EFI_SUCCESS             The boot option is created successfully.
  @retval Others                  Failed to create new boot option.

**/
EFI_STATUS
HttpBootAddBootOption (
  IN   HTTP_BOOT_PRIVATE_DATA   *Private,
  IN   BOOLEAN                  UsingIpv6,
  IN   CHAR16                   *Description,
  IN   CHAR16                   *Uri
  )
{
  EFI_DEV_PATH               *Node;
  EFI_DEVICE_PATH_PROTOCOL   *TmpDevicePath;
  EFI_DEVICE_PATH_PROTOCOL   *NewDevicePath;
  UINTN                      Length;
  CHAR8                      AsciiUri[URI_STR_MAX_SIZE];
  CHAR16                     *CurrentOrder;
  EFI_STATUS                 Status;
  UINTN                      OrderCount;
  UINTN                      TargetLocation;
  BOOLEAN                    Found;
  UINT8                      *TempByteBuffer;
  UINT8                      *TempByteStart;
  UINTN                      DescSize;
  UINTN                      FilePathSize;
  CHAR16                     OptionStr[10];
  UINT16                     *NewOrder;
  UINTN                      Index;

  NewOrder      = NULL;
  TempByteStart = NULL;
  NewDevicePath = NULL;
  NewOrder      = NULL;
  Node          = NULL;
  TmpDevicePath = NULL;
  CurrentOrder  = NULL;

  if (StrLen (Description) == 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Convert the scheme to all lower case.
  //
  for (Index = 0; Index < StrLen (Uri); Index++) {
    if (Uri[Index] == L':') {
      break;
    }
    if (Uri[Index] >= L'A' && Uri[Index] <= L'Z') {
      Uri[Index] -= (CHAR16)(L'A' - L'a');
    }
  }

  //
  // Only accept http and https URI.
  //
  if ((StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 7) != 0)) {
    return EFI_INVALID_PARAMETER;
  }
  
  //
  // Create a new device path by appending the IP node and URI node to
  // the driver's parent device path
  //
  if (!UsingIpv6) {
    Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));
    if (Node == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }
    Node->Ipv4.Header.Type    = MESSAGING_DEVICE_PATH;
    Node->Ipv4.Header.SubType = MSG_IPv4_DP;
    SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
  } else {
    Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
    if (Node == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ON_EXIT;
    }
    Node->Ipv6.Header.Type     = MESSAGING_DEVICE_PATH;
    Node->Ipv6.Header.SubType  = MSG_IPv6_DP;
    SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));
  }
  TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
  FreePool (Node);
  if (TmpDevicePath == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Update the URI node with the input boot file URI.
  //
  UnicodeStrToAsciiStr (Uri, AsciiUri);
  Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri);
  Node = AllocatePool (Length);
  if (Node == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    FreePool (TmpDevicePath);
    goto ON_EXIT;
  }
  Node->DevPath.Type    = MESSAGING_DEVICE_PATH;
  Node->DevPath.SubType = MSG_URI_DP;
  SetDevicePathNodeLength (Node, Length);
  CopyMem ((UINT8*) Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), AsciiUri, AsciiStrSize (AsciiUri));
  NewDevicePath = AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
  FreePool (Node);
  FreePool (TmpDevicePath);
  if (NewDevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  //
  // Get current "BootOrder" variable and find a free target.
  //
  Length = 0;
  Status = GetVariable2 (
             L"BootOrder",
             &gEfiGlobalVariableGuid,
             (VOID **)&CurrentOrder,
             &Length 
             );
  if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {
    goto ON_EXIT;
  }
  OrderCount = Length / sizeof (UINT16);
  Found = FALSE;
  for (TargetLocation=0; TargetLocation < 0xFFFF; TargetLocation++) {
    Found = TRUE;
    for (Index = 0; Index < OrderCount; Index++) {
      if (CurrentOrder[Index] == TargetLocation) {
        Found = FALSE;
        break;
      }
    }
    if (Found) {
      break;
    }
  }

  if (TargetLocation == 0xFFFF) {
    DEBUG ((EFI_D_ERROR, "Could not find unused target index.\n"));
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  } else {
    DEBUG ((EFI_D_INFO, "TargetIndex = %04x.\n", TargetLocation));
  }
  
  //
  // Construct and set the "Boot####" variable
  //
  DescSize = StrSize(Description);
  FilePathSize = GetDevicePathSize (NewDevicePath);
  TempByteBuffer = AllocateZeroPool(sizeof(EFI_LOAD_OPTION) + DescSize + FilePathSize);
  if (TempByteBuffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  TempByteStart = TempByteBuffer;
  *((UINT32 *) TempByteBuffer) = LOAD_OPTION_ACTIVE;      // Attributes
  TempByteBuffer += sizeof (UINT32);

  *((UINT16 *) TempByteBuffer) = (UINT16)FilePathSize;    // FilePathListLength
  TempByteBuffer += sizeof (UINT16);

  CopyMem (TempByteBuffer, Description, DescSize);
  TempByteBuffer += DescSize;
  CopyMem (TempByteBuffer, NewDevicePath, FilePathSize);

  UnicodeSPrint (OptionStr, sizeof(OptionStr), L"%s%04x", L"Boot", TargetLocation);
  Status = gRT->SetVariable (
                  OptionStr,
                  &gEfiGlobalVariableGuid,
                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                  sizeof(UINT32) + sizeof(UINT16) + DescSize + FilePathSize,
                  TempByteStart
                  );
  if (EFI_ERROR (Status)) {
    goto ON_EXIT;
  }

  //
  // Insert into the order list and set "BootOrder" variable
  //
  NewOrder = AllocateZeroPool ((OrderCount + 1) * sizeof (UINT16));
  if (NewOrder == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }
  CopyMem(NewOrder, CurrentOrder, OrderCount * sizeof(UINT16));
  NewOrder[OrderCount] = (UINT16) TargetLocation;
  Status = gRT->SetVariable (
                  L"BootOrder",
                  &gEfiGlobalVariableGuid,
                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                  ((OrderCount + 1) * sizeof (UINT16)),
                  NewOrder
                  );
  

ON_EXIT:

  if (CurrentOrder != NULL) {
    FreePool (CurrentOrder);
  }
  if (NewOrder != NULL) {
    FreePool (NewOrder);
  }
  if (TempByteStart != NULL) {
    FreePool (TempByteStart);
  }
  if (NewDevicePath != NULL) {
    FreePool (NewDevicePath);
  }

  return Status;
}
Beispiel #20
0
/**

  Convert the UEFI DevicePath to full text representation with DevPathToText,
  then match the UEFI device path fragment in Translated against it.

  @param[in] Translated        UEFI device path fragment, translated from
                               OpenFirmware format, to search for.

  @param[in] TranslatedLength  The length of Translated in CHAR16's.

  @param[in] DevicePath        Boot option device path whose textual rendering
                               to search in.

  @param[in] DevPathToText  Binary-to-text conversion protocol for DevicePath.


  @retval TRUE   If Translated was found at the beginning of DevicePath after
                 converting the latter to text.

  @retval FALSE  If DevicePath was NULL, or it could not be converted, or there
                 was no match.

**/
STATIC
BOOLEAN
Match (
  IN  CONST CHAR16                           *Translated,
  IN  UINTN                                  TranslatedLength,
  IN  CONST EFI_DEVICE_PATH_PROTOCOL         *DevicePath
  )
{
  CHAR16  *Converted;
  BOOLEAN Result;

  Converted = ConvertDevicePathToText (
                DevicePath,
                FALSE, // DisplayOnly
                FALSE  // AllowShortcuts
                );
  if (Converted == NULL) {
    return FALSE;
  }

  //
  // Attempt to expand any relative UEFI device path starting with HD() to an
  // absolute device path first. The logic imitates BdsLibBootViaBootOption().
  // We don't have to free the absolute device path,
  // BdsExpandPartitionPartialDevicePathToFull() has internal caching.
  //
  Result = FALSE;
  if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH &&
      DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP) {
    EFI_DEVICE_PATH_PROTOCOL *AbsDevicePath;
    CHAR16                   *AbsConverted;

    AbsDevicePath = BdsExpandPartitionPartialDevicePathToFull (
                      (HARDDRIVE_DEVICE_PATH *) DevicePath);
    if (AbsDevicePath == NULL) {
      goto Exit;
    }
    AbsConverted = ConvertDevicePathToText (AbsDevicePath, FALSE, FALSE);
    if (AbsConverted == NULL) {
      goto Exit;
    }
    DEBUG ((DEBUG_VERBOSE,
      "%a: expanded relative device path \"%s\" for prefix matching\n",
      __FUNCTION__, Converted));
    FreePool (Converted);
    Converted = AbsConverted;
  }

  //
  // Is Translated a prefix of Converted?
  //
  Result = (BOOLEAN)(StrnCmp (Converted, Translated, TranslatedLength) == 0);
  DEBUG ((
    DEBUG_VERBOSE,
    "%a: against \"%s\": %a\n",
    __FUNCTION__,
    Converted,
    Result ? "match" : "no match"
    ));
Exit:
  FreePool (Converted);
  return Result;
}
Beispiel #21
0
int compare(struct sorted_data * sd1, 
            struct sorted_data * sd2, 
            ULONG col, 
            BOOL case_on)
{
  ULONG len = MIN(sd1->len, sd2->len);
 
#warning It seems like StrnCmp of locale does not work.
#if 1
  LONG retval = 0;
  
  if (TRUE == case_on)
  {
    int i = col;
    
    while (i < len)
    {
      BOOL a,b;
      a = IsUpper(locale,(ULONG)*(sd1->data+col+i));
      b = IsUpper(locale,(ULONG)*(sd2->data+col+i));
      
      if (a == b)
      {
        if (0 != (retval = StrnCmp(locale,
                           sd1->data+col,
                           sd2->data+col,
                           1,
                           SC_COLLATE2))); 
          break;
      }
      else
      {
       retval = b - a;
       break;
      }
      
      i++;
    }
  }
  else
  {

    retval=StrnCmp(locale,
                   sd1->data+col,
                   sd2->data+col,
                   len,
                   SC_COLLATE2);  

    if (0 == retval)
    {
      if (sd1->len < sd2->len)
        retval = -100;
      else
        retval = +100;
    }
  }
  
  return retval;

#else  
  int i = col;
  char * str1 = sd1->data;
  char * str2 = sd2->data;

  while (i < len)
  {
    if (str1[i] != str2[i])
      return (int)(str1[i] - str2[i]);

    i++;
  }
  
  return (int)sd1->len - (int)sd2->len;
#endif
} 
Beispiel #22
0
EFI_STATUS
FindApplicationMatchingUiSection (
  IN  CHAR16      *UiString,
  OUT EFI_HANDLE  *FvHandle,
  OUT EFI_GUID    *NameGuid
  )
{
  EFI_STATUS                    Status;
  EFI_STATUS                    NextStatus;
  UINTN                         NoHandles;
  EFI_HANDLE                    *Buffer;
  UINTN                         Index;
  EFI_FV_FILETYPE               FileType;
  EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
  VOID                          *Key;
  EFI_FV_FILE_ATTRIBUTES        Attributes;
  UINTN                         Size;
  UINTN                         UiStringLen;
  CHAR16                        *UiSection;
  UINT32                        Authentication;


  UiStringLen = 0;
  if (UiString != NULL) {
    DEBUG ((DEBUG_ERROR, "UiString %s\n", UiString));
    UiStringLen = StrLen (UiString);
  }

  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Buffer);
  if (!EFI_ERROR (Status)) {
    for (Index = 0; Index < NoHandles; Index++) {
      Status = gBS->HandleProtocol (Buffer[Index], &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
      if (!EFI_ERROR (Status)) {
        Key = AllocatePool (Fv->KeySize);
        ASSERT (Key != NULL);
        ZeroMem (Key, Fv->KeySize);

        FileType = EFI_FV_FILETYPE_APPLICATION;

        do {
          NextStatus = Fv->GetNextFile (Fv, Key, &FileType, NameGuid, &Attributes, &Size);
          if (!EFI_ERROR (NextStatus)) {
            if (UiString == NULL) {
              //
              // If UiString is NULL match first application we find.
              //
              *FvHandle = Buffer[Index];
              FreePool (Key);
              return Status;
            }

            UiSection = NULL;
            Status = Fv->ReadSection (
                          Fv,
                          NameGuid,
                          EFI_SECTION_USER_INTERFACE,
                          0,
                          (VOID **)&UiSection,
                          &Size,
                          &Authentication
                          );
            if (!EFI_ERROR (Status)) {
              if (StrnCmp (UiString, UiSection, UiStringLen) == 0) {
                //
                // We found a UiString match.
                //
                *FvHandle = Buffer[Index];
                FreePool (Key);
                FreePool (UiSection);
                return Status;
              }
              FreePool (UiSection);
            }
          }
        } while (!EFI_ERROR (NextStatus));

        FreePool (Key);
      }
    }

    FreePool (Buffer);
   }

  return EFI_NOT_FOUND;
}
Beispiel #23
0
EFI_STATUS
EFIAPI
ShellAppMain (
  IN UINTN Argc,
  IN CHAR16 **Argv
  )
{
  EFI_STATUS    Status;
  UINT16        *BootVariable;
  UINTN         BootVariableSize;
  UINT16        LDAttr;
  CHAR16        *Name;
  UINTN         NewNameSize;
  UINTN         NameSize;
  UINTN         i;
  UINT32        Attr;
  EFI_GUID      VarGuid;
  

  ParseOpt(Argc, Argv);

  //------------Usage-----------------------
  if (opts.usage){
  	Usage();
  	return EFI_SUCCESS;
  }
  //----------Set BootOrder-----------------
  if (opts.set_bootorder){
  	BootVariable = mGetVariable(L"BootOrder", &gEfiGlobalVariableGuid, &BootVariableSize, &Attr);
    BootVariable[0]=opts.bootnum;
    Status = gRT->SetVariable(L"BootOrder", &gEfiGlobalVariableGuid, Attr, BootVariableSize, BootVariable);
    if (!EFI_ERROR(Status))
      Print(L"Set first boot to Boot%04x\n", opts.bootnum);
    return Status;
  }


  //----------Show Boot UEFI variables--------
  //get BootCurrent
  BootVariable = mGetVariable(L"BootCurrent", &gEfiGlobalVariableGuid, &BootVariableSize, NULL);
  if (BootVariable != NULL)
    Print(L"BootCurrent: %04x\n", *BootVariable);
  //get BootOrder
  BootVariable = mGetVariable(L"BootOrder", &gEfiGlobalVariableGuid, &BootVariableSize, &Attr);
  if (BootVariable != NULL){
  	Print(L"BootOrder:  ");
    for(i=0; i<(BootVariableSize/2); i++){
    	Print(L" %04x ",BootVariable[i]);
    }
    Print(L"\n");
  }

  //Print all BOOT#### Load Options
  NameSize = sizeof(CHAR16);
  Name     = AllocateZeroPool(NameSize);
  for (i=0; ;i++ ){
  	NewNameSize = NameSize;
  	//search all EFI variables
  	Status = gRT->GetNextVariableName (&NewNameSize, Name, &VarGuid);
  	  if (Status == EFI_BUFFER_TOO_SMALL) {
      Name = ReallocatePool (NameSize, NewNameSize, Name);
      Status = gRT->GetNextVariableName (&NewNameSize, Name, &VarGuid);
      NameSize = NewNameSize;
    }
    //
    if (Status == EFI_NOT_FOUND) {
      break;
    }
    //skip if not Global variable
    if (!CompareGuid(&VarGuid, &gEfiGlobalVariableGuid))
    	continue;
    //check BOOT#### variable
    if(!StrnCmp(Name, L"Boot", 4) &&
    	IsCharDigit(Name[4]) && IsCharDigit(Name[5]) &&
    	IsCharDigit(Name[6]) && IsCharDigit(Name[7]))
    {
    	Print(L"%s:", Name);
        //get BOOT####
        BootVariable = mGetVariable(Name, &gEfiGlobalVariableGuid, &BootVariableSize, NULL);
        //print attribute
        LDAttr = BootVariable[0];
        if (opts.show_verbose){
        	i = 6;   //for adjust display
          if (LDAttr == 0)
        	Print(L"CB*", i--);     //category boot
          if (LDAttr & 1)
           	Print(L"A* ", i--);      //active
          if (LDAttr & 2)
           	Print(L"FR*", i--);     //force reconnect
          if (LDAttr & 8)
           	Print(L"H* ", i--);      //hidden
          if (LDAttr & 0x100)
           	Print(L"CA*", i--);     //category app
           //Print(L"\n");
           while (i--){
           	Print(L"   ");
           }
        }
        //print EFI_LOAD_OPTION description
        Print(L" %s",(CHAR16 *)(BootVariable+3));
        Print(L"\n");
        
    }
  }

  return Status;
}