Ejemplo n.º 1
0
/**
  Returns the size of a device path in bytes.

  This function returns the size, in bytes, of the device path data structure 
  specified by DevicePath including the end of device path node. If DevicePath 
  is NULL, then 0 is returned. If the length of the device path is bigger than
  MaxSize, also return 0 to indicate this is an invalidate device path.

  @param  DevicePath         A pointer to a device path data structure.
  @param  MaxSize            Max valid device path size. If big than this size, 
                             return error.
  
  @retval 0                  An invalid device path.
  @retval Others             The size of a device path in bytes.

**/
UINTN
BmGetDevicePathSizeEx (
  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  IN UINTN                           MaxSize
  )
{
  UINTN  Size;
  UINTN  NodeSize;

  if (DevicePath == NULL) {
    return 0;
  }

  //
  // Search for the end of the device path structure
  //
  Size = 0;
  while (!IsDevicePathEnd (DevicePath)) {
    NodeSize = DevicePathNodeLength (DevicePath);
    if (NodeSize == 0) {
      return 0;
    }
    Size += NodeSize;
    if (Size > MaxSize) {
      return 0;
    }
    DevicePath = NextDevicePathNode (DevicePath);
  }
  Size += DevicePathNodeLength (DevicePath);
  if (Size > MaxSize) {
    return 0;
  }

  return Size;
}
Ejemplo n.º 2
0
EFI_DEVICE_PATH *
UnpackDevicePath (
    IN EFI_DEVICE_PATH  *DevPath
    )
{
    EFI_DEVICE_PATH     *Src, *Dest, *NewPath;
    UINTN               Size;
    
    //
    // Walk device path and round sizes to valid boundries
    //    

    Src = DevPath;
    Size = 0;
    for (; ;) {
        Size += DevicePathNodeLength(Src);
        Size += ALIGN_SIZE(Size);

        if (IsDevicePathEnd(Src)) {
            break;
        }

        Src = NextDevicePathNode(Src);
    }


    //
    // Allocate space for the unpacked path
    //

    NewPath = AllocateZeroPool (Size);
    if (NewPath) {

        ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0);

        //
        // Copy each node
        //

        Src = DevPath;
        Dest = NewPath;
        for (; ;) {
            Size = DevicePathNodeLength(Src);
            CopyMem (Dest, Src, Size);
            Size += ALIGN_SIZE(Size);
            SetDevicePathNodeLength (Dest, Size);
            Dest->Type |= EFI_DP_TYPE_UNPACKED;
            Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size);

            if (IsDevicePathEnd(Src)) {
                break;
            }

            Src = NextDevicePathNode(Src);
        }
    }

    return NewPath;
}
Ejemplo n.º 3
0
/**
  Determine whether a given device path is valid.
  If DevicePath is NULL, then ASSERT().

  @param  DevicePath  A pointer to a device path data structure.
  @param  MaxSize     The maximum size of the device path data structure.

  @retval TRUE        DevicePath is valid.
  @retval FALSE       The length of any node node in the DevicePath is less
                      than sizeof (EFI_DEVICE_PATH_PROTOCOL).
  @retval FALSE       If MaxSize is not zero, the size of the DevicePath
                      exceeds MaxSize.
  @retval FALSE       If PcdMaximumDevicePathNodeCount is not zero, the node
                      count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.
**/
BOOLEAN
EFIAPI
IsDevicePathValid (
  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
  IN       UINTN                    MaxSize
  )
{
  UINTN Count;
  UINTN Size;
  UINTN NodeLength;

  ASSERT (DevicePath != NULL);

  if (MaxSize == 0) {
    MaxSize = MAX_UINTN;
  }

  //
  // Validate the input size big enough to touch the first node.
  //
  if (MaxSize < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
    return FALSE;
  }

  for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
    NodeLength = DevicePathNodeLength (DevicePath);
    if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
      return FALSE;
    }

    if (NodeLength > MAX_UINTN - Size) {
      return FALSE;
    }
    Size += NodeLength;

    //
    // Validate next node before touch it.
    //
    if (Size > MaxSize - END_DEVICE_PATH_LENGTH ) {
      return FALSE;
    }

    if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) {
      Count++;
      if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) {
        return FALSE;
      }
    }
  }

  //
  // Only return TRUE when the End Device Path node is valid.
  //
  return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH);
}
Ejemplo n.º 4
0
/**
  Get the URI address string from the input device path.

  Caller need to free the buffer in the UriAddress pointer.
  
  @param[in]   FilePath         Pointer to the device path which contains a URI device path node.
  @param[out]  UriAddress       The URI address string extract from the device path.
  
  @retval EFI_SUCCESS            The URI string is returned.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.

**/
EFI_STATUS
HttpBootParseFilePath (
  IN     EFI_DEVICE_PATH_PROTOCOL     *FilePath,
     OUT CHAR8                        **UriAddress
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
  URI_DEVICE_PATH           *UriDevicePath;
  CHAR8                     *Uri;
  UINTN                     UriStrLength;

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

  *UriAddress = NULL;

  //
  // Extract the URI address from the FilePath
  //
  TempDevicePath = FilePath;
  while (!IsDevicePathEnd (TempDevicePath)) {
    if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) &&
        (DevicePathSubType (TempDevicePath) == MSG_URI_DP)) {
      UriDevicePath = (URI_DEVICE_PATH*) TempDevicePath;
      //
      // UEFI Spec doesn't require the URI to be a NULL-terminated string
      // So we allocate a new buffer and always append a '\0' to it.
      //
      UriStrLength = DevicePathNodeLength (UriDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
      if (UriStrLength == 0) {
        //
        // return a NULL UriAddress if it's a empty URI device path node.
        //
        break;
      }
      Uri = AllocatePool (UriStrLength + 1);
      if (Uri == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
      CopyMem (Uri, UriDevicePath->Uri, DevicePathNodeLength (UriDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL));
      Uri[DevicePathNodeLength (UriDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL)] = '\0';

      *UriAddress = Uri;
    }
    TempDevicePath = NextDevicePathNode (TempDevicePath);
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 5
0
/**
  This function retrieves an SD card slot number based on the input device path.

  The GetSlotNumber() function retrieves slot number for the SD card specified by
  the DevicePath node. If DevicePath is NULL, EFI_INVALID_PARAMETER is returned.

  If DevicePath is not a device path node type that the SD Pass Thru driver supports,
  EFI_UNSUPPORTED is returned.

  @param[in]  This              A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
  @param[in]  DevicePath        A pointer to the device path node that describes a SD
                                card on the SD controller.
  @param[out] Slot              On return, points to the slot number of an SD card on
                                the SD controller.

  @retval EFI_SUCCESS           SD card slot number is returned in Slot.
  @retval EFI_INVALID_PARAMETER Slot or DevicePath is NULL.
  @retval EFI_UNSUPPORTED       DevicePath is not a device path node type that the SD
                                Pass Thru driver supports.

**/
EFI_STATUS
EFIAPI
SdMmcPassThruGetSlotNumber (
  IN  EFI_SD_MMC_PASS_THRU_PROTOCOL          *This,
  IN  EFI_DEVICE_PATH_PROTOCOL               *DevicePath,
  OUT UINT8                                  *Slot
  )
{
  SD_MMC_HC_PRIVATE_DATA          *Private;
  SD_DEVICE_PATH                  *SdNode;
  EMMC_DEVICE_PATH                *EmmcNode;
  UINT8                           SlotNumber;

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

  Private = SD_MMC_HC_PRIVATE_FROM_THIS (This);

  //
  // Check whether the DevicePath belongs to SD_DEVICE_PATH or EMMC_DEVICE_PATH
  //
  if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
      ((DevicePath->SubType != MSG_SD_DP) &&
       (DevicePath->SubType != MSG_EMMC_DP)) ||
      (DevicePathNodeLength(DevicePath) != sizeof(SD_DEVICE_PATH)) ||
      (DevicePathNodeLength(DevicePath) != sizeof(EMMC_DEVICE_PATH))) {
    return EFI_UNSUPPORTED;
  }

  if (DevicePath->SubType == MSG_SD_DP) {
    SdNode = (SD_DEVICE_PATH *) DevicePath;
    SlotNumber = SdNode->SlotNumber;
  } else {
    EmmcNode = (EMMC_DEVICE_PATH *) DevicePath;
    SlotNumber = EmmcNode->SlotNumber;
  }

  if (SlotNumber >= SD_MMC_HC_MAX_SLOT) {
    return EFI_NOT_FOUND;
  }

  if (Private->Slot[SlotNumber].Enable) {
    *Slot = SlotNumber;
    return EFI_SUCCESS;
  } else {
    return EFI_NOT_FOUND;
  }
}
Ejemplo n.º 6
0
/**
  Determine whether a given device path is valid.
  If DevicePath is NULL, then ASSERT().

  @param  DevicePath  A pointer to a device path data structure.
  @param  MaxSize     The maximum size of the device path data structure.

  @retval TRUE        DevicePath is valid.
  @retval FALSE       The length of any node node in the DevicePath is less
                      than sizeof (EFI_DEVICE_PATH_PROTOCOL).
  @retval FALSE       If MaxSize is not zero, the size of the DevicePath
                      exceeds MaxSize.
  @retval FALSE       If PcdMaximumDevicePathNodeCount is not zero, the node
                      count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.
**/
BOOLEAN
EFIAPI
IsDevicePathValid (
  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
  IN       UINTN                    MaxSize
  )
{
  UINTN Count;
  UINTN Size;
  UINTN NodeLength;

  ASSERT (DevicePath != NULL);

  if (MaxSize == 0){
    MaxSize = MAX_UINTN;
  }

  Size = 0;
  Count = 0;

  while (MaxSize >= sizeof (EFI_DEVICE_PATH_PROTOCOL) &&
        (MaxSize - sizeof (EFI_DEVICE_PATH_PROTOCOL) >= Size) &&
        !IsDevicePathEnd (DevicePath)) {
    NodeLength = DevicePathNodeLength (DevicePath);
    if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
      return FALSE;
    }

    if (NodeLength > MAX_UINTN - Size) {
      return FALSE;
    }

    Size += NodeLength;

    if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) {
      Count++;
      if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) {
        return FALSE;
      }
    }

    DevicePath = NextDevicePathNode (DevicePath);
  }

  //
  // Only return TRUE when the End Device Path node is valid.
  //
  return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH);
}
Ejemplo n.º 7
0
static VOID
_DevPathIPv6 (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    IPv6_DEVICE_PATH     *IP;

    IP = DevPath;
    CatPrint( Str , L"IPv6(") ;
    CatPrintIPv6( Str , & IP-> RemoteIpAddress ) ;
    CatPrint( Str , L",") ;
    CatPrintNetworkProtocol( Str, IP-> Protocol ) ;
    CatPrint( Str , L",%s," , IP-> IPAddressOrigin ?
        ( IP-> IPAddressOrigin == 1 ? L"StatelessAutoConfigure" :
        L"StatefulAutoConfigure" ) : L"Static" ) ;
    CatPrintIPv6( Str , & IP-> LocalIpAddress ) ;
    if ( DevicePathNodeLength( & IP-> Header ) == sizeof( IPv6_DEVICE_PATH ) ) {
        CatPrint( Str , L",") ;
        CatPrintIPv6( Str , & IP-> GatewayIpAddress ) ;
        CatPrint( Str , L",") ;
        CatPrint( Str , L"%d" , & IP-> PrefixLength ) ;
    }
    CatPrint( Str , L")") ;
}
Ejemplo n.º 8
0
static VOID
_DevPathMacAddr (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    MAC_ADDR_DEVICE_PATH    *MAC;
    UINTN                   HwAddressSize;
    UINTN                   Index;

    MAC = DevPath;

    /* HwAddressSize = sizeof(EFI_MAC_ADDRESS); */
    HwAddressSize = DevicePathNodeLength( & MAC-> Header ) ;
    HwAddressSize -= sizeof( MAC-> Header ) ;
    HwAddressSize -= sizeof( MAC-> IfType ) ;
    if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
        HwAddressSize = 6;
    }
    
    CatPrint(Str, L"Mac(");

    for(Index = 0; Index < HwAddressSize; Index++) {
        CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]);
    }
    if ( MAC-> IfType != 0 ) {
        CatPrint(Str, L",%d" , MAC-> IfType ) ;
    }
    CatPrint(Str, L")");
}
Ejemplo n.º 9
0
/**
  Returns the size of a device path in bytes.

  This function returns the size, in bytes, of the device path data structure
  specified by DevicePath including the end of device path node.
  If DevicePath is NULL or invalid, then 0 is returned.

  @param  DevicePath  A pointer to a device path data structure.

  @retval 0           If DevicePath is NULL or invalid.
  @retval Others      The size of a device path in bytes.

**/
UINTN
EFIAPI
UefiDevicePathLibGetDevicePathSize (
  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
  )
{
  CONST EFI_DEVICE_PATH_PROTOCOL  *Start;

  if (DevicePath == NULL) {
    return 0;
  }

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

  //
  // Search for the end of the device path structure
  //
  Start = DevicePath;
  while (!IsDevicePathEnd (DevicePath)) {
    DevicePath = NextDevicePathNode (DevicePath);
  }

  //
  // Compute the size and add back in the size of the end device path structure
  //
  return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath);
}
Ejemplo n.º 10
0
EFI_DEVICE_PATH *
AppendDevicePathNode (
    IN EFI_DEVICE_PATH  *Src1,
    IN EFI_DEVICE_PATH  *Src2
    )
