Esempio n. 1
0
/*++
 * @name EfiInitpGetDeviceNode
 *
 *     The EfiInitpGetDeviceNode routine 
 *
 * @param  DevicePath
 *         UEFI Image Handle for the current loaded application.
 *
 * @return None
 *
 *--*/
EFI_DEVICE_PATH_PROTOCOL*
EfiInitpGetDeviceNode (
    _In_ EFI_DEVICE_PATH_PROTOCOL *DevicePath
    )
{
    EFI_DEVICE_PATH_PROTOCOL* NextPath;

    /* Check if we hit the end terminator */
    if (IsDevicePathEndType(DevicePath))
    {
        return DevicePath;
    }

    /* Loop each device path, until we get to the end or to a file path device node */
    for ((NextPath = NextDevicePathNode(DevicePath));
         !(IsDevicePathEndType(NextPath)) && ((NextPath->Type != MEDIA_DEVICE_PATH) ||
                                              (NextPath->SubType != MEDIA_FILEPATH_DP));
         (NextPath = NextDevicePathNode(NextPath)))
    {
        /* Keep iterating down */
        DevicePath = NextPath;
    }

    /* Return the path found */
    return DevicePath;
}
Esempio n. 2
0
/* Currently this function is useless */
void GetFilePathList(BDS_LOAD_OPTION* BdsLoadOption, char* buffer, int descSize)
{
    if (BdsLoadOption->FilePathListLength <= 0)
        return;

    EFI_DEVICE_PATH_PROTOCOL* DevicePathNode = BdsLoadOption->FilePathList;

    // File path fields
    DevicePathNode = BdsLoadOption->FilePathList;
    if (DevicePathType(DevicePathNode) != MEDIA_DEVICE_PATH_TYPE)
        return;

    while (!IsDevicePathEndType(DevicePathNode))
    {
        switch (DevicePathSubType(DevicePathNode))
        {
        case HARDDRIVE_SUBTYPE:
            printf("HDD");
            break;

        case FILE_PATH_SUBTYPE:
            printf("FILE");
            break;
        }


        DevicePathNode = NextDevicePathNode(DevicePathNode);
    }
}
Esempio n. 3
0
EFI_DEVICE_PATH *
DevicePathInstance (
    IN OUT EFI_DEVICE_PATH  **DevicePath,
    OUT UINTN               *Size
    )
{
    EFI_DEVICE_PATH         *Start, *Next, *DevPath;
    UINTN                   Count;

    DevPath = *DevicePath;
    Start = DevPath;

    if (!DevPath) {
        return NULL;
    }

    //
    // Check for end of device path type
    //    

    for (Count = 0; ; Count++) {
        Next = NextDevicePathNode(DevPath);

        if (IsDevicePathEndType(DevPath)) {
            break;
        }

        if (Count > 01000) {
            //
            // BugBug: Debug code to catch bogus device paths
            //
            DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) ));
            DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start);
            break;
        }

        DevPath = Next;
    }

    ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE ||
            DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE);

    //
    // Set next position
    //

    if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
        Next = NULL;
    }

    *DevicePath = Next;

    //
    // Return size and start of device path instance
    //

    *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start);
    return Start;
}
Esempio n. 4
0
/**
  Determines if a device path node is an end node of a device path instance.

  Determines if a device path node specified by Node is an end node of a device 
  path instance.
  If Node represents the end of a device path instance, then TRUE is returned.  
  Otherwise, FALSE is returned.

  If Node is NULL, then ASSERT().

  @param  Node      A pointer to a device path node data structure.

  @retval TRUE      The device path node specified by Node is the end of a device 
  path instance.
  @retval FALSE     The device path node specified by Node is not the end of a 
  device path instance.

**/
BOOLEAN
EFIAPI
IsDevicePathEndInstance (
  IN CONST VOID  *Node
  )
{
  ASSERT (Node != NULL);
  return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
}
Esempio n. 5
0
static NVME_NAMESPACE_DEVICE_PATH *get_nvme_device_path(EFI_DEVICE_PATH *p)
{
	for (; !IsDevicePathEndType(p); p = NextDevicePathNode(p)) {
		if (DevicePathType(p) == MESSAGING_DEVICE_PATH
		   && DevicePathSubType(p) == MSG_NVME_NAMESPACE_DP)
			return (NVME_NAMESPACE_DEVICE_PATH *)p;
	}

	return NULL;
}
PCI_DEVICE_PATH* get_pci_device_path(EFI_DEVICE_PATH *p)
{
	while (!IsDevicePathEndType(p)) {
		if (DevicePathType(p) == HARDWARE_DEVICE_PATH
		    && DevicePathSubType(p) == HW_PCI_DP)
			return (PCI_DEVICE_PATH *)p;
		p = NextDevicePathNode(p);
	}
	return NULL;
}
Esempio n. 7
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. 8
0
// Return the last non end-type Device Path Node from a Device Path
EFI_DEVICE_PATH*
GetLastDevicePathNode (
  IN EFI_DEVICE_PATH*  DevicePath
  )
{
  EFI_DEVICE_PATH*     PrevDevicePathNode;

  PrevDevicePathNode = DevicePath;
  while (!IsDevicePathEndType (DevicePath)) {
    PrevDevicePathNode = DevicePath;
    DevicePath = NextDevicePathNode (DevicePath);
  }

  return PrevDevicePathNode;
}
Esempio n. 9
0
BOOLEAN
IsNodeInDevicePath (
  IN EFI_DEVICE_PATH_PROTOCOL  *Node,
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  EFI_DEVICE_PATH_PROTOCOL    *DevPath;
  UINTN                       Length;

  DevPath = DevicePath;
  while (!IsDevicePathEndType (DevPath)) {

    Length = (UINTN)(DevPath->Length[1] << 8 | DevPath->Length[0]);

    if (!CompareMem (DevPath, Node, Length)) {
      return TRUE;
    }

    DevPath = NextDevicePathNode (DevPath);
  }

  return FALSE;
}
Esempio n. 10
0
/**
  Connect the console device base on the variable ConVarName, if
  device path of the ConVarName is multi-instance device path and
  anyone of the instances is connected success, then this function
  will return success.
  If the handle associate with one device path node can not
  be created successfully, then still give chance to do the dispatch,
  which load the missing drivers if possible..

  @param  ConVarName               Console related variable name, ConIn, ConOut,
                                   ErrOut.

  @retval EFI_NOT_FOUND            There is not any console devices connected
                                   success
  @retval EFI_SUCCESS              Success connect any one instance of the console
                                   device path base on the variable ConVarName.

**/
EFI_STATUS
EFIAPI
BdsLibConnectConsoleVariable (
  IN  CHAR16                 *ConVarName
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *StartDevicePath;
  UINTN                     VariableSize;
  EFI_DEVICE_PATH_PROTOCOL  *Instance;
  EFI_DEVICE_PATH_PROTOCOL  *Next;
  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;
  UINTN                     Size;
  BOOLEAN                   DeviceExist;

  Status      = EFI_SUCCESS;
  DeviceExist = FALSE;

  //
  // Check if the console variable exist
  //
  StartDevicePath = BdsLibGetVariableAndSize (
                      ConVarName,
                      &gEfiGlobalVariableGuid,
                      &VariableSize
                      );
  if (StartDevicePath == NULL) {
    return EFI_UNSUPPORTED;
  }

  CopyOfDevicePath = StartDevicePath;
  do {
    //
    // Check every instance of the console variable
    //
    Instance  = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);
    if (Instance == NULL) {
      FreePool (StartDevicePath);
      return EFI_UNSUPPORTED;
    }
    
    Next      = Instance;
    while (!IsDevicePathEndType (Next)) {
      Next = NextDevicePathNode (Next);
    }

    SetDevicePathEndNode (Next);
    //
    // Connect the USB console
    // USB console device path is a short-form device path that 
    //  starts with the first element being a USB WWID
    //  or a USB Class device path
    //
    if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
       ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)
       || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)
       )) {
      Status = BdsLibConnectUsbDevByShortFormDP (0xFF, Instance);
      if (!EFI_ERROR (Status)) {
        DeviceExist = TRUE;
      }
    } else {
      //
      // Connect the instance device path
      //
      Status = BdsLibConnectDevicePath (Instance);

      if (EFI_ERROR (Status)) {
        //
        // Delete the instance from the console varialbe
        //
        BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance);
      } else {
        DeviceExist = TRUE;
      }
    }
    FreePool(Instance);
  } while (CopyOfDevicePath != NULL);

  FreePool (StartDevicePath);

  if (!DeviceExist) {
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}
Esempio n. 11
0
EFI_DEVICE_PATH_PROTOCOL *
DevicePathInstance (
  IN OUT EFI_DEVICE_PATH_PROTOCOL   **DevicePath,
  OUT UINTN                         *Size
  )
