Esempio n. 1
0
EFIAPI
DuplicateDevicePathProtocolInterface (
  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  return DuplicateDevicePath (DevicePath);
}
Esempio n. 2
0
EFI_STATUS
CreateSingleSupportFile (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevicePath,
  IN CHAR16                       *FileName,
  IN EFI_HANDLE                   ImageHandle,
  IN VOID                         *Context,
  OUT EFI_SCT_TEST_FILE           **SupportFile
  )
/*++

Routine Description:

  Create a test support file data structure.

--*/
{
  EFI_STATUS  Status;

  //
  // Check parameter
  //
  if ((DevicePath == NULL) || (FileName == NULL) || (SupportFile == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Allocate memory for the support file
  //
  Status = BS->AllocatePool (
                 EfiBootServicesData,
                 sizeof(EFI_SCT_TEST_FILE),
                 SupportFile
                 );
  if (EFI_ERROR(Status)) {
    EFI_SCT_DEBUG ((EFI_SCT_D_ERROR, L"Allocate pool - %r", Status));
    return Status;
  }

  ZeroMem (*SupportFile, sizeof(EFI_SCT_TEST_FILE));

  //
  // Initialize the items of support file
  //
  (*SupportFile)->Signature   = EFI_SCT_TEST_FILE_SIGNATURE;
  (*SupportFile)->Revision    = EFI_SCT_TEST_FILE_REVISION;

  (*SupportFile)->DevicePath  = DuplicateDevicePath (DevicePath);
  (*SupportFile)->FileName    = StrDuplicate (FileName);
  (*SupportFile)->ImageHandle = ImageHandle;
  (*SupportFile)->Type        = EFI_SCT_TEST_FILE_TYPE_SUPPORT;
  (*SupportFile)->Context     = Context;

  //
  // Done
  //
  return EFI_SUCCESS;
}
Esempio n. 3
0
EFI_STATUS
CheckStore (
  IN  EFI_HANDLE                 SimpleFileSystemHandle,
  IN  UINT32                     VolumeId,
  OUT EFI_DEVICE_PATH_PROTOCOL   **Device
  )
{
#define BLOCK_SIZE              0x200
#define FAT16_VOLUME_ID_OFFSET  39
#define FAT32_VOLUME_ID_OFFSET  67
  EFI_STATUS                      Status;
  EFI_BLOCK_IO_PROTOCOL           *BlkIo;
  UINT8                           BootSector[BLOCK_SIZE];

  *Device = NULL;
  Status  = gBS->HandleProtocol (
                   SimpleFileSystemHandle,
                   &gEfiBlockIoProtocolGuid, // BlockIo should be supported if it supports SimpleFileSystem
                   (VOID*)&BlkIo
                   );

  if (EFI_ERROR (Status)) {
    goto ErrHandle;
  }
  if (!BlkIo->Media->MediaPresent) {
    DEBUG ((EFI_D_ERROR, "FwhMappedFile: Media not present!\n"));
    Status = EFI_NO_MEDIA;
    goto ErrHandle;
  }
  if (BlkIo->Media->ReadOnly) {
    DEBUG ((EFI_D_ERROR, "FwhMappedFile: Media is read-only!\n"));
    Status = EFI_ACCESS_DENIED;
    goto ErrHandle;
  }

  Status = BlkIo->ReadBlocks(
                    BlkIo,
                    BlkIo->Media->MediaId,
                    0,
                    BLOCK_SIZE,
                    BootSector
                    );
  ASSERT_EFI_ERROR (Status);
  if ((*(UINT32 *) &BootSector[FAT16_VOLUME_ID_OFFSET] != VolumeId) &&
      (*(UINT32 *) &BootSector[FAT32_VOLUME_ID_OFFSET] != VolumeId)
      ) {
    Status = EFI_NOT_FOUND;
    goto ErrHandle;
  }

  *Device = DuplicateDevicePath (DevicePathFromHandle (SimpleFileSystemHandle));
  ASSERT (*Device != NULL);

ErrHandle:
  return Status;
}
Esempio n. 4
0
EFI_DEVICE_PATH_PROTOCOL *
AppendDevicePathInstance (
  IN EFI_DEVICE_PATH_PROTOCOL  *Src,
  IN EFI_DEVICE_PATH_PROTOCOL  *Instance
  )
/*++

Routine Description:
  Function is used to add a device path instance to a device path.

Arguments:
  Src          - A pointer to a device path data structure

  Instance     - A pointer to a device path instance.

Returns:

  This function returns a pointer to the new device path.
  If there is not enough temporary pool memory available to complete this function,
  then NULL is returned. It is up to the caller to free the memory used by Src and
  Instance if they are no longer needed.

--*/
{
  UINT8                     *Ptr;
  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
  UINTN                     SrcSize;
  UINTN                     InstanceSize;

  if (Src == NULL) {
    return DuplicateDevicePath (Instance);
  }
  SrcSize = DevicePathSize(Src);
  InstanceSize = DevicePathSize(Instance);
  Ptr = AllocatePool (SrcSize + InstanceSize);
  DevPath = (EFI_DEVICE_PATH_PROTOCOL *)Ptr;
  ASSERT(DevPath);

  CopyMem (Ptr, Src, SrcSize);
//    FreePool (Src);

  while (!IsDevicePathEnd(DevPath)) {
    DevPath = NextDevicePathNode(DevPath);
  }
  //
  // Convert the End to an End Instance, since we are
  //  appending another instacne after this one its a good
  //  idea.
  //
  DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;

  DevPath = NextDevicePathNode(DevPath);
  CopyMem (DevPath, Instance, InstanceSize);
  return (EFI_DEVICE_PATH_PROTOCOL *)Ptr;
}
Esempio n. 5
0
EFIAPI
GetNextDevicePathInstance (
  IN OUT EFI_DEVICE_PATH_PROTOCOL    **DevicePath,
  OUT UINTN                          *Size
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
  EFI_DEVICE_PATH_PROTOCOL  *ReturnValue;
  UINT8                     Temp;

  ASSERT (Size != NULL);

  if (DevicePath == NULL || *DevicePath == NULL) {
    *Size = 0;
    return NULL;
  }

  if (!IsDevicePathValid (*DevicePath, 0)) {
    return NULL;
  }

  //
  // Find the end of the device path instance
  //
  DevPath = *DevicePath;
  while (!IsDevicePathEndType (DevPath)) {
    DevPath = NextDevicePathNode (DevPath);
  }

  //
  // Compute the size of the device path instance
  //
  *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
 
  //
  // Make a copy and return the device path instance
  //
  Temp              = DevPath->SubType;
  DevPath->SubType  = END_ENTIRE_DEVICE_PATH_SUBTYPE;
  ReturnValue       = DuplicateDevicePath (*DevicePath);
  DevPath->SubType  = Temp;

  //
  // If DevPath is the end of an entire device path, then another instance
  // does not follow, so *DevicePath is set to NULL.
  //
  if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
    *DevicePath = NULL;
  } else {
    *DevicePath = NextDevicePathNode (DevPath);
  }

  return ReturnValue;
}
Esempio n. 6
0
EFI_DEVICE_PATH*
GetAlignedDevicePath (
  IN EFI_DEVICE_PATH* DevicePath
  )
{
  if ((UINTN)DevicePath & 0x1) {
    return DuplicateDevicePath (DevicePath);
  } else {
    return DevicePath;
  }
}
Esempio n. 7
0
EFI_STATUS
BdsLoadOptionFileSystemUpdateDevicePath (
  IN EFI_DEVICE_PATH            *OldDevicePath,
  IN CHAR16*                    FileName,
  OUT EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath
  )
{
  EFI_STATUS  Status;
  CHAR16      BootFilePath[BOOT_DEVICE_FILEPATH_MAX];
  UINTN       BootFilePathSize;
  FILEPATH_DEVICE_PATH* EndingDevicePath;
  FILEPATH_DEVICE_PATH* FilePathDevicePath;
  EFI_DEVICE_PATH*  DevicePath;

  DevicePath = DuplicateDevicePath (OldDevicePath);

  EndingDevicePath = (FILEPATH_DEVICE_PATH*)GetLastDevicePathNode (DevicePath);

  Print(L"File path of the %s: ", FileName);
  StrnCpy (BootFilePath, EndingDevicePath->PathName, BOOT_DEVICE_FILEPATH_MAX);
  Status = EditHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  BootFilePathSize = StrSize(BootFilePath);
  if (BootFilePathSize == 2) {
    *NewDevicePath = NULL;
    return EFI_NOT_FOUND;
  }

  // Create the FilePath Device Path node
  FilePathDevicePath = (FILEPATH_DEVICE_PATH*)AllocatePool(SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);
  if (NULL == FilePathDevicePath)
  {
    return EFI_INVALID_PARAMETER;
  }
  FilePathDevicePath->Header.Type = MEDIA_DEVICE_PATH;
  FilePathDevicePath->Header.SubType = MEDIA_FILEPATH_DP;
  SetDevicePathNodeLength (FilePathDevicePath, SIZE_OF_FILEPATH_DEVICE_PATH + BootFilePathSize);
  CopyMem (FilePathDevicePath->PathName, BootFilePath, BootFilePathSize);

  // Generate the new Device Path by replacing the last node by the updated node
  SetDevicePathEndNode (EndingDevicePath);
  *NewDevicePath = AppendDevicePathNode (DevicePath, (CONST EFI_DEVICE_PATH_PROTOCOL *)FilePathDevicePath);
  FreePool(DevicePath);

  return EFI_SUCCESS;
}
Esempio n. 8
0
EFI_STATUS
CheckStore (
  IN  EFI_HANDLE SimpleFileSystemHandle,
  OUT EFI_DEVICE_PATH_PROTOCOL **Device
  )
{
  EFI_STATUS Status;
  EFI_BLOCK_IO_PROTOCOL *BlkIo;
  EFI_FILE_PROTOCOL *File;

  *Device = NULL;
  Status = gBS->HandleProtocol (
                  SimpleFileSystemHandle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID*)&BlkIo
                );

  if (EFI_ERROR (Status)) {
    goto ErrHandle;
  }
  if (!BlkIo->Media->MediaPresent) {
    DEBUG ((DEBUG_ERROR, "FwhMappedFile: Media not present!\n"));
    Status = EFI_NO_MEDIA;
    goto ErrHandle;
  }
  if (BlkIo->Media->ReadOnly) {
    DEBUG ((DEBUG_ERROR, "FwhMappedFile: Media is read-only!\n"));
    Status = EFI_ACCESS_DENIED;
    goto ErrHandle;
  }

  Status = FileOpen (DevicePathFromHandle (SimpleFileSystemHandle),
             mFvInstance->MappedFile, &File,
             EFI_FILE_MODE_READ);
  if (EFI_ERROR (Status)) {
    goto ErrHandle;
  }

  /* We found it! Maybe do more checks...? */

  FileClose (File);
  *Device = DuplicateDevicePath (DevicePathFromHandle (SimpleFileSystemHandle));

  ASSERT (*Device != NULL);

ErrHandle:
  return Status;
}
Esempio n. 9
0
UINTN
GetUnalignedDevicePathSize (
  IN EFI_DEVICE_PATH* DevicePath
  )
{
  UINTN Size;
  EFI_DEVICE_PATH* AlignedDevicePath;

  if ((UINTN)DevicePath & 0x1) {
    AlignedDevicePath = DuplicateDevicePath (DevicePath);
    Size = GetDevicePathSize (AlignedDevicePath);
    FreePool (AlignedDevicePath);
  } else {
    Size = GetDevicePathSize (DevicePath);
  }
  return Size;
}
Esempio n. 10
0
/**
  Find the platform active active video controller and connect it.

  @retval EFI_NOT_FOUND There is no active video controller.
  @retval EFI_SUCCESS   The video controller is connected.
**/
EFI_STATUS
ConnectVideoController (
  VOID
  )
{
  EFI_HANDLE                 VideoController;
  EFI_DEVICE_PATH_PROTOCOL   *Gop;
  
  //
  // Get the platform vga device
  //
  VideoController = GetVideoController ();
  
  if (VideoController == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // Try to connect the PCI device path, so that GOP dirver could start on this 
  // device and create child handles with GraphicsOutput Protocol installed
  // on them, then we get device paths of these child handles and select 
  // them as possible console device.
  //
  gBS->ConnectController (VideoController, NULL, NULL, FALSE);

  Gop = EfiBootManagerGetGopDevicePath (VideoController);
  if (Gop == NULL) {
    //
    // Last chance - just try VGA controller
    // Don't assume all VGA controller support GOP operation
    //
    DEBUG ((EFI_D_ERROR, "[Bds] GOP not found, try VGA device path!\n"));
    Gop = DuplicateDevicePath (DevicePathFromHandle (VideoController));
    if (Gop == NULL) {
      return EFI_NOT_FOUND;
    }
  }

  EfiBootManagerUpdateConsoleVariable (ConOut, Gop, NULL);
  FreePool (Gop);

  //
  // Necessary for ConPlatform and ConSplitter driver to start up again after ConOut is updated.
  //
  return gBS->ConnectController (VideoController, NULL, NULL, TRUE);
}
Esempio n. 11
0
EFI_STATUS
BdsLoadOptionMemMapUpdateDevicePath (
  IN EFI_DEVICE_PATH            *OldDevicePath,
  IN CHAR16*                    FileName,
  OUT EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath
  )
{
  EFI_STATUS          Status;
  CHAR16              StrStartingAddress[BOOT_DEVICE_ADDRESS_MAX];
  CHAR16              StrEndingAddress[BOOT_DEVICE_ADDRESS_MAX];
  MEMMAP_DEVICE_PATH* EndingDevicePath;
  EFI_DEVICE_PATH*    DevicePath;

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

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

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

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

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

  return Status;
}
Esempio n. 12
0
/**
  Update the parameters of a Pxe boot option

  @param[in]   OldDevicePath  Current complete device path of the Pxe boot option.
                              This has to be a valid complete Pxe boot option path.
  @param[in]   FileName       Description of the file the path is asked for
  @param[out]  NewDevicePath  Pointer to the new complete device path.

  @retval  EFI_SUCCESS            Update completed
  @retval  EFI_OUT_OF_RESOURCES   Fail to perform the update due to lack of resource
**/
EFI_STATUS
BdsLoadOptionPxeUpdateDevicePath (
  IN EFI_DEVICE_PATH            *OldDevicePath,
  IN CHAR16*                    FileName,
  OUT EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath
  )
{
  //
  // Make a copy of the complete device path that is made of :
  // the device path of the device supporting the Pxe base code protocol
  // followed by an end node.
  //
  *NewDevicePath = DuplicateDevicePath (OldDevicePath);
  if (*NewDevicePath == NULL) {
    return EFI_OUT_OF_RESOURCES;
  } else {
    return EFI_SUCCESS;
  }
}
Esempio n. 13
0
// Get the parent device in an EFI_DEVICE_PATH
// Note: the returned device path is allocated and must be freed
static EFI_DEVICE_PATH* GetParentDevice(CONST EFI_DEVICE_PATH* DevicePath)
{
    EFI_DEVICE_PATH *dp, *ldp;

    dp = DuplicateDevicePath((EFI_DEVICE_PATH*)DevicePath);
    if (dp == NULL)
            return NULL;

    ldp = GetLastDevicePath(dp);
    if (ldp == NULL)
        return NULL;

    ldp->Type = END_DEVICE_PATH_TYPE;
    ldp->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;

    SetDevicePathNodeLength(ldp, sizeof (*ldp));

    return dp;
}
Esempio n. 14
0
static EFI_STATUS
FindSubDevicePath(EFI_DEVICE_PATH *In, UINT8 Type, UINT8 SubType,
		  EFI_DEVICE_PATH **Out)
{
	EFI_DEVICE_PATH *dp = In;
	if (!In || !Out)
		return EFI_INVALID_PARAMETER;

	for (dp = In; !IsDevicePathEnd(dp); dp = NextDevicePathNode(dp)) {
		if (DevicePathType(dp) == Type &&
				DevicePathSubType(dp) == SubType) {
			*Out = DuplicateDevicePath(dp);
			if (!*Out)
				return EFI_OUT_OF_RESOURCES;
			return EFI_SUCCESS;
		}
	}
	*Out = NULL;
	return EFI_NOT_FOUND;
}
Esempio n. 15
0
/**
  Get the device path info saved in the menu structure.

  @param KeyValue        Key value to identify the type of data to expect.

**/
VOID
LibGetDevicePath (
  IN UINT16                       KeyValue
  )
{
  UINT16          FileOptionMask;
  MENU_ENTRY      *NewMenuEntry;
  FILE_CONTEXT    *NewFileContext;

  FileOptionMask    = (UINT16) (FILE_OPTION_MASK & KeyValue) - mQuestionIdUpdate;

  NewMenuEntry = LibGetMenuEntry (gFileExplorerPrivate.FsOptionMenu, FileOptionMask);

  NewFileContext = (FILE_CONTEXT *) NewMenuEntry->VariableContext;

  if (gFileExplorerPrivate.RetDevicePath != NULL) {
    FreePool (gFileExplorerPrivate.RetDevicePath);
  }
  gFileExplorerPrivate.RetDevicePath = DuplicateDevicePath (NewFileContext->DevicePath);
}
/**
  Initialize a load option.

  @param Option           Pointer to the load option to be initialized.
  @param OptionNumber     Option number of the load option.
  @param OptionType       Type of the load option.
  @param Attributes       Attributes of the load option.
  @param Description      Description of the load option.
  @param FilePath         Device path of the load option.
  @param OptionalData     Optional data of the load option.
  @param OptionalDataSize Size of the optional data of the load option.

  @retval EFI_SUCCESS           The load option was initialized successfully.
  @retval EFI_INVALID_PARAMETER Option, Description or FilePath is NULL.
**/
EFI_STATUS
EFIAPI
EfiBootManagerInitializeLoadOption (
  IN OUT EFI_BOOT_MANAGER_LOAD_OPTION   *Option,
  IN  UINTN                             OptionNumber,
  IN  EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType,
  IN  UINT32                            Attributes,
  IN  CHAR16                            *Description,
  IN  EFI_DEVICE_PATH_PROTOCOL          *FilePath,
  IN  UINT8                             *OptionalData,   OPTIONAL
  IN  UINT32                            OptionalDataSize
  )
{
  if ((Option == NULL) || (Description == NULL) || (FilePath == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (((OptionalData != NULL) && (OptionalDataSize == 0)) ||
      ((OptionalData == NULL) && (OptionalDataSize != 0))) {
    return EFI_INVALID_PARAMETER;
  }

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

  ZeroMem (Option, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));
  Option->OptionNumber       = OptionNumber;
  Option->OptionType         = OptionType;
  Option->Attributes         = Attributes;
  Option->Description        = AllocateCopyPool (StrSize (Description), Description);
  Option->FilePath           = DuplicateDevicePath (FilePath);
  if (OptionalData != NULL) {
    Option->OptionalData     = AllocateCopyPool (OptionalDataSize, OptionalData);
    Option->OptionalDataSize = OptionalDataSize;
  }

  return EFI_SUCCESS;
}
Esempio n. 17
0
EFI_DEVICE_PATH*
AppendDevicePathInstance (
    IN EFI_DEVICE_PATH  *Src,
    IN EFI_DEVICE_PATH  *Instance
    )
{
    UINT8           *Ptr;
    EFI_DEVICE_PATH *DevPath;
    UINTN           SrcSize;
    UINTN           InstanceSize;

    if (Src == NULL) {
        return DuplicateDevicePath (Instance);
    }
    SrcSize = DevicePathSize(Src);
    InstanceSize = DevicePathSize(Instance);
    Ptr = AllocatePool (SrcSize + InstanceSize);
    DevPath = (EFI_DEVICE_PATH *)Ptr;
    ASSERT(DevPath);

    CopyMem (Ptr, Src, SrcSize);
//    FreePool (Src);
    
    while (!IsDevicePathEnd(DevPath)) {
        DevPath = NextDevicePathNode(DevPath);
    }
    //
    // Convert the End to an End Instance, since we are
    //  appending another instacne after this one its a good
    //  idea.
    //
    DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
    
    DevPath = NextDevicePathNode(DevPath);
    CopyMem (DevPath, Instance, InstanceSize);
    return (EFI_DEVICE_PATH *)Ptr;
}
Esempio n. 18
0
/**
  Find the file handle from the input device path info.
  
  @param  RootDirectory    Device path info.
  @param  RetFileHandle    Return the file handle for the input device path.
  @param  ParentFileName   Parent file name.
  @param  DeviceHandle     Driver handle for this partition.
  
  @retval EFI_SUCESS       Find the file handle success.
  @retval Other            Find the file handle failure.
**/
EFI_STATUS
LibGetFileHandleFromDevicePath (
  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDirectory,  
  OUT EFI_FILE_HANDLE           *RetFileHandle,
  OUT UINT16                    **ParentFileName,
  OUT EFI_HANDLE                *DeviceHandle
  )
{
  EFI_DEVICE_PATH_PROTOCOL          *DevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL          *TempDevicePathNode;
  EFI_STATUS                        Status;
  EFI_HANDLE                        Handle;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Volume;
  EFI_FILE_HANDLE                   FileHandle;
  EFI_FILE_HANDLE                   LastHandle;
  CHAR16                            *TempPath;

  *ParentFileName = NULL;

  //
  // Attempt to access the file via a file system interface
  //
  DevicePathNode = RootDirectory;
  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathNode, &Handle);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&Volume);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  
  //
  // Open the Volume to get the File System handle
  //
  Status = Volume->OpenVolume (Volume, &FileHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  *DeviceHandle = Handle;

  if (IsDevicePathEnd(DevicePathNode)) {
    *ParentFileName = AllocateCopyPool (StrSize (L"\\"), L"\\");
    *RetFileHandle = FileHandle;
    return EFI_SUCCESS;
  }
  
  //
  // Duplicate the device path to avoid the access to unaligned device path node.
  // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH
  // nodes, It assures the fields in device path nodes are 2 byte aligned.
  //
  TempDevicePathNode = DuplicateDevicePath (DevicePathNode);
  if (TempDevicePathNode == NULL) {

    //
    // Setting Status to an EFI_ERROR value will cause the rest of
    // the file system support below to be skipped.
    //
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }
        
  //
  // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the
  // directory information and filename can be seperate. The goal is to inch
  // our way down each device path node and close the previous node
  //
  DevicePathNode = TempDevicePathNode;
  while (!EFI_ERROR (Status) && !IsDevicePathEnd (DevicePathNode)) {
    if (DevicePathType (DevicePathNode) != MEDIA_DEVICE_PATH ||
        DevicePathSubType (DevicePathNode) != MEDIA_FILEPATH_DP) {
      Status = EFI_UNSUPPORTED;
      goto Done;
    }

    LastHandle = FileHandle;
    FileHandle = NULL;

    Status = LastHandle->Open (
                          LastHandle,
                          &FileHandle,
                          ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName,
                          EFI_FILE_MODE_READ,
                          0
                          );
    if (*ParentFileName == NULL) {
      *ParentFileName = AllocateCopyPool (StrSize (((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName), ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName);
    } else {
      TempPath = LibAppendFileName (*ParentFileName, ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName);
      if (TempPath == NULL) {
        LastHandle->Close (LastHandle);
        Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }
      FreePool (*ParentFileName);
      *ParentFileName = TempPath;
    }

    //
    // Close the previous node
    //
    LastHandle->Close (LastHandle);

    DevicePathNode = NextDevicePathNode (DevicePathNode);
  }

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

  *RetFileHandle = FileHandle;

  Status = EFI_SUCCESS;

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

  if ((FileHandle != NULL) && (EFI_ERROR (Status))) {
    FileHandle->Close (FileHandle);
  }

  return Status;
}
Esempio n. 19
0
/**
Open a device named by PathName. The PathName includes a device name and
path separated by a :. See file header for more details on the PathName
syntax. There is no checking to prevent a file from being opened more than
one type.

SectionType is only used to open an FV. Each file in an FV contains multiple
sections and only the SectionType section is opened.

For any file that is opened with EfiOpen() must be closed with EfiClose().

@param  PathName    Path to parse to open
@param  OpenMode    Same as EFI_FILE.Open()
@param  SectionType Section in FV to open.

@return NULL  Open failed
@return Valid EFI_OPEN_FILE handle

**/
EFI_OPEN_FILE *
EfiOpen (
  IN        CHAR8               *PathName,
  IN  CONST UINT64              OpenMode,
  IN  CONST EFI_SECTION_TYPE    SectionType
  )
{
  EFI_STATUS                Status;
  EFI_OPEN_FILE             *File;
  EFI_OPEN_FILE             FileData;
  UINTN                     StrLen;
  UINTN                     FileStart;
  UINTN                     DevNumber = 0;
  EFI_OPEN_FILE_GUARD       *GuardFile;
  BOOLEAN                   VolumeNameMatch;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  UINTN                     Size;
  EFI_IP_ADDRESS            Ip;
  CHAR8                     *CwdPlusPathName;
  UINTN                     Index;
  EFI_SECTION_TYPE          ModifiedSectionType;

  EblUpdateDeviceLists ();

  File = &FileData;
  ZeroMem (File, sizeof (EFI_OPEN_FILE));

  StrLen = AsciiStrSize (PathName);
  if (StrLen <= 1) {
    // Smallest valid path is 1 char and a null
    return NULL;
  }

  for (FileStart = 0; FileStart < StrLen; FileStart++) {
    if (PathName[FileStart] == ':') {
      FileStart++;
      break;
    }
  }

  //
  // Matching volume name has precedence over handle based names
  //
  VolumeNameMatch = EblMatchVolumeName (PathName, FileStart, &DevNumber);
  if (!VolumeNameMatch) {
    if (FileStart == StrLen) {
      // No Volume name or device name, so try Current Working Directory
      if (gCwd == NULL) {
        // No CWD
        return NULL;
      }

      // We could add a current working directory concept
      CwdPlusPathName = AllocatePool (AsciiStrSize (gCwd) + AsciiStrSize (PathName));
      if (CwdPlusPathName == NULL) {
        return NULL;
      }

      if ((PathName[0] == '/') || (PathName[0] == '\\')) {
        // PathName starts in / so this means we go to the root of the device in the CWD.
        CwdPlusPathName[0] = '\0';
        for (FileStart = 0; gCwd[FileStart] != '\0'; FileStart++) {
          CwdPlusPathName[FileStart] = gCwd[FileStart];
          if (gCwd[FileStart] == ':') {
            FileStart++;
            CwdPlusPathName[FileStart] = '\0';
            break;
          }
        }
      } else {
        AsciiStrCpy (CwdPlusPathName, gCwd);
        StrLen = AsciiStrLen (gCwd);
        if ((*PathName != '/') && (*PathName != '\\') && (gCwd[StrLen-1] != '/') && (gCwd[StrLen-1] != '\\')) {
          AsciiStrCat (CwdPlusPathName, "\\");
        }
      }

      AsciiStrCat (CwdPlusPathName, PathName);
      if (AsciiStrStr (CwdPlusPathName, ":") == NULL) {
        // Extra error check to make sure we don't recurse and blow stack
        return NULL;
      }

      File = EfiOpen (CwdPlusPathName, OpenMode, SectionType);
      FreePool (CwdPlusPathName);
      return File;
    }

    DevNumber = EblConvertDevStringToNumber ((CHAR8 *)PathName);
  }

  File->DeviceName = AllocatePool (StrLen);
  AsciiStrCpy (File->DeviceName, PathName);
  File->DeviceName[FileStart - 1] = '\0';
  File->FileName = &File->DeviceName[FileStart];
  if (File->FileName[0] == '\0') {
    // if it is just a file name use / as root
    File->FileName = "\\";
  }

  //
  // Use best match algorithm on the dev names so we only need to look at the
  // first few charters to match the full device name. Short name forms are
  // legal from the caller.
  //
  Status = EFI_SUCCESS;
  if (*PathName == 'f' || *PathName == 'F' || VolumeNameMatch) {
    if (PathName[1] == 's' || PathName[1] == 'S' || VolumeNameMatch) {
      if (DevNumber >= mFsCount) {
        goto ErrorExit;
      }
      File->Type = EfiOpenFileSystem;
      File->EfiHandle = mFs[DevNumber];
      Status = EblFileDevicePath (File, &PathName[FileStart], OpenMode);

    } else if (PathName[1] == 'v' || PathName[1] == 'V') {
      if (DevNumber >= mFvCount) {
        goto ErrorExit;
      }
      File->Type = EfiOpenFirmwareVolume;
      File->EfiHandle = mFv[DevNumber];

      if ((PathName[FileStart] == '/') || (PathName[FileStart] == '\\')) {
        // Skip leading / as its not really needed for the FV since no directories are supported
        FileStart++;
      }

      // Check for 2nd :
      ModifiedSectionType = SectionType;
      for (Index = FileStart; PathName[Index] != '\0'; Index++) {
        if (PathName[Index] == ':') {
          // Support fv0:\DxeCore:0x10
          // This means open the PE32 Section of the file
          ModifiedSectionType = (EFI_SECTION_TYPE)AsciiStrHexToUintn (&PathName[Index + 1]);
          PathName[Index] = '\0';
        }
      }
      File->FvSectionType = ModifiedSectionType;
      Status = EblFvFileDevicePath (File, &PathName[FileStart], ModifiedSectionType);
    }
  } else if ((*PathName == 'A') || (*PathName == 'a')) {
    // Handle a:0x10000000:0x1234 address form a:ADDRESS:SIZE
    File->Type = EfiOpenMemoryBuffer;
    // 1st colon is at PathName[FileStart - 1]
    File->Buffer = (VOID *)AsciiStrHexToUintn (&PathName[FileStart]);

    // Find 2nd colon
    while ((PathName[FileStart] != ':') && (PathName[FileStart] != '\0')) {
      FileStart++;
    }

    // If we ran out of string, there's no extra data
    if (PathName[FileStart] == '\0') {
      File->Size = 0;
    } else {
      File->Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
    }

    // if there's no number after the second colon, default
    // the end of memory
    if (File->Size == 0) {
      File->Size =  (UINTN)(0 - (UINTN)File->Buffer);
    }

    File->MaxPosition = File->Size;
    File->BaseOffset = (UINTN)File->Buffer;

  } else if (*PathName== 'l' || *PathName == 'L') {
    if (DevNumber >= mLoadFileCount) {
      goto ErrorExit;
    }
    File->Type = EfiOpenLoadFile;
    File->EfiHandle = mLoadFile[DevNumber];

    Status = gBS->HandleProtocol (File->EfiHandle, &gEfiLoadFileProtocolGuid, (VOID **)&File->LoadFile);
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }

    Status = gBS->HandleProtocol (File->EfiHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }
    File->DevicePath = DuplicateDevicePath (DevicePath);

  } else if (*PathName == 'b' || *PathName == 'B') {
    // Handle b#:0x10000000:0x1234 address form b#:ADDRESS:SIZE
    if (DevNumber >= mBlkIoCount) {
      goto ErrorExit;
    }
    File->Type = EfiOpenBlockIo;
    File->EfiHandle = mBlkIo[DevNumber];
    EblFileDevicePath (File, "", OpenMode);

    // 1st colon is at PathName[FileStart - 1]
    File->DiskOffset = AsciiStrHexToUintn (&PathName[FileStart]);

    // Find 2nd colon
    while ((PathName[FileStart] != ':') && (PathName[FileStart] != '\0')) {
      FileStart++;
    }

    // If we ran out of string, there's no extra data
    if (PathName[FileStart] == '\0') {
      Size = 0;
    } else {
      Size = AsciiStrHexToUintn (&PathName[FileStart + 1]);
    }

    // if a zero size is passed in (or the size is left out entirely),
    // go to the end of the device.
    if (Size == 0) {
      File->Size = File->Size - File->DiskOffset;
    } else {
      File->Size = Size;
    }

    File->MaxPosition = File->Size;
    File->BaseOffset = File->DiskOffset;
  } else if ((*PathName) >= '0' && (*PathName <= '9')) {

    // Get current IP address
    Status = EblGetCurrentIpAddress (&Ip);
    if (EFI_ERROR(Status)) {
      AsciiPrint("Device IP Address is not configured.\n");
      goto ErrorExit;
    }


    // Parse X.X.X.X:Filename, only support IPv4 TFTP for now...
    File->Type = EfiOpenTftp;
    File->IsDirty = FALSE;
    File->IsBufferValid = FALSE;

    Status = ConvertIpStringToEfiIp (PathName, &File->ServerIp);
  }

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

  GuardFile = (EFI_OPEN_FILE_GUARD *)AllocateZeroPool (sizeof (EFI_OPEN_FILE_GUARD));
  if (GuardFile == NULL) {
    goto ErrorExit;
  }

  GuardFile->Header = EFI_OPEN_FILE_GUARD_HEADER;
  CopyMem (&(GuardFile->File), &FileData, sizeof (EFI_OPEN_FILE));
  GuardFile->Footer = EFI_OPEN_FILE_GUARD_FOOTER;

  return &(GuardFile->File);

ErrorExit:
  FreePool (File->DeviceName);
  return NULL;
}
Esempio n. 20
0
/**
  Build a list containing all serial devices.


  @retval EFI_SUCCESS The function complete successfully.
  @retval EFI_UNSUPPORTED No serial ports present.

**/
EFI_STATUS
LocateSerialIo (
  VOID
  )
{
  UINTN                     Index;
  UINTN                     Index2;
  UINTN                     NoHandles;
  EFI_HANDLE                *Handles;
  EFI_STATUS                Status;
  ACPI_HID_DEVICE_PATH      *Acpi;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_SERIAL_IO_PROTOCOL    *SerialIo;
  EFI_DEVICE_PATH_PROTOCOL  *Node;
  EFI_DEVICE_PATH_PROTOCOL  *OutDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *InpDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *ErrDevicePath;
  BM_MENU_ENTRY             *NewMenuEntry;
  BM_TERMINAL_CONTEXT       *NewTerminalContext;
  EFI_DEVICE_PATH_PROTOCOL  *NewDevicePath;
  VENDOR_DEVICE_PATH        Vendor;
  UINT32                    FlowControl;
  //
  // Get all handles that have SerialIo protocol installed
  //
  InitializeListHead (&TerminalMenu.Head);
  TerminalMenu.MenuNumber = 0;
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiSerialIoProtocolGuid,
                  NULL,
                  &NoHandles,
                  &Handles
                  );
  if (EFI_ERROR (Status)) {
    //
    // No serial ports present
    //
    return EFI_UNSUPPORTED;
  }

  //
  // Sort Uart handles array with Acpi->UID from low to high
  // then Terminal menu can be built from low Acpi->UID to high Acpi->UID
  //
  SortedUartHandle (Handles, NoHandles);

  for (Index = 0; Index < NoHandles; Index++) {
    //
    // Check to see whether the handle has DevicePath Protocol installed
    //
    gBS->HandleProtocol (
          Handles[Index],
          &gEfiDevicePathProtocolGuid,
          (VOID **) &DevicePath
          );

    Acpi = NULL;
    for (Node = DevicePath; !IsDevicePathEnd (Node); Node = NextDevicePathNode (Node)) {
      if ((DevicePathType (Node) == MESSAGING_DEVICE_PATH) && (DevicePathSubType (Node) == MSG_UART_DP)) {
        break;
      }
      //
      // Acpi points to the node before Uart node
      //
      Acpi = (ACPI_HID_DEVICE_PATH *) Node;
    }

    if ((Acpi != NULL) && IsIsaSerialNode (Acpi)) {
      NewMenuEntry = BOpt_CreateMenuEntry (BM_TERMINAL_CONTEXT_SELECT);
      if (NewMenuEntry == NULL) {
        FreePool (Handles);
        return EFI_OUT_OF_RESOURCES;
      }

      NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
      CopyMem (&NewMenuEntry->OptionNumber, &Acpi->UID, sizeof (UINT32));
      NewTerminalContext->DevicePath = DuplicateDevicePath (DevicePath);
      //
      // BugBug: I have no choice, calling EfiLibStrFromDatahub will hang the system!
      // coz' the misc data for each platform is not correct, actually it's the device path stored in
      // datahub which is not completed, so a searching for end of device path will enter a
      // dead-loop.
      //
      NewMenuEntry->DisplayString = EfiLibStrFromDatahub (DevicePath);
      if (NULL == NewMenuEntry->DisplayString) {
        NewMenuEntry->DisplayString = DevicePathToStr (DevicePath);
      }

      NewMenuEntry->HelpString = NULL;

      gBS->HandleProtocol (
            Handles[Index],
            &gEfiSerialIoProtocolGuid,
            (VOID **) &SerialIo
            );

      CopyMem (
        &NewTerminalContext->BaudRate,
        &SerialIo->Mode->BaudRate,
        sizeof (UINT64)
        );

      CopyMem (
        &NewTerminalContext->DataBits,
        &SerialIo->Mode->DataBits,
        sizeof (UINT8)
        );

      CopyMem (
        &NewTerminalContext->Parity,
        &SerialIo->Mode->Parity,
        sizeof (UINT8)
        );

      CopyMem (
        &NewTerminalContext->StopBits,
        &SerialIo->Mode->StopBits,
        sizeof (UINT8)
        );

      NewTerminalContext->FlowControl = 0;
      SerialIo->GetControl(SerialIo, &FlowControl);
      if ((FlowControl & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) != 0) {
        NewTerminalContext->FlowControl = UART_FLOW_CONTROL_HARDWARE;
      }

      InsertTailList (&TerminalMenu.Head, &NewMenuEntry->Link);
      TerminalMenu.MenuNumber++;
    }
  }
  if (Handles != NULL) {
    FreePool (Handles);
  }

  //
  // Get L"ConOut", L"ConIn" and L"ErrOut" from the Var
  //
  OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);
  InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);
  ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);
  if (OutDevicePath != NULL) {
    UpdateComAttributeFromVariable (OutDevicePath);
  }

  if (InpDevicePath != NULL) {
    UpdateComAttributeFromVariable (InpDevicePath);
  }

  if (ErrDevicePath != NULL) {
    UpdateComAttributeFromVariable (ErrDevicePath);
  }

  for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
    NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
    if (NULL == NewMenuEntry) {
      return EFI_NOT_FOUND;
    }

    NewTerminalContext                = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;

    NewTerminalContext->TerminalType  = 0;
    NewTerminalContext->IsConIn       = FALSE;
    NewTerminalContext->IsConOut      = FALSE;
    NewTerminalContext->IsStdErr      = FALSE;

    Vendor.Header.Type                = MESSAGING_DEVICE_PATH;
    Vendor.Header.SubType             = MSG_VENDOR_DP;

    for (Index2 = 0; Index2 < 4; Index2++) {
      CopyMem (&Vendor.Guid, &TerminalTypeGuid[Index2], sizeof (EFI_GUID));
      SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
      NewDevicePath = AppendDevicePathNode (
                        NewTerminalContext->DevicePath,
                        (EFI_DEVICE_PATH_PROTOCOL *) &Vendor
                        );
      if (NewMenuEntry->HelpString != NULL) {
        FreePool (NewMenuEntry->HelpString);
      }
      //
      // NewMenuEntry->HelpString = DevicePathToStr (NewDevicePath);
      // NewMenuEntry->DisplayString = NewMenuEntry->HelpString;
      //
      NewMenuEntry->HelpString = NULL;

      if (BdsLibMatchDevicePaths (OutDevicePath, NewDevicePath)) {
        NewTerminalContext->IsConOut      = TRUE;
        NewTerminalContext->TerminalType  = (UINT8) Index2;
      }

      if (BdsLibMatchDevicePaths (InpDevicePath, NewDevicePath)) {
        NewTerminalContext->IsConIn       = TRUE;
        NewTerminalContext->TerminalType  = (UINT8) Index2;
      }

      if (BdsLibMatchDevicePaths (ErrDevicePath, NewDevicePath)) {
        NewTerminalContext->IsStdErr      = TRUE;
        NewTerminalContext->TerminalType  = (UINT8) Index2;
      }
    }
  }

  return EFI_SUCCESS;
}
Esempio n. 21
0
/**
  Build up Console Menu based on types passed in. The type can
  be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
  and BM_CONSOLE_ERR_CONTEXT_SELECT.

  @param ConsoleMenuType Can be BM_CONSOLE_IN_CONTEXT_SELECT, BM_CONSOLE_OUT_CONTEXT_SELECT
                         and BM_CONSOLE_ERR_CONTEXT_SELECT.

  @retval EFI_UNSUPPORTED The type passed in is not in the 3 types defined.
  @retval EFI_NOT_FOUND   If the EFI Variable defined in UEFI spec with name "ConOutDev", 
                          "ConInDev" or "ConErrDev" doesn't exists.
  @retval EFI_OUT_OF_RESOURCES Not enough resource to complete the operations.
  @retval EFI_SUCCESS          Function completes successfully.

**/
EFI_STATUS
GetConsoleMenu (
  IN UINTN              ConsoleMenuType
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *AllDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *MultiDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;
  UINTN                     Size;
  UINTN                     AllCount;
  UINTN                     Index;
  UINTN                     Index2;
  BM_MENU_ENTRY             *NewMenuEntry;
  BM_CONSOLE_CONTEXT        *NewConsoleContext;
  TYPE_OF_TERMINAL          Terminal;
  UINTN                     Com;
  BM_MENU_OPTION            *ConsoleMenu;

  DevicePath    = NULL;
  AllDevicePath = NULL;
  AllCount      = 0;
  switch (ConsoleMenuType) {
  case BM_CONSOLE_IN_CONTEXT_SELECT:
    ConsoleMenu = &ConsoleInpMenu;
    DevicePath = EfiLibGetVariable (
                  L"ConIn",
                  &gEfiGlobalVariableGuid
                  );

    AllDevicePath = EfiLibGetVariable (
                      L"ConInDev",
                      &gEfiGlobalVariableGuid
                      );
    break;

  case BM_CONSOLE_OUT_CONTEXT_SELECT:
    ConsoleMenu = &ConsoleOutMenu;
    DevicePath = EfiLibGetVariable (
                  L"ConOut",
                  &gEfiGlobalVariableGuid
                  );

    AllDevicePath = EfiLibGetVariable (
                      L"ConOutDev",
                      &gEfiGlobalVariableGuid
                      );
    break;

  case BM_CONSOLE_ERR_CONTEXT_SELECT:
    ConsoleMenu = &ConsoleErrMenu;
    DevicePath = EfiLibGetVariable (
                  L"ErrOut",
                  &gEfiGlobalVariableGuid
                  );

    AllDevicePath = EfiLibGetVariable (
                      L"ErrOutDev",
                      &gEfiGlobalVariableGuid
                      );
    break;

  default:
    return EFI_UNSUPPORTED;
  }

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

  InitializeListHead (&ConsoleMenu->Head);

  AllCount                = EfiDevicePathInstanceCount (AllDevicePath);
  ConsoleMenu->MenuNumber = 0;
  //
  // Following is menu building up for Console Devices selected.
  //
  MultiDevicePath = AllDevicePath;
  Index2          = 0;
  for (Index = 0; Index < AllCount; Index++) {
    DevicePathInst  = GetNextDevicePathInstance (&MultiDevicePath, &Size);

    NewMenuEntry    = BOpt_CreateMenuEntry (BM_CONSOLE_CONTEXT_SELECT);
    if (NULL == NewMenuEntry) {
      return EFI_OUT_OF_RESOURCES;
    }

    NewConsoleContext             = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
    NewMenuEntry->OptionNumber    = Index2;

    NewConsoleContext->DevicePath = DuplicateDevicePath (DevicePathInst);
    ASSERT (NewConsoleContext->DevicePath != NULL);
    NewMenuEntry->DisplayString   = EfiLibStrFromDatahub (NewConsoleContext->DevicePath);
    if (NULL == NewMenuEntry->DisplayString) {
      NewMenuEntry->DisplayString = DevicePathToStr (NewConsoleContext->DevicePath);
    }

    NewConsoleContext->IsTerminal = IsTerminalDevicePath (
                                      NewConsoleContext->DevicePath,
                                      &Terminal,
                                      &Com
                                      );

    NewConsoleContext->IsActive = BdsLibMatchDevicePaths (
                                    DevicePath,
                                    NewConsoleContext->DevicePath
                                    );

    if (NewConsoleContext->IsTerminal) {
      BOpt_DestroyMenuEntry (NewMenuEntry);
    } else {
      Index2++;
      ConsoleMenu->MenuNumber++;
      InsertTailList (&ConsoleMenu->Head, &NewMenuEntry->Link);
    }
  }

  return EFI_SUCCESS;
}
Esempio n. 22
0
EFI_STATUS
find_boot_option(EFI_DEVICE_PATH *dp, EFI_DEVICE_PATH *fulldp,
                 CHAR16 *filename, CHAR16 *label, CHAR16 *arguments,
                 UINT16 *optnum)
{
	unsigned int size = sizeof(UINT32) + sizeof (UINT16) +
		StrLen(label)*2 + 2 + DevicePathSize(dp) +
		StrLen(arguments) * 2;

	CHAR8 *data = AllocateZeroPool(size + 2);
	if (!data)
		return EFI_OUT_OF_RESOURCES;
	CHAR8 *cursor = data;
	*(UINT32 *)cursor = LOAD_OPTION_ACTIVE;
	cursor += sizeof (UINT32);
	*(UINT16 *)cursor = DevicePathSize(dp);
	cursor += sizeof (UINT16);
	StrCpy((CHAR16 *)cursor, label);
	cursor += StrLen(label)*2 + 2;
	CopyMem(cursor, dp, DevicePathSize(dp));
	cursor += DevicePathSize(dp);
	StrCpy((CHAR16 *)cursor, arguments);

	int i = 0;
	CHAR16 varname[] = L"Boot0000";
	CHAR16 hexmap[] = L"0123456789ABCDEF";
	EFI_GUID global = EFI_GLOBAL_VARIABLE;
	EFI_STATUS rc;

	CHAR8 *candidate = AllocateZeroPool(size);
	if (!candidate) {
		FreePool(data);
		return EFI_OUT_OF_RESOURCES;
	}

	for(i = 0; i < nbootorder && i < 0x10000; i++) {
		varname[4] = hexmap[(bootorder[i] & 0xf000) >> 12];
		varname[5] = hexmap[(bootorder[i] & 0x0f00) >> 8];
		varname[6] = hexmap[(bootorder[i] & 0x00f0) >> 4];
		varname[7] = hexmap[(bootorder[i] & 0x000f) >> 0];

		UINTN candidate_size = size;
		rc = uefi_call_wrapper(RT->GetVariable, 5, varname, &global,
					NULL, &candidate_size, candidate);
		if (EFI_ERROR(rc))
			continue;

		if (candidate_size != size)
			continue;

		if (CompareMem(candidate, data, size))
			continue;

		/* at this point, we have duplicate data. */
		if (!first_new_option) {
			first_new_option = DuplicateDevicePath(fulldp);
			first_new_option_args = arguments;
			first_new_option_size = StrLen(arguments) * sizeof (CHAR16);
		}

		*optnum = i;
		FreePool(candidate);
		FreePool(data);
		return EFI_SUCCESS;
	}
	FreePool(candidate);
	FreePool(data);
	return EFI_NOT_FOUND;
}
Esempio n. 23
0
/**
  Update the parameters of a TFTP boot option

  The function asks sequentially to update the IPv4 parameters as well as the boot file path,
  providing the previously set value if any.

  @param[in]   OldDevicePath  Current complete device path of the Tftp boot option.
                              This has to be a valid complete Tftp boot option path.
                              By complete, we mean that it is not only the Tftp
                              specific end part built by the
                              "BdsLoadOptionTftpCreateDevicePath()" function.
                              This path is handled as read only.
  @param[in]   FileName       Description of the file the path is asked for
  @param[out]  NewDevicePath  Pointer to the new complete device path.

  @retval  EFI_SUCCESS            Update completed
  @retval  EFI_ABORTED            Update aborted by the user
  @retval  EFI_OUT_OF_RESOURCES   Fail to perform the update due to lack of resource
**/
EFI_STATUS
BdsLoadOptionTftpUpdateDevicePath (
  IN   EFI_DEVICE_PATH            *OldDevicePath,
  IN   CHAR16                     *FileName,
  OUT  EFI_DEVICE_PATH_PROTOCOL  **NewDevicePath
  )
{
  EFI_STATUS             Status;
  EFI_DEVICE_PATH       *DevicePath;
  EFI_DEVICE_PATH       *DevicePathNode;
  UINT8                 *Ipv4NodePtr;
  IPv4_DEVICE_PATH       Ipv4Node;
  BOOLEAN                IsDHCP;
  EFI_IP_ADDRESS         OldIp;
  EFI_IP_ADDRESS         OldSubnetMask;
  EFI_IP_ADDRESS         OldGatewayIp;
  EFI_IP_ADDRESS         LocalIp;
  EFI_IP_ADDRESS         SubnetMask;
  EFI_IP_ADDRESS         GatewayIp;
  EFI_IP_ADDRESS         RemoteIp;
  UINT8                 *FileNodePtr;
  CHAR16                 BootFilePath[BOOT_DEVICE_FILEPATH_MAX];
  UINTN                  PathSize;
  UINTN                  BootFilePathSize;
  FILEPATH_DEVICE_PATH  *NewFilePathNode;

  Ipv4NodePtr = NULL;

  //
  // Make a copy of the complete device path that is made of :
  // the device path of the device that support the Simple Network protocol
  // followed by an IPv4 node (type IPv4_DEVICE_PATH),
  // followed by a file path node (type FILEPATH_DEVICE_PATH) and ended up
  // by an end node. The IPv6 case is not handled yet.
  //

  DevicePath = DuplicateDevicePath (OldDevicePath);
  if (DevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }

  //
  // Because of the check done by "BdsLoadOptionTftpIsSupported()" prior to the
  // call to this function, we know that the device path ends with an IPv4 node
  // followed by a file path node and finally an end node. To get the address of
  // the last IPv4 node, we loop over the whole device path, noting down the
  // address of each encountered IPv4 node.
  //

  for (DevicePathNode = DevicePath;
       !IsDevicePathEnd (DevicePathNode);
       DevicePathNode = NextDevicePathNode (DevicePathNode))
  {
    if (IS_DEVICE_PATH_NODE (DevicePathNode, MESSAGING_DEVICE_PATH, MSG_IPv4_DP)) {
      Ipv4NodePtr = (UINT8*)DevicePathNode;
    }
  }

  // Copy for alignment of the IPv4 node data
  CopyMem (&Ipv4Node, Ipv4NodePtr, sizeof (IPv4_DEVICE_PATH));

  Print (L"Get the IP address from DHCP: ");
  Status = GetHIInputBoolean (&IsDHCP);
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  if (!IsDHCP) {
    Print (L"Local static IP address: ");
    if (Ipv4Node.StaticIpAddress) {
      CopyMem (&OldIp.v4, &Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
      Status = EditHIInputIP (&OldIp, &LocalIp);
    } else {
      Status = GetHIInputIP (&LocalIp);
    }
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }

    Print (L"Get the network mask: ");
    if (Ipv4Node.StaticIpAddress) {
      CopyMem (&OldSubnetMask.v4, &Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
      Status = EditHIInputIP (&OldSubnetMask, &SubnetMask);
    } else {
      Status = GetHIInputIP (&SubnetMask);
    }
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }

    Print (L"Get the gateway IP address: ");
    if (Ipv4Node.StaticIpAddress) {
      CopyMem (&OldGatewayIp.v4, &Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));
      Status = EditHIInputIP (&OldGatewayIp, &GatewayIp);
    } else {
      Status = GetHIInputIP (&GatewayIp);
    }
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }
  }

  Print (L"TFTP server IP address: ");
  // Copy remote IPv4 address into IPv4 or IPv6 union
  CopyMem (&OldIp.v4, &Ipv4Node.RemoteIpAddress, sizeof (EFI_IPv4_ADDRESS));

  Status = EditHIInputIP (&OldIp, &RemoteIp);
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  // Get the path of the boot file and its size in number of bytes
  FileNodePtr = Ipv4NodePtr + sizeof (IPv4_DEVICE_PATH);
  BootFilePathSize = DevicePathNodeLength (FileNodePtr) - SIZE_OF_FILEPATH_DEVICE_PATH;

  //
  // Ask for update of the boot file path
  //
  do {
    // Copy for 2-byte alignment of the Unicode string
    CopyMem (
      BootFilePath, FileNodePtr + SIZE_OF_FILEPATH_DEVICE_PATH,
      MIN (BootFilePathSize, BOOT_DEVICE_FILEPATH_MAX)
      );
    BootFilePath[BOOT_DEVICE_FILEPATH_MAX - 1] = L'\0';

    Print (L"File path of the %s: ", FileName);
    Status = EditHIInputStr (BootFilePath, BOOT_DEVICE_FILEPATH_MAX);
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }
    PathSize = StrSize (BootFilePath);
    if (PathSize > 2) {
      break;
    }
    // Empty string, give the user another try
    Print (L"Empty string - Invalid path\n");
  } while (PathSize <= 2) ;

  //
  // Update the IPv4 node. IPv6 case not handled yet.
  //
  if (IsDHCP) {
    Ipv4Node.StaticIpAddress = FALSE;
    ZeroMem (&Ipv4Node.LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
    ZeroMem (&Ipv4Node.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
    ZeroMem (&Ipv4Node.GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));
  } else {
    Ipv4Node.StaticIpAddress = TRUE;
    CopyMem (&Ipv4Node.LocalIpAddress, &LocalIp.v4, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Ipv4Node.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Ipv4Node.GatewayIpAddress, &GatewayIp.v4, sizeof (EFI_IPv4_ADDRESS));
  }

  CopyMem (&Ipv4Node.RemoteIpAddress, &RemoteIp.v4, sizeof (EFI_IPv4_ADDRESS));
  CopyMem (Ipv4NodePtr, &Ipv4Node, sizeof (IPv4_DEVICE_PATH));

  //
  // Create the new file path node
  //
  NewFilePathNode = (FILEPATH_DEVICE_PATH*)AllocatePool (
                                             SIZE_OF_FILEPATH_DEVICE_PATH +
                                             PathSize
                                             );
  NewFilePathNode->Header.Type    = MEDIA_DEVICE_PATH;
  NewFilePathNode->Header.SubType = MEDIA_FILEPATH_DP;
  SetDevicePathNodeLength (
    NewFilePathNode,
    SIZE_OF_FILEPATH_DEVICE_PATH + PathSize
    );
  CopyMem (NewFilePathNode->PathName, BootFilePath, PathSize);

  //
  // Generate the new Device Path by replacing the file path node at address
  // "FileNodePtr" by the new one "NewFilePathNode" and return its address.
  //
  SetDevicePathEndNode (FileNodePtr);
  *NewDevicePath = AppendDevicePathNode (
                     DevicePath,
                     (CONST EFI_DEVICE_PATH_PROTOCOL*)NewFilePathNode
                     );

ErrorExit:
  if (DevicePath != NULL) {
    FreePool (DevicePath) ;
  }

  return Status;
}
Esempio n. 24
0
EFI_STATUS
EFIAPI
TOLOpen (
    IN EFI_TEST_OUTPUT_LIBRARY_PROTOCOL       *This,
    IN EFI_DEVICE_PATH_PROTOCOL               *DevicePath,
    IN CHAR16                                 *FileName,
    IN BOOLEAN                                OverwriteFile,
    OUT EFI_FILE                              **FileHandle
)
/*++

Routine Description:

  One interface function of the TestOutputLibrary to open a file.

Arguments:

  This                  - the protocol instance structure.
  DevicePath            - the file's root device path.
  FileName              - the file's name relative to the root.
  OverwriteFile         - whether to overwrite the file.
  FileHandle            - return the file's handle.

Returns:

  EFI_SUCCESS           - open the file successfully.
  EFI_NOT_READY         - to overwrite an opened file is not allowed.
  EFI_OUT_OF_RESOURCES  - not enough memory.

--*/
{
    EFI_STATUS                        Status;
    TEST_OUTPUT_FILE                  *OutputFile;
    TEST_OUTPUT_PRIVATE_DATA          *Private;
    EFI_HANDLE                        DeviceHandle;
    EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Vol;
    EFI_FILE_HANDLE                   RootDir;
    EFI_FILE_HANDLE                   Handle;
    UINTN                             BufSize;
    CHAR8                             Buffer[2];
    EFI_DEVICE_PATH_PROTOCOL          *PreDevicePath;

    Private = TEST_OUTPUT_PRIVATE_DATA_FROM_THIS (This);

    //
    // Search the file in OutputFileList to see whether the file has been opened
    //
    OutputFile = Private->OutputFileList;
    while (OutputFile != NULL) {
        if ((SctDevicePathCompare (DevicePath, OutputFile->DevicePath) == 0) &&
                (StrCmp (FileName, OutputFile->FileName)                   == 0)) {
            break;
        }
        OutputFile = OutputFile->Next;
    }

    if (OutputFile == NULL) {
        //
        // Not found, open the file and add to the list
        //

        PreDevicePath = DevicePath;
        //
        //  Determine device handle for fs protocol on specified device path
        //
        Status = BS->LocateDevicePath (
                     &gEfiSimpleFileSystemProtocolGuid,
                     &PreDevicePath,
                     &DeviceHandle
                 );
        if (EFI_ERROR (Status)) {
            return Status;
        }

        //
        //  Determine volume for file system on device handle
        //
        Status = BS->HandleProtocol (
                     DeviceHandle,
                     &gEfiSimpleFileSystemProtocolGuid,
                     (VOID*)&Vol
                 );
        if (EFI_ERROR (Status)) {
            return Status;
        }

        //
        // Open volume for file system on device path
        //
        Status = Vol->OpenVolume (Vol, &RootDir);
        if (EFI_ERROR (Status)) {
            return Status;
        }

        //
        // Determine the existence of the file
        //
        Status = RootDir->Open (
                     RootDir,
                     &Handle,
                     FileName,
                     EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ,
                     0
                 );
        if (Status == EFI_NOT_FOUND) {
            //
            // The file not exist, create it
            //
            Status = SctCreateFile (RootDir, FileName, &Handle);
            if (EFI_ERROR (Status)) {
                RootDir->Close (RootDir);
                return Status;
            }

            //
            // Write the head of Unicode text file
            //
            Buffer[0] = 0xff;
            Buffer[1] = 0xfe;
            BufSize = 2;
            Status = Handle->Write (Handle, &BufSize, Buffer);
            if (EFI_ERROR (Status)) {
                Handle->Close (Handle);
                return Status;
            }
        } else if (EFI_ERROR (Status)) {
            RootDir->Close(RootDir);
            return Status;
        }

        if (OverwriteFile) {
            //
            // Overwrite the file
            //

            //
            // Delete the file
            //
            Status = Handle->Delete (Handle);

            //
            // EFI_FILE.Delete() return a warning status
            //
            if (Status != EFI_SUCCESS) {
                RootDir->Close (RootDir);
                return EFI_UNSUPPORTED;
            }

            //
            // Recreate the file
            //
            Status = RootDir->Open (
                         RootDir,
                         &Handle,
                         FileName,
                         EFI_FILE_MODE_CREATE|EFI_FILE_MODE_WRITE|EFI_FILE_MODE_READ,
                         0
                     );
            if (EFI_ERROR (Status)) {
                RootDir->Close (RootDir);
                return Status;
            }

            //
            // Write the head of Unicode text file
            //
            Buffer[0] = 0xff;
            Buffer[1] = 0xfe;
            BufSize = 2;
            Status = Handle->Write (Handle, &BufSize, Buffer);
            if (EFI_ERROR (Status)) {
                Handle->Close (Handle);
                return Status;
            }
        } else {
            //
            // Append the file
            //

            //
            // Set position to the end of file
            //
            Status = Handle->SetPosition (Handle, (UINT64)-1);
            if (EFI_ERROR (Status)) {
                RootDir->Close (RootDir);
                return Status;
            }
        }
        RootDir->Close (RootDir);

        //
        // Add the opened file to the OutputFileList
        //
        Status = BS->AllocatePool (
                     EfiBootServicesData,
                     sizeof(TEST_OUTPUT_FILE),
                     (VOID **)&OutputFile
                 );
        if (EFI_ERROR (Status)) {
            Handle->Close (Handle);
            return Status;
        }
        ZeroMem (OutputFile, sizeof(TEST_OUTPUT_FILE));

        OutputFile->DevicePath = DuplicateDevicePath (DevicePath);
        if (OutputFile->DevicePath == NULL) {
            Handle->Close (Handle);
            BS->FreePool (OutputFile);
            return EFI_OUT_OF_RESOURCES;
        }
        OutputFile->FileName = StrDuplicate (FileName);
        if (OutputFile->FileName == NULL) {
            Handle->Close (Handle);
            BS->FreePool (OutputFile->DevicePath);
            BS->FreePool (OutputFile);
            return EFI_OUT_OF_RESOURCES;
        }

        OutputFile->FileHandle = Handle;
        OutputFile->Next = Private->OutputFileList;
        Private->OutputFileList = OutputFile;
    }

    //
    // Add the open count and return the file handle
    //
    OutputFile->OpenCount ++;
    *FileHandle = OutputFile->FileHandle;

    return EFI_SUCCESS;
}
Esempio n. 25
0
EFI_STATUS
add_boot_option(EFI_DEVICE_PATH *hddp, EFI_DEVICE_PATH *fulldp,
		CHAR16 *filename, CHAR16 *label, CHAR16 *arguments)
{
	static int i = 0;
	CHAR16 varname[] = L"Boot0000";
	CHAR16 hexmap[] = L"0123456789ABCDEF";
	EFI_GUID global = EFI_GLOBAL_VARIABLE;
	EFI_STATUS rc;

	for(; i <= 0xffff; i++) {
		varname[4] = hexmap[(i & 0xf000) >> 12];
		varname[5] = hexmap[(i & 0x0f00) >> 8];
		varname[6] = hexmap[(i & 0x00f0) >> 4];
		varname[7] = hexmap[(i & 0x000f) >> 0];

		void *var = LibGetVariable(varname, &global);
		if (!var) {
			int size = sizeof(UINT32) + sizeof (UINT16) +
				StrLen(label)*2 + 2 + DevicePathSize(hddp) +
				StrLen(arguments) * 2;

			CHAR8 *data = AllocateZeroPool(size + 2);
			CHAR8 *cursor = data;
			*(UINT32 *)cursor = LOAD_OPTION_ACTIVE;
			cursor += sizeof (UINT32);
			*(UINT16 *)cursor = DevicePathSize(hddp);
			cursor += sizeof (UINT16);
			StrCpy((CHAR16 *)cursor, label);
			cursor += StrLen(label)*2 + 2;
			CopyMem(cursor, hddp, DevicePathSize(hddp));
			cursor += DevicePathSize(hddp);
			StrCpy((CHAR16 *)cursor, arguments);

			Print(L"Creating boot entry \"%s\" with label \"%s\" "
					L"for file \"%s\"\n",
				varname, label, filename);

			if (!first_new_option) {
				first_new_option = DuplicateDevicePath(fulldp);
				first_new_option_args = arguments;
				first_new_option_size = StrLen(arguments) * sizeof (CHAR16);
			}

			rc = uefi_call_wrapper(RT->SetVariable, 5, varname,
				&global, EFI_VARIABLE_NON_VOLATILE |
					 EFI_VARIABLE_BOOTSERVICE_ACCESS |
					 EFI_VARIABLE_RUNTIME_ACCESS,
				size, data);

			FreePool(data);

			if (EFI_ERROR(rc)) {
				Print(L"Could not create variable: %d\n", rc);
				return rc;
			}

			CHAR16 *newbootorder = AllocateZeroPool(sizeof (CHAR16)
							* (nbootorder + 1));
			if (!newbootorder)
				return EFI_OUT_OF_RESOURCES;

			int j = 0;
			newbootorder[0] = i & 0xffff;
			if (nbootorder) {
				for (j = 0; j < nbootorder; j++)
					newbootorder[j+1] = bootorder[j];
				FreePool(bootorder);
			}
			bootorder = newbootorder;
			nbootorder += 1;
#ifdef DEBUG_FALLBACK
			Print(L"nbootorder: %d\nBootOrder: ", nbootorder);
			for (j = 0 ; j < nbootorder ; j++)
				Print(L"%04x ", bootorder[j]);
			Print(L"\n");
#endif

			return EFI_SUCCESS;
		}
	}
	return EFI_OUT_OF_RESOURCES;
}
Esempio n. 26
0
EFI_STATUS
BootAndroidBootImg (
  IN UINTN    BufferSize,
  IN VOID    *Buffer
  )
{
  EFI_STATUS                          Status;
  CHAR8                               KernelArgs[BOOTIMG_KERNEL_ARGS_SIZE];
  VOID                               *Kernel;
  UINTN                               KernelSize;
  VOID                               *Ramdisk;
  UINTN                               RamdiskSize;
  MEMORY_DEVICE_PATH                  KernelDevicePath;
  MEMORY_DEVICE_PATH*                 RamdiskDevicePath;

  Status = ParseAndroidBootImg (
            Buffer,
            &Kernel,
            &KernelSize,
            &Ramdisk,
            &RamdiskSize,
            KernelArgs
            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  KernelDevicePath = MemoryDevicePathTemplate;

  // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to
  // appease GCC.
  KernelDevicePath.Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel;
  KernelDevicePath.Node1.EndingAddress   = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel + KernelSize;

  RamdiskDevicePath = NULL;
  if (RamdiskSize != 0) {
    RamdiskDevicePath = (MEMORY_DEVICE_PATH*)DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*) &MemoryDevicePathTemplate);

    RamdiskDevicePath->Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk;
    RamdiskDevicePath->Node1.EndingAddress   = ((EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk) + RamdiskSize;
  }

  Status = BdsBootLinuxFdt (
              (EFI_DEVICE_PATH_PROTOCOL *) &KernelDevicePath,
              (EFI_DEVICE_PATH_PROTOCOL *) RamdiskDevicePath,
              KernelArgs
              );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Couldn't Boot Linux: %d\n", Status));
    return EFI_DEVICE_ERROR;
  }

  if (RamdiskDevicePath) {
    FreePool (RamdiskDevicePath);
  }

  // If we got here we do a confused face because BootLinuxFdt returned,
  // reporting success.
  DEBUG ((EFI_D_ERROR, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n"));
  return EFI_SUCCESS;
}
Esempio n. 27
0
EFI_STATUS
EFIAPI
BdsLibConnectDevicePath (
    IN EFI_DEVICE_PATH_PROTOCOL  *DevicePathToConnect
)
{
    EFI_STATUS                Status;
    EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
    EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;
    EFI_DEVICE_PATH_PROTOCOL  *Instance;
    EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;
    EFI_DEVICE_PATH_PROTOCOL  *Next;
    EFI_HANDLE                Handle;
    EFI_HANDLE                PreviousHandle;
    UINTN                     Size;

    if (DevPathToTxt == NULL)
    {
        Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevPathToTxt);
        ASSERT((!EFI_ERROR(Status)));
    }
    if (DevicePathToConnect == NULL) {
        return EFI_SUCCESS;
    }

    DEBUG((DEBUG_INFO, "%a:%d dev path '%s' to connect\n", __FILE__, __LINE__, DevPathToTxt->ConvertDevicePathToText(DevicePathToConnect, TRUE, FALSE)));
    DevicePath        = DuplicateDevicePath (DevicePathToConnect);
    if (DevicePath == NULL) {
        return EFI_OUT_OF_RESOURCES;
    }
    CopyOfDevicePath  = DevicePath;

    do {
        //
        // The outer loop handles multi instance device paths.
        // Only console variables contain multiple instance device paths.
        //
        // After this call DevicePath points to the next Instance
        //
        Instance  = GetNextDevicePathInstance (&DevicePath, &Size);
        if (Instance == NULL) {
            FreePool (CopyOfDevicePath);
            return EFI_OUT_OF_RESOURCES;
        }

        Next      = Instance;
        while (!IsDevicePathEndType (Next)) {
            Next = NextDevicePathNode (Next);
        }

        SetDevicePathEndNode (Next);

        //
        // Start the real work of connect with RemainingDevicePath
        //
        PreviousHandle = NULL;
        do {
            //
            // Find the handle that best matches the Device Path. If it is only a
            // partial match the remaining part of the device path is returned in
            // RemainingDevicePath.
            //
            RemainingDevicePath = Instance;
            Status              = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);

            if (!EFI_ERROR (Status)) {
                if (Handle == PreviousHandle) {
                    //
                    // If no forward progress is made try invoking the Dispatcher.
                    // A new FV may have been added to the system an new drivers
                    // may now be found.
                    // Status == EFI_SUCCESS means a driver was dispatched
                    // Status == EFI_NOT_FOUND means no new drivers were dispatched
                    //
                    Status = gDS->Dispatch ();
                }

                if (!EFI_ERROR (Status)) {
                    PreviousHandle = Handle;
                    //
                    // Connect all drivers that apply to Handle and RemainingDevicePath,
                    // the Recursive flag is FALSE so only one level will be expanded.
                    //
                    // Do not check the connect status here, if the connect controller fail,
                    // then still give the chance to do dispatch, because partial
                    // RemainingDevicepath may be in the new FV
                    //
                    // 1. If the connect fail, RemainingDevicepath and handle will not
                    //    change, so next time will do the dispatch, then dispatch's status
                    //    will take effect
                    // 2. If the connect success, the RemainingDevicepath and handle will
                    //    change, then avoid the dispatch, we have chance to continue the
                    //    next connection
                    //
                    gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);
                }
            }
            //
            // Loop until RemainingDevicePath is an empty device path
            //
        } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));

    } while (DevicePath != NULL);

    if (CopyOfDevicePath != NULL) {
        FreePool (CopyOfDevicePath);
    }
    //
    // All handle with DevicePath exists in the handle database
    //
    return Status;
}
Esempio n. 28
0
/**
  Save lines in HBufferImage to disk.
  NOT ALLOW TO WRITE TO ANOTHER DISK!!!!!!!!!

  @param[in] DeviceName   The device name.
  @param[in] Offset       The offset.
  @param[in] Size         The size.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @retval EFI_LOAD_ERROR        A load error occured.
  @retval EFI_INVALID_PARAMETER A parameter was invalid.  
**/
EFI_STATUS
HDiskImageSave (
  IN CHAR16 *DeviceName,
  IN UINTN  Offset,
  IN UINTN  Size
  )
{

  CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL        *DupDevicePath;
  EFI_BLOCK_IO_PROTOCOL           *BlkIo;
  EFI_STATUS                      Status;
  EFI_HANDLE                      Handle;
  VOID                            *Buffer;
  UINTN                           Bytes;

  UINT64                          ByteOffset;

  EDIT_FILE_TYPE                  BufferTypeBackup;

  //
  // if not modified, directly return
  //
  if (HBufferImage.Modified == FALSE) {
    return EFI_SUCCESS;
  }

  BufferTypeBackup        = HBufferImage.BufferType;
  HBufferImage.BufferType = FileTypeDiskBuffer;

  DevicePath              = gEfiShellProtocol->GetDevicePathFromMap(DeviceName);
  if (DevicePath == NULL) {
//    StatusBarSetStatusString (L"Cannot Find Device");
    return EFI_INVALID_PARAMETER;
  }
  DupDevicePath = DuplicateDevicePath(DevicePath);

  //
  // get blkio interface
  //
  Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle);
  FreePool(DupDevicePath);
  if (EFI_ERROR (Status)) {
//    StatusBarSetStatusString (L"Read Disk Failed");
    return Status;
  }
  Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  if (EFI_ERROR (Status)) {
//    StatusBarSetStatusString (L"Read Disk Failed");
    return Status;
  }

  Bytes   = BlkIo->Media->BlockSize * Size;
  Buffer  = AllocateZeroPool (Bytes);

  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // concatenate the line list to a buffer
  //
  Status = HBufferImageListToBuffer (Buffer, Bytes);
  if (EFI_ERROR (Status)) {
    FreePool (Buffer);
    return Status;
  }

  ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize);

  //
  // write the buffer to disk
  //
  Status = BlkIo->WriteBlocks (
                    BlkIo,
                    BlkIo->Media->MediaId,
                    Offset,
                    Bytes,
                    Buffer
                    );

  FreePool (Buffer);

  if (EFI_ERROR (Status)) {
    return EFI_LOAD_ERROR;
  }
  //
  // now not modified
  //
  HBufferImage.Modified = FALSE;

  return EFI_SUCCESS;
}
Esempio n. 29
0
/**
  Read a disk from disk into HBufferImage.

  @param[in] DeviceName   filename to read.
  @param[in] Offset       The offset.
  @param[in] Size         The size.
  @param[in] Recover      if is for recover, no information print.

  @retval EFI_SUCCESS           The operation was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
  @retval EFI_LOAD_ERROR        A load error occured.
  @retval EFI_INVALID_PARAMETER A parameter was invalid.  
**/
EFI_STATUS
HDiskImageRead (
  IN CONST CHAR16   *DeviceName,
  IN UINTN    Offset,
  IN UINTN    Size,
  IN BOOLEAN  Recover
  )
{
  CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL        *DupDevicePath;
  EFI_DEVICE_PATH_PROTOCOL        *DupDevicePathForFree;
  EFI_HANDLE                      Handle;
  EFI_BLOCK_IO_PROTOCOL           *BlkIo;
  EFI_STATUS                      Status;

  VOID                            *Buffer;
  CHAR16                          *Str;
  UINTN                           Bytes;

  HEFI_EDITOR_LINE                *Line;
  UINT64                          ByteOffset;

  EDIT_FILE_TYPE                  BufferTypeBackup;

  BufferTypeBackup        = HBufferImage.BufferType;
  HBufferImage.BufferType = FileTypeDiskBuffer;

  DevicePath              = gEfiShellProtocol->GetDevicePathFromMap(DeviceName);
  if (DevicePath == NULL) {
    StatusBarSetStatusString (L"Cannot Find Device");
    return EFI_INVALID_PARAMETER;
  }
  DupDevicePath = DuplicateDevicePath(DevicePath);
  DupDevicePathForFree = DupDevicePath;
  //
  // get blkio interface
  //
  Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle);
  FreePool(DupDevicePathForFree);
  if (EFI_ERROR (Status)) {
    StatusBarSetStatusString (L"Read Disk Failed");
    return Status;
  }
  Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
  if (EFI_ERROR (Status)) {
    StatusBarSetStatusString (L"Read Disk Failed");
    return Status;
  }
  //
  // if Offset exceeds LastBlock,
  //   return error
  //
  if (Offset > BlkIo->Media->LastBlock || Offset + Size > BlkIo->Media->LastBlock) {
    StatusBarSetStatusString (L"Invalid Offset + Size");
    return EFI_LOAD_ERROR;
  }

  Bytes   = BlkIo->Media->BlockSize * Size;
  Buffer  = AllocateZeroPool (Bytes);

  if (Buffer == NULL) {
    StatusBarSetStatusString (L"Read Disk Failed");
    return EFI_OUT_OF_RESOURCES;
  }

  ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize);

  //
  // read from disk
  //
  Status = BlkIo->ReadBlocks (
                    BlkIo,
                    BlkIo->Media->MediaId,
                    Offset,
                    Bytes,
                    Buffer
                    );

  if (EFI_ERROR (Status)) {
    FreePool (Buffer);
    StatusBarSetStatusString (L"Read Disk Failed");
    return EFI_LOAD_ERROR;
  }

  HBufferImageFree ();

  //
  // convert buffer to line list
  //
  Status = HBufferImageBufferToList (Buffer, Bytes);
  FreePool (Buffer);

  if (EFI_ERROR (Status)) {
    StatusBarSetStatusString (L"Read Disk Failed");
    return Status;
  }

  Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size);
  if (EFI_ERROR (Status)) {
    StatusBarSetStatusString (L"Read Disk Failed");
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // initialize some variables
  //
  HDiskImage.BlockSize                = BlkIo->Media->BlockSize;

  HBufferImage.DisplayPosition.Row    = 2;
  HBufferImage.DisplayPosition.Column = 10;

  HBufferImage.MousePosition.Row      = 2;
  HBufferImage.MousePosition.Column   = 10;

  HBufferImage.LowVisibleRow          = 1;
  HBufferImage.HighBits               = TRUE;

  HBufferImage.BufferPosition.Row     = 1;
  HBufferImage.BufferPosition.Column  = 1;

  if (!Recover) {
    Str = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines);
    if (Str == NULL) {
      StatusBarSetStatusString (L"Read Disk Failed");
      return EFI_OUT_OF_RESOURCES;
    }

    StatusBarSetStatusString (Str);
    SHELL_FREE_NON_NULL (Str);

    HMainEditor.SelectStart = 0;
    HMainEditor.SelectEnd   = 0;

  }

  //
  // has line
  //
  if (HBufferImage.Lines != NULL) {
    HBufferImage.CurrentLine = CR (
                                HBufferImage.ListHead->ForwardLink,
                                HEFI_EDITOR_LINE,
                                Link,
                                EFI_EDITOR_LINE_LIST
                                );
  } else {
    //
    // create a dummy line
    //
    Line = HBufferImageCreateLine ();
    if (Line == NULL) {
      StatusBarSetStatusString (L"Read Disk Failed");
      return EFI_OUT_OF_RESOURCES;
    }

    HBufferImage.CurrentLine = Line;
  }

  HBufferImage.Modified           = FALSE;
  HBufferImageNeedRefresh         = TRUE;
  HBufferImageOnlyLineNeedRefresh = FALSE;
  HBufferImageMouseNeedRefresh    = TRUE;

  return EFI_SUCCESS;
}
Esempio n. 30
0
EFI_DEVICE_PATH *
AppendDevicePath (
    IN EFI_DEVICE_PATH  *Src1,
    IN EFI_DEVICE_PATH  *Src2
    )