// Src1 may have multiple "instances" and each instance is appended
// Src2 is a signal device path node (without a terminator) that is
// appended to each instance is Src1.
{
    EFI_DEVICE_PATH     *Temp, *Eop;
    UINTN               Length;

    //
    // Build a Src2 that has a terminator on it
    //

    Length = DevicePathNodeLength(Src2);
    Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH));
    if (!Temp) {
        return NULL;
    }

    CopyMem (Temp, Src2, Length);
    Eop = NextDevicePathNode(Temp); 
    SetDevicePathEndNode(Eop);

    //
    // Append device paths
    //

    Src1 = AppendDevicePath (Src1, Temp);
    FreePool (Temp);
    return Src1;
}
Ejemplo n.º 11
0
EFI_STATUS
BusDriver1BindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS        Status;
  EFI_DEV_PATH      *Node;

  if (RemainingDevicePath != NULL) {
    Node = (EFI_DEV_PATH *)RemainingDevicePath;
    if (Node->DevPath.Type != HARDWARE_DEVICE_PATH ||
        Node->DevPath.SubType != HW_VENDOR_DP ||
        DevicePathNodeLength(&Node->DevPath) != sizeof(VENDOR_DEVICE_PATH)) {
      return EFI_UNSUPPORTED;
    }
  }

  Status = gtBS->OpenProtocol (
                      Controller,
                      &mInterfaceFunctionTestProtocol1Guid,
                      NULL,
                      This->DriverBindingHandle,
                      Controller,
                      EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                      );
  if (EFI_ERROR(Status)) {
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}
Ejemplo n.º 12
0
EFIAPI
NextDevicePathNode (
  IN CONST VOID  *Node
  )
{
  ASSERT (Node != NULL);
  return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLength(Node));
}
Ejemplo n.º 13
0
// Compare device paths
static INTN CompareDevicePaths(CONST EFI_DEVICE_PATH *dp1, CONST EFI_DEVICE_PATH *dp2)
{
    if (dp1 == NULL || dp2 == NULL)
        return -1;

    while (1) {
        UINT8 type1, type2;
        UINT8 subtype1, subtype2;
        UINT16 len1, len2;
        INTN ret;

        type1 = DevicePathType(dp1);
        type2 = DevicePathType(dp2);

        if (type1 != type2)
                return (int) type2 - (int) type1;

        subtype1 = DevicePathSubType(dp1);
        subtype2 = DevicePathSubType(dp2);

        if (subtype1 != subtype2)
                return (int) subtype1 - (int) subtype2;

        len1 = DevicePathNodeLength(dp1);
        len2 = DevicePathNodeLength(dp2);
        if (len1 != len2)
                return (int) len1 - (int) len2;

        ret = CompareMem(dp1, dp2, len1);
        if (ret != 0)
                return ret;

        if (IsDevicePathEnd(dp1))
                break;

        dp1 = (EFI_DEVICE_PATH*) ((char *)dp1 + len1);
        dp2 = (EFI_DEVICE_PATH*) ((char *)dp2 + len2);
    }

    return 0;
}
Ejemplo n.º 14
0
static VOID
_DevPathIPv4 (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    IPv4_DEVICE_PATH     *IP;
    BOOLEAN show ;

    IP = DevPath;
    CatPrint( Str , L"IPv4(") ;
    CatPrintIPv4( Str , & IP-> RemoteIpAddress ) ;
    CatPrint( Str , L",") ;
    CatPrintNetworkProtocol( Str , IP-> Protocol ) ;
    CatPrint( Str , L",%s" , IP-> StaticIpAddress ? L"Static" : L"DHCP" ) ;
    show = IsNotNullIPv4( & IP-> LocalIpAddress ) ;
    if ( ! show && DevicePathNodeLength( & IP-> Header ) == sizeof( IPv4_DEVICE_PATH ) ) {
        /* only version 2 includes gateway and netmask */
        show |= IsNotNullIPv4( & IP-> GatewayIpAddress ) ;
        show |= IsNotNullIPv4( & IP-> SubnetMask  ) ;
    }
    if ( show ) {
        CatPrint( Str , L"," ) ;
        CatPrintIPv4( Str , & IP-> LocalIpAddress ) ;
        if ( DevicePathNodeLength( & IP-> Header ) == sizeof( IPv4_DEVICE_PATH ) ) {
            /* only version 2 includes gateway and netmask */
            show = IsNotNullIPv4( & IP-> GatewayIpAddress ) ;
            show |= IsNotNullIPv4( & IP-> SubnetMask ) ;
            if ( show ) {
                CatPrint( Str , L",") ;
                CatPrintIPv4( Str , & IP-> GatewayIpAddress ) ;
                if ( IsNotNullIPv4( & IP-> SubnetMask ) ) {
                    CatPrint( Str , L",") ;
                    CatPrintIPv4( Str , & IP-> SubnetMask ) ;
                }
            }
        }
    }
    CatPrint( Str , L")") ;
}
Ejemplo n.º 15
0
/**
  Check to see if this driver supports the given controller

  @param  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param  Controller           The handle of the controller to test.
  @param  RemainingDevicePath  A pointer to the remaining portion of a device path.

  @return EFI_SUCCESS          This driver can support the given controller

**/
EFI_STATUS
EFIAPI
SerialControllerDriverSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )

{
  EFI_STATUS                                Status;
  UART_DEVICE_PATH                          *Uart;
  UART_FLOW_CONTROL_DEVICE_PATH             *FlowControl;

  //
  // Test RemainingDevicePath
  //
  if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
    Status = EFI_UNSUPPORTED;

    Uart = SkipControllerDevicePathNode (RemainingDevicePath, NULL, NULL);
    if (DevicePathType (Uart) != MESSAGING_DEVICE_PATH ||
        DevicePathSubType (Uart) != MSG_UART_DP ||
        DevicePathNodeLength (Uart) != sizeof (UART_DEVICE_PATH)
        ) {
      return EFI_UNSUPPORTED;
    }

    //
    // Do a rough check because Clock Rate is unknown until DriverBindingStart()
    //
    if (!VerifyUartParameters (0, Uart->BaudRate, Uart->DataBits, Uart->Parity, Uart->StopBits, NULL, NULL)) {
      return EFI_UNSUPPORTED;
    }

    FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart);
    if (IsUartFlowControlDevicePathNode (FlowControl)) {
      //
      // If the second node is Flow Control Node,
      //   return error when it request other than hardware flow control.
      //
      if ((ReadUnaligned32 (&FlowControl->FlowControlMap) & ~UART_FLOW_CONTROL_HARDWARE) != 0) {
        return EFI_UNSUPPORTED;
      }
    }
  }

  Status = IsSioSerialController (Controller);
  if (EFI_ERROR (Status)) {
    Status = IsPciSerialController (Controller);
  }
  return Status;
}
Ejemplo n.º 16
0
/**
  Determine whether a given device path is valid.
  If DevicePath is NULL, then ASSERT().

  @param  DevicePath  A pointer to a device path data structure.
  @param  MaxSize     The maximum size of the device path data structure.

  @retval TRUE        DevicePath is valid.
  @retval FALSE       The length of any node node in the DevicePath is less
                      than sizeof (EFI_DEVICE_PATH_PROTOCOL).
  @retval FALSE       If MaxSize is not zero, the size of the DevicePath
                      exceeds MaxSize.
  @retval FALSE       If PcdMaximumDevicePathNodeCount is not zero, the node
                      count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.
**/
BOOLEAN
EFIAPI
IsDevicePathValid (
  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
  IN       UINTN                    MaxSize
  )
{
  UINTN Count;
  UINTN Size;
  UINTN NodeLength;

  ASSERT (DevicePath != NULL);

  for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
    NodeLength = DevicePathNodeLength (DevicePath);
    if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
      return FALSE;
    }

    if (MaxSize > 0) {
      Size += NodeLength;
      if (Size + END_DEVICE_PATH_LENGTH > MaxSize) {
        return FALSE;
      }
    }

    if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) {
      Count++;
      if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) {
        return FALSE;
      }
    }
  }

  //
  // Only return TRUE when the End Device Path node is valid.
  //
  return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH);
}
Ejemplo n.º 17
0
INTN
_DevPathCompareDefault (
  IN EFI_DEVICE_PATH_PROTOCOL       *DevicePath1,
  IN EFI_DEVICE_PATH_PROTOCOL       *DevicePath2
  )
{
  UINTN DevPathSize1;
  UINTN DevPathSize2;

  ASSERT(DevicePath1 != NULL);
  ASSERT(DevicePath2 != NULL);

  DevPathSize1  = DevicePathNodeLength (DevicePath1);
  DevPathSize2  = DevicePathNodeLength (DevicePath2);
  if (DevPathSize1 > DevPathSize2) {
    return 1;
  } else if (DevPathSize1 < DevPathSize2) {
    return -1;
  } else {
    return CompareMem (DevicePath1, DevicePath2, DevPathSize1);
  }
}
Ejemplo n.º 18
0
EFI_DEVICE_PATH_PROTOCOL *
AppendDevicePathNode (
  IN EFI_DEVICE_PATH_PROTOCOL  *Src1,
  IN EFI_DEVICE_PATH_PROTOCOL  *Src2
  )