/*++

Routine Description:
  Function retrieves the next device path instance from a device path data structure.

Arguments:
  DevicePath           - A pointer to a device path data structure.

  Size                 - A pointer to the size of a device path instance in bytes.

Returns:

  This function returns a pointer to the current device path instance.
  In addition, it returns the size in bytes of the current device path instance in Size,
  and a pointer to the next device path instance in DevicePath.
  If there are no more device path instances in DevicePath, then DevicePath will be set to NULL.

--*/
{
  EFI_DEVICE_PATH_PROTOCOL    *Start, *Next, *DevPath;
  UINTN                       Count;

  DevPath = *DevicePath;
  Start = DevPath;

  if (!DevPath) {
    return NULL;
  }

  //
  // Check for end of device path type
  //

  for (Count = 0; ; Count++) {
    Next = NextDevicePathNode(DevPath);

    if (IsDevicePathEndType(DevPath)) {
      break;
    }

    if (Count > 01000) {
      //
      // BugBug: Debug code to catch bogus device paths
      //
      DEBUG((EFI_D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) ));
      DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start);
      break;
    }

    DevPath = Next;
  }

  ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE ||
          DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE);

  //
  // Set next position
  //

  if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
    Next = NULL;
  }

  *DevicePath = Next;

  //
  // Return size and start of device path instance
  //
  *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start) + sizeof(EFI_DEVICE_PATH_PROTOCOL);
  return Start;
}
Esempio n. 12
0
EFI_STATUS
BdsLoadOptionMemMapList (
  IN OUT LIST_ENTRY* BdsLoadOptionList
  )
{
  EFI_STATUS                          Status;
  UINTN                               HandleCount;
  EFI_HANDLE                         *HandleBuffer;
  UINTN                               DevicePathHandleCount;
  EFI_HANDLE                         *DevicePathHandleBuffer;
  BOOLEAN                             IsParent;
  UINTN                               Index;
  UINTN                               Index2;
  BDS_SUPPORTED_DEVICE               *SupportedDevice;
  EFI_DEVICE_PATH_PROTOCOL*           DevicePathProtocol;
  EFI_DEVICE_PATH*                    DevicePath;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL    *FileProtocol;
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol;

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

  for (Index = 0; Index < HandleCount; Index++) {
    // We only select handles WITH a Device Path AND not part of Media (to
    // avoid duplication with HardDisk, CDROM, etc). Skip handles used by
    // Simple Filesystem or used for Variable Storage.


    Status = gBS->HandleProtocol (HandleBuffer[Index],
                                  &gEfiSimpleFileSystemProtocolGuid,
                                  (VOID *)&FileProtocol);
    if (!EFI_ERROR(Status)) {
      // SimpleFilesystem supported on this handle, skip
      continue;
    }

    Status = gBS->HandleProtocol (HandleBuffer[Index],
                                  &gEfiFirmwareVolumeBlockProtocolGuid,
                                  (VOID *)&FvbProtocol);
    if (!EFI_ERROR(Status)) {
      // Firmware Volme Block / Variable storage supported on this handle, skip
      continue;
    }

    Status = gBS->HandleProtocol (HandleBuffer[Index],
                                  &gEfiFirmwareVolumeBlock2ProtocolGuid,
                                  (VOID *)&FvbProtocol);
    if (!EFI_ERROR(Status)) {
      // Firmware Volme Block / Variable storage supported on this handle, skip
      continue;
    }

    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);
    if (!EFI_ERROR(Status)) {
      // BlockIo is not part of Media Device Path
      DevicePath = DevicePathProtocol;
      while (!IsDevicePathEndType (DevicePath) && (DevicePathType (DevicePath) != MEDIA_DEVICE_PATH)) {
        DevicePath = NextDevicePathNode (DevicePath);
      }
      if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) {
        continue;
      }

      // Open all the handle supporting the DevicePath protocol and verify this handle has not got any child
      Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiDevicePathProtocolGuid, NULL, &DevicePathHandleCount, &DevicePathHandleBuffer);
      ASSERT_EFI_ERROR (Status);
      IsParent = FALSE;
      for (Index2 = 0; (Index2 < DevicePathHandleCount) && !IsParent; Index2++) {
        if (HandleBuffer[Index] != DevicePathHandleBuffer[Index2]) {
          gBS->HandleProtocol (DevicePathHandleBuffer[Index2], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
          if (IsParentDevicePath (DevicePathProtocol, DevicePath)) {
            IsParent = TRUE;
          }
        }
      }
      if (IsParent) {
        continue;
      }

      // Allocate BDS Supported Device structure
      SupportedDevice = (BDS_SUPPORTED_DEVICE*)AllocatePool(sizeof(BDS_SUPPORTED_DEVICE));

      Status = GenerateDeviceDescriptionName (HandleBuffer[Index], SupportedDevice->Description);
      ASSERT_EFI_ERROR (Status);
      if(NULL != SupportedDevice)
      {
          SupportedDevice->DevicePathProtocol = DevicePathProtocol;
          SupportedDevice->Support = &BdsLoadOptionSupportList[BDS_DEVICE_MEMMAP];
      }

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

  return EFI_SUCCESS;
}
Esempio n. 13
0
/*
  Initialise: Open the Android NVM device and find the partitions on it. Save them in
  a list along with the "PartitionName" fields for their GPT entries.
  We will use these partition names as the key in
  ArmFastbootPlatformFlashPartition.
*/
EFI_STATUS
ArmFastbootPlatformInit (
  VOID
  )
{
  EFI_STATUS                          Status;
  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePath;
  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePathDup;
  EFI_DEVICE_PATH_PROTOCOL           *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL           *NextNode;
  HARDDRIVE_DEVICE_PATH              *PartitionNode;
  UINTN                               NumHandles;
  EFI_HANDLE                         *AllHandles;
  UINTN                               LoopIndex;
  EFI_HANDLE                          FlashHandle;
  EFI_BLOCK_IO_PROTOCOL              *FlashBlockIo;
  EFI_PARTITION_ENTRY                *PartitionEntries;
  FASTBOOT_PARTITION_LIST            *Entry;

  InitializeListHead (&mPartitionListHead);

  //
  // Get EFI_HANDLES for all the partitions on the block devices pointed to by
  // PcdFastbootFlashDevicePath, also saving their GPT partition labels.
  // There's no way to find all of a device's children, so we get every handle
  // in the system supporting EFI_BLOCK_IO_PROTOCOL and then filter out ones
  // that don't represent partitions on the flash device.
  //

  FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));

  //
  // Open the Disk IO protocol on the flash device - this will be used to read
  // partition names out of the GPT entries
  //
  // Create another device path pointer because LocateDevicePath will modify it.
  FlashDevicePathDup = FlashDevicePath;
  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePathDup, &FlashHandle);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Warning: Couldn't locate Android NVM device (status: %r)\n", Status));
    // Failing to locate partitions should not prevent to do other Android FastBoot actions
    return EFI_SUCCESS;
  }

  Status = gBS->OpenProtocol (
                  FlashHandle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **) &FlashBlockIo,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Fastboot platform: Couldn't open Android NVM device (status: %r)\n", Status));
    return EFI_DEVICE_ERROR;
  }

  // Read the GPT partition entry array into memory so we can get the partition names
  Status = ReadPartitionEntries (FlashBlockIo, &PartitionEntries);
  if (EFI_ERROR (Status)) {
	DEBUG ((EFI_D_ERROR, "Warning: Failed to read partitions from Android NVM device (status: %r)\n", Status));
	// Failing to locate partitions should not prevent to do other Android FastBoot actions
	return EFI_SUCCESS;
  }

  // Get every Block IO protocol instance installed in the system
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiBlockIoProtocolGuid,
                  NULL,
                  &NumHandles,
                  &AllHandles
                  );
  ASSERT_EFI_ERROR (Status);

  // Filter out handles that aren't children of the flash device
  for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) {
    // Get the device path for the handle
    Status = gBS->OpenProtocol (
                    AllHandles[LoopIndex],
                    &gEfiDevicePathProtocolGuid,
                    (VOID **) &DevicePath,
                    gImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    ASSERT_EFI_ERROR (Status);

    // Check if it is a sub-device of the flash device
    if (!CompareMem (DevicePath, FlashDevicePath, FLASH_DEVICE_PATH_SIZE (FlashDevicePath))) {
      // Device path starts with path of flash device. Check it isn't the flash
      // device itself.
      NextNode = NextDevicePathNode (DevicePath);
      if (IsDevicePathEndType (NextNode)) {
        continue;
      }

      // Assert that this device path node represents a partition.
      ASSERT (NextNode->Type == MEDIA_DEVICE_PATH &&
              NextNode->SubType == MEDIA_HARDDRIVE_DP);

      PartitionNode = (HARDDRIVE_DEVICE_PATH *) NextNode;

      // Assert that the partition type is GPT. ReadPartitionEntries checks for
      // presence of a GPT, so we should never find MBR partitions.
      // ("MBRType" is a misnomer - this field is actually called "Partition
      //  Format")
      ASSERT (PartitionNode->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER);

      // The firmware may install a handle for "partition 0", representing the
      // whole device. Ignore it.
      if (PartitionNode->PartitionNumber == 0) {
        continue;
      }

      //
      // Add the partition handle to the list
      //

      // Create entry
      Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST));
      if (Entry == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        FreePartitionList ();
        goto Exit;
      }

      // Copy handle and partition name
      Entry->PartitionHandle = AllHandles[LoopIndex];
      StrnCpy (
        Entry->PartitionName,
        PartitionEntries[PartitionNode->PartitionNumber - 1].PartitionName, // Partition numbers start from 1.
        PARTITION_NAME_MAX_LENGTH
        );
      InsertTailList (&mPartitionListHead, &Entry->Link);

      // Print a debug message if the partition label is empty or looks like
      // garbage.
      if (!IS_ALPHA (Entry->PartitionName[0])) {
        DEBUG ((EFI_D_ERROR,
          "Warning: Partition %d doesn't seem to have a GPT partition label. "
          "You won't be able to flash it with Fastboot.\n",
          PartitionNode->PartitionNumber
          ));
      }
    }
  }

