Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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;
}