Пример #1
0
/**
  Get section entry value.

  @param[in]  Section         Section entry list.
  @param[in]  SectionName     Section name.
  @param[in]  EntryName       Section entry name.
  @param[out] EntryValue      Point to the got entry value.

  @retval EFI_NOT_FOUND  Section is not found.
  @retval EFI_SUCCESS    Section entry value is got.

**/
EFI_STATUS
UpdateGetProfileString (
  IN      SECTION_ITEM                  *Section,
  IN      CHAR8                         *SectionName,
  IN      CHAR8                         *EntryName,
  OUT     CHAR8                         **EntryValue
  )
{
  *EntryValue   = NULL;

  while (Section != NULL) {
    if (AsciiStrCmp ((CONST CHAR8 *) Section->PtrSection, (CONST CHAR8 *) SectionName) == 0) {
      if (Section->PtrEntry != NULL) {
        if (AsciiStrCmp ((CONST CHAR8 *) Section->PtrEntry, (CONST CHAR8 *) EntryName) == 0) {
          break;
        }
      }
    }
    Section     = Section->PtrNext;
  }

  if (Section == NULL) {
    return EFI_NOT_FOUND;
  }

  *EntryValue   = Section->PtrValue;

  return EFI_SUCCESS;
}
Пример #2
0
INTN find_entry(CONST CHAR8 *propName, CONST CHAR8 *propValue, DTEntry *entryH)
{
	DeviceTreeNode *nodeP = (DeviceTreeNode *) (VOID *) startingP;
	UINTN k;

	if (nodeP->nProperties == 0) return(kError);	// End of the list of nodes
	startingP = (CHAR8 *) (nodeP + 1);

	// Search current entry
	for (k = 0; k < nodeP->nProperties; ++k) {
		DeviceTreeNodeProperty *propP = (DeviceTreeNodeProperty *) (VOID *) startingP;

		startingP += sizeof (*propP) + ((propP->length + 3) & -4);

		if (AsciiStrCmp ((CHAR8*)propP->name, (CHAR8*)propName) == 0) {
			if (propValue == NULL || AsciiStrCmp( (CHAR8*)(propP + 1), (CHAR8*)propValue) == 0)
			{
				*entryH = (DTEntry)nodeP;
				return(kSuccess);
			}
		}
	}

	// Search child nodes
	for (k = 0; k < nodeP->nChildren; ++k)
	{
		if (find_entry(propName, propValue, entryH) == kSuccess)
			return(kSuccess);
	}
	return(kError);
}
Пример #3
0
VOID Ext2DebugListTree (IN EXT2_DEV *Private, EXT2_EFI_FILE_PRIVATE *PrivateFile) {

    EXT2_EFI_FILE_PRIVATE *pFile;
    struct vop_readdir_args ap;
    int a_eofflag;
    off_t *a_cookies;
    ap.a_vp = PrivateFile;
    struct dirent *dir;
    void *c;
    struct uio uio;
    struct iovec uio_iov;
    int error;
    int ino = PrivateFile->File->i_number;
    //CHAR16 Name[255];

    uio_iov.iov_base = AllocateZeroPool (2048);
    c = uio_iov.iov_base;
    uio_iov.iov_len = 2048;
    uio.uio_iov = &uio_iov;
    uio.uio_offset = 0;
    uio.uio_resid = 2048;
    uio.uio_rw = UIO_READ;
    ap.a_uio = &uio;
    ap.a_eofflag = &a_eofflag;
    ap.a_cookies = &a_cookies;
    ap.a_cred = 0;
    
    error = ext2fs_readdir(&ap);
    dir = (struct dirent *) c;

    DEBUG ((EFI_D_INFO, "\n *** In folder %s ***\n", PrivateFile->Filename));
    while (dir->d_fileno != 0) {
    
	Ext2DebugDirent(dir);
	//AsciiStrToUnicodeStr(dir->d_name, Name);
	if ((dir->d_fileno != ino) && (AsciiStrCmp(dir->d_name,".") != 0) 
	    && (AsciiStrCmp(dir->d_name,"..") != 0)) {
	  error = ext2fs_vget(Private, dir->d_fileno, &pFile);
	//  pFile->Filename = AllocateZeroPool ((1+AsciiStrLen(dir->d_name))*sizeof(CHAR16));
	//  StrCpy(pFile->Filename, Name);
	  if (pFile->v_type == VREG) {
	      Ext2DebugPrintContent(pFile);
	  } else {
	      Ext2DebugListTree(Private,pFile);
	  }
	//  FreePool(pFile->Filename);
	  FreePool(pFile);
	}
	dir = (struct dirent *) ((char *)dir + dir->d_reclen);
    }
}
Пример #4
0
RealDTEntry
FindChild(RealDTEntry cur, CHAR8 *buf)
{
	RealDTEntry	child;
	UINT32      index;
	CHAR8*			str;
	UINT32      dummy;

	if (cur->nChildren == 0) {
		return NULL;
	}
	index = 1;
	child = GetFirstChild(cur);
	while (1) {
		if (DTGetProperty(child, "name", (VOID **)&str, &dummy) != kSuccess) {
			break;
		}
		if (AsciiStrCmp((CHAR8*)str, (CHAR8*)buf) == 0) {
			return child;
		}
		if (index >= cur->nChildren) {
			break;
		}
		child = GetNextChild(child);
		index++;
	}
	return NULL;
}
Пример #5
0
/**
  Search for a file given its name coded in Ascii.

  When searching through the files of the volume, if a file is currently not
  open, its name was written on the media and is kept in RAM in the
  "HwDescription.Footer.Filename[]" field of the file's description.

  If a file is currently open, its name might not have been written on the
  media yet, and as the "HwDescription" is a mirror in RAM of what is on the
  media the "HwDescription.Footer.Filename[]" might be outdated. In that case,
  the up to date name of the file is stored in the "Info" field of the file's
  description.

  @param[in]   Instance       Pointer to the description of the volume in which
                              the file has to be search for.
  @param[in]   AsciiFileName  Name of the file.

  @param[out]  File           Pointer to the description of the file if the
                              file was found.

  @retval  EFI_SUCCESS    The file was found.
  @retval  EFI_NOT_FOUND  The file was not found.

**/
EFI_STATUS
BootMonGetFileFromAsciiFileName (
  IN  BOOTMON_FS_INSTANCE   *Instance,
  IN  CHAR8*                AsciiFileName,
  OUT BOOTMON_FS_FILE       **File
  )
{
  LIST_ENTRY       *Entry;
  BOOTMON_FS_FILE  *FileEntry;
  CHAR8            OpenFileAsciiFileName[MAX_NAME_LENGTH];
  CHAR8            *AsciiFileNameToCompare;

  // Go through all the files in the list and return the file handle
  for (Entry = GetFirstNode (&Instance->RootFile->Link);
       !IsNull (&Instance->RootFile->Link, Entry);
       Entry = GetNextNode (&Instance->RootFile->Link, Entry)
       )
  {
    FileEntry = BOOTMON_FS_FILE_FROM_LINK_THIS (Entry);
    if (FileEntry->Info != NULL) {
      UnicodeStrToAsciiStr (FileEntry->Info->FileName, OpenFileAsciiFileName);
      AsciiFileNameToCompare = OpenFileAsciiFileName;
    } else {
      AsciiFileNameToCompare = FileEntry->HwDescription.Footer.Filename;
    }

    if (AsciiStrCmp (AsciiFileNameToCompare, AsciiFileName) == 0) {
      *File = FileEntry;
      return EFI_SUCCESS;
    }
  }
  return EFI_NOT_FOUND;
}
Пример #6
0
EFI_STATUS FixDataMatchingTag( CHAR8* buffer, CHAR8* tag,UINT32* lenPtr)
{
	EFI_STATUS	Status;
	UINT32		length;
	UINT32		start;
	UINT32		stop;
	CHAR8*		endTag;

	start = 0;
	while (1)
	{
		Status = GetNextTag(((UINT8 *)buffer) + start, &endTag, &stop,&length);
		if (EFI_ERROR(Status)) 
			return Status;

		if ((*endTag == '/') && !AsciiStrCmp(endTag + 1, tag)) 
			break;
		start += length;
	}

	buffer[start + stop] = '\0';
	*lenPtr=start + length;

	return EFI_SUCCESS;
}
Пример #7
0
STATIC
EFI_STATUS
SetFileName (
  IN  BOOTMON_FS_FILE *File,
  IN  CHAR16          *FileNameUnicode
  )
{
  CHAR8                 *FileNameAscii;
  UINT16                 SavedChar;
  UINTN                  FileNameSize;
  BOOTMON_FS_FILE       *SameFile;
  EFI_STATUS             Status;

  // EFI Shell inserts '\' in front of the filename that must be stripped
  if (FileNameUnicode[0] == L'\\') {
    FileNameUnicode++;
  }
  //
  // Convert Unicode into Ascii
  //
  SavedChar = L'\0';
  FileNameSize = StrLen (FileNameUnicode) + 1;
  FileNameAscii = AllocatePool (FileNameSize * sizeof (CHAR8));
  if (FileNameAscii == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  // If Unicode string is too long then truncate it.
  if (FileNameSize > MAX_NAME_LENGTH) {
    SavedChar = FileNameUnicode[MAX_NAME_LENGTH - 1];
    FileNameUnicode[MAX_NAME_LENGTH - 1] = L'\0';
  }
  UnicodeStrToAsciiStr (FileNameUnicode, FileNameAscii);
  // If the unicode string was truncated then restore its original content.
  if (SavedChar != L'\0') {
    FileNameUnicode[MAX_NAME_LENGTH - 1] = SavedChar;
  }

  // If we're changing the file name
  if (AsciiStrCmp (FileNameAscii, File->HwDescription.Footer.Filename) == 0) {
    // No change to filename.
    Status = EFI_SUCCESS;
  } else if (!(File->OpenMode & EFI_FILE_MODE_WRITE)) {
    // You can only change the filename if you open the file for write.
    Status = EFI_ACCESS_DENIED;
  } else if (BootMonGetFileFromAsciiFileName (
                File->Instance,
                File->HwDescription.Footer.Filename,
                &SameFile) != EFI_NOT_FOUND) {
    // A file with that name already exists.
    Status = EFI_ACCESS_DENIED;
  } else {
    // OK, change the filename.
    AsciiStrCpy (FileNameAscii, File->HwDescription.Footer.Filename);
    Status = EFI_SUCCESS;
  }

  FreePool (FileNameAscii);
  return Status;
}
Пример #8
0
EFI_STATUS
ArmFastbootPlatformGetVar (
  IN  CHAR8   *Name,
  OUT CHAR8   *Value
  )
{
  if (AsciiStrCmp (Name, "product")) {
    AsciiStrCpy (Value, FixedPcdGetPtr (PcdFirmwareVendor));
  } else {
    *Value = '\0';
  }
  return EFI_SUCCESS;
}
Пример #9
0
BOOLEAN
SettingBoolGet (
  CONST CHAR8* Name
)
{
  CHAR8* Value = UtilGetEFIDroidVariable(Name);
  if (!Value)
    return FALSE;

  BOOLEAN Ret = (!AsciiStrCmp(Value, "1"));
  FreePool(Value);
  return Ret;
}
Пример #10
0
/**
  Compare a standalone key against a user structure containing an embedded key.

  @param[in] StandaloneKey  Pointer to the bare key.

  @param[in] UserStruct     Pointer to the user structure with the embedded
                            key.

  @retval <0  If StandaloneKey compares less than UserStruct's key.

  @retval  0  If StandaloneKey compares equal to UserStruct's key.

  @retval >0  If StandaloneKey compares greater than UserStruct's key.
**/
STATIC
INTN
EFIAPI
BlobKeyCompare (
  IN CONST VOID *StandaloneKey,
  IN CONST VOID *UserStruct
  )
{
  CONST BLOB *Blob;

  Blob = UserStruct;
  return AsciiStrCmp (StandaloneKey, (CONST CHAR8 *)Blob->File);
}
Пример #11
0
MACHINE_TYPES
GetModelFromString (
  CHAR8 *ProductName
  )
{
  UINTN i;
  
  for (i = 0; i < MaxMachineType; ++i) {
    if (AsciiStrCmp (AppleProductName[i], ProductName) == 0) {
      return i;
    }
  }
  // return ending enum as "not found"
  return MaxMachineType;
}
Пример #12
0
/**
Check whether the Token is a known one which is uesed by core.

@param  Token      Pointer to a Null-terminated ASCII string

@retval TRUE       Is a known one used by core.
@retval FALSE      Not a known one.

**/
BOOLEAN
IsKnownTokens (
  IN CONST CHAR8  *Token
  )
{
  if (Token == NULL) {
    return FALSE;
  }

  if (AsciiStrCmp (Token, SEC_TOK) == 0 ||
      AsciiStrCmp (Token, PEI_TOK) == 0 ||
      AsciiStrCmp (Token, DXE_TOK) == 0 ||
      AsciiStrCmp (Token, BDS_TOK) == 0 ||
      AsciiStrCmp (Token, DRIVERBINDING_START_TOK) == 0 ||
      AsciiStrCmp (Token, DRIVERBINDING_SUPPORT_TOK) == 0 ||
      AsciiStrCmp (Token, DRIVERBINDING_STOP_TOK) == 0 ||
      AsciiStrCmp (Token, LOAD_IMAGE_TOK) == 0 ||
      AsciiStrCmp (Token, START_IMAGE_TOK) == 0 ||
      AsciiStrCmp (Token, PEIM_TOK) == 0) {
    return TRUE;
  } else {
    return FALSE;
  }
}
Пример #13
0
/**
  Check whether header field called FieldName is in DeleteList.

  @param[in]  DeleteList        Pointer to array of key/value header pairs.
  @param[in]  DeleteCount       The number of header pairs.
  @param[in]  FieldName         Pointer to header field's name.

  @return     TRUE if FieldName is not in DeleteList, that means this header field is valid.
  @return     FALSE if FieldName is in DeleteList, that means this header field is invalid.

**/
BOOLEAN
IsValidHttpHeader (
  IN  CHAR8            *DeleteList[],
  IN  UINTN            DeleteCount,
  IN  CHAR8            *FieldName
  )
{
  UINTN                       Index;

  for (Index = 0; Index < DeleteCount; Index++) {
    if (AsciiStrCmp (FieldName, DeleteList[Index]) == 0) {
      return FALSE;
    }
  }
  
  return TRUE;
}
Пример #14
0
SymbolPtr FindSymbol( char * string, SymbolPtr * prevSymbol )
{
	SymbolPtr symbol, prev;

	symbol = gSymbolsHead;
	prev = 0;

	while (symbol != 0) {
		if (!AsciiStrCmp(symbol->string, string)) break;

		prev = symbol;
		symbol = symbol->next;
	}

	if ((symbol != 0) && (prevSymbol != 0)) *prevSymbol = prev;

	return symbol;
}
Пример #15
0
/**
  Find required header field in HeaderFields.

  @param[in]  HeaderFields        Pointer to array of key/value header pairs.
  @param[in]  FieldCount          The number of header pairs.
  @param[in]  FieldName           Pointer to header field's name.

  @return     Pointer to the queried header field.
  @return     NULL if not find this required header field.

**/
EFI_HTTP_HEADER *
FindHttpHeader (
  IN  EFI_HTTP_HEADER  *HeaderFields,
  IN  UINTN            FieldCount,
  IN  CHAR8            *FieldName
  )
{
  UINTN                       Index;

  for (Index = 0; Index < FieldCount; Index++) {
    if (AsciiStrCmp (FieldName, HeaderFields[Index].FieldName) == 0) {
      //
      // Find the required header field.
      //
      return &HeaderFields[Index];
    }
  }
  return NULL;
}
Пример #16
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;
  }
}
Пример #17
0
INTN
DTGetProperty(CONST DTEntry entry, CONST CHAR8 *propertyName, VOID **propertyValue, UINT32 *propertySize)
{
	DeviceTreeNodeProperty *prop;
	UINTN k;

	if (entry == NULL || entry->nProperties == 0) {
		return kError;
	} else {
		prop = (DeviceTreeNodeProperty *) (entry + 1);
		for (k = 0; k < entry->nProperties; k++) {
			if (AsciiStrCmp((CHAR8*)prop->name, (CHAR8*)propertyName) == 0) {
				*propertyValue = (VOID *) (((UINT8*)prop)
						+ sizeof(DeviceTreeNodeProperty));
				*propertySize = prop->length;
				return kSuccess;
			}
			prop = next_prop(prop);
		}
	}
	return kError;
}
Пример #18
0
TagPtr GetProperty( TagPtr dict, const CHAR8* key )
{
	TagPtr tagList, tag;

	if (dict->type != kTagTypeDict) 
		return NULL;

	tag = 0;
	tagList = dict->tag;
	while (tagList)
	{
		tag = tagList;
		tagList = tag->tagNext;

		if ((tag->type != kTagTypeKey) || (tag->string == 0)) 
			continue;

		if (!AsciiStrCmp(tag->string, key)) 
			return tag->tag;
	}

	return NULL;
}
/**
  Used to translate a device path node to a Target ID and LUN.

  @param[in]  This       A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
  @param[in]  DevicePath A pointer to a single device path node that describes the SCSI device
                         on the SCSI channel.
  @param[out] Target     A pointer to the Target Array which represents the ID of a SCSI device
                         on the SCSI channel.
  @param[out]  Lun       A pointer to the LUN of a SCSI device on the SCSI channel.

  @retval EFI_SUCCESS           DevicePath was successfully translated to a Target ID and
                                LUN, and they were returned in Target and Lun.
  @retval EFI_INVALID_PARAMETER DevicePath or Target or Lun is NULL.
  @retval EFI_NOT_FOUND         A valid translation from DevicePath to a Target ID and LUN
                                does not exist.Currently not implemented.
  @retval EFI_UNSUPPORTED       This driver does not support the device path node type in
                                DevicePath.
**/
EFI_STATUS
EFIAPI
IScsiExtScsiPassThruGetTargetLun (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN EFI_DEVICE_PATH_PROTOCOL         *DevicePath,
  OUT UINT8                           **Target,
  OUT UINT64                          *Lun
  )
{
  ISCSI_DRIVER_DATA           *Private;
  ISCSI_SESSION_CONFIG_NVDATA *ConfigNvData;

  if ((DevicePath == NULL) || (Target == NULL) || (Lun == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
      (DevicePath->SubType != MSG_ISCSI_DP) ||
      (DevicePathNodeLength (DevicePath) <= sizeof (ISCSI_DEVICE_PATH))
      ) {
    return EFI_UNSUPPORTED;
  }

  Private       = ISCSI_DRIVER_DATA_FROM_EXT_SCSI_PASS_THRU (This);
  ConfigNvData  = &Private->Session.ConfigData.NvData;

  SetMem (*Target, TARGET_MAX_BYTES, 0xFF);
  (*Target)[0] = 0;

  if (AsciiStrCmp (ConfigNvData->TargetName, (CHAR8 *) DevicePath + sizeof (ISCSI_DEVICE_PATH)) != 0) {
    return EFI_UNSUPPORTED;
  }

  CopyMem (Lun, ConfigNvData->BootLun, sizeof (UINT64));

  return EFI_SUCCESS;
}
Пример #20
0
/**
  Find the matching SPD with Indexer.

  @param[in] Selector    The pointer to the EFI_IPSEC_SPD_SELECTOR structure.
  @param[in] Data        The pointer to the EFI_IPSEC_SPD_DATA structure.
  @param[in] Indexer     The pointer to the SPD_ENTRY_INDEXER structure.

  @retval TRUE     The matched SPD is found.
  @retval FALSE    The matched SPD is not found.
**/
BOOLEAN
MatchSpdEntry (
  IN EFI_IPSEC_SPD_SELECTOR    *Selector,
  IN EFI_IPSEC_SPD_DATA        *Data,
  IN SPD_ENTRY_INDEXER         *Indexer
  )
{
  BOOLEAN    Match;

  Match = FALSE;
  if (Indexer->Name != NULL) {
    if ((Data->Name != NULL) && (AsciiStrCmp ((CHAR8 *) Indexer->Name, (CHAR8 *) Data->Name) == 0)) {
      Match = TRUE;
    }
  } else {
    if (Indexer->Index == 0) {
      Match = TRUE;
    }

    Indexer->Index--;
  }

  return Match;
}
Пример #21
0
/**
  Patch version string of Physical Presence interface supported by platform. The initial string tag in TPM 
ACPI table is "$PV".

  @param[in, out] Table          The TPM item in ACPI table.
  @param[in]      PPVer          Version string of Physical Presence interface supported by platform.

  @return                        The allocated address for the found region.

**/
EFI_STATUS
UpdatePPVersion (
  EFI_ACPI_DESCRIPTION_HEADER    *Table,
  CHAR8                          *PPVer
  )
{
  EFI_STATUS  Status;
  UINT8       *DataPtr;

  //
  // Patch some pointers for the ASL code before loading the SSDT.
  //
  for (DataPtr  = (UINT8 *)(Table + 1);
       DataPtr <= (UINT8 *) ((UINT8 *) Table + Table->Length - PHYSICAL_PRESENCE_VERSION_SIZE);
       DataPtr += 1) {
    if (AsciiStrCmp((CHAR8 *)DataPtr,  PHYSICAL_PRESENCE_VERSION_TAG) == 0) {
      Status = AsciiStrCpyS((CHAR8 *)DataPtr, PHYSICAL_PRESENCE_VERSION_SIZE, PPVer);
      DEBUG((EFI_D_INFO, "TPM2 Physical Presence Interface Version update status 0x%x\n", Status));
      return Status;
    }
  }

  return EFI_NOT_FOUND;
}
Пример #22
0
STATIC
UINT64
SerialPortGetBaseAddress (
  VOID
  )
{
  UINT64              BaudRate;
  UINT32              ReceiveFifoDepth;
  EFI_PARITY_TYPE     Parity;
  UINT8               DataBits;
  EFI_STOP_BITS_TYPE  StopBits;
  VOID                *DeviceTreeBase;
  INT32               Node, Prev;
  INT32               Len;
  CONST CHAR8         *Compatible;
  CONST CHAR8         *NodeStatus;
  CONST CHAR8         *CompatibleItem;
  CONST UINT64        *RegProperty;
  UINTN               UartBase;
  RETURN_STATUS       Status;

  DeviceTreeBase = (VOID *)(UINTN)PcdGet64 (PcdDeviceTreeInitialBaseAddress);

  if ((DeviceTreeBase == NULL) || (fdt_check_header (DeviceTreeBase) != 0)) {
    return 0;
  }

  //
  // Enumerate all FDT nodes looking for a PL011 and capture its base address
  //
  for (Prev = 0;; Prev = Node) {
    Node = fdt_next_node (DeviceTreeBase, Prev, NULL);
    if (Node < 0) {
      break;
    }

    Compatible = fdt_getprop (DeviceTreeBase, Node, "compatible", &Len);
    if (Compatible == NULL) {
      continue;
    }

    //
    // Iterate over the NULL-separated items in the compatible string
    //
    for (CompatibleItem = Compatible; CompatibleItem < Compatible + Len;
      CompatibleItem += 1 + AsciiStrLen (CompatibleItem)) {

      if (AsciiStrCmp (CompatibleItem, "arm,pl011") == 0) {
        NodeStatus = fdt_getprop (DeviceTreeBase, Node, "status", &Len);
        if (NodeStatus != NULL && AsciiStrCmp (NodeStatus, "okay") != 0) {
          continue;
        }

        RegProperty = fdt_getprop (DeviceTreeBase, Node, "reg", &Len);
        if (Len != 16) {
          return 0;
        }
        UartBase = (UINTN)fdt64_to_cpu (ReadUnaligned64 (RegProperty));

        BaudRate = (UINTN)FixedPcdGet64 (PcdUartDefaultBaudRate);
        ReceiveFifoDepth = 0; // Use the default value for Fifo depth
        Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
        DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
        StopBits = (EFI_STOP_BITS_TYPE) FixedPcdGet8 (PcdUartDefaultStopBits);

        Status = PL011UartInitializePort (
                   UartBase,
                   FixedPcdGet32 (PL011UartClkInHz),
                   &BaudRate,
                   &ReceiveFifoDepth,
                   &Parity,
                   &DataBits,
                   &StopBits
                   );
        if (!EFI_ERROR (Status)) {
          return UartBase;
        }
      }
    }
  }
  return 0;
}
Пример #23
0
int strcmp (const char *s1, const char *s2)
{
  return (int)AsciiStrCmp(s1, s2);
}
Пример #24
0
/**

  Translate an OpenFirmware device path fragment to a UEFI device path
  fragment, and advance in the input string.

  @param[in out] Ptr             Address of the pointer pointing to the start
                                 of the path string. After successful
                                 translation (RETURN_SUCCESS) or at least
                                 successful parsing (RETURN_UNSUPPORTED,
                                 RETURN_BUFFER_TOO_SMALL), *Ptr is set to the
                                 byte immediately following the consumed
                                 characters. In other error cases, it points to
                                 the byte that caused the error.

  @param[out]    Translated      Destination array receiving the UEFI path
                                 fragment, allocated by the caller. If the
                                 return value differs from RETURN_SUCCESS, its
                                 contents is indeterminate.

  @param[in out] TranslatedSize  On input, the number of CHAR16's in
                                 Translated. On RETURN_SUCCESS this parameter
                                 is assigned the number of non-NUL CHAR16's
                                 written to Translated. In case of other return
                                 values, TranslatedSize is indeterminate.


  @retval RETURN_SUCCESS            Translation successful.

  @retval RETURN_BUFFER_TOO_SMALL   The OpenFirmware device path was parsed
                                    successfully, but its translation did not
                                    fit into the number of bytes provided.
                                    Further calls to this function are
                                    possible.

  @retval RETURN_UNSUPPORTED        The OpenFirmware device path was parsed
                                    successfully, but it can't be translated in
                                    the current implementation. Further calls
                                    to this function are possible.

  @retval RETURN_NOT_FOUND          Translation terminated. On input, *Ptr was
                                    pointing to the empty string or "HALT". On
                                    output, *Ptr points to the empty string
                                    (ie. "HALT" is consumed transparently when
                                    present).

  @retval RETURN_INVALID_PARAMETER  Parse error. This is a permanent error.

**/
STATIC
RETURN_STATUS
TranslateOfwPath (
  IN OUT  CONST CHAR8 **Ptr,
  OUT     CHAR16      *Translated,
  IN OUT  UINTN       *TranslatedSize
  )
{
  UINTN         NumNodes;
  RETURN_STATUS Status;
  OFW_NODE      Node[EXAMINED_OFW_NODES];
  BOOLEAN       IsFinal;
  OFW_NODE      Skip;

  IsFinal = FALSE;
  NumNodes = 0;
  if (AsciiStrCmp (*Ptr, "HALT") == 0) {
    *Ptr += 4;
    Status = RETURN_NOT_FOUND;
  } else {
    Status = ParseOfwNode (Ptr, &Node[NumNodes], &IsFinal);
  }

  if (Status == RETURN_NOT_FOUND) {
    DEBUG ((DEBUG_VERBOSE, "%a: no more nodes\n", __FUNCTION__));
    return RETURN_NOT_FOUND;
  }

  while (Status == RETURN_SUCCESS && !IsFinal) {
    ++NumNodes;
    Status = ParseOfwNode (
               Ptr,
               (NumNodes < EXAMINED_OFW_NODES) ? &Node[NumNodes] : &Skip,
               &IsFinal
               );
  }

  switch (Status) {
  case RETURN_SUCCESS:
    ++NumNodes;
    break;

  case RETURN_INVALID_PARAMETER:
    DEBUG ((DEBUG_VERBOSE, "%a: parse error\n", __FUNCTION__));
    return RETURN_INVALID_PARAMETER;

  default:
    ASSERT (0);
  }

  Status = TranslateOfwNodes (
             Node,
             NumNodes < EXAMINED_OFW_NODES ? NumNodes : EXAMINED_OFW_NODES,
             Translated,
             TranslatedSize);
  switch (Status) {
  case RETURN_SUCCESS:
    DEBUG ((DEBUG_VERBOSE, "%a: success: \"%s\"\n", __FUNCTION__, Translated));
    break;

  case RETURN_BUFFER_TOO_SMALL:
    DEBUG ((DEBUG_VERBOSE, "%a: buffer too small\n", __FUNCTION__));
    break;

  case RETURN_UNSUPPORTED:
    DEBUG ((DEBUG_VERBOSE, "%a: unsupported\n", __FUNCTION__));
    break;

  default:
    ASSERT (0);
  }
  return Status;
}
Пример #25
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;
}
Пример #26
0
/**
  Enable the use of UEFI HTTP boot function.

  If the driver has already been started but not satisfy the requirement (IP stack and 
  specified boot file path), this function will stop the driver and start it again.

  @param[in]    Private            The pointer to the driver's private data.
  @param[in]    UsingIpv6          Specifies the type of IP addresses that are to be
                                   used during the session that is being started.
                                   Set to TRUE for IPv6, and FALSE for IPv4.
  @param[in]    FilePath           The device specific path of the file to load.

  @retval EFI_SUCCESS              HTTP boot was successfully enabled.
  @retval EFI_INVALID_PARAMETER    Private is NULL or FilePath is NULL.
  @retval EFI_INVALID_PARAMETER    The FilePath doesn't contain a valid URI device path node.
  @retval EFI_ALREADY_STARTED      The driver is already in started state.
  @retval EFI_OUT_OF_RESOURCES     There are not enough resources.
  
**/
EFI_STATUS
HttpBootStart (
  IN HTTP_BOOT_PRIVATE_DATA           *Private,
  IN BOOLEAN                          UsingIpv6,
  IN EFI_DEVICE_PATH_PROTOCOL         *FilePath
  )
{
  UINTN                Index;
  EFI_STATUS           Status;
  CHAR8                *Uri;
  

  if (Private == NULL || FilePath == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  
  //
  // Check the URI in the input FilePath, in order to see whether it is
  // required to boot from a new specified boot file. 
  //
  Status = HttpBootParseFilePath (FilePath, &Uri);
  if (EFI_ERROR (Status)) {
    return EFI_INVALID_PARAMETER;
  }
  
  //
  // Check whether we need to stop and restart the HTTP boot driver.
  //
  if (Private->Started) {
    //
    // Restart is needed in 2 cases:
    // 1. Http boot driver has already been started but not on the required IP stack.
    // 2. The specified boot file URI in FilePath is different with the one we have
    // recorded before.
    //
    if ((UsingIpv6 != Private->UsingIpv6) || 
        ((Uri != NULL) && (AsciiStrCmp (Private->BootFileUri, Uri) != 0))) {
      //
      // Restart is required, first stop then continue this start function.
      //
      Status = HttpBootStop (Private);
      if (EFI_ERROR (Status)) {
        return Status;
      }
    } else {
      //
      // Restart is not required.
      //
      if (Uri != NULL) {
        FreePool (Uri);
      }
      return EFI_ALREADY_STARTED;
    }
  }

  //
  // Detect whether using ipv6 or not, and set it to the private data.
  //
  if (UsingIpv6 && Private->Ip6Nic != NULL) {
    Private->UsingIpv6 = TRUE;
  } else if (!UsingIpv6 && Private->Ip4Nic != NULL) {
    Private->UsingIpv6 = FALSE;
  } else {
    if (Uri != NULL) {
      FreePool (Uri);
    }
    return EFI_UNSUPPORTED;
  }

  //
  // Record the specified URI and prepare the URI parser if needed.
  //
  Private->FilePathUri = Uri;
  if (Private->FilePathUri != NULL) {
    Status = HttpParseUrl (
               Private->FilePathUri,
               (UINT32) AsciiStrLen (Private->FilePathUri),
               FALSE,
               &Private->FilePathUriParser
               );
    if (EFI_ERROR (Status)) {
      FreePool (Private->FilePathUri);
      return Status;
    }
  }
  
  //
  // Init the content of cached DHCP offer list.
  //
  ZeroMem (Private->OfferBuffer, sizeof (Private->OfferBuffer));
  if (!Private->UsingIpv6) {
    for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) {
      Private->OfferBuffer[Index].Dhcp4.Packet.Offer.Size = HTTP_BOOT_DHCP4_PACKET_MAX_SIZE;
    }
  } else {
    for (Index = 0; Index < HTTP_BOOT_OFFER_MAX_NUM; Index++) {
      Private->OfferBuffer[Index].Dhcp6.Packet.Offer.Size = HTTP_BOOT_DHCP6_PACKET_MAX_SIZE;
    }
  }

  if (Private->UsingIpv6) {
    //
    // Set Ip6 policy to Automatic to start the Ip6 router discovery.
    //
    Status = HttpBootSetIp6Policy (Private);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }
  Private->Started   = TRUE;

  return EFI_SUCCESS;
}
Пример #27
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;
  
}
Пример #28
0
int OnigStrCmp (char* Str1, char* Str2)
{
  return (int)AsciiStrCmp (Str1, Str2);
}
Пример #29
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;
}
Пример #30
0
/**
  This function checks the received iSCSI Login Response during the security
  negotiation stage.

  @param[in] Conn             The iSCSI connection.

  @retval EFI_SUCCESS          The Login Response passed the CHAP validation.
  @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
  @retval EFI_PROTOCOL_ERROR   Some kind of protocol error occurred.
  @retval Others               Other errors as indicated.

**/
EFI_STATUS
IScsiCHAPOnRspReceived (
  IN ISCSI_CONNECTION  *Conn
  )
{
  EFI_STATUS                  Status;
  ISCSI_SESSION               *Session;
  ISCSI_CHAP_AUTH_DATA        *AuthData;
  CHAR8                       *Value;
  UINT8                       *Data;
  UINT32                      Len;
  LIST_ENTRY                  *KeyValueList;
  UINTN                       Algorithm;
  CHAR8                       *Identifier;
  CHAR8                       *Challenge;
  CHAR8                       *Name;
  CHAR8                       *Response;
  UINT8                       TargetRsp[ISCSI_CHAP_RSP_LEN];
  UINT32                      RspLen;
  UINTN                       Result;

  ASSERT (Conn->CurrentStage == ISCSI_SECURITY_NEGOTIATION);
  ASSERT (Conn->RspQue.BufNum != 0);

  Session     = Conn->Session;
  AuthData    = &Session->AuthData.CHAP;
  Len         = Conn->RspQue.BufSize;
  Data        = AllocateZeroPool (Len);
  if (Data == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // Copy the data in case the data spans over multiple PDUs.
  //
  NetbufQueCopy (&Conn->RspQue, 0, Len, Data);

  //
  // Build the key-value list from the data segment of the Login Response.
  //
  KeyValueList = IScsiBuildKeyValueList ((CHAR8 *) Data, Len);
  if (KeyValueList == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ON_EXIT;
  }

  Status = EFI_PROTOCOL_ERROR;

  switch (Conn->AuthStep) {
  case ISCSI_AUTH_INITIAL:
    //
    // The first Login Response.
    //
    Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_TARGET_PORTAL_GROUP_TAG);
    if (Value == NULL) {
      goto ON_EXIT;
    }

    Result = IScsiNetNtoi (Value);
    if (Result > 0xFFFF) {
      goto ON_EXIT;
    }

    Session->TargetPortalGroupTag = (UINT16) Result;

    Value                         = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_AUTH_METHOD);
    if (Value == NULL) {
      goto ON_EXIT;
    }
    //
    // Initiator mandates CHAP authentication but target replies without "CHAP", or
    // initiator suggets "None" but target replies with some kind of auth method.
    //
    if (Session->AuthType == ISCSI_AUTH_TYPE_NONE) {
      if (AsciiStrCmp (Value, ISCSI_KEY_VALUE_NONE) != 0) {
        goto ON_EXIT;
      }
    } else if (Session->AuthType == ISCSI_AUTH_TYPE_CHAP) {
      if (AsciiStrCmp (Value, ISCSI_AUTH_METHOD_CHAP) != 0) {
        goto ON_EXIT;
      }
    } else {
      goto ON_EXIT;
    }

    //
    // Transit to CHAP step one.
    //
    Conn->AuthStep  = ISCSI_CHAP_STEP_ONE;
    Status          = EFI_SUCCESS;
    break;

  case ISCSI_CHAP_STEP_TWO:
    //
    // The Target replies with CHAP_A=<A> CHAP_I=<I> CHAP_C=<C>
    //
    Value = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_ALGORITHM);
    if (Value == NULL) {
      goto ON_EXIT;
    }

    Algorithm = IScsiNetNtoi (Value);
    if (Algorithm != ISCSI_CHAP_ALGORITHM_MD5) {
      //
      // Unsupported algorithm is chosen by target.
      //
      goto ON_EXIT;
    }

    Identifier = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_IDENTIFIER);
    if (Identifier == NULL) {
      goto ON_EXIT;
    }

    Challenge = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_CHALLENGE);
    if (Challenge == NULL) {
      goto ON_EXIT;
    }
    //
    // Process the CHAP identifier and CHAP Challenge from Target.
    // Calculate Response value.
    //
    Result = IScsiNetNtoi (Identifier);
    if (Result > 0xFF) {
      goto ON_EXIT;
    }

    AuthData->InIdentifier      = (UINT32) Result;
    AuthData->InChallengeLength = ISCSI_CHAP_AUTH_MAX_LEN;
    IScsiHexToBin ((UINT8 *) AuthData->InChallenge, &AuthData->InChallengeLength, Challenge);
    Status = IScsiCHAPCalculateResponse (
               AuthData->InIdentifier,
               AuthData->AuthConfig->CHAPSecret,
               (UINT32) AsciiStrLen (AuthData->AuthConfig->CHAPSecret),
               AuthData->InChallenge,
               AuthData->InChallengeLength,
               AuthData->CHAPResponse
               );

    //
    // Transit to next step.
    //
    Conn->AuthStep = ISCSI_CHAP_STEP_THREE;
    break;

  case ISCSI_CHAP_STEP_THREE:
    //
    // One way CHAP authentication and the target would like to
    // authenticate us.
    //
    Status = EFI_SUCCESS;
    break;

  case ISCSI_CHAP_STEP_FOUR:
    ASSERT (AuthData->AuthConfig->CHAPType == ISCSI_CHAP_MUTUAL);
    //
    // The forth step, CHAP_N=<N> CHAP_R=<R> is received from Target.
    //
    Name = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_NAME);
    if (Name == NULL) {
      goto ON_EXIT;
    }

    Response = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_RESPONSE);
    if (Response == NULL) {
      goto ON_EXIT;
    }

    RspLen = ISCSI_CHAP_RSP_LEN;
    IScsiHexToBin (TargetRsp, &RspLen, Response);

    //
    // Check the CHAP Name and Response replied by Target.
    //
    Status = IScsiCHAPAuthTarget (AuthData, TargetRsp);
    break;

  default:
    break;
  }

ON_EXIT:

  if (KeyValueList != NULL) {
    IScsiFreeKeyValueList (KeyValueList);
  }

  FreePool (Data);

  return Status;
}