// Src1 may have multiple "instances" and each instance is appended
// Src2 is appended to each instance is Src1.  (E.g., it's possible
// to append a new instance to the complete device path by passing 
// it in Src2)
{
    UINTN               Src1Size, Src1Inst, Src2Size, Size;
    EFI_DEVICE_PATH     *Dst, *Inst;
    UINT8               *DstPos;

    //
    // If there's only 1 path, just duplicate it
    //

    if (!Src1) {
        ASSERT (!IsDevicePathUnpacked (Src2));
        return DuplicateDevicePath (Src2);
    }

    if (!Src2) {
        ASSERT (!IsDevicePathUnpacked (Src1));
        return DuplicateDevicePath (Src1);
    }

    //
    // Verify we're not working with unpacked paths
    //

//    ASSERT (!IsDevicePathUnpacked (Src1));
//    ASSERT (!IsDevicePathUnpacked (Src2));

    //
    // Append Src2 to every instance in Src1
    //

    Src1Size = DevicePathSize(Src1);
    Src1Inst = DevicePathInstanceCount(Src1);
    Src2Size = DevicePathSize(Src2);
    Size = Src1Size * Src1Inst + Src2Size;
    
    Dst = (EFI_DEVICE_PATH *) AllocatePool (Size);
    if (Dst) {
        DstPos = (UINT8 *) Dst;

        //
        // Copy all device path instances
        //

        while (Inst = DevicePathInstance (&Src1, &Size)) {

            BS->CopyMem(DstPos, Inst, Size);
            DstPos += Size;

            BS->CopyMem(DstPos, Src2, Src2Size);
            DstPos += Src2Size;

            BS->CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH));
            DstPos += sizeof(EFI_DEVICE_PATH);
        }

        // Change last end marker
        DstPos -= sizeof(EFI_DEVICE_PATH);
        BS->CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH));
    }

    return Dst;
}