Exit:
  FreePool (PartitionEntries);
  FreePool (FlashDevicePath);
  FreePool (AllHandles);
  return Status;

}
Esempio n. 14
0
/**
  Connect the console device base on the variable ConsoleType.

  @param  ConsoleType              ConIn, ConOut or ErrOut.
  @param  NeedDispatch             Whether need to dispatch.

  @retval EFI_NOT_FOUND            There is not any console devices connected
                                   success
  @retval EFI_SUCCESS              Success connect any one instance of the console
                                   device path base on the variable ConVarName.

**/
EFI_STATUS
EFIAPI
EfiBootManagerConnectConsoleVariable (
  IN  CONSOLE_TYPE              ConsoleType,
  IN  BOOLEAN                   NeedDispatch
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *StartDevicePath;
  UINTN                     VariableSize;
  EFI_DEVICE_PATH_PROTOCOL  *Instance;
  EFI_DEVICE_PATH_PROTOCOL  *Next;
  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;
  UINTN                     Size;
  BOOLEAN                   DeviceExist;
  EFI_HANDLE                Handle;

  if ((ConsoleType != ConIn) && (ConsoleType != ConOut) && (ConsoleType != ErrOut)) {
    return EFI_INVALID_PARAMETER;
  }

  Status      = EFI_SUCCESS;
  DeviceExist = FALSE;

  //
  // Check if the console variable exist
  //
  StartDevicePath = EfiBootManagerGetVariableAndSize (
                      mConVarName[ConsoleType],
                      &gEfiGlobalVariableGuid,
                      &VariableSize
                      );
  if (StartDevicePath == NULL) {
    return EFI_UNSUPPORTED;
  }

  CopyOfDevicePath = StartDevicePath;
  do {
    //
    // Check every instance of the console variable
    //
    Instance  = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);
    if (Instance == NULL) {
      FreePool (StartDevicePath);
      return EFI_UNSUPPORTED;
    }
    
    Next      = Instance;
    while (!IsDevicePathEndType (Next)) {
      Next = NextDevicePathNode (Next);
    }

    SetDevicePathEndNode (Next);
    //
    // Connect the USB console
    // USB console device path is a short-form device path that 
    //  starts with the first element being a USB WWID
    //  or a USB Class device path
    //
    if (FeaturePcdGet (PcdShortformBootSupport) &&
        (DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
        ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP) || (DevicePathSubType (Instance) == MSG_USB_WWID_DP))
       ) {
      Status = EfiBootManagerConnectUsbShortFormDevicePath (Instance);
      if (!EFI_ERROR (Status)) {
        DeviceExist = TRUE;
      }
    } else {
      //
      // Connect the instance device path
      //
      Status = ConnectDevicePath (Instance, NeedDispatch, NULL);
      if (EFI_ERROR (Status)) {
        //
        // Do not delete the instance from the console variable if the device path is of GOP type
        // and the parent controller exists in the system
        // This is to support the monitor hotplug in a headless boot
        //
        for (Next = Instance; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {
          if (DevicePathType (Next) == ACPI_DEVICE_PATH && DevicePathSubType (Next) == ACPI_ADR_DP) {
            break;
          }
        }
        if (!IsDevicePathEnd (Next)) {
          Next = Instance;
          Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Next, &Handle);
          if (!EFI_ERROR (Status) && (DevicePathType (Next) != ACPI_DEVICE_PATH || DevicePathSubType (Next) != ACPI_ADR_DP)) {
            //
            // We found the parent controller but it's not the direct parent of the ADR device path instance
            // which indicates the video controller doesn't exist.
            // If this happens, we need to delete the invalid device path from ConOut
            //
            Status = EFI_NOT_FOUND;
          }
        }
      } else {
        DeviceExist = TRUE;
      }

      if (EFI_ERROR (Status)) {
        //
        // Delete the instance from the console variable
        //
        EfiBootManagerUpdateConsoleVariable (ConsoleType, NULL, Instance);
      }
    }
    FreePool(Instance);
  } while (CopyOfDevicePath != NULL);

  FreePool (StartDevicePath);

  if ((ConsoleType == ConOut) && FeaturePcdGet (PcdBdsFindDisplay) && !HasLocalDisplay ()) {
    //
    // Force to connect local video controller
    // Backward compatible to old platforms which don't insert the GOP device path to ConOut
    //
    DEBUG ((EFI_D_ERROR, "[Bds] Local display isn't found, find & connect it automatically\n"));
    Status = ConnectVideoController ();
    if (!EFI_ERROR (Status)) {
      DeviceExist = TRUE;
    }
  }

  if (!DeviceExist) {
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}
Esempio n. 15
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. 16
0
/** 
  Get a human readable name for an image handle.
  The following methods will be tried orderly:
    1. Image PDB
    2. ComponentName2 protocol
    3. FFS UI section
    4. Image GUID
    5. Image DevicePath
    6. Unknown Driver Name

  @param[in]    Handle

  @post   The resulting Unicode name string is stored in the
          mGaugeString global array.

**/
VOID
DpGetNameFromHandle (
  IN EFI_HANDLE   Handle
  )
{
  EFI_STATUS                  Status;
  EFI_LOADED_IMAGE_PROTOCOL   *Image;
  CHAR8                       *PdbFileName;
  EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
  EFI_STRING                  StringPtr;
  EFI_DEVICE_PATH_PROTOCOL    *LoadedImageDevicePath;
  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
  EFI_GUID                    *NameGuid;
  CHAR16                      *NameString;
  UINTN                       StringSize;
  CHAR8                       *PlatformLanguage;
  EFI_COMPONENT_NAME2_PROTOCOL      *ComponentName2;

  Image = NULL;
  LoadedImageDevicePath = NULL;
  DevicePath = NULL;

  //
  // Method 1: Get the name string from image PDB
  //
  Status = gBS->HandleProtocol (
                  Handle,
                  &gEfiLoadedImageProtocolGuid,
                  (VOID **) &Image
                  );

  if (EFI_ERROR (Status)) {
    Status = gBS->OpenProtocol (
                    Handle,
                    &gEfiDriverBindingProtocolGuid,
                    (VOID **) &DriverBinding,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      Status = gBS->HandleProtocol (
                      DriverBinding->ImageHandle,
                      &gEfiLoadedImageProtocolGuid,
                      (VOID **) &Image
                      );
    }
  }

  if (!EFI_ERROR (Status)) {
    PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase);

    if (PdbFileName != NULL) {
      DpGetShortPdbFileName (PdbFileName, mGaugeString);
      return;
    }
  }

  //
  // Method 2: Get the name string from ComponentName2 protocol
  //
  Status = gBS->HandleProtocol (
                  Handle,
                  &gEfiComponentName2ProtocolGuid,
                  (VOID **) &ComponentName2
                  );
  if (!EFI_ERROR (Status)) {
    //
    // Get the current platform language setting
    //
    PlatformLanguage = GetBestLanguageForDriver(ComponentName2->SupportedLanguages, NULL, FALSE);
    Status = ComponentName2->GetDriverName (
                               ComponentName2,
                               PlatformLanguage != NULL ? PlatformLanguage : "en-US",
                               &StringPtr
                               );
    if (!EFI_ERROR (Status)) {
      SHELL_FREE_NON_NULL (PlatformLanguage);
      StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, StringPtr, DP_GAUGE_STRING_LENGTH);
      mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
      return;
    }
  }

  Status = gBS->HandleProtocol (
                  Handle,
                  &gEfiLoadedImageDevicePathProtocolGuid,
                  (VOID **) &LoadedImageDevicePath
                  );
  if (!EFI_ERROR (Status) && (LoadedImageDevicePath != NULL)) {
    DevicePath = LoadedImageDevicePath;
  } else if (Image != NULL) {
    DevicePath = Image->FilePath;
  }

  if (DevicePath != NULL) {
    //
    // Try to get image GUID from image DevicePath
    //
    NameGuid = NULL;
    while (!IsDevicePathEndType (DevicePath)) {
      NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePath);
      if (NameGuid != NULL) {
        break;
      }
      DevicePath = NextDevicePathNode (DevicePath);
    }

    if (NameGuid != NULL) {
      //
      // Try to get the image's FFS UI section by image GUID
      //
      NameString = NULL;
      StringSize = 0;
      Status = GetSectionFromAnyFv (
                NameGuid,
                EFI_SECTION_USER_INTERFACE,
                0,
                (VOID **) &NameString,
                &StringSize
                );

      if (!EFI_ERROR (Status)) {
        //
        // Method 3. Get the name string from FFS UI section
        //
        StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, NameString, DP_GAUGE_STRING_LENGTH);
        mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
        FreePool (NameString);
      } else {
        //
        // Method 4: Get the name string from image GUID
        //
        UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", NameGuid);
      }
      return;
    } else {
      //
      // Method 5: Get the name string from image DevicePath
      //
      NameString = ConvertDevicePathToText (DevicePath, TRUE, FALSE);
      if (NameString != NULL) {
        StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, NameString, DP_GAUGE_STRING_LENGTH);
        mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;
        FreePool (NameString);
        return;
      }
    }
  }

  //
  // Method 6: Unknown Driver Name
  //
  StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_ERROR_NAME), NULL);
  ASSERT (StringPtr != NULL);
  StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, StringPtr, DP_GAUGE_STRING_LENGTH);
  FreePool (StringPtr);
}
Esempio n. 17
0
BOOL ValidateBootEntry(UINT8* buffer)
{

    //char buffer[512];					//Block of bytes
    BDS_LOAD_OPTION* pBootEntry;

    if (!buffer)
        return FALSE;

    //Alocate New BootDevice
    pBootEntry = (BDS_LOAD_OPTION*)calloc(1, sizeof(BDS_LOAD_OPTION));
    if (!pBootEntry)
        return FALSE;

    //Get Attributes
    pBootEntry->Attributes = GET_ATTRIBUTES(buffer);

    //Get FilePathListLength
    pBootEntry->FilePathListLength = GET_FILELISTLENGTH(buffer);

    //Get Description
    int descSize = wstrlen((WCHAR*)DESCRIPTION_OFFSET(buffer));// GET_DESCRIPTION_LENGTH(buffer);
    if (descSize == 0)
        return FALSE;

    pBootEntry->Description = ALLOCATE_WCHAR_STRING(descSize);
    if (pBootEntry->Description == NULL)
        return FALSE;

    memcpy(pBootEntry->Description, DESCRIPTION_OFFSET(buffer), descSize);

    //Get FilePathList
    pBootEntry->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)calloc(1, pBootEntry->FilePathListLength);
    if (pBootEntry->FilePathList == NULL)
        return FALSE;

    memcpy(pBootEntry->FilePathList, (EFI_DEVICE_PATH_PROTOCOL*)(DESCRIPTION_OFFSET(buffer) + descSize), pBootEntry->FilePathListLength);

    //Read FilePathList
    //GetFilePathList(pBootEntry, buffer, descSize);

    if (pBootEntry->FilePathListLength <= 0)
        return FALSE;

    EFI_DEVICE_PATH_PROTOCOL* DevicePathNode = pBootEntry->FilePathList;

    // File path fields
    DevicePathNode = pBootEntry->FilePathList;
    if (DevicePathType(DevicePathNode) != MEDIA_DEVICE_PATH_TYPE)
        return FALSE;


    while (!IsDevicePathEndType(DevicePathNode)) {

        DevicePathNode = NextDevicePathNode(DevicePathNode);
    }

    GUID* pG;
    while (!IsDevicePathEndType(DevicePathNode))
    {
        if (DevicePathNode->Type != 0x7F)
            if (DevicePathNode->Type < 0x01 || DevicePathNode->Type > 0x05)
            {
                return FALSE;
            }
        switch (DevicePathSubType(DevicePathNode))
        {
        case HARDDRIVE_SUBTYPE:
            HARDDRIVE_DEVICE_PATH* hd;
            hd = (HARDDRIVE_DEVICE_PATH *)DevicePathNode;
#if 0
            wprintf(L"\t PartitionFormat:%d\n", hd->PartitionFormat);
            wprintf(L"\t Partition No:%d\n", hd->PartitionNumber);
            wprintf(L"\t Partition Size:%d\n", hd->PartitionSize);
            wprintf(L"\t Partition Start:%d\n", hd->PartitionStart);
            wprintf(L"\t Signature type:%d\n", hd->SignatureType);
            pG = (GUID*)&hd->Signature;
            LPOLESTR xds;
            _GUID y;
            StringFromCLSID(*pG, &xds);
            wprintf(L"\t Partition Signature:%s\n", xds);
#endif
            break;

        case FILE_PATH_SUBTYPE:
            FILEPATH_DEVICE_PATH* f;
            f = (FILEPATH_DEVICE_PATH*)DevicePathNode;
#if 0
            wprintf(L"\t PathName:%s\n", f->PathName);
#endif
            break;
        }


        DevicePathNode = NextDevicePathNode(DevicePathNode);
    }

    return TRUE;
}
Esempio n. 18
0
/**
  For a bootable Device path, return its boot type.

  @param  DevicePath        The bootable device Path to check

  @retval AcpiFloppyBoot    If given device path contains ACPI_DEVICE_PATH type device path node
                            which HID is floppy device.
  @retval MessageAtapiBoot  If given device path contains MESSAGING_DEVICE_PATH type device path node
                            and its last device path node's subtype is MSG_ATAPI_DP.
  @retval MessageSataBoot   If given device path contains MESSAGING_DEVICE_PATH type device path node
                            and its last device path node's subtype is MSG_SATA_DP.
  @retval MessageScsiBoot   If given device path contains MESSAGING_DEVICE_PATH type device path node
                            and its last device path node's subtype is MSG_SCSI_DP.
  @retval MessageUsbBoot    If given device path contains MESSAGING_DEVICE_PATH type device path node
                            and its last device path node's subtype is MSG_USB_DP.
  @retval BmMiscBoot        If tiven device path doesn't match the above condition.

**/
BM_BOOT_TYPE
BmDevicePathType (
  IN  EFI_DEVICE_PATH_PROTOCOL     *DevicePath
  )
{
  EFI_DEVICE_PATH_PROTOCOL      *Node;
  EFI_DEVICE_PATH_PROTOCOL      *NextNode;

  ASSERT (DevicePath != NULL);

  for (Node = DevicePath; !IsDevicePathEndType (Node); Node = NextDevicePathNode (Node)) {
    switch (DevicePathType (Node)) {

      case ACPI_DEVICE_PATH:
        if (EISA_ID_TO_NUM (((ACPI_HID_DEVICE_PATH *) Node)->HID) == 0x0604) {
          return BmAcpiFloppyBoot;
        }
        break;

      case HARDWARE_DEVICE_PATH:
        if (DevicePathSubType (Node) == HW_CONTROLLER_DP) {
          return BmHardwareDeviceBoot;
        }
        break;

      case MESSAGING_DEVICE_PATH:
        //
        // Skip LUN device node
        //
        NextNode = Node;
        do {
          NextNode = NextDevicePathNode (NextNode);
        } while (
            (DevicePathType (NextNode) == MESSAGING_DEVICE_PATH) &&
            (DevicePathSubType(NextNode) == MSG_DEVICE_LOGICAL_UNIT_DP)
            );

        //
        // If the device path not only point to driver device, it is not a messaging device path,
        //
        if (!IsDevicePathEndType (NextNode)) {
          continue;
        }

        switch (DevicePathSubType (Node)) {
        case MSG_ATAPI_DP:
          return BmMessageAtapiBoot;
          break;

        case MSG_SATA_DP:
          return BmMessageSataBoot;
          break;

        case MSG_USB_DP:
          return BmMessageUsbBoot;
          break;

        case MSG_SCSI_DP:
          return BmMessageScsiBoot;
          break;
        }
    }
  }

  return BmMiscBoot;
}
Esempio n. 19
0
/**
  Connect the console device base on the variable ConsoleType.

  @param  ConsoleType              ConIn, ConOut or ErrOut.

  @retval EFI_NOT_FOUND            There is not any console devices connected
                                   success
  @retval EFI_SUCCESS              Success connect any one instance of the console
                                   device path base on the variable ConVarName.

**/
EFI_STATUS
EFIAPI
EfiBootManagerConnectConsoleVariable (
  IN  CONSOLE_TYPE              ConsoleType
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *StartDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *Instance;
  EFI_DEVICE_PATH_PROTOCOL  *Next;
  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;
  UINTN                     Size;
  BOOLEAN                   DeviceExist;
  EFI_HANDLE                Handle;

  if ((ConsoleType != ConIn) && (ConsoleType != ConOut) && (ConsoleType != ErrOut)) {
    return EFI_INVALID_PARAMETER;
  }

  Status      = EFI_SUCCESS;
  DeviceExist = FALSE;
  Handle      = NULL;

  //
  // Check if the console variable exist
  //
  GetEfiGlobalVariable2 (mConVarName[ConsoleType], (VOID **) &StartDevicePath, NULL);
  if (StartDevicePath == NULL) {
    return EFI_UNSUPPORTED;
  }

  CopyOfDevicePath = StartDevicePath;
  do {
    //
    // Check every instance of the console variable
    //
    Instance  = GetNextDevicePathInstance (&CopyOfDevicePath, &Size);
    if (Instance == NULL) {
      FreePool (StartDevicePath);
      return EFI_UNSUPPORTED;
    }
    
    Next      = Instance;
    while (!IsDevicePathEndType (Next)) {
      Next = NextDevicePathNode (Next);
    }

    SetDevicePathEndNode (Next);
    //
    // Connect the USB console
    // USB console device path is a short-form device path that 
    //  starts with the first element being a USB WWID
    //  or a USB Class device path
    //
    if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
        ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP) || (DevicePathSubType (Instance) == MSG_USB_WWID_DP))
       ) {
      Status = BmConnectUsbShortFormDevicePath (Instance);
      if (!EFI_ERROR (Status)) {
        DeviceExist = TRUE;
      }
    } else {
      for (Next = Instance; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {
        if (DevicePathType (Next) == ACPI_DEVICE_PATH && DevicePathSubType (Next) == ACPI_ADR_DP) {
          break;
        } else if (DevicePathType (Next) == HARDWARE_DEVICE_PATH && 
                   DevicePathSubType (Next) == HW_CONTROLLER_DP &&
                   DevicePathType (NextDevicePathNode (Next)) == ACPI_DEVICE_PATH &&
                   DevicePathSubType (NextDevicePathNode (Next)) == ACPI_ADR_DP
                   ) {
          break;
        }
      }
      if (!IsDevicePathEnd (Next)) {
        //
        // For GOP device path, start the video driver with NULL remaining device path
        //
        SetDevicePathEndNode (Next);
        Status = EfiBootManagerConnectDevicePath (Instance, &Handle);
        if (!EFI_ERROR (Status)) {
          gBS->ConnectController (Handle, NULL, NULL, TRUE);
        }
      } else {
        Status = EfiBootManagerConnectDevicePath (Instance, NULL);
      }
      if (EFI_ERROR (Status)) {
        //
        // Delete the instance from the console varialbe
        //
        EfiBootManagerUpdateConsoleVariable (ConsoleType, NULL, Instance);
      } else {
        DeviceExist = TRUE;
      }
    }
    FreePool(Instance);
  } while (CopyOfDevicePath != NULL);

  FreePool (StartDevicePath);

  if (!DeviceExist) {
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}
Esempio n. 20
0
/*++
 * @name EfiInitpConvertEfiDevicePath
 *
 *     The EfiInitpConvertEfiDevicePath routine 
 *
 * @param  DevicePath
 *         UEFI Image Handle for the current loaded application.
 *
 * @param  DeviceType
 *         Pointer to the UEFI System Table.
 *
 * @param  Option
 *         Pointer to the UEFI System Table.
 *
 * @param  MaximumLength
 *         Pointer to the UEFI System Table.
 *
 * @return None
 *
 *--*/
