Beispiel #1
0
EFI_DEVICE_PATH *
LibDuplicateDevicePathInstance (
    IN EFI_DEVICE_PATH  *DevPath
    )
{
    EFI_DEVICE_PATH     *NewDevPath,*DevicePathInst,*Temp;
    UINTN               Size = 0;    

    //
    // get the size of an instance from the input
    //

    Temp = DevPath;
    DevicePathInst = DevicePathInstance (&Temp, &Size);
    
    //
    // Make a copy and set proper end type
    //
    NewDevPath = NULL;
    if (Size) { 
        NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH));
    }

    if (NewDevPath) {
        CopyMem (NewDevPath, DevicePathInst, Size);
        Temp = NextDevicePathNode(NewDevPath); 
        SetDevicePathEndNode(Temp);
    }

    return NewDevPath;
}
Beispiel #2
0
UINTN
DevicePathInstanceCount (
  IN EFI_DEVICE_PATH_PROTOCOL      *DevicePath
  )
/*++

Routine Description:
  Function is used to determine the number of device path instances that exist in a device path.

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

Returns:

  This function counts and returns the number of device path instances in DevicePath.

--*/
{
  UINTN       Count, Size;

  Count = 0;
  while (DevicePathInstance(&DevicePath, &Size)) {
    Count += 1;
  }
  return Count;
}
Beispiel #3
0
BOOLEAN
LibMatchDevicePaths (
  IN  EFI_DEVICE_PATH_PROTOCOL *Multi,
  IN  EFI_DEVICE_PATH_PROTOCOL *Single
  )
/*++

Routine Description:
  Function compares a device path data structure to that of all the nodes of a
  second device path instance.

Arguments:
  Multi        - A pointer to a multi-instance device path data structure.

  Single       - A pointer to a single-instance device path data structure.

Returns:

  The function returns TRUE if the Single is contained within Multi.
  Otherwise, FALSE is returned.

--*/
{
  EFI_DEVICE_PATH_PROTOCOL    *DevicePath, *DevicePathInst;
  UINTN                       Size;

  if (!Multi || !Single) {
    return FALSE;
  }

  DevicePath = Multi;
  DevicePathInst = DevicePathInstance (&DevicePath, &Size);
  while (DevicePathInst) {
    if (CompareMem (Single, DevicePathInst, Size - sizeof(EFI_DEVICE_PATH_PROTOCOL)) == 0) {
      return TRUE;
    }
    DevicePathInst = DevicePathInstance (&DevicePath, &Size);
  }
  return FALSE;
}
Beispiel #4
0
UINTN
DevicePathInstanceCount (
    IN EFI_DEVICE_PATH      *DevicePath
    )
{
    UINTN       Count, Size;

    Count = 0;
    while (DevicePathInstance(&DevicePath, &Size)) {
        Count += 1;
    }

    return Count;
}
Beispiel #5
0
EFI_DEVICE_PATH_PROTOCOL *
LibDuplicateDevicePathInstance (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevPath
  )
/*++

Routine Description:
  Function creates a device path data structure that identically matches the
  device path passed in.

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

Returns:

  The new copy of DevPath is created to identically match the input.
  Otherwise, NULL is returned.

--*/
{
  EFI_DEVICE_PATH_PROTOCOL    *NewDevPath,*DevicePathInst,*Temp;
  UINTN                       Size;

  //
  // get the size of an instance from the input
  //
  Temp = DevPath;
  DevicePathInst = DevicePathInstance (&Temp, &Size);

  //
  // Make a copy
  //
  NewDevPath = NULL;
  if (Size) {
    NewDevPath = AllocatePool (Size);
  }

  if (NewDevPath) {
    CopyMem (NewDevPath, DevicePathInst, Size);
//    Temp = NextDevicePathNode(NewDevPath);
//    SetDevicePathEndNode(Temp);
  }
  return NewDevPath;
}
Beispiel #6
0
BOOLEAN
LibMatchDevicePaths (
    IN  EFI_DEVICE_PATH *Multi,
    IN  EFI_DEVICE_PATH *Single
    )
{
    EFI_DEVICE_PATH     *DevicePath, *DevicePathInst;
    UINTN               Size;

    if (!Multi || !Single) {
        return FALSE;
    }

    DevicePath = Multi;
    while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) {
        if (CompareMem (Single, DevicePathInst, Size) == 0) {
            return TRUE;
        }
    }
    return FALSE;
}
Beispiel #7
0
EFI_IMAGE_EXECUTION_INFO *
configtable_find_image(const EFI_DEVICE_PATH *DevicePath)
{
	EFI_IMAGE_EXECUTION_INFO_TABLE *t = configtable_get_image_table();

	if (!t)
		return NULL;

	int entries = t->NumberOfImages;
	EFI_IMAGE_EXECUTION_INFO *e = t->InformationInfo;

	int i;
	for (i = 0; i < entries; i++) {
#ifdef DEBUG_CONFIG
		console_print(L"InfoSize = %d  Action = %d\n", e->InfoSize, e->Action);

		/* print what we have for debugging */
		UINT8 *d = (UINT8 *)e; // + sizeof(UINT32)*2;
		console_print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
		      d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 
		d += 16;
		console_print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
		      d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 
		d += 16;
		console_print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
		      d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 
		d += 16;
		console_print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
		      d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 
		d += 16;
		console_print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
		      d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 
		d += 16;
		console_print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
		      d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); 
#endif
		CHAR16 *name = (CHAR16 *)(e->Data);
		int skip = 0;

		/* There's a bug in a lot of EFI platforms and they forget to
		 * put the name here.  The only real way of detecting it is to
		 * look for either a UC16 NULL or ASCII as UC16 */
		if (name[0] == '\0' || (e->Data[1] == 0 && e->Data[3] == 0)) {
			skip = StrSize(name);
#ifdef DEBUG_CONFIG
			console_print(L"FOUND NAME %s (%d)\n", name, skip);
#endif
		}
		EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *)(e->Data + skip), *dpn = dp;
		if (dp->Type == 0 || dp->Type > 6 || dp->SubType == 0
		    || ((unsigned)((dp->Length[1] << 8) + dp->Length[0]) > e->InfoSize)) {
			/* Parse error, table corrupt, bail */
			console_print(L"Image Execution Information table corrupt\n");
			break;
		}

		UINTN Size;
		DevicePathInstance(&dpn, &Size);
#ifdef DEBUG_CONFIG
		console_print(L"Path: %s\n", DevicePathToStr(dp));
		console_print(L"Device Path Size %d\n", Size);
#endif
		if (Size > e->InfoSize) {
			/* parse error; the platform obviously has a 
			 * corrupted image table; bail */
			console_print(L"Image Execution Information table corrupt\n");
			break;
		}
		
		if (CompareMem(dp, (void *)DevicePath, Size) == 0) {
#ifdef DEBUG_CONFIG
			console_print(L"***FOUND\n");
			console_get_keystroke();
#endif
			return e;
		}
		e = (EFI_IMAGE_EXECUTION_INFO *)((UINT8 *)e + e->InfoSize);
	}

#ifdef DEBUG_CONFIG
	console_print(L"***NOT FOUND\n");
	console_get_keystroke();
#endif

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

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

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

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

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

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

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

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

        //
        // Copy all device path instances
        //

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

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

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

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

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

    return Dst;
}
Beispiel #9
0
EFI_DEVICE_PATH_PROTOCOL *
AppendDevicePath (
  IN EFI_DEVICE_PATH_PROTOCOL  *Src1,
  IN EFI_DEVICE_PATH_PROTOCOL  *Src2
  )
/*++

Routine Description:
  Function is used to append a device path 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:

  A pointer to the new device path is returned.
  NULL is returned if space for the new device path could not be allocated from pool.
  It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed.

  Src1 may have multiple "instances" and each instance is appended
  Src2 is appended to each instance is Src1.  (E.g., it's possible
  to append a new instance to the complete device path by passing
  it in Src2)

--*/
{
  UINTN                       Src1Size, Src1Inst, Src2Size, Size;
  EFI_DEVICE_PATH_PROTOCOL    *Dst, *Inst;
  UINT8                       *DstPos;

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

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

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

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

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

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

  Src1Size = DevicePathSize(Src1);
  Src1Inst = DevicePathInstanceCount(Src1);
  Src2Size = DevicePathSize(Src2);
  Size = Src1Size * Src1Inst + Src2Size;
  Size -= Src1Inst * sizeof(EFI_DEVICE_PATH_PROTOCOL);

  Dst = AllocatePool (Size);
  if (Dst) {
    DstPos = (UINT8 *) Dst;

    //
    // Copy all device path instances
    //
    Inst = DevicePathInstance (&Src1, &Size);
    while (Inst) {

      CopyMem(DstPos, Inst, Size);
      DstPos += Size - sizeof(EFI_DEVICE_PATH_PROTOCOL);

      CopyMem(DstPos, Src2, Src2Size);
      DstPos += Src2Size - sizeof(EFI_DEVICE_PATH_PROTOCOL);

      CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH_PROTOCOL));
      DstPos += sizeof(EFI_DEVICE_PATH_PROTOCOL);

      Inst = DevicePathInstance (&Src1, &Size);
    }

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

  return Dst;
}