/*++

Routine Description:
  Function is used to append a device path node to all the instances in another device path.

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

  Src2           - A pointer to a device path data structure.

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.

  Src1 may have multiple "instances" and each instance is appended
  Src2 is a signal device path node (without a terminator) that is
  appended to each instance is Src1.

--*/
{
  EFI_DEVICE_PATH_PROTOCOL    *Temp, *Eop;
  UINTN                       Length;

  //
  // Build a Src2 that has a terminator on it
  //
  Length = DevicePathNodeLength(Src2);
  Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH_PROTOCOL));
  if (!Temp) {
    return NULL;
  }

  CopyMem (Temp, Src2, Length);
  Eop = NextDevicePathNode(Temp);
  SetDevicePathEndNode(Eop);

  //
  // Append device paths
  //

  Src1 = AppendDevicePath (Src1, Temp);
  FreePool (Temp);
  return Src1;
}
Ejemplo n.º 19
0
/**
  Validate the device path instance. 

  Only base on the length filed in the device path node to validate the device path. 

  @param  DevicePath         A pointer to a device path data structure.
  @param  MaxSize            Max valid device path size. If big than this size, 
                             return error.
  
  @retval TRUE               An valid device path.
  @retval FALSE              An invalid device path.

**/
BOOLEAN
IsValidDevicePath (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  IN UINTN                     MaxSize
  )
{
  UINTN  Size;
  UINTN  NodeSize;

  if (DevicePath == NULL) {
    return TRUE;
  }

  Size = 0;

  while (!IsDevicePathEnd (DevicePath)) {
    NodeSize = DevicePathNodeLength (DevicePath);
    if (NodeSize < END_DEVICE_PATH_LENGTH) {
      return FALSE;
    }

    Size += NodeSize;
    if (Size > MaxSize) {
      return FALSE;
    }

    DevicePath = NextDevicePathNode (DevicePath);
  }

  Size += DevicePathNodeLength (DevicePath);
  if (Size > MaxSize) {
    return FALSE;
  }

  return TRUE;
}
Ejemplo n.º 20
0
Archivo: Lib.c Proyecto: jief666/clover
EFIAPI
FileDevicePathToText(EFI_DEVICE_PATH_PROTOCOL *FilePathProto)
{
	EFI_STATUS			Status;
	FILEPATH_DEVICE_PATH 		*FilePath;
	CHAR16				FilePathText[256]; // possible problem: if filepath is bigger
	CHAR16				*OutFilePathText;
	INTN				Size;
	INTN				SizeAll;
	INTN				i;
	
	FilePathText[0] = L'\0';
	i = 4;
	SizeAll = 0;
	//PRINT("FilePathProto->Type: %d, SubType: %d, Length: %d\n", FilePathProto->Type, FilePathProto->SubType, DevicePathNodeLength(FilePathProto));
	while (FilePathProto != NULL && FilePathProto->Type != END_DEVICE_PATH_TYPE && i > 0) {
		if (FilePathProto->Type == MEDIA_DEVICE_PATH && FilePathProto->SubType == MEDIA_FILEPATH_DP) {
			FilePath = (FILEPATH_DEVICE_PATH *) FilePathProto;
			Size = (DevicePathNodeLength(FilePathProto) - 4) / 2;
			if (SizeAll + Size < 256) {
				if (SizeAll > 0 && FilePathText[SizeAll / 2 - 2] != L'\\') {
					StrCatS(FilePathText, 256, L"\\");
				}
				StrCatS(FilePathText, 256, FilePath->PathName);
				SizeAll = StrSize(FilePathText);
			}
		}
		FilePathProto = NextDevicePathNode(FilePathProto);
		//PRINT("FilePathProto->Type: %d, SubType: %d, Length: %d\n", FilePathProto->Type, FilePathProto->SubType, DevicePathNodeLength(FilePathProto));
		i--;
		//PRINT("FilePathText: %s\n", FilePathText);
	}
	
	OutFilePathText = NULL;
	Size = StrSize(FilePathText);
	if (Size > 2) {
		// we are allocating mem here - should be released by caller
		Status = gBS->AllocatePool(EfiBootServicesData, Size, (VOID*)&OutFilePathText);
		if (Status == EFI_SUCCESS) {
			StrCpyS(OutFilePathText, Size/sizeof(CHAR16), FilePathText);
		} else {
			OutFilePathText = NULL;
		}
	}
	
	return OutFilePathText;
}
Ejemplo n.º 21
0
static VOID
_DevPathNodeUnknown (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    EFI_DEVICE_PATH * Path ;
    UINT8 * value ;
    int length , index ;
    Path = DevPath ;
    value = DevPath ;
    value += 4 ;
    switch ( Path-> Type ) {
        case HARDWARE_DEVICE_PATH : { /* Unknown Hardware Device Path */
            CatPrint( Str , L"HardwarePath(%d" , Path-> SubType ) ;
            break ;
        }
        case ACPI_DEVICE_PATH : { /* Unknown ACPI Device Path */
            CatPrint( Str , L"AcpiPath(%d" , Path-> SubType ) ;
            break ;
        }
        case MESSAGING_DEVICE_PATH : { /* Unknown Messaging Device Path */
            CatPrint( Str , L"Msg(%d" , Path-> SubType ) ;
            break ;
        }
        case MEDIA_DEVICE_PATH : { /* Unknown Media Device Path */
            CatPrint( Str , L"MediaPath(%d" , Path-> SubType ) ;
            break ;
        }
        case BBS_DEVICE_PATH : { /* Unknown BIOS Boot Specification Device Path */
            CatPrint( Str , L"BbsPath(%d" , Path-> SubType ) ;
            break ;
        }
        default : { /* Unknown Device Path */
            CatPrint( Str , L"Path(%d,%d" , Path-> Type , Path-> SubType ) ;
            break ;
        }
    }
    length = DevicePathNodeLength( Path ) ;
    for ( index = 0 ; index < length ; index ++ ) {
        if ( index == 0 ) CatPrint( Str , L",0x" ) ;
        CatPrint( Str , L"%02x" , * value ) ;
	value ++ ;
    }
    CatPrint( Str , L")" ) ;
}
Ejemplo n.º 22
0
static INTN
dp_size(EFI_DEVICE_PATH *dp, INTN limit)
{
	INTN ret = 0;
	while (1) {
		if (limit < 4)
			break;
		INTN nodelen = DevicePathNodeLength(dp);
		if (nodelen > limit)
			break;
		limit -= nodelen;
		ret += nodelen;

		if (IsDevicePathEnd(dp))
			return ret;
		dp = NextDevicePathNode(dp);
	}
	return -1;
}
Ejemplo n.º 23
0
/**
  Used to translate a device path node to a namespace ID.

  The EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL.GetNamespace() function determines the namespace ID associated with the
  namespace described by DevicePath.

  If DevicePath is a device path node type that the NVM Express Pass Thru driver supports, then the NVM Express
  Pass Thru driver will attempt to translate the contents DevicePath into a namespace ID.

  If this translation is successful, then that namespace ID is returned in NamespaceId, and EFI_SUCCESS is returned

  @param[in]  This                A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance.
  @param[in]  DevicePath          A pointer to the device path node that describes an NVM Express namespace on
                                  the NVM Express controller.
  @param[out] NamespaceId         The NVM Express namespace ID contained in the device path node.

  @retval EFI_SUCCESS             DevicePath was successfully translated to NamespaceId.
  @retval EFI_INVALID_PARAMETER   If DevicePath or NamespaceId are NULL, then EFI_INVALID_PARAMETER is returned.
  @retval EFI_UNSUPPORTED         If DevicePath is not a device path node type that the NVM Express Pass Thru driver
                                  supports, then EFI_UNSUPPORTED is returned.
  @retval EFI_NOT_FOUND           If DevicePath is a device path node type that the NVM Express Pass Thru driver
                                  supports, but there is not a valid translation from DevicePath to a namespace ID,
                                  then EFI_NOT_FOUND is returned.
**/
EFI_STATUS
EFIAPI
NvmExpressGetNamespace (
  IN     EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL          *This,
  IN     EFI_DEVICE_PATH_PROTOCOL                    *DevicePath,
     OUT UINT32                                      *NamespaceId
  )
{
  NVME_NAMESPACE_DEVICE_PATH       *Node;
  NVME_CONTROLLER_PRIVATE_DATA     *Private;

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

  if (DevicePath->Type != MESSAGING_DEVICE_PATH) {
    return EFI_UNSUPPORTED;
  }

  Node    = (NVME_NAMESPACE_DEVICE_PATH *)DevicePath;
  Private = NVME_CONTROLLER_PRIVATE_DATA_FROM_PASS_THRU (This);

  if (DevicePath->SubType == MSG_NVME_NAMESPACE_DP) {
    if (DevicePathNodeLength(DevicePath) != sizeof(NVME_NAMESPACE_DEVICE_PATH)) {
      return EFI_NOT_FOUND;
    }

    //
    // Check NamespaceId in the device path node is valid or not.
    //
    if ((Node->NamespaceId == 0) ||
      (Node->NamespaceId > Private->ControllerData->Nn)) {
      return EFI_NOT_FOUND;
    }

    *NamespaceId = Node->NamespaceId;

    return EFI_SUCCESS;
  } else {
    return EFI_UNSUPPORTED;
  }
}
/**
  Used to translate a device path node to a Target ID and LUN.

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

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

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

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

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

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

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

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

  return EFI_SUCCESS;
}
Ejemplo n.º 25
0
/**
  Get file name from device path.

  The file name may contain one or more device path node. Save the file name in a
  buffer if file name is found. The caller is responsible to free the buffer.

  @param[in]  DevicePath     A pointer to a device path.
  @param[out] FileName       The callee allocated buffer to save the file name if file name is found.
  @param[out] FileNameOffset The offset of file name in device path if file name is found.

  @retval     UINTN          The file name length. 0 means file name is not found.

**/
UINTN
GetFileName (
  IN  CONST EFI_DEVICE_PATH_PROTOCOL          *DevicePath,
  OUT UINT8                                   **FileName,
  OUT UINTN                                   *FileNameOffset
  )
{
  UINTN                                       Length;
  EFI_DEVICE_PATH_PROTOCOL                    *TmpDevicePath;
  EFI_DEVICE_PATH_PROTOCOL                    *RootDevicePath;
  CHAR8                                       *NodeStr;
  UINTN                                       NodeStrLength;
  CHAR16                                      LastNodeChar;
  CHAR16                                      FirstNodeChar;

  //
  // Get the length of DevicePath before file name.
  //
  Length = 0;
  RootDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;
  while (!IsDevicePathEnd (RootDevicePath)) {
    if ((DevicePathType(RootDevicePath) == MEDIA_DEVICE_PATH) && (DevicePathSubType(RootDevicePath) == MEDIA_FILEPATH_DP)) {
      break;
    }
    Length += DevicePathNodeLength (RootDevicePath);
    RootDevicePath = NextDevicePathNode (RootDevicePath);
  }

  *FileNameOffset = Length;
  if (Length == 0) {
    return 0;
  }

  //
  // Get the file name length.
  //
  Length = 0;
  TmpDevicePath = RootDevicePath;
  while (!IsDevicePathEnd (TmpDevicePath)) {
    if ((DevicePathType(TmpDevicePath) != MEDIA_DEVICE_PATH) || (DevicePathSubType(TmpDevicePath) != MEDIA_FILEPATH_DP)) {
      break;
    }
    Length += DevicePathNodeLength (TmpDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL);
    TmpDevicePath = NextDevicePathNode (TmpDevicePath);
  }
  if (Length == 0) {
    return 0;
  }

  *FileName = AllocateZeroPool (Length);
  ASSERT (*FileName != NULL);

  //
  // Copy the file name to the buffer.
  //
  Length = 0;
  LastNodeChar = '\\';
  TmpDevicePath = RootDevicePath;
  while (!IsDevicePathEnd (TmpDevicePath)) {
    if ((DevicePathType(TmpDevicePath) != MEDIA_DEVICE_PATH) || (DevicePathSubType(TmpDevicePath) != MEDIA_FILEPATH_DP)) {
      break;
    }

    FirstNodeChar = (CHAR16) ReadUnaligned16 ((UINT16 *)((UINT8 *)TmpDevicePath + sizeof (EFI_DEVICE_PATH_PROTOCOL)));
    NodeStr = (CHAR8 *)TmpDevicePath + sizeof (EFI_DEVICE_PATH_PROTOCOL);
    NodeStrLength = DevicePathNodeLength (TmpDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL) - sizeof(CHAR16);

    if ((FirstNodeChar == '\\') && (LastNodeChar == '\\')) {
      //
      // Skip separator "\" when there are two separators.
      //
      NodeStr += sizeof (CHAR16);
      NodeStrLength -= sizeof (CHAR16);
    } else if ((FirstNodeChar != '\\') && (LastNodeChar != '\\')) {
      //
      // Add separator "\" when there is no separator.
      //
      WriteUnaligned16 ((UINT16 *)(*FileName + Length), '\\');
      Length += sizeof (CHAR16);
    }
    CopyMem (*FileName + Length, NodeStr, NodeStrLength);
    Length += NodeStrLength;

    LastNodeChar  = (CHAR16) ReadUnaligned16 ((UINT16 *) (NodeStr + NodeStrLength - sizeof(CHAR16)));
    TmpDevicePath = NextDevicePathNode (TmpDevicePath);
  }

  return Length;
}
Ejemplo n.º 26
0
void
efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table)
{
	static EFI_GUID image_protocol = LOADED_IMAGE_PROTOCOL;
	EFI_LOADED_IMAGE *img;
	CHAR16 *argp, *args, **argv;
	EFI_STATUS status;
	int argc, addprog;

	IH = image_handle;
	ST = system_table;
	BS = ST->BootServices;
	RS = ST->RuntimeServices;

	heapsize = 512*1024;
	status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
	    EFI_SIZE_TO_PAGES(heapsize), &heap);
	if (status != EFI_SUCCESS)
		BS->Exit(IH, status, 0, NULL);

	setheap((void *)heap, (void *)(heap + heapsize));

	/* Use exit() from here on... */

	status = BS->HandleProtocol(IH, &image_protocol, (VOID**)&img);
	if (status != EFI_SUCCESS)
		exit(status);

	/*
	 * Pre-process the (optional) load options. If the option string
	 * is given as an ASCII string, we use a poor man's ASCII to
	 * Unicode-16 translation. The size of the option string as given
	 * to us includes the terminating null character. We assume the
	 * string is an ASCII string if strlen() plus the terminating
	 * '\0' is less than LoadOptionsSize. Even if all Unicode-16
	 * characters have the upper 8 bits non-zero, the terminating
	 * null character will cause a one-off.
	 * If the string is already in Unicode-16, we make a copy so that
	 * we know we can always modify the string.
	 */
	if (img->LoadOptionsSize > 0 && img->LoadOptions != NULL) {
		if (img->LoadOptionsSize == strlen(img->LoadOptions) + 1) {
			args = malloc(img->LoadOptionsSize << 1);
			for (argc = 0; argc < img->LoadOptionsSize; argc++)
				args[argc] = ((char*)img->LoadOptions)[argc];
		} else {
			args = malloc(img->LoadOptionsSize);
			memcpy(args, img->LoadOptions, img->LoadOptionsSize);
		}
	} else
		args = NULL;

	/*
	 * Use a quick and dirty algorithm to build the argv vector. We
	 * first count the number of words. Then, after allocating the
	 * vector, we split the string up. We don't deal with quotes or
	 * other more advanced shell features.
	 * The EFI shell will pas the name of the image as the first
	 * word in the argument list. This does not happen if we're
	 * loaded by the boot manager. This is not so easy to figure
	 * out though. The ParentHandle is not always NULL, because
	 * there can be a function (=image) that will perform the task
	 * for the boot manager.
	 */
	/* Part 1: Figure out if we need to add our program name. */
	addprog = (args == NULL || img->ParentHandle == NULL ||
	    img->FilePath == NULL) ? 1 : 0;
	if (!addprog) {
		addprog =
		    (DevicePathType(img->FilePath) != MEDIA_DEVICE_PATH ||
		     DevicePathSubType(img->FilePath) != MEDIA_FILEPATH_DP ||
		     DevicePathNodeLength(img->FilePath) <=
			sizeof(FILEPATH_DEVICE_PATH)) ? 1 : 0;
		if (!addprog) {
			/* XXX todo. */
		}
	}
	/* Part 2: count words. */
	argc = (addprog) ? 1 : 0;
	argp = args;
	while (argp != NULL && *argp != 0) {
		argp = arg_skipsep(argp);
		if (*argp == 0)
			break;
		argc++;
		argp = arg_skipword(argp);
	}
	/* Part 3: build vector. */
	argv = malloc((argc + 1) * sizeof(CHAR16*));
	argc = 0;
	if (addprog)
		argv[argc++] = L"loader.efi";
	argp = args;
	while (argp != NULL && *argp != 0) {
		argp = arg_skipsep(argp);
		if (*argp == 0)
			break;
		argv[argc++] = argp;
		argp = arg_skipword(argp);
		/* Terminate the words. */
		if (*argp != 0)
			*argp++ = 0;
	}
	argv[argc] = NULL;

	status = main(argc, argv);
	exit(status);
}
Ejemplo n.º 27
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;
}
Ejemplo n.º 28
0
/**
  Test to see if this driver supports ControllerHandle. Any ControllerHandle
  than contains a BlockIo and DiskIo protocol or a BlockIo2 protocol can be
  supported.

  @param[in]  This                Protocol instance pointer.
  @param[in]  ControllerHandle    Handle of device to test.
  @param[in]  RemainingDevicePath Optional parameter use to pick a specific child
                                  device to start.

  @retval EFI_SUCCESS         This driver supports this device
  @retval EFI_ALREADY_STARTED This driver is already running on this device
  @retval other               This driver does not support this device

**/
EFI_STATUS
EFIAPI
PartitionDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;
  EFI_DISK_IO_PROTOCOL      *DiskIo;
  EFI_DEV_PATH              *Node;

  //
  // Check RemainingDevicePath validation
  //
  if (RemainingDevicePath != NULL) {
    //
    // Check if RemainingDevicePath is the End of Device Path Node, 
    // if yes, go on checking other conditions
    //
    if (!IsDevicePathEnd (RemainingDevicePath)) {
      //
      // If RemainingDevicePath isn't the End of Device Path Node,
      // check its validation
      //
      Node = (EFI_DEV_PATH *) RemainingDevicePath;
      if (Node->DevPath.Type != MEDIA_DEVICE_PATH ||
        Node->DevPath.SubType != MEDIA_HARDDRIVE_DP ||
        DevicePathNodeLength (&Node->DevPath) != sizeof (HARDDRIVE_DEVICE_PATH)) {
        return EFI_UNSUPPORTED;
      }
    }
  }

  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDiskIoProtocolGuid,
                  (VOID **) &DiskIo,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Close the I/O Abstraction(s) used to perform the supported test
  //
  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiDiskIoProtocolGuid,
         This->DriverBindingHandle,
         ControllerHandle
         );

  //
  // Open the EFI Device Path protocol needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close protocol, don't use device path protocol in the Support() function
  //
  gBS->CloseProtocol (
        ControllerHandle,
        &gEfiDevicePathProtocolGuid,
        This->DriverBindingHandle,
        ControllerHandle
        );

  //
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiBlockIoProtocolGuid,
                  NULL,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );

  return Status;
}
Ejemplo n.º 29
0
//
// TDS 3.2
//
EFI_STATUS
BBTestWholeDevicePathConformanceAutoTest (
    IN EFI_BB_TEST_PROTOCOL       *This,
    IN VOID                       *ClientInterface,
    IN EFI_TEST_LEVEL             TestLevel,
    IN EFI_HANDLE                 SupportHandle
)
{
    EFI_STANDARD_TEST_LIBRARY_PROTOCOL   *StandardLib;
    EFI_STATUS                           Status;
    EFI_DEVICE_PATH_PROTOCOL             *DevicePath;
    EFI_TEST_ASSERTION                   AssertionType;
    UINT16                               Type;
    UINT16                               SubType;
    UINT16                               Length;
    UINT16                               Count;
    UINT16                               PCIRootFirst;
    UINT16                               SCSICount;
    UINT16                               ATAPICount;
    ACPI_HID_DEVICE_PATH                 *Acpi;
    CHAR16                               *DevStr;

    //
    // Verify whether it is one of IHV interfaces
    //
    if (! IsIhvInterface (ClientInterface, SupportHandle)) {
        return EFI_UNSUPPORTED;
    }

    //
    // Get the Standard Library Interface
    //
    Status = gtBS->HandleProtocol (
                 SupportHandle,
                 &gEfiStandardTestLibraryGuid,
                 &StandardLib
             );

    if (EFI_ERROR(Status)) {
        StandardLib->RecordAssertion (
            StandardLib,
            EFI_TEST_ASSERTION_FAILED,
            gTestGenericFailureGuid,
            L"BS.HandleProtocol - Handle standard test library",
            L"%a:%d:Status - %r",
            __FILE__,
            __LINE__,
            Status
        );
        return Status;
    }

    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)ClientInterface;

    DevStr = DevicePathToStr (DevicePath);
    StandardLib->RecordMessage (
        StandardLib,
        EFI_VERBOSE_LEVEL_QUIET,
        L"\nVerifying device path: %s\n",
        DevStr
    );
    gtBS->FreePool (DevStr);

    Count = 0;
    PCIRootFirst = 0;
    SCSICount = 0;
    ATAPICount = 0;

    while (!IsDevicePathEnd (DevicePath)) {
        Type    = (UINT16)DevicePathType (DevicePath);
        SubType = (UINT16)DevicePathSubType (DevicePath);
        Length  = (UINT16)DevicePathNodeLength (DevicePath);

        Count++;
        //
        // Assertion Point 3.2.2.1
        // BIOS Root Specification Device Path
        //
        if ((Type == 5) && (SubType == 1)) {
            if (Count != 1) {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            } else {
                DevicePath = NextDevicePathNode (DevicePath);
                if(IsDevicePathEnd (DevicePath)) {
                    AssertionType = EFI_TEST_ASSERTION_PASSED;
                } else {
                    AssertionType = EFI_TEST_ASSERTION_FAILED;
                }
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid030,
                L"EFI_DEVICE_PATH_PROTOCOL - BIOS Root Specification Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
            break;
        }
        //
        // Assertion Point 3.2.2.2
        // PCI Root Bus Device Path Node
        //
        else if ((Type == 2) && (SubType == 1 || SubType == 2)) {
            Acpi = (ACPI_HID_DEVICE_PATH*)DevicePath;
            if (EISA_ID_TO_NUM(Acpi->HID) == 0x0A03) {
                if (Count == 1) {
                    PCIRootFirst++;
                    AssertionType = EFI_TEST_ASSERTION_PASSED;
                } else {
                    AssertionType = EFI_TEST_ASSERTION_FAILED;
                }

                StandardLib->RecordAssertion (
                    StandardLib,
                    AssertionType,
                    gDevicePathBBTestFunctionAssertionGuid031,
                    L"EFI_DEVICE_PATH_PROTOCOL - PCI Root Bus Device Path Node",
                    L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                    __FILE__,
                    __LINE__,
                    Type,
                    SubType,
                    Length
                );
            }
            //
            // Assertion Point 3.2.2.5
            // EISA Device Path Node
            //
            else if ((EISA_ID_TO_NUM(Acpi->HID) == 0x0604) ||
                     (EISA_ID_TO_NUM(Acpi->HID) == 0x0303) ||
                     (EISA_ID_TO_NUM(Acpi->HID) == 0x0F03) ||
                     (EISA_ID_TO_NUM(Acpi->HID) == 0x0501) ||
                     (EISA_ID_TO_NUM(Acpi->HID) == 0x0401)) {
                if (Count == (PCIRootFirst + 1)) {
                    AssertionType = EFI_TEST_ASSERTION_PASSED;
                } else {
                    AssertionType = EFI_TEST_ASSERTION_FAILED;
                }
                StandardLib->RecordAssertion (
                    StandardLib,
                    AssertionType,
                    gDevicePathBBTestFunctionAssertionGuid032,
                    L"EFI_DEVICE_PATH_PROTOCOL - EISA Device Path Node",
                    L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                    __FILE__,
                    __LINE__,
                    Type,
                    SubType,
                    Length
                );
            }
        }
        //
        // Assertion Point 3.2.2.3
        // PCI Device Path Node
        //
        else if ((Type == 1) && (SubType == 1)) {
            if (Count == (PCIRootFirst + 1)) {
                PCIRootFirst++;
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid033,
                L"EFI_DEVICE_PATH_PROTOCOL - PCI Device Path Node",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.2.2.4
        // Memory Mapped Device Path Node
        //
        else if ((Type == 1) && (SubType == 3)) {
            if (Count == 1) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid034,
                L"EFI_DEVICE_PATH_PROTOCOL - Memory Mapped Device Path Node",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.2.2.6
        // ATAPI Device Path Node
        //
        else if ((Type == 3) && (SubType == 1)) {
            if (Count == (PCIRootFirst + 1)) {
                ATAPICount = (UINT16)(PCIRootFirst + 1);
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid035,
                L"EFI_DEVICE_PATH_PROTOCOL - ATAPI Device Path Node",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }

        DevicePath = NextDevicePathNode (DevicePath);
    }
    //
    // Assertion Point 3.2.2.10
    // Device Path must be terminated
    //
    Type    = (UINT16)DevicePathType (DevicePath);
    SubType = (UINT16)DevicePathSubType (DevicePath);
    Length  = (UINT16)DevicePathNodeLength (DevicePath);

    if ((Type == 0x7F || Type == 0xFF) && (SubType == 0xFF)) {
        AssertionType = EFI_TEST_ASSERTION_PASSED;
    } else {
        AssertionType = EFI_TEST_ASSERTION_FAILED;
    }

    StandardLib->RecordAssertion (
        StandardLib,
        AssertionType,
        gDevicePathBBTestFunctionAssertionGuid039,
        L"EFI_DEVICE_PATH_PROTOCOL - Device Path must be terminated",
        L"%a:%d:Type - %d, Subtype - %d, Length - %d",
        __FILE__,
        __LINE__,
        Type,
        SubType,
        Length
    );

    return EFI_SUCCESS;
}
Ejemplo n.º 30
0
//
// TDS 3.1
//
EFI_STATUS
BBTestDevicePathNodeConformanceAutoTest (
    IN EFI_BB_TEST_PROTOCOL       *This,
    IN VOID                       *ClientInterface,
    IN EFI_TEST_LEVEL             TestLevel,
    IN EFI_HANDLE                 SupportHandle
)
{
    EFI_STANDARD_TEST_LIBRARY_PROTOCOL   *StandardLib;
    EFI_STATUS                           Status;
    EFI_DEVICE_PATH_PROTOCOL             *DevicePath;
    EFI_TEST_ASSERTION                   AssertionType;
    UINT16                               Type;
    UINT16                               SubType;
    UINT16                               Length;
    MEMMAP_DEVICE_PATH                   *MemMap;
    IPv4_DEVICE_PATH                     *IPv4;
    IPv6_DEVICE_PATH                     *IPv6;
    ATAPI_DEVICE_PATH                    *Atapi;
    UART_DEVICE_PATH                     *Uart;
    VENDOR_DEVICE_PATH                   *Vendor;
    HARDDRIVE_DEVICE_PATH                *Hd;
    CHAR16                               *DevStr;

    //
    // Verify whether it is one of IHV interfaces
    //
    if (! IsIhvInterface (ClientInterface, SupportHandle)) {
        return EFI_UNSUPPORTED;
    }

    //
    // Get the Standard Library Interface
    //
    Status = gtBS->HandleProtocol (
                 SupportHandle,
                 &gEfiStandardTestLibraryGuid,
                 &StandardLib
             );

    if (EFI_ERROR(Status)) {
        StandardLib->RecordAssertion (
            StandardLib,
            EFI_TEST_ASSERTION_FAILED,
            gTestGenericFailureGuid,
            L"BS.HandleProtocol - Handle standard test library",
            L"%a:%d:Status - %r",
            __FILE__,
            __LINE__,
            Status
        );
        return Status;
    }

    DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)ClientInterface;

    DevStr = DevicePathToStr (DevicePath);
    StandardLib->RecordMessage (
        StandardLib,
        EFI_VERBOSE_LEVEL_QUIET,
        L"\nVerifying device path: %s\n",
        DevStr
    );
    gtBS->FreePool (DevStr);

    while (!IsDevicePathEnd (DevicePath)) {
        Type    = (UINT16)DevicePathType (DevicePath);
        SubType = (UINT16)DevicePathSubType (DevicePath);
        Length  = (UINT16)DevicePathNodeLength (DevicePath);

        //
        // Assertion Point 3.1.2.2
        // Check End of Hardware Device Path: End This Device Path
        //
        if ((Type == 0x7F || Type == 0xFF) && (SubType == 0x01)) {
            if (Length == 4) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid001,
                L"EFI_DEVICE_PATH_PROTOCOL - End of Hardware Device Path - End This Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.3
        // Check Hardware Device Path: PCI Device Path
        //
        else if ((Type == 1) && (SubType == 1)) {
            if (Length == 6) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid002,
                L"EFI_DEVICE_PATH_PROTOCOL - Hardware Device Path - PCI Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.4
        // Check Hardware Device Path: PCCARD Device Path
        //
        else if ((Type == 1) && (SubType == 2)) {
            if (Length == 5) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid003,
                L"EFI_DEVICE_PATH_PROTOCOL - Hardware Device Path - PCCARD Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.5
        // Check Hardware Device Path: Memory Mapped Device Path
        //
        else if ((Type == 1) && (SubType == 3)) {
            MemMap = (MEMMAP_DEVICE_PATH *)DevicePath;
            if ((Length == 24) &&
                    (MemMap->MemoryType < EfiMaxMemoryType || MemMap->MemoryType > 0x7FFFFFFF) &&
                    (MemMap->EndingAddress >= MemMap->StartingAddress)) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid004,
                L"EFI_DEVICE_PATH_PROTOCOL - Hardware Device Path - Memory Mapped Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.6
        // Check Hardware Device Path: Vendor Device Path
        //
        else if ((Type == 1) && (SubType == 4)) {
            if (Length >= 20) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid005,
                L"EFI_DEVICE_PATH_PROTOCOL - Hardware Device Path - Vendor Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.7
        // Check Hardware Device Path: Controller Device Path
        //
        else if ((Type == 1) && (SubType == 5)) {
            if (Length == 8) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid006,
                L"EFI_DEVICE_PATH_PROTOCOL - Hardware Device Path - Controller Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.8
        // Check ACPI Device Path: ACPI Device Path
        //
        else if ((Type == 2) && (SubType == 1)) {
            if (Length == 12) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid007,
                L"EFI_DEVICE_PATH_PROTOCOL - ACPI Device Path - ACPI Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.9
        // Check ACPI Device Path: Expanded ACPI Device Path
        //
        else if ((Type == 2) && (SubType == 2)) {
            if (Length >= 19) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid008,
                L"EFI_DEVICE_PATH_PROTOCOL - ACPI Device Path - Expanded ACPI Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.10
        // Check Messaging Device Path: ATAPI Device Path
        //
        else if ((Type == 3) && (SubType == 1)) {
            Atapi = (ATAPI_DEVICE_PATH*)DevicePath;
            if ((Length == 8) &&
                    (Atapi->PrimarySecondary == 0 || Atapi->PrimarySecondary == 1) &&
                    (Atapi->SlaveMaster == 0 || Atapi->SlaveMaster == 1)) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid009,
                L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - ATAPI Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.11
        // Check Messaging Device Path: SCSI Device Path
        //
        else if ((Type == 3) && (SubType == 2)) {
            if (Length == 8) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid010,
                L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - SCSI Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.12
        // Check Messaging Device Path: Fibre Channel Device Path
        //
        else if ((Type == 3) && (SubType == 3)) {
            if (Length == 24) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid011,
                L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - Fibre Channel Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.13
        // Check Messaging Device Path: 1394 Device Path
        //
        else if ((Type == 3) && (SubType == 4)) {
            if (Length == 16) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid012,
                L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - 1394 Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.14
        // Check Messaging Device Path: USB Device Path
        //
        else if ((Type == 3) && (SubType == 5)) {
            if (Length == 6) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid013,
                L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - USB Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.15
        // Check Messaging Device Path: USB Class Device Path
        //
        else if ((Type == 3) && (SubType == 15)) {
            if (Length == 11) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid014,
                L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - USB Class Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.16
        // Check Messaging Device Path: I2O Device Path
        //
        else if ((Type == 3) && (SubType == 6)) {
            if (Length == 8) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid015,
                L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - I2O Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.17
        // Check Messaging Device Path: MAC Address Device Path
        //
        else if ((Type == 3) && (SubType == 11)) {
            if (Length == 37) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid016,
                L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - MAC Address Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.18
        // Check Messaging Device Path: IPv4 Device Path
        //
        else if ((Type == 3) && (SubType == 12)) {
            IPv4 = (IPv4_DEVICE_PATH*)DevicePath;
            if ((Length == 19) &&
                    (IPv4->StaticIpAddress == 0 || IPv4->StaticIpAddress == 1)) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid017,
                L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - IPv4 Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.19
        // Check Messaging Device Path: IPv6 Device Path
        //
        else if ((Type == 3) && (SubType == 13)) {
            IPv6 = (IPv6_DEVICE_PATH*)DevicePath;
            if ((Length == 43) &&
                    (IPv6->StaticIpAddress == 0 || IPv6->StaticIpAddress == 1)) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid018,
                L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - IPv6 Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.20
        // Check Messaging Device Path: InfiniBand Device Path
        //
        else if ((Type == 3) && (SubType == 9)) {
            if (Length == 48) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid019,
                L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - InfiniBand Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.21
        // Check Messaging Device Path: UART Device Path
        //
        else if ((Type == 3) && (SubType == 14)) {
            Uart = (UART_DEVICE_PATH*)DevicePath;
            if ((Length == 19) &&
                    (Uart->Parity >= 0x00 && Uart->Parity <= 0x05) &&
                    (Uart->StopBits >= 0x00 && Uart->StopBits <= 0x03)) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid020,
                L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - UART Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        else if ((Type == 3) && (SubType == 10)) {
            Vendor = (VENDOR_DEVICE_PATH*)DevicePath;
            //
            // Assertion Point 3.1.2.22
            // Check Messaging Device Path: Vendor-Defined Device Path
            //
            if (CompareMem (&Vendor->Guid, &gEfiDevicePathMessagingUartFlowControlGuid, sizeof (EFI_GUID)) != 0) {
                if (Length >= 20) {
                    AssertionType = EFI_TEST_ASSERTION_PASSED;
                } else {
                    AssertionType = EFI_TEST_ASSERTION_FAILED;
                }

                StandardLib->RecordAssertion (
                    StandardLib,
                    AssertionType,
                    gDevicePathBBTestFunctionAssertionGuid021,
                    L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - Vendor-Defined Device Path",
                    L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                    __FILE__,
                    __LINE__,
                    Type,
                    SubType,
                    Length
                );
            }
            //
            // Assertion Point 3.1.2.23
            // Check Messaging Device Path: UART Flow Control Messaging Path
            //
            else {
                if (Length == 24) {
                    AssertionType = EFI_TEST_ASSERTION_PASSED;
                } else {
                    AssertionType = EFI_TEST_ASSERTION_FAILED;
                }

                StandardLib->RecordAssertion (
                    StandardLib,
                    AssertionType,
                    gDevicePathBBTestFunctionAssertionGuid022,
                    L"EFI_DEVICE_PATH_PROTOCOL - Messaging Device Path - UART Flow Control Messaging Path",
                    L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                    __FILE__,
                    __LINE__,
                    Type,
                    SubType,
                    Length
                );
            }
        }
        //
        // Assertion Point 3.1.2.24
        // Check Media Device Path: Hard Drive Media Device Path
        //
        else if ((Type == 4) && (SubType == 1)) {
            Hd = (HARDDRIVE_DEVICE_PATH*)DevicePath;
            if ((Length == 42) &&
                    (Hd->MBRType == 0x01 || Hd->MBRType == 0x02) &&
                    (Hd->SignatureType == 0x00 || Hd->SignatureType == 0x01 || Hd->SignatureType == 0x02)) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid023,
                L"EFI_DEVICE_PATH_PROTOCOL - Media Device Path - Hard Drive Media Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.25
        // Check Media Device Path: CD-ROM Media Device Path
        //
        else if ((Type == 4) && (SubType == 2)) {
            if (Length == 24) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid024,
                L"EFI_DEVICE_PATH_PROTOCOL - Media Device Path - CD-ROM Media Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.26
        // Check Media Device Path: Vendor-Defined Media Device Path
        //
        else if ((Type == 4) && (SubType == 3)) {
            if (Length >= 20) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid025,
                L"EFI_DEVICE_PATH_PROTOCOL - Media Device Path - Vendor-Defined Media Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.27
        // Check Media Device Path: File Path Media Device Path
        //
        else if ((Type == 4) && (SubType == 4)) {
            if (Length >= 4) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid026,
                L"EFI_DEVICE_PATH_PROTOCOL - Media Device Path - File Path Media Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.28
        // Check Media Device Path: Media Protocol Device Path
        //
        else if ((Type == 4) && (SubType == 5)) {
            if (Length == 20) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid027,
                L"EFI_DEVICE_PATH_PROTOCOL - Media Device Path - Media Protocol Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        }
        //
        // Assertion Point 3.1.2.29
        // Check BIOS Boot Specification Device Path
        //
        else if ((Type == 5) && (SubType == 1)) {
            if (Length >= 8) {
                AssertionType = EFI_TEST_ASSERTION_PASSED;
            } else {
                AssertionType = EFI_TEST_ASSERTION_FAILED;
            }

            StandardLib->RecordAssertion (
                StandardLib,
                AssertionType,
                gDevicePathBBTestFunctionAssertionGuid028,
                L"EFI_DEVICE_PATH_PROTOCOL - BIOS Boot Specification Device Path",
                L"%a:%d:Type - %d, Subtype - %d, Length - %d",
                __FILE__,
                __LINE__,
                Type,
                SubType,
                Length
            );
        } else {
            StandardLib->RecordMessage (
                StandardLib,
                EFI_VERBOSE_LEVEL_QUIET,
                L"Unknown Node(Type - %d, Subtype - %d, Length - %d)\n",
                Type,
                SubType,
                Length
            );
        }


        DevicePath = NextDevicePathNode (DevicePath);
    }

    //
    // Assertion Point 3.1.2.1
    // Check End of Hardware Device Path: End Entire Device Path
    //
    Type    = (UINT16)DevicePathType (DevicePath);
    SubType = (UINT16)DevicePathSubType (DevicePath);
    Length  = (UINT16)DevicePathNodeLength (DevicePath);

    if ((Type == 0x7F || Type == 0xFF) && (SubType == 0xFF)) {
        if (Length == 4) {
            AssertionType = EFI_TEST_ASSERTION_PASSED;
        } else {
            AssertionType = EFI_TEST_ASSERTION_FAILED;
        }

        StandardLib->RecordAssertion (
            StandardLib,
            AssertionType,
            gDevicePathBBTestFunctionAssertionGuid029,
            L"EFI_DEVICE_PATH_PROTOCOL - End of Hardware Device Path - End Entire Device Path",
            L"%a:%d:Type - %d, Subtype - %d, Length - %d",
            __FILE__,
            __LINE__,
            Type,
            SubType,
            Length
        );
    }

    return EFI_SUCCESS;
}