NTSTATUS
EfiInitpConvertEfiFilePath (
    _In_ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
    _In_ ULONG PathType,
    _In_ PBL_BCD_OPTION Option,
    _In_ ULONG MaximumLength
    )
{
    ULONG BytesAppended, DataSize, StringLength;
    PWCHAR StringEntry, PathString;
    FILEPATH_DEVICE_PATH *FilePath;
    NTSTATUS Status;

    /* Make sure we have enough space for the option */
    if (MaximumLength < sizeof(*Option))
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Set the initial size of the option, and consume from our buffer */
    DataSize = sizeof(*Option);
    MaximumLength -= sizeof(*Option);

    /* Zero out and fill the option header */
    RtlZeroMemory(Option, DataSize);
    Option->Type = PathType;
    Option->DataOffset = sizeof(*Option);

    /* Extract the string option */
    StringEntry = (PWCHAR)(Option + 1);
    PathString = StringEntry;

    /* Start parsing the device path */
    FilePath = (FILEPATH_DEVICE_PATH*)DevicePath;
    while (IsDevicePathEndType(FilePath) == FALSE)
    {
        /* Is this a file path? */
        if ((FilePath->Header.Type == MEDIA_DEVICE_PATH) &&
            (FilePath->Header.SubType == MEDIA_FILEPATH_DP))
        {
            /* Get the length of the file path string, avoiding overflow */
            StringLength = DevicePathNodeLength(FilePath) -
                           FIELD_OFFSET(FILEPATH_DEVICE_PATH, PathName);
            if (StringLength < (ULONG)FIELD_OFFSET(FILEPATH_DEVICE_PATH, PathName))
            {
                Status = STATUS_INTEGER_OVERFLOW;
                goto Quickie;
            }

            /* Append this path string to the current path string */
            Status = EfiInitpAppendPathString(PathString,
                                              MaximumLength,
                                              FilePath->PathName,
                                              StringLength,
                                              &BytesAppended);
            if (!NT_SUCCESS(Status))
            {
                return Status;
            }

            /* Increase the size of the data, consume buffer space */
            DataSize += BytesAppended;
            MaximumLength -= BytesAppended;

            /* Move to the next path string */
            PathString = (PWCHAR)((ULONG_PTR)PathString + BytesAppended);
        }

        /* Move to the next path node */
        FilePath = (FILEPATH_DEVICE_PATH*)NextDevicePathNode(FilePath);
    }

    /* Check if we still have space for a NULL-terminator */
    if (MaximumLength < sizeof(UNICODE_NULL))
    {
        Status = STATUS_INVALID_PARAMETER;
        goto Quickie;
    }

    /* We do -- NULL-terminate the string */
    *PathString = UNICODE_NULL;
    DataSize += sizeof(UNICODE_NULL);

    /* Check if all of this has amounted to a single NULL-char */
    if (PathString == StringEntry)
    {
        /* Then this option is empty */
        Option->Empty = TRUE;
    }

    /* Set the final size of the option */
    Option->DataSize = DataSize;

Quickie:
    return STATUS_SUCCESS;
}
Esempio n. 21
0
/**
  Get the image type.

  @param[in]    File    This is a pointer to the device path of the file
                        that is being dispatched.

  @return       UINT32  Image Type

**/
UINT32
GetFileType (
  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *File
  )
{
  EFI_STATUS                        Status;
  EFI_HANDLE                        DeviceHandle;
  EFI_DEVICE_PATH_PROTOCOL          *TempDevicePath;
  EFI_BLOCK_IO_PROTOCOL             *BlockIo;

  //
  // First check to see if File is from a Firmware Volume
  //
  DeviceHandle      = NULL;
  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
  Status = gBS->LocateDevicePath (
                  &gEfiFirmwareVolume2ProtocolGuid,
                  &TempDevicePath,
                  &DeviceHandle
                  );
  if (!EFI_ERROR (Status)) {
    Status = gBS->OpenProtocol (
                    DeviceHandle,
                    &gEfiFirmwareVolume2ProtocolGuid,
                    NULL,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      return IMAGE_FROM_FV;
    }
  }

  //
  // Next check to see if File is from a Block I/O device
  //
  DeviceHandle   = NULL;
  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
  Status = gBS->LocateDevicePath (
                  &gEfiBlockIoProtocolGuid,
                  &TempDevicePath,
                  &DeviceHandle
                  );
  if (!EFI_ERROR (Status)) {
    BlockIo = NULL;
    Status = gBS->OpenProtocol (
                    DeviceHandle,
                    &gEfiBlockIoProtocolGuid,
                    (VOID **) &BlockIo,
                    NULL,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status) && BlockIo != NULL) {
      if (BlockIo->Media != NULL) {
        if (BlockIo->Media->RemovableMedia) {
          //
          // Block I/O is present and specifies the media is removable
          //
          return IMAGE_FROM_REMOVABLE_MEDIA;
        } else {
          //
          // Block I/O is present and specifies the media is not removable
          //
          return IMAGE_FROM_FIXED_MEDIA;
        }
      }
    }
  }

  //
  // File is not in a Firmware Volume or on a Block I/O device, so check to see if
  // the device path supports the Simple File System Protocol.
  //
  DeviceHandle   = NULL;
  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
  Status = gBS->LocateDevicePath (
                  &gEfiSimpleFileSystemProtocolGuid,
                  &TempDevicePath,
                  &DeviceHandle
                  );
  if (!EFI_ERROR (Status)) {
    //
    // Simple File System is present without Block I/O, so assume media is fixed.
    //
    return IMAGE_FROM_FIXED_MEDIA;
  }

  //
  // File is not from an FV, Block I/O or Simple File System, so the only options
  // left are a PCI Option ROM and a Load File Protocol such as a PXE Boot from a NIC.
  //
  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
  while (!IsDevicePathEndType (TempDevicePath)) {
    switch (DevicePathType (TempDevicePath)) {

    case MEDIA_DEVICE_PATH:
      if (DevicePathSubType (TempDevicePath) == MEDIA_RELATIVE_OFFSET_RANGE_DP) {
        return IMAGE_FROM_OPTION_ROM;
      }
      break;

    case MESSAGING_DEVICE_PATH:
      if (DevicePathSubType(TempDevicePath) == MSG_MAC_ADDR_DP) {
        return IMAGE_FROM_REMOVABLE_MEDIA;
      }
      break;

    default:
      break;
    }
    TempDevicePath = NextDevicePathNode (TempDevicePath);
  }
  return IMAGE_UNKNOWN;
}
Esempio n. 22
0
File: Connect.c Progetto: b-man/edk2
/**
  Do a connect from an EFI variable via it's key name.

  @param[in] Key      The name of the EFI Variable.

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
ShellConnectFromDevPaths (
  IN CONST CHAR16 *Key
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevPath;
  EFI_DEVICE_PATH_PROTOCOL  *Instance;
  EFI_DEVICE_PATH_PROTOCOL  *Next;
  UINTN                     Length;
  UINTN                     Index;
  UINTN                     HandleArrayCount;
  UINTN                     Size;
  EFI_HANDLE                *HandleArray;
  EFI_STATUS                Status;
  BOOLEAN                   AtLeastOneConnected;
  EFI_PCI_IO_PROTOCOL       *PciIo;
  UINT8                     Class[3];

  DevPath = NULL;
  Length  = 0;
  AtLeastOneConnected = FALSE;

  //
  // Get the DevicePath buffer from the variable...
  //
  Status = gRT->GetVariable((CHAR16*)Key, (EFI_GUID*)&gEfiGlobalVariableGuid, NULL, &Length, DevPath);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    DevPath = AllocateZeroPool(Length);
    if (DevPath == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    Status = gRT->GetVariable((CHAR16*)Key, (EFI_GUID*)&gEfiGlobalVariableGuid, NULL, &Length, DevPath);
    if (EFI_ERROR (Status)) {
      if (DevPath != NULL) {
        FreePool (DevPath);
      }
      return Status;
    }
  } else if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = EFI_NOT_FOUND;

  CopyOfDevPath = DevPath;
  //
  // walk the list of devices and connect them
  //
  do {
    //
    // Check every instance of the console variable
    //
    Instance = GetNextDevicePathInstance (&CopyOfDevPath, &Size);
    if (Instance == NULL) {
      if (DevPath != NULL) {
        FreePool (DevPath);
      }
      return EFI_UNSUPPORTED;
    }

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

    SetDevicePathEndNode (Next);
    //
    // connect short form device path
    //
    if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) &&
      ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP)
      || (DevicePathSubType (Instance) == MSG_USB_WWID_DP)
      )) {

      Status = ShellConnectPciRootBridge ();
      if (EFI_ERROR(Status)) {
        FreePool(Instance);
        FreePool(DevPath);
        return Status;
      }

      Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiPciIoProtocolGuid,
                  NULL,
                  &HandleArrayCount,
                  &HandleArray
                  );

      if (!EFI_ERROR (Status)) {
        for (Index = 0; Index < HandleArrayCount; Index++) {
          Status = gBS->HandleProtocol (
                      HandleArray[Index],
                      &gEfiPciIoProtocolGuid,
                      (VOID **)&PciIo
                      );

          if (!EFI_ERROR (Status)) {
            Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
            if (!EFI_ERROR (Status)) {
              if ((PCI_CLASS_SERIAL == Class[2]) &&
                  (PCI_CLASS_SERIAL_USB == Class[1])) {
                Status = gBS->ConnectController (
                              HandleArray[Index],
                              NULL,
                              Instance,
                              FALSE
                              );
                if (!EFI_ERROR(Status)) {
                  AtLeastOneConnected = TRUE;
                }
              }
            }
          }
        }
      }

      if (HandleArray != NULL) {
        FreePool (HandleArray);
      }
    } else {
      //
      // connect the entire device path
      //
      Status = ShellConnectDevicePath (Instance);
      if (!EFI_ERROR (Status)) {
        AtLeastOneConnected = TRUE;
      }
    }
    FreePool (Instance);

  } while (CopyOfDevPath != NULL);

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

  if (AtLeastOneConnected) {
    return EFI_SUCCESS;
  } else {
    return EFI_NOT_FOUND;
  }

}