Beispiel #1
0
/**
  Extract device path for given HII handle and class guid.

  @param Handle          The HII handle.

  @retval  NULL          Fail to get the device path string.
  @return  PathString    Get the device path string.

**/
CHAR16 *
BmmExtractDevicePathFromHiiHandle (
  IN      EFI_HII_HANDLE      Handle
  )
{
  EFI_STATUS                       Status;
  EFI_HANDLE                       DriverHandle;

  ASSERT (Handle != NULL);

  if (Handle == NULL) {
    return NULL;
  }

  Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  //
  // Get device path string.
  //
  return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE);

}
Beispiel #2
0
/**
  This function gets driver name from Component Name 2 protocol interface and Component Name protocol interface
  in turn. It first tries UEFI 2.0 Component Name 2 protocol interface and try to get the driver name.
  If the attempt fails, it then gets the driver name from EFI 1.1 Component Name protocol for backward
  compatibility support.

  @param  DriverBindingHandle  The handle on which the Component Name (2) protocol instance is retrieved.

  @return A pointer to the Unicode string to return. This Unicode string is the name of the controller
          specified by ControllerHandle and ChildHandle.


**/
CHAR16 *
DriverHealthManagerGetDriverName (
  IN  EFI_HANDLE  DriverBindingHandle
  )
{
  EFI_STATUS      Status;
  CHAR16          *DriverName;

  //
  // Get driver name from UEFI 2.0 Component Name 2 protocol interface.
  //
  Status = DriverHealthManagerGetDriverNameWorker (&gEfiComponentName2ProtocolGuid, DriverBindingHandle, &DriverName);
  if (EFI_ERROR (Status)) {
    //
    // If it fails to get the driver name from Component Name protocol interface, we should fall back on
    // EFI 1.1 Component Name protocol interface.
    //
    Status = DriverHealthManagerGetDriverNameWorker (&gEfiComponentNameProtocolGuid, DriverBindingHandle, &DriverName);
  }

  if (!EFI_ERROR (Status)) {
    return AllocateCopyPool (StrSize (DriverName), DriverName);
  } else {
    return ConvertDevicePathToText (DevicePathFromHandle (DriverBindingHandle), FALSE, TRUE);
  }
}
Beispiel #3
0
Datei: Dh.c Projekt: pmj/edk2
/**
  Gets the name of the loaded image.

  @param[in] TheHandle    The handle of the driver to get info on.
  @param[out] Name        The pointer to the pointer.  Valid upon a successful return.

  @retval EFI_SUCCESS     The operation was successful.
**/
EFI_STATUS
GetDriverImageName (
  IN EFI_HANDLE   TheHandle,
  OUT CHAR16      **Name
  )
{
  // get loaded image and devicepathtotext on image->Filepath
  EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  if (TheHandle == NULL || Name == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  Status = gBS->OpenProtocol (
                TheHandle,
                &gEfiLoadedImageProtocolGuid,
                (VOID **) &LoadedImage,
                gImageHandle,
                NULL,
                EFI_OPEN_PROTOCOL_GET_PROTOCOL
               );
  if (EFI_ERROR(Status)) {
    return (Status);
  }
  DevicePath = LoadedImage->FilePath;
  *Name = ConvertDevicePathToText(DevicePath, TRUE, TRUE);
  return (EFI_SUCCESS);
}
Beispiel #4
0
EFIAPI
DevicePathToStr (
  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath
  )
{
  return ConvertDevicePathToText (DevPath, TRUE, TRUE);
}
Beispiel #5
0
/**
  Get a device path (in text format) for a given handle.

  @param[in] TheHandle      The handle to get the device path for.

  @retval NULL    An error occured.
  @return         A pointer to the driver path as a string.  The callee must 
                  free this memory.
**/
CHAR16*
GetDevicePathTextForHandle(
  IN EFI_HANDLE TheHandle
  )
{
  EFI_STATUS                Status;
  EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
  EFI_DEVICE_PATH_PROTOCOL  *ImageDevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *FinalPath;
  CHAR16                    *RetVal;

  FinalPath = NULL;

  Status = gBS->OpenProtocol (
                TheHandle,
                &gEfiLoadedImageProtocolGuid,
                (VOID**)&LoadedImage,
                gImageHandle,
                NULL,
                EFI_OPEN_PROTOCOL_GET_PROTOCOL
               );
  if (!EFI_ERROR (Status)) {
    Status = gBS->OpenProtocol (
                  LoadedImage->DeviceHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID**)&ImageDevicePath,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                 );
    if (!EFI_ERROR (Status)) {
      FinalPath = AppendDevicePath (ImageDevicePath, LoadedImage->FilePath);
      gBS->CloseProtocol(
        LoadedImage->DeviceHandle,
        &gEfiDevicePathProtocolGuid,
        gImageHandle,
        NULL);
    }
    gBS->CloseProtocol(
                TheHandle,
                &gEfiLoadedImageProtocolGuid,
                gImageHandle,
                NULL);
  }

  if (FinalPath == NULL) {
    return (NULL);
  }
  RetVal = gEfiShellProtocol->GetFilePathFromDevicePath(FinalPath);
  if (RetVal == NULL) {
    RetVal = ConvertDevicePathToText(FinalPath, TRUE, TRUE);
  }
  FreePool(FinalPath);
  return (RetVal);
}
Beispiel #6
0
/**
  Locate all handles that carry the specified protocol, filter them with a
  callback function, and pass each handle that passes the filter to another
  callback.

  @param[in] ProtocolGuid  The protocol to look for.

  @param[in] Filter        The filter function to pass each handle to. If this
                           parameter is NULL, then all handles are processed.

  @param[in] Process       The callback function to pass each handle to that
                           clears the filter.
**/
STATIC
VOID
FilterAndProcess (
  IN EFI_GUID          *ProtocolGuid,
  IN FILTER_FUNCTION   Filter         OPTIONAL,
  IN CALLBACK_FUNCTION Process
  )
{
  EFI_STATUS Status;
  EFI_HANDLE *Handles;
  UINTN      NoHandles;
  UINTN      Idx;

  Status = gBS->LocateHandleBuffer (ByProtocol, ProtocolGuid,
                  NULL /* SearchKey */, &NoHandles, &Handles);
  if (EFI_ERROR (Status)) {
    //
    // This is not an error, just an informative condition.
    //
    DEBUG ((EFI_D_VERBOSE, "%a: %g: %r\n", __FUNCTION__, ProtocolGuid,
      Status));
    return;
  }

  ASSERT (NoHandles > 0);
  for (Idx = 0; Idx < NoHandles; ++Idx) {
    CHAR16        *DevicePathText;
    STATIC CHAR16 Fallback[] = L"<device path unavailable>";

    //
    // The ConvertDevicePathToText() function handles NULL input transparently.
    //
    DevicePathText = ConvertDevicePathToText (
                       DevicePathFromHandle (Handles[Idx]),
                       FALSE, // DisplayOnly
                       FALSE  // AllowShortcuts
                       );
    if (DevicePathText == NULL) {
      DevicePathText = Fallback;
    }

    if (Filter == NULL || Filter (Handles[Idx], DevicePathText)) {
      Process (Handles[Idx], DevicePathText);
    }

    if (DevicePathText != Fallback) {
      FreePool (DevicePathText);
    }
  }
  gBS->FreePool (Handles);
}
/**
  Dump SMI child context.

  @param HandlerType  the handler type
  @param Context      the handler context
  @param ContextSize  the handler context size
**/
VOID
DumpSmiChildContext (
  IN EFI_GUID   *HandlerType,
  IN VOID       *Context,
  IN UINTN      ContextSize
  )
{
  CHAR16        *Str;

  if (CompareGuid (HandlerType, &gEfiSmmSwDispatch2ProtocolGuid)) {
    Print(L" SwSmi=\"0x%lx\"", ((SMI_HANDLER_PROFILE_SW_REGISTER_CONTEXT *)Context)->SwSmiInputValue);
  } else if (CompareGuid (HandlerType, &gEfiSmmSxDispatch2ProtocolGuid)) {
    Print(L" SxType=\"%a\"", SxTypeToString(((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Type));
    Print(L" SxPhase=\"%a\"", SxPhaseToString(((EFI_SMM_SX_REGISTER_CONTEXT *)Context)->Phase));
  } else if (CompareGuid (HandlerType, &gEfiSmmPowerButtonDispatch2ProtocolGuid)) {
    Print(L" PowerButtonPhase=\"%a\"", PowerButtonPhaseToString(((EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Context)->Phase));
  } else if (CompareGuid (HandlerType, &gEfiSmmStandbyButtonDispatch2ProtocolGuid)) {
    Print(L" StandbyButtonPhase=\"%a\"", StandbyButtonPhaseToString(((EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Context)->Phase));
  } else if (CompareGuid (HandlerType, &gEfiSmmPeriodicTimerDispatch2ProtocolGuid)) {
    Print(L" PeriodicTimerPeriod=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->Period);
    Print(L" PeriodicTimerSmiTickInterval=\"%ld\"", ((EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT *)Context)->SmiTickInterval);
  } else if (CompareGuid (HandlerType, &gEfiSmmGpiDispatch2ProtocolGuid)) {
    Print(L" GpiNum=\"0x%lx\"", ((EFI_SMM_GPI_REGISTER_CONTEXT *)Context)->GpiNum);
  } else if (CompareGuid (HandlerType, &gEfiSmmIoTrapDispatch2ProtocolGuid)) {
    Print(L" IoTrapAddress=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Address);
    Print(L" IoTrapLength=\"0x%x\"", ((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Length);
    Print(L" IoTrapType=\"%a\"", IoTrapTypeToString(((EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context)->Type));
  } else if (CompareGuid (HandlerType, &gEfiSmmUsbDispatch2ProtocolGuid)) {
    Print(L" UsbType=\"0x%x\"", UsbTypeToString(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context)->Type));
    Str = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL *)(((SMI_HANDLER_PROFILE_USB_REGISTER_CONTEXT *)Context) + 1), TRUE, TRUE);
    Print(L" UsbDevicePath=\"%s\"", Str);
    if (Str != NULL) {
      FreePool (Str);
    }
  } else {
    Print(L" Context=\"");
    InternalDumpData (Context, ContextSize);
    Print(L"\"");
  }
}
Beispiel #8
0
/**
  Create an action OpCode with QuestionID and DevicePath on a given OpCodeHandle.

  @param[in]  QuestionID            The question ID.
  @param[in]  DevicePath            Points to device path.
  @param[in]  OpCodeHandle          Points to container for dynamic created opcodes.

**/
VOID
AddDevicePath (
  IN  UINTN                                     QuestionID,
  IN  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath,
  IN     VOID                                   *OpCodeHandle
  )
{
  EFI_DEVICE_PATH_PROTOCOL          *Next;
  EFI_STRING_ID                     NameID;
  EFI_STRING                        DriverName;

  //
  // Get driver file name node.
  //
  Next = DevicePath;
  while (!IsDevicePathEnd (Next)) {
    DevicePath  = Next;
    Next        = NextDevicePathNode (Next);
  }

  //
  // Display the device path in form.
  //
  DriverName = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
  NameID = HiiSetString (mCallbackInfo->HiiHandle, 0, DriverName, NULL);
  FreePool (DriverName);
  if (NameID == 0) {
    return ;
  }

  HiiCreateActionOpCode (
    OpCodeHandle,                   // Container for dynamic created opcodes
    (UINT16) QuestionID,            // Question ID
    NameID,                         // Prompt text
    STRING_TOKEN (STR_NULL_STRING), // Help text
    EFI_IFR_FLAG_CALLBACK,          // Question flag
    0                               // Action String ID
    );
}
Beispiel #9
0
/**
  Append some of the unselected active boot options to the boot order.

  This function should accommodate any further policy changes in "boot option
  survival". Currently we're adding back everything that starts with neither
  PciRoot() nor HD().

  @param[in,out] BootOrder     The structure holding the boot order to
                               complete. The caller is responsible for
                               initializing (and potentially populating) it
                               before calling this function.

  @param[in,out] ActiveOption  The array of active boot options to scan.
                               Entries marked as Appended will be skipped.
                               Those of the rest that satisfy the survival
                               policy will be added to BootOrder with
                               BootOrderAppend().

  @param[in]     ActiveCount   Number of elements in ActiveOption.


  @retval RETURN_SUCCESS  BootOrder has been extended with any eligible boot
                          options.

  @return                 Error codes returned by BootOrderAppend().
**/
STATIC
RETURN_STATUS
BootOrderComplete (
  IN OUT  BOOT_ORDER    *BootOrder,
  IN OUT  ACTIVE_OPTION *ActiveOption,
  IN      UINTN         ActiveCount
  )
{
  RETURN_STATUS Status;
  UINTN         Idx;

  Status = RETURN_SUCCESS;
  Idx = 0;
  while (!RETURN_ERROR (Status) && Idx < ActiveCount) {
    if (!ActiveOption[Idx].Appended) {
      CONST BDS_COMMON_OPTION        *Current;
      CONST EFI_DEVICE_PATH_PROTOCOL *FirstNode;

      Current = ActiveOption[Idx].BootOption;
      FirstNode = Current->DevicePath;
      if (FirstNode != NULL) {
        CHAR16        *Converted;
        STATIC CHAR16 ConvFallBack[] = L"<unable to convert>";
        BOOLEAN       Keep;

        Converted = ConvertDevicePathToText (FirstNode, FALSE, FALSE);
        if (Converted == NULL) {
          Converted = ConvFallBack;
        }

        Keep = TRUE;
        if (DevicePathType(FirstNode) == MEDIA_DEVICE_PATH &&
            DevicePathSubType(FirstNode) == MEDIA_HARDDRIVE_DP) {
          //
          // drop HD()
          //
          Keep = FALSE;
        } else if (DevicePathType(FirstNode) == ACPI_DEVICE_PATH &&
                   DevicePathSubType(FirstNode) == ACPI_DP) {
          ACPI_HID_DEVICE_PATH *Acpi;

          Acpi = (ACPI_HID_DEVICE_PATH *) FirstNode;
          if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST &&
              EISA_ID_TO_NUM (Acpi->HID) == 0x0a03) {
            //
            // drop PciRoot()
            //
            Keep = FALSE;
          }
        }

        if (Keep) {
          Status = BootOrderAppend (BootOrder, &ActiveOption[Idx]);
          if (!RETURN_ERROR (Status)) {
            DEBUG ((DEBUG_VERBOSE, "%a: keeping \"%s\"\n", __FUNCTION__,
              Converted));
          }
        } else {
          DEBUG ((DEBUG_VERBOSE, "%a: dropping \"%s\"\n", __FUNCTION__,
            Converted));
        }

        if (Converted != ConvFallBack) {
          FreePool (Converted);
        }
      }
    }
    ++Idx;
  }
  return Status;
}
Beispiel #10
0
/**
  Dump Provisioned Capsule.

  @param[in]  DumpCapsuleInfo  The flag to indicate whether to dump the capsule inforomation.

**/
VOID
DumpProvisionedCapsule (
  IN BOOLEAN                      DumpCapsuleInfo
  )
{
  EFI_STATUS                      Status;
  CHAR16                          CapsuleVarName[30];
  CHAR16                          *TempVarName;
  UINTN                           Index;
  EFI_PHYSICAL_ADDRESS            *CapsuleDataPtr64;
  UINT16                          *BootNext;
  CHAR16                          BootOptionName[20];
  EFI_BOOT_MANAGER_LOAD_OPTION    BootNextOptionEntry;
  EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
  EFI_SHELL_PROTOCOL              *ShellProtocol;

  Index             = 0;
  CapsuleDataPtr64  = NULL;
  BootNext          = NULL;

  ShellProtocol = GetShellProtocol ();
  if (ShellProtocol == NULL) {
    Print (L"Get Shell Protocol Fail\n");
    return ;
  }

  //
  // Dump capsule provisioned on Memory
  //
  Print (L"#########################\n");
  Print (L"### Capsule on Memory ###\n");
  Print (L"#########################\n");
  StrCpyS (CapsuleVarName, sizeof(CapsuleVarName)/sizeof(CHAR16), EFI_CAPSULE_VARIABLE_NAME);
  TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
  while (TRUE) {
    if (Index > 0) {
      UnicodeValueToStringS (
        TempVarName,
        sizeof (CapsuleVarName) - ((UINTN)TempVarName - (UINTN)CapsuleVarName),
        0,
        Index,
        0
        );
    }

    Status = GetVariable2 (
              CapsuleVarName,
              &gEfiCapsuleVendorGuid,
              (VOID **) &CapsuleDataPtr64,
              NULL
              );
    if (EFI_ERROR (Status) || CapsuleDataPtr64 == NULL) {
      if (Index == 0) {
        Print (L"No data.\n");
      }
      break;
    }

    Index++;
    Print (L"Capsule Description at 0x%08x\n", *CapsuleDataPtr64);
    DumpBlockDescriptors ((EFI_CAPSULE_BLOCK_DESCRIPTOR*) (UINTN) *CapsuleDataPtr64, DumpCapsuleInfo);
  }

  //
  // Dump capsule provisioned on Disk
  //
  Print (L"#########################\n");
  Print (L"### Capsule on Disk #####\n");
  Print (L"#########################\n");
  Status = GetVariable2 (
             L"BootNext",
             &gEfiGlobalVariableGuid,
             (VOID **) &BootNext,
             NULL
            );
  if (EFI_ERROR (Status) || BootNext == NULL) {
    Print (L"Get BootNext Variable Fail. Status = %r\n", Status);
  } else {
    UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04x", *BootNext);
    Status = EfiBootManagerVariableToLoadOption (BootOptionName, &BootNextOptionEntry);
    if (!EFI_ERROR (Status)) {
      //
      // Display description and device path
      //
      GetEfiSysPartitionFromBootOptionFilePath (BootNextOptionEntry.FilePath, &DevicePath, &Fs);
      if(!EFI_ERROR (Status)) {
        Print (L"Capsules are provisioned on BootOption: %s\n", BootNextOptionEntry.Description);
        Print (L"    %s %s\n", ShellProtocol->GetMapFromDevicePath (&DevicePath), ConvertDevicePathToText(DevicePath, TRUE, TRUE));
        DumpCapsuleFromDisk (Fs, DumpCapsuleInfo);
      }
    }
  }
}
Beispiel #11
0
/**
  Function to read in HII configuration information from a file.

  @param[in] Handle           The handle to get info for.
  @param[in] FileName         The filename to read the info from.
**/
SHELL_STATUS
EFIAPI
ConfigFromFile(
  IN       EFI_HANDLE     Handle,
  IN CONST CHAR16         *FileName
  )
{
  EFI_HII_DATABASE_PROTOCOL     *HiiDatabase;
  EFI_STATUS                    Status;
  VOID                          *MainBuffer;
  UINT64                        Temp;
  UINTN                         MainBufferSize;
  EFI_HII_HANDLE                HiiHandle;
  SHELL_FILE_HANDLE             FileHandle;
  CHAR16                        *TempDevPathString;
  EFI_HII_PACKAGE_LIST_HEADER   *PackageListHeader;
  EFI_HII_PACKAGE_HEADER        *PackageHeader;
  EFI_DEVICE_PATH_PROTOCOL      *DevPath;
  UINTN                         HandleIndex;

  HiiDatabase       = NULL;
  MainBufferSize    = 0;
  MainBuffer        = NULL;
  FileHandle        = NULL;

  Status = ShellOpenFileByName(FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
  if (EFI_ERROR(Status)) {
    ShellPrintHiiEx(
      -1,
      -1,
      NULL,
      STRING_TOKEN(STR_GEN_FILE_OPEN), 
      gShellDriver1HiiHandle, 
      FileName, 
      Status);
    return (SHELL_DEVICE_ERROR);
  }

  //
  // Locate HII Database protocol
  //
  Status = gBS->LocateProtocol (
                  &gEfiHiiDatabaseProtocolGuid,
                  NULL,
                  (VOID **) &HiiDatabase
                  );

  if (EFI_ERROR(Status) || HiiDatabase == NULL) {
    ShellPrintHiiEx(
      -1, 
      -1, 
      NULL,
      STRING_TOKEN(STR_GEN_PROTOCOL_NF), 
      gShellDriver1HiiHandle, 
      L"EfiHiiDatabaseProtocol", 
      &gEfiHiiDatabaseProtocolGuid);
    ShellCloseFile(&FileHandle);
    return (SHELL_NOT_FOUND);
  }

  Status = ShellGetFileSize(FileHandle, &Temp);
  MainBufferSize = (UINTN)Temp;
  if (EFI_ERROR(Status)) {
    ShellPrintHiiEx(
      -1, 
      -1, 
      NULL, 
      STRING_TOKEN(STR_FILE_READ_FAIL), 
      gShellDriver1HiiHandle, 
      FileName,
      Status);
    ShellCloseFile(&FileHandle);
    return (SHELL_DEVICE_ERROR);   
  }
  MainBuffer = AllocateZeroPool((UINTN)MainBufferSize);  
  if (EFI_ERROR(Status)) {
    ShellPrintHiiEx(
      -1, 
      -1, 
      NULL, 
      STRING_TOKEN(STR_GEN_OUT_MEM), 
      gShellDriver1HiiHandle);
    ShellCloseFile(&FileHandle);
    return (SHELL_DEVICE_ERROR);   
  }
  Status = ShellReadFile(FileHandle, &MainBufferSize, MainBuffer);
  if (EFI_ERROR(Status)) {
    ShellPrintHiiEx(
      -1, 
      -1, 
      NULL, 
      STRING_TOKEN(STR_FILE_READ_FAIL), 
      gShellDriver1HiiHandle, 
      FileName,
      Status);
    ShellCloseFile(&FileHandle);
    SHELL_FREE_NON_NULL(MainBuffer);
    return (SHELL_DEVICE_ERROR);   
  }

  ShellCloseFile(&FileHandle);

  if (Handle != NULL) {
    //
    // User override in place.  Just do it.
    //
    HiiHandle         = NULL;
    Status = ConvertHandleToHiiHandle(Handle, &HiiHandle, HiiDatabase);
    if (EFI_ERROR(Status)) {
      ShellPrintHiiEx(
        -1, 
        -1, 
        NULL, 
        STRING_TOKEN(STR_GEN_HANDLE_NOT), 
        gShellDriver1HiiHandle, 
        ConvertHandleToHandleIndex(Handle), 
        L"Device");
      ShellCloseFile(&FileHandle);
      return (SHELL_DEVICE_ERROR);   
    }
    Status = HiiDatabase->UpdatePackageList(HiiDatabase, HiiHandle, MainBuffer);
    if (EFI_ERROR(Status)) {
      ShellPrintHiiEx(
        -1, 
        -1, 
        NULL, 
        STRING_TOKEN(STR_GEN_UEFI_FUNC_ERROR), 
        gShellDriver1HiiHandle, 
        L"HiiDatabase->UpdatePackageList", 
        Status);
      return (SHELL_DEVICE_ERROR);   
    }
  } else {
    //
    // we need to parse the buffer and try to match the device paths for each item to try to find it's device path.
    //

    for (PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)MainBuffer
      ;  PackageListHeader != NULL && ((CHAR8*)PackageListHeader) < (((CHAR8*)MainBuffer)+MainBufferSize)
      ;  PackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER*)(((CHAR8*)(PackageListHeader)) + PackageListHeader->PackageLength )) {
        for (PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageListHeader))+sizeof(EFI_HII_PACKAGE_LIST_HEADER))
          ; PackageHeader != NULL && ((CHAR8*)PackageHeader) < (((CHAR8*)MainBuffer)+MainBufferSize) && PackageHeader->Type != EFI_HII_PACKAGE_END
          ; PackageHeader = (EFI_HII_PACKAGE_HEADER*)(((CHAR8*)(PackageHeader))+PackageHeader->Length)) {
            if (PackageHeader->Type == EFI_HII_PACKAGE_DEVICE_PATH) {
              HiiHandle         = NULL;
              Status = FindHiiHandleViaDevPath((EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER)), &HiiHandle, HiiDatabase);
              if (EFI_ERROR(Status)) {
                //
                // print out an error.
                //
                TempDevPathString = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER)), TRUE, TRUE);
                ShellPrintHiiEx(
                  -1, 
                  -1, 
                  NULL, 
                  STRING_TOKEN(STR_DRVCFG_IN_FILE_NF), 
                  gShellDriver1HiiHandle, 
                  TempDevPathString);
                SHELL_FREE_NON_NULL(TempDevPathString);
             } else {
                Status = HiiDatabase->UpdatePackageList(HiiDatabase, HiiHandle, PackageListHeader);
                if (EFI_ERROR(Status)) {
                  ShellPrintHiiEx(
                    -1, 
                    -1, 
                    NULL, 
                    STRING_TOKEN(STR_GEN_UEFI_FUNC_ERROR), 
                    gShellDriver1HiiHandle, 
                    L"HiiDatabase->UpdatePackageList", 
                    Status);
                  return (SHELL_DEVICE_ERROR);
                } else {
                  DevPath = (EFI_DEVICE_PATH_PROTOCOL*)(((CHAR8*)PackageHeader) + sizeof(EFI_HII_PACKAGE_HEADER));
                  gBS->LocateDevicePath(&gEfiHiiConfigAccessProtocolGuid, &DevPath, &Handle);
                  HandleIndex = ConvertHandleToHandleIndex(Handle);
                  ShellPrintHiiEx(
                    -1, 
                    -1, 
                    NULL, 
                    STRING_TOKEN(STR_DRVCFG_DONE_HII), 
                    gShellDriver1HiiHandle, 
                    HandleIndex);
                }
              }              
            }
        }
    }
  }

  SHELL_FREE_NON_NULL(MainBuffer);


  ShellPrintHiiEx(
    -1, 
    -1,
    NULL,
    STRING_TOKEN(STR_DRVCFG_COMP), 
    gShellDriver1HiiHandle);
  return (SHELL_SUCCESS);
}
Beispiel #12
0
/**
  Update the form to include the driver health instances.

  @param ConfigureOnly  Only include the configure required driver health instances
                        when TRUE, include all the driver health instances otherwise.
**/
VOID
DriverHealthManagerUpdateForm (
  BOOLEAN                     ConfigureOnly
  )
{
  EFI_STATUS                  Status;
  EFI_IFR_GUID_LABEL          *StartLabel;
  EFI_IFR_GUID_LABEL          *EndLabel;
  VOID                        *StartOpCodeHandle;
  VOID                        *EndOpCodeHandle;
  UINTN                       Index;
  EFI_STRING_ID               Prompt;
  EFI_STRING_ID               Help;
  CHAR16                      String[512];
  UINTN                       StringCount;
  EFI_STRING                  TmpString;
  EFI_STRING                  DriverName;
  EFI_STRING                  ControllerName;
  UINTN                       MessageIndex;
  EFI_HANDLE                  DriverHandle;
  EFI_STRING_ID               DevicePath;
  EFI_GUID                    FormsetGuid;

  EfiBootManagerFreeDriverHealthInfo (mDriverHealthManagerHealthInfo, mDriverHealthManagerHealthInfoCount);
  mDriverHealthManagerHealthInfo = EfiBootManagerGetDriverHealthInfo (&mDriverHealthManagerHealthInfoCount);

  //
  // Allocate space for creation of UpdateData Buffer
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode as the start opcode
  //
  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number       = LABEL_BEGIN;

  //
  // Create Hii Extend Label OpCode as the end opcode
  //
  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number       = LABEL_END;

  for (Index = 0; Index < mDriverHealthManagerHealthInfoCount; Index++) {
    if (ConfigureOnly && mDriverHealthManagerHealthInfo[Index].HealthStatus != EfiDriverHealthStatusConfigurationRequired) {
      continue;
    }
    DriverName = DriverHealthManagerGetDriverName (mDriverHealthManagerHealthInfo[Index].DriverHealthHandle);
    ASSERT (DriverName != NULL);

    if (mDriverHealthManagerHealthInfo[Index].ControllerHandle == NULL) {
      //
      // The ControllerHandle is set to NULL and the HealthStatus is set to EfiDriverHealthStatusHealthy
      // if all the controllers managed by the driver are in healthy state.
      //
      ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy);
      UnicodeSPrint (String, sizeof (String), L"%s", DriverName);
    } else {
      ControllerName = DriverHealthManagerGetControllerName (
                         mDriverHealthManagerHealthInfo[Index].DriverHealthHandle,
                         mDriverHealthManagerHealthInfo[Index].ControllerHandle,
                         mDriverHealthManagerHealthInfo[Index].ChildHandle
                         );
      ASSERT (ControllerName != NULL);
      UnicodeSPrint (String, sizeof (String), L"%s    %s", DriverName, ControllerName);
      FreePool (ControllerName);
    }
    FreePool (DriverName);

    Prompt = HiiSetString (mDriverHealthManagerHiiHandle, 0, String, NULL);

    switch(mDriverHealthManagerHealthInfo[Index].HealthStatus) {
    case EfiDriverHealthStatusRepairRequired:
      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_REPAIR_REQUIRED), NULL);
      break;
    case EfiDriverHealthStatusConfigurationRequired:
      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_CONFIGURATION_REQUIRED), NULL);
      break;
    case EfiDriverHealthStatusFailed:
      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_FAILED), NULL);
      break;
    case EfiDriverHealthStatusReconnectRequired:
      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_RECONNECT_REQUIRED), NULL);
      break;
    case EfiDriverHealthStatusRebootRequired:
      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_REBOOT_REQUIRED), NULL);
      break;
    default:
      ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy);
      TmpString = HiiGetString (mDriverHealthManagerHiiHandle, STRING_TOKEN (STR_HEALTHY), NULL);
      break;
    }
    StringCount = UnicodeSPrint (String, sizeof (String), L"%s\n", TmpString);
    FreePool (TmpString);

    //
    // Add the message of the Module itself provided as the help.
    //
    if (mDriverHealthManagerHealthInfo[Index].MessageList != NULL) {
      for (MessageIndex = 0; mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].HiiHandle != NULL; MessageIndex++) {
        TmpString = HiiGetString (
                      mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].HiiHandle,
                      mDriverHealthManagerHealthInfo[Index].MessageList[MessageIndex].StringId,
                      NULL
                      );
        StringCount += UnicodeSPrint (String + StringCount, sizeof (String) - sizeof (String[0]) * StringCount, L"\n%s", TmpString);
        FreePool (TmpString);
      }
    }
    Help = HiiSetString (mDriverHealthManagerHiiHandle, 0, String, NULL);

    switch (mDriverHealthManagerHealthInfo[Index].HealthStatus) {
    case EfiDriverHealthStatusConfigurationRequired:
      Status = mDriverHealthManagerDatabase->GetPackageListHandle (
                                               mDriverHealthManagerDatabase,
                                               mDriverHealthManagerHealthInfo[Index].HiiHandle,
                                               &DriverHandle
                                               );
      ASSERT_EFI_ERROR (Status);
      TmpString  = ConvertDevicePathToText (DevicePathFromHandle (DriverHandle), FALSE, TRUE);
      DevicePath = HiiSetString (mDriverHealthManagerHiiHandle, 0, TmpString, NULL);
      FreePool (TmpString);

      Status = DriverHealthManagerGetFormsetId (mDriverHealthManagerHealthInfo[Index].HiiHandle, &FormsetGuid);
      ASSERT_EFI_ERROR (Status);

      HiiCreateGotoExOpCode (
        StartOpCodeHandle,
        0,
        Prompt,
        Help,
        0,
        0,
        0,
        &FormsetGuid,
        DevicePath
        );
      break;

    case EfiDriverHealthStatusRepairRequired:
    case EfiDriverHealthStatusReconnectRequired:
    case EfiDriverHealthStatusRebootRequired:
      HiiCreateActionOpCode (
        StartOpCodeHandle,
        (EFI_QUESTION_ID) (Index + QUESTION_ID_DRIVER_HEALTH_BASE),
        Prompt,
        Help,
        EFI_IFR_FLAG_CALLBACK,
        0
        );
      break;

    default:
      ASSERT (mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusHealthy ||
              mDriverHealthManagerHealthInfo[Index].HealthStatus == EfiDriverHealthStatusFailed);
      HiiCreateTextOpCode (
        StartOpCodeHandle,
        Prompt,
        Help,
        0
        );
      break;
    }
  }

  Status = HiiUpdateForm (
             mDriverHealthManagerHiiHandle,
             ConfigureOnly ? PcdGetPtr (PcdDriverHealthConfigureForm) : &mDriverHealthManagerForm,
             DRIVER_HEALTH_FORM_ID,
             StartOpCodeHandle,
             EndOpCodeHandle
             );
  ASSERT_EFI_ERROR (Status);

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
}
Beispiel #13
0
EFIAPI
GetResourcePadding (
  IN  EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
  IN  EFI_DEVICE_PATH_PROTOCOL       *HpcDevicePath,
  IN  UINT64                         HpcPciAddress,
  OUT EFI_HPC_STATE                  *HpcState,
  OUT VOID                           **Padding,
  OUT EFI_HPC_PADDING_ATTRIBUTES     *Attributes
  )
{
  DEBUG_CODE (
    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *Address;
    CHAR16                                      *DevicePathString;

    Address = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&HpcPciAddress;
    DevicePathString = ConvertDevicePathToText (HpcDevicePath, FALSE, FALSE);

    DEBUG ((EFI_D_VERBOSE, "%a: Address=%02x:%02x.%x DevicePath=%s\n",
      __FUNCTION__, Address->Bus, Address->Device, Address->Function,
      (DevicePathString == NULL) ? L"<unavailable>" : DevicePathString));

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

  if (HpcState == NULL || Padding == NULL || Attributes == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *Padding = AllocateCopyPool (sizeof mPadding, &mPadding);
/**
  Function to compare 2 device paths for use in QuickSort.

  @param[in] Buffer1            pointer to Device Path poiner to compare
  @param[in] Buffer2            pointer to second DevicePath pointer to compare

  @retval 0                     Buffer1 equal to Buffer2
  @retval <0                    Buffer1 is less than Buffer2
  @retval >0                    Buffer1 is greater than Buffer2
**/
INTN
EFIAPI
DevicePathCompare (
  IN  CONST VOID             *Buffer1,
  IN  CONST VOID             *Buffer2
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath1;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath2;
  CHAR16                    *TextPath1;
  CHAR16                    *TextPath2;
  EFI_STATUS                Status;
  INTN                      RetVal;

  DevicePath1 = *(EFI_DEVICE_PATH_PROTOCOL**)Buffer1;
  DevicePath2 = *(EFI_DEVICE_PATH_PROTOCOL**)Buffer2;

  if (DevicePath1 == NULL) {
    if (DevicePath2 == NULL) {
      return 0;
    }

    return -1;
  }

  if (DevicePath2 == NULL) {
    return 1;
  }

  if (mUnicodeCollation == NULL) {
    Status = gBS->LocateProtocol(
      &gEfiUnicodeCollation2ProtocolGuid,
      NULL,
      (VOID**)&mUnicodeCollation);

    ASSERT_EFI_ERROR(Status);
  }

  TextPath1 = ConvertDevicePathToText(
    DevicePath1,
    FALSE,
    FALSE);

  TextPath2 = ConvertDevicePathToText(
    DevicePath2,
    FALSE,
    FALSE);

  if (TextPath1 == NULL) {
    RetVal = -1;
  } else if (TextPath2 == NULL) {
    RetVal = 1;
  } else {
    RetVal = mUnicodeCollation->StriColl(
      mUnicodeCollation,
      TextPath1,
      TextPath2);
  }

  USL_FREE_NON_NULL(TextPath1);
  USL_FREE_NON_NULL(TextPath2);

  return (RetVal);
}
Beispiel #15
0
/**
  Download an image from a TFTP server

  @param[in]   DevicePath           Device path of the TFTP boot option
  @param[in]   ControllerHandle     Handle of the network controller
  @param[in]   RemainingDevicePath  Device path of the TFTP boot option but
                                    the first node that identifies the network controller
  @param[in]   Type                 Type to allocate memory pages
  @param[out]  Image                Address of the bufer where the image is stored in
                                    case of success
  @param[out]  ImageSize            Size in number of bytes of the i;age in case of
                                    success

  @retval  EFI_SUCCESS   The image was returned.
  @retval  !EFI_SUCCESS  Something went wrong.

**/
EFI_STATUS
BdsTftpLoadImage (
  IN OUT EFI_DEVICE_PATH       **DevicePath,
  IN     EFI_HANDLE            ControllerHandle,
  IN     EFI_DEVICE_PATH       *RemainingDevicePath,
  IN     EFI_ALLOCATE_TYPE     Type,
  IN OUT EFI_PHYSICAL_ADDRESS  *Image,
  OUT    UINTN                 *ImageSize
  )
{
  EFI_STATUS               Status;
  EFI_HANDLE               Dhcp4ChildHandle;
  EFI_DHCP4_PROTOCOL       *Dhcp4;
  BOOLEAN                  Dhcp4ToStop;
  EFI_HANDLE               Mtftp4ChildHandle;
  EFI_MTFTP4_PROTOCOL      *Mtftp4;
  DHCP4_OPTION             ParaList;
  EFI_DHCP4_PACKET_OPTION  *OptionList[2];
  EFI_DHCP4_CONFIG_DATA    Dhcp4CfgData;
  EFI_DHCP4_MODE_DATA      Dhcp4Mode;
  EFI_MTFTP4_CONFIG_DATA   Mtftp4CfgData;
  IPv4_DEVICE_PATH         *IPv4DevicePathNode;
  CHAR16                   *PathName;
  CHAR8                    *AsciiFilePath;
  EFI_MTFTP4_TOKEN         Mtftp4Token;
  UINT64                   FileSize;
  UINT64                   TftpBufferSize;
  BDS_TFTP_CONTEXT         *TftpContext;

  ASSERT(IS_DEVICE_PATH_NODE (RemainingDevicePath, MESSAGING_DEVICE_PATH, MSG_IPv4_DP));
  IPv4DevicePathNode = (IPv4_DEVICE_PATH*)RemainingDevicePath;

  Dhcp4ChildHandle  = NULL;
  Dhcp4             = NULL;
  Dhcp4ToStop       = FALSE;
  Mtftp4ChildHandle = NULL;
  Mtftp4            = NULL;
  AsciiFilePath     = NULL;
  TftpContext       = NULL;

  if (!IPv4DevicePathNode->StaticIpAddress) {
    //
    // Using the DHCP4 Service Binding Protocol, create a child handle of the DHCP4 service and
    // install the DHCP4 protocol on it. Then, open the DHCP protocol.
    //
    Status = NetLibCreateServiceChild (
               ControllerHandle,
               gImageHandle,
               &gEfiDhcp4ServiceBindingProtocolGuid,
               &Dhcp4ChildHandle
               );
    if (!EFI_ERROR (Status)) {
      Status = gBS->OpenProtocol (
                      Dhcp4ChildHandle,
                      &gEfiDhcp4ProtocolGuid,
                      (VOID **) &Dhcp4,
                      gImageHandle,
                      ControllerHandle,
                      EFI_OPEN_PROTOCOL_BY_DRIVER
                      );
    }
    if (EFI_ERROR (Status)) {
      Print (L"Unable to open DHCP4 protocol\n");
      goto Error;
    }
  }

  //
  // Using the MTFTP4 Service Binding Protocol, create a child handle of the MTFTP4 service and
  // install the MTFTP4 protocol on it. Then, open the MTFTP4 protocol.
  //
  Status = NetLibCreateServiceChild (
             ControllerHandle,
             gImageHandle,
             &gEfiMtftp4ServiceBindingProtocolGuid,
             &Mtftp4ChildHandle
             );
  if (!EFI_ERROR (Status)) {
    Status = gBS->OpenProtocol (
                    Mtftp4ChildHandle,
                    &gEfiMtftp4ProtocolGuid,
                    (VOID **) &Mtftp4,
                    gImageHandle,
                    ControllerHandle,
                    EFI_OPEN_PROTOCOL_BY_DRIVER
                    );
  }
  if (EFI_ERROR (Status)) {
    Print (L"Unable to open MTFTP4 protocol\n");
    goto Error;
  }

  if (!IPv4DevicePathNode->StaticIpAddress) {
    //
    // Configure the DHCP4, all default settings. It is acceptable for the configuration to
    // fail if the return code is equal to EFI_ACCESS_DENIED which means that the configuration
    // has been done by another instance of the DHCP4 protocol or that the DHCP configuration
    // process has been started but is not completed yet.
    //
    ZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA));
    ParaList.Head.OpCode     = DHCP_TAG_PARA_LIST;
    ParaList.Head.Length     = 2;
    ParaList.Head.Data[0]    = DHCP_TAG_NETMASK;
    ParaList.Route           = DHCP_TAG_ROUTER;
    OptionList[0]            = &ParaList.Head;
    Dhcp4CfgData.OptionCount = 1;
    Dhcp4CfgData.OptionList  = OptionList;

    Status = Dhcp4->Configure (Dhcp4, &Dhcp4CfgData);
    if (EFI_ERROR (Status)) {
      if (Status != EFI_ACCESS_DENIED) {
        Print (L"Error while configuring the DHCP4 protocol\n");
        goto Error;
      }
    }

    //
    // Start the DHCP configuration. This may have already been done thus do not leave in error
    // if the return code is EFI_ALREADY_STARTED.
    //
    Status = Dhcp4->Start (Dhcp4, NULL);
    if (EFI_ERROR (Status)) {
      if (Status != EFI_ALREADY_STARTED) {
        Print (L"DHCP configuration failed\n");
        goto Error;
      }
    } else {
      Dhcp4ToStop = TRUE;
    }

    Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);
    if (EFI_ERROR (Status)) {
      goto Error;
    }

    if (Dhcp4Mode.State != Dhcp4Bound) {
      Status = EFI_TIMEOUT;
      Print (L"DHCP configuration failed\n");
      goto Error;
    }
  }

  //
  // Configure the TFTP4 protocol
  //

  ZeroMem (&Mtftp4CfgData, sizeof (EFI_MTFTP4_CONFIG_DATA));
  Mtftp4CfgData.UseDefaultSetting = FALSE;
  Mtftp4CfgData.TimeoutValue      = 4;
  Mtftp4CfgData.TryCount          = 6;

  if (IPv4DevicePathNode->StaticIpAddress) {
    CopyMem (&Mtftp4CfgData.StationIp , &IPv4DevicePathNode->LocalIpAddress, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Mtftp4CfgData.SubnetMask, &IPv4DevicePathNode->SubnetMask, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Mtftp4CfgData.GatewayIp , &IPv4DevicePathNode->GatewayIpAddress, sizeof (EFI_IPv4_ADDRESS));
  } else {
    CopyMem (&Mtftp4CfgData.StationIp , &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Mtftp4CfgData.SubnetMask, &Dhcp4Mode.SubnetMask   , sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Mtftp4CfgData.GatewayIp , &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));
  }

  CopyMem (&Mtftp4CfgData.ServerIp  , &IPv4DevicePathNode->RemoteIpAddress, sizeof (EFI_IPv4_ADDRESS));

  Status = Mtftp4->Configure (Mtftp4, &Mtftp4CfgData);
  if (EFI_ERROR (Status)) {
    Print (L"Error while configuring the MTFTP4 protocol\n");
    goto Error;
  }

  // The Device Path might contain multiple FilePath nodes
  PathName      = ConvertDevicePathToText ((EFI_DEVICE_PATH_PROTOCOL*)(IPv4DevicePathNode + 1), FALSE, FALSE);
  AsciiFilePath = AllocatePool (StrLen (PathName) + 1);
  UnicodeStrToAsciiStr (PathName, AsciiFilePath);

  //
  // Try to get the size of the file in bytes from the server. If it fails,
  // start with a 8MB buffer to download the file.
  //
  FileSize = 0;
  if (Mtftp4GetFileSize (Mtftp4, AsciiFilePath, &FileSize) == EFI_SUCCESS) {
    TftpBufferSize = FileSize;
  } else {
    TftpBufferSize = SIZE_16MB;
  }

  TftpContext = AllocatePool (sizeof (BDS_TFTP_CONTEXT));
  if (TftpContext == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }
  TftpContext->FileSize = FileSize;

  for (; TftpBufferSize <= FixedPcdGet32 (PcdMaxTftpFileSize);
         TftpBufferSize = (TftpBufferSize + SIZE_16MB) & (~(SIZE_16MB-1))) {
    //
    // Allocate a buffer to hold the whole file.
    //
    Status = gBS->AllocatePages (
                    Type,
                    EfiBootServicesCode,
                    EFI_SIZE_TO_PAGES (TftpBufferSize),
                    Image
                    );
    if (EFI_ERROR (Status)) {
      Print (L"Failed to allocate space for image\n");
      goto Error;
    }

    TftpContext->DownloadedNbOfBytes   = 0;
    TftpContext->LastReportedNbOfBytes = 0;

    ZeroMem (&Mtftp4Token, sizeof (EFI_MTFTP4_TOKEN));
    Mtftp4Token.Filename    = (UINT8*)AsciiFilePath;
    Mtftp4Token.BufferSize  = TftpBufferSize;
    Mtftp4Token.Buffer      = (VOID *)(UINTN)*Image;
    Mtftp4Token.CheckPacket = Mtftp4CheckPacket;
    Mtftp4Token.Context     = (VOID*)TftpContext;

    Print (L"Downloading the file <%a> from the TFTP server\n", AsciiFilePath);
    Status = Mtftp4->ReadFile (Mtftp4, &Mtftp4Token);
    Print (L"\n");
    if (EFI_ERROR (Status)) {
      gBS->FreePages (*Image, EFI_SIZE_TO_PAGES (TftpBufferSize));
      if (Status == EFI_BUFFER_TOO_SMALL) {
        Print (L"Downloading failed, file larger than expected.\n");
        continue;
      } else {
        goto Error;
      }
    }

    *ImageSize = Mtftp4Token.BufferSize;
    break;
  }

Error:
  if (Dhcp4ChildHandle != NULL) {
    if (Dhcp4 != NULL) {
      if (Dhcp4ToStop) {
        Dhcp4->Stop (Dhcp4);
      }
      gBS->CloseProtocol (
             Dhcp4ChildHandle,
             &gEfiDhcp4ProtocolGuid,
             gImageHandle,
             ControllerHandle
            );
    }
    NetLibDestroyServiceChild (
      ControllerHandle,
      gImageHandle,
      &gEfiDhcp4ServiceBindingProtocolGuid,
      Dhcp4ChildHandle
      );
  }

  if (Mtftp4ChildHandle != NULL) {
    if (Mtftp4 != NULL) {
      if (AsciiFilePath != NULL) {
        FreePool (AsciiFilePath);
      }
      if (TftpContext != NULL) {
        FreePool (TftpContext);
      }
      gBS->CloseProtocol (
             Mtftp4ChildHandle,
             &gEfiMtftp4ProtocolGuid,
             gImageHandle,
             ControllerHandle
            );
    }
    NetLibDestroyServiceChild (
      ControllerHandle,
      gImageHandle,
      &gEfiMtftp4ServiceBindingProtocolGuid,
      Mtftp4ChildHandle
      );
  }

  if (EFI_ERROR (Status)) {
    *Image = 0;
    Print (L"Failed to download the file - Error=%r\n", Status);
  }

  return Status;
}
Beispiel #16
0
/**

  Convert the UEFI DevicePath to full text representation with DevPathToText,
  then match the UEFI device path fragment in Translated against it.

  @param[in] Translated        UEFI device path fragment, translated from
                               OpenFirmware format, to search for.

  @param[in] TranslatedLength  The length of Translated in CHAR16's.

  @param[in] DevicePath        Boot option device path whose textual rendering
                               to search in.

  @param[in] DevPathToText  Binary-to-text conversion protocol for DevicePath.


  @retval TRUE   If Translated was found at the beginning of DevicePath after
                 converting the latter to text.

  @retval FALSE  If DevicePath was NULL, or it could not be converted, or there
                 was no match.

**/
STATIC
BOOLEAN
Match (
  IN  CONST CHAR16                           *Translated,
  IN  UINTN                                  TranslatedLength,
  IN  CONST EFI_DEVICE_PATH_PROTOCOL         *DevicePath
  )
{
  CHAR16  *Converted;
  BOOLEAN Result;

  Converted = ConvertDevicePathToText (
                DevicePath,
                FALSE, // DisplayOnly
                FALSE  // AllowShortcuts
                );
  if (Converted == NULL) {
    return FALSE;
  }

  //
  // Attempt to expand any relative UEFI device path starting with HD() to an
  // absolute device path first. The logic imitates BdsLibBootViaBootOption().
  // We don't have to free the absolute device path,
  // BdsExpandPartitionPartialDevicePathToFull() has internal caching.
  //
  Result = FALSE;
  if (DevicePathType (DevicePath) == MEDIA_DEVICE_PATH &&
      DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP) {
    EFI_DEVICE_PATH_PROTOCOL *AbsDevicePath;
    CHAR16                   *AbsConverted;

    AbsDevicePath = BdsExpandPartitionPartialDevicePathToFull (
                      (HARDDRIVE_DEVICE_PATH *) DevicePath);
    if (AbsDevicePath == NULL) {
      goto Exit;
    }
    AbsConverted = ConvertDevicePathToText (AbsDevicePath, FALSE, FALSE);
    if (AbsConverted == NULL) {
      goto Exit;
    }
    DEBUG ((DEBUG_VERBOSE,
      "%a: expanded relative device path \"%s\" for prefix matching\n",
      __FUNCTION__, Converted));
    FreePool (Converted);
    Converted = AbsConverted;
  }

  //
  // Is Translated a prefix of Converted?
  //
  Result = (BOOLEAN)(StrnCmp (Converted, Translated, TranslatedLength) == 0);
  DEBUG ((
    DEBUG_VERBOSE,
    "%a: against \"%s\": %a\n",
    __FUNCTION__,
    Converted,
    Result ? "match" : "no match"
    ));
Exit:
  FreePool (Converted);
  return Result;
}
Beispiel #17
0
/**
  Dump the resource map of all the devices under Bridge.
  
  @param[in] Bridge     Bridge device instance.
  @param[in] IoNode     IO resource descriptor for the bridge device.
  @param[in] Mem32Node  Mem32 resource descriptor for the bridge device.
  @param[in] PMem32Node PMem32 resource descriptor for the bridge device.
  @param[in] Mem64Node  Mem64 resource descriptor for the bridge device.
  @param[in] PMem64Node PMem64 resource descriptor for the bridge device.
**/
VOID
DumpResourceMap (
  IN PCI_IO_DEVICE     *Bridge,
  IN PCI_RESOURCE_NODE *IoNode,
  IN PCI_RESOURCE_NODE *Mem32Node,
  IN PCI_RESOURCE_NODE *PMem32Node,
  IN PCI_RESOURCE_NODE *Mem64Node,
  IN PCI_RESOURCE_NODE *PMem64Node
  )
{
  EFI_STATUS                       Status;
  LIST_ENTRY                       *Link;
  PCI_IO_DEVICE                    *Device;
  PCI_RESOURCE_NODE                *ChildIoNode;
  PCI_RESOURCE_NODE                *ChildMem32Node;
  PCI_RESOURCE_NODE                *ChildPMem32Node;
  PCI_RESOURCE_NODE                *ChildMem64Node;
  PCI_RESOURCE_NODE                *ChildPMem64Node;
  CHAR16                           *Str;

  DEBUG ((EFI_D_INFO, "PciBus: Resource Map for "));

  Status = gBS->OpenProtocol (
                  Bridge->Handle,
                  &gEfiPciRootBridgeIoProtocolGuid,
                  NULL,
                  NULL,
                  NULL,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      EFI_D_INFO, "Bridge [%02x|%02x|%02x]\n",
      Bridge->BusNumber, Bridge->DeviceNumber, Bridge->FunctionNumber
      ));
  } else {
    Str = ConvertDevicePathToText (
            DevicePathFromHandle (Bridge->Handle),
            FALSE,
            FALSE
            );
    DEBUG ((EFI_D_INFO, "Root Bridge %s\n", Str != NULL ? Str : L""));
    if (Str != NULL) {
      FreePool (Str);
    }
  }

  DumpBridgeResource (IoNode);
  DumpBridgeResource (Mem32Node);
  DumpBridgeResource (PMem32Node);
  DumpBridgeResource (Mem64Node);
  DumpBridgeResource (PMem64Node);
  DEBUG ((EFI_D_INFO, "\n"));

  for ( Link = Bridge->ChildList.ForwardLink
      ; Link != &Bridge->ChildList
      ; Link = Link->ForwardLink
      ) {
    Device = PCI_IO_DEVICE_FROM_LINK (Link);
    if (IS_PCI_BRIDGE (&Device->Pci)) {

      ChildIoNode     = (IoNode     == NULL ? NULL : FindResourceNode (Device, IoNode));
      ChildMem32Node  = (Mem32Node  == NULL ? NULL : FindResourceNode (Device, Mem32Node));
      ChildPMem32Node = (PMem32Node == NULL ? NULL : FindResourceNode (Device, PMem32Node));
      ChildMem64Node  = (Mem64Node  == NULL ? NULL : FindResourceNode (Device, Mem64Node));
      ChildPMem64Node = (PMem64Node == NULL ? NULL : FindResourceNode (Device, PMem64Node));

      DumpResourceMap (
        Device,
        ChildIoNode,
        ChildMem32Node,
        ChildPMem32Node,
        ChildMem64Node,
        ChildPMem64Node
        );
    }
  }
}
Beispiel #18
0
/**
  The security handler is used to abstract platform-specific policy 
  from the DXE core response to an attempt to use a file that returns a 
  given status for the authentication check from the section extraction protocol.  

  The possible responses in a given SAP implementation may include locking 
  flash upon failure to authenticate, attestation logging for all signed drivers, 
  and other exception operations.  The File parameter allows for possible logging 
  within the SAP of the driver.

  If File is NULL, then EFI_INVALID_PARAMETER is returned.

  If the file specified by File with an authentication status specified by 
  AuthenticationStatus is safe for the DXE Core to use, then EFI_SUCCESS is returned.

  If the file specified by File with an authentication status specified by 
  AuthenticationStatus is not safe for the DXE Core to use under any circumstances, 
  then EFI_ACCESS_DENIED is returned.

  If the file specified by File with an authentication status specified by 
  AuthenticationStatus is not safe for the DXE Core to use right now, but it 
  might be possible to use it at a future time, then EFI_SECURITY_VIOLATION is 
  returned.

  @param[in]      AuthenticationStatus  This is the authentication status returned
                                        from the securitymeasurement services for the
                                        input file.
  @param[in]      File       This is a pointer to the device path of the file that is
                             being dispatched. This will optionally be used for logging.
  @param[in]      FileBuffer File buffer matches the input file device path.
  @param[in]      FileSize   Size of File buffer matches the input file device path.
  @param[in]      BootPolicy A boot policy that was used to call LoadImage() UEFI service.

  @retval EFI_SUCCESS             The file specified by DevicePath and non-NULL
                                  FileBuffer did authenticate, and the platform policy dictates
                                  that the DXE Foundation may use the file.
  @retval other error value
**/
EFI_STATUS
EFIAPI
DxeTpmMeasureBootHandler (
  IN  UINT32                           AuthenticationStatus,
  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *File,
  IN  VOID                             *FileBuffer,
  IN  UINTN                            FileSize,
  IN  BOOLEAN                          BootPolicy
  )
{
  EFI_TCG_PROTOCOL                    *TcgProtocol;
  EFI_STATUS                          Status;
  TCG_EFI_BOOT_SERVICE_CAPABILITY     ProtocolCapability;
  UINT32                              TCGFeatureFlags;
  EFI_PHYSICAL_ADDRESS                EventLogLocation;
  EFI_PHYSICAL_ADDRESS                EventLogLastEntry;
  EFI_DEVICE_PATH_PROTOCOL            *DevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL            *OrigDevicePathNode;
  EFI_HANDLE                          Handle;
  EFI_HANDLE                          TempHandle;
  BOOLEAN                             ApplicationRequired;
  PE_COFF_LOADER_IMAGE_CONTEXT        ImageContext;
  EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL  *FvbProtocol;
  EFI_PHYSICAL_ADDRESS                FvAddress;
  UINT32                              Index;

  Status = gBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, (VOID **) &TcgProtocol);
  if (EFI_ERROR (Status)) {
    //
    // TCG protocol is not installed. So, TPM is not present.
    // Don't do any measurement, and directly return EFI_SUCCESS.
    //
    return EFI_SUCCESS;
  }

  ProtocolCapability.Size = (UINT8) sizeof (ProtocolCapability);
  Status = TcgProtocol->StatusCheck (
             TcgProtocol, 
             &ProtocolCapability,
             &TCGFeatureFlags,
             &EventLogLocation,
             &EventLogLastEntry
           );
  if (EFI_ERROR (Status) || ProtocolCapability.TPMDeactivatedFlag) {
    //
    // TPM device doesn't work or activate.
    //
    return EFI_SUCCESS;
  }

  //
  // Copy File Device Path
  //
  OrigDevicePathNode = DuplicateDevicePath (File);
  
  //
  // 1. Check whether this device path support BlockIo protocol.
  // Is so, this device path may be a GPT device path.
  //
  DevicePathNode = OrigDevicePathNode;
  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathNode, &Handle);
  if (!EFI_ERROR (Status) && !mMeasureGptTableFlag) {
    //
    // Find the gpt partion on the given devicepath
    //
    DevicePathNode = OrigDevicePathNode;
    ASSERT (DevicePathNode != NULL);
    while (!IsDevicePathEnd (DevicePathNode)) {
      //
      // Find the Gpt partition
      //
      if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH &&
            DevicePathSubType (DevicePathNode) == MEDIA_HARDDRIVE_DP) {
        //
        // Check whether it is a gpt partition or not
        //                           
        if (((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER && 
            ((HARDDRIVE_DEVICE_PATH *) DevicePathNode)->SignatureType == SIGNATURE_TYPE_GUID) {

          //
          // Change the partition device path to its parent device path (disk) and get the handle.
          //
          DevicePathNode->Type    = END_DEVICE_PATH_TYPE;
          DevicePathNode->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
          DevicePathNode          = OrigDevicePathNode;
          Status = gBS->LocateDevicePath (
                         &gEfiDiskIoProtocolGuid,
                         &DevicePathNode,
                         &Handle
                         );
          if (!EFI_ERROR (Status)) {
            //
            // Measure GPT disk.
            //
            Status = TcgMeasureGptTable (TcgProtocol, Handle);
            if (!EFI_ERROR (Status)) {
              //
              // GPT disk check done.
              //
              mMeasureGptTableFlag = TRUE;
            }
          }
          FreePool (OrigDevicePathNode);
          OrigDevicePathNode = DuplicateDevicePath (File);
          ASSERT (OrigDevicePathNode != NULL);
          break;
        }
      }
      DevicePathNode    = NextDevicePathNode (DevicePathNode);
    }
  }
  
  //
  // 2. Measure PE image.
  //
  ApplicationRequired = FALSE;

  //
  // Check whether this device path support FVB protocol.
  //
  DevicePathNode = OrigDevicePathNode;
  Status = gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, &DevicePathNode, &Handle);
  if (!EFI_ERROR (Status)) {
    //
    // Don't check FV image, and directly return EFI_SUCCESS.
    // It can be extended to the specific FV authentication according to the different requirement.
    //
    if (IsDevicePathEnd (DevicePathNode)) {
      return EFI_SUCCESS;
    }
    //
    // The PE image from unmeasured Firmware volume need be measured
    // The PE image from measured Firmware volume will be mearsured according to policy below.
    //   If it is driver, do not measure
    //   If it is application, still measure.
    //
    ApplicationRequired = TRUE;

    if (mCacheMeasuredHandle != Handle && mMeasuredHobData != NULL) {
      //
      // Search for Root FV of this PE image
      //
      TempHandle = Handle;
      do {
        Status = gBS->HandleProtocol(
                        TempHandle, 
                        &gEfiFirmwareVolumeBlockProtocolGuid,
                        (VOID**)&FvbProtocol
                        );
        TempHandle = FvbProtocol->ParentHandle;
      } while (!EFI_ERROR(Status) && FvbProtocol->ParentHandle != NULL);

      //
      // Search in measured FV Hob
      //
      Status = FvbProtocol->GetPhysicalAddress(FvbProtocol, &FvAddress);
      if (EFI_ERROR(Status)){
        return Status;
      }

      ApplicationRequired = FALSE;

      for (Index = 0; Index < mMeasuredHobData->Num; Index++) {
        if(mMeasuredHobData->MeasuredFvBuf[Index].BlobBase == FvAddress) {
          //
          // Cache measured FV for next measurement
          //
          mCacheMeasuredHandle = Handle;
          ApplicationRequired  = TRUE;
          break;
        }
      }
    }
  }

  //
  // File is not found.
  //
  if (FileBuffer == NULL) {
    Status = EFI_SECURITY_VIOLATION;
    goto Finish;
  }

  mImageSize  = FileSize;
  mFileBuffer = FileBuffer;

  //
  // Measure PE Image
  //
  DevicePathNode = OrigDevicePathNode;
  ZeroMem (&ImageContext, sizeof (ImageContext));
  ImageContext.Handle    = (VOID *) FileBuffer;
  ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) DxeTpmMeasureBootLibImageRead;

  //
  // Get information about the image being loaded
  //
  Status = PeCoffLoaderGetImageInfo (&ImageContext);
  if (EFI_ERROR (Status)) {
    //
    // The information can't be got from the invalid PeImage
    //
    goto Finish;
  }
  
  //
  // Measure only application if Application flag is set
  // Measure drivers and applications if Application flag is not set
  //
  if ((!ApplicationRequired) || 
        (ApplicationRequired && ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION)) {  
    //
    // Print the image path to be measured.
    //    
    DEBUG_CODE_BEGIN ();
      CHAR16                            *ToText;
      ToText = ConvertDevicePathToText (
                 DevicePathNode,
                 FALSE,
                 TRUE
                 );
      if (ToText != NULL) {
        DEBUG ((DEBUG_INFO, "The measured image path is %s.\n", ToText));
        FreePool (ToText);
      }
    DEBUG_CODE_END ();

    //
    // Measure PE image into TPM log.
    //
    Status = TcgMeasurePeImage (
               TcgProtocol,
               (EFI_PHYSICAL_ADDRESS) (UINTN) FileBuffer, 
               FileSize, 
               (UINTN) ImageContext.ImageAddress, 
               ImageContext.ImageType, 
               DevicePathNode
               );
  }

  //
  // Done, free the allocated resource.
  //
Finish:
  if (OrigDevicePathNode != NULL) {
    FreePool (OrigDevicePathNode);
  }

  return Status;
}
Beispiel #19
0
/** 
  Get a human readable name for an image handle.
  The following methods will be tried orderly:
    1. Image PDB
    2. ComponentName2 protocol
    3. FFS UI section
    4. Image GUID
    5. Image DevicePath
    6. Unknown Driver Name

  @param[in]    Handle

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

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

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

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

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

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

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

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

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

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

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

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

  //
  // Method 6: Unknown Driver Name
  //
  StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_ERROR_NAME), NULL);
  ASSERT (StringPtr != NULL);
  StrnCpyS (mGaugeString, DP_GAUGE_STRING_LENGTH + 1, StringPtr, DP_GAUGE_STRING_LENGTH);
  FreePool (StringPtr);
}
Beispiel #20
0
static EFI_STATUS EFIAPI
FSBindingStart(EFI_DRIVER_BINDING_PROTOCOL *This,
		EFI_HANDLE ControllerHandle,
		EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
{
	EFI_STATUS Status;
	EFI_FS *Instance;
	EFI_DEVICE_PATH *DevicePath;

	PrintDebug(L"FSBindingStart\n");

	/* Allocate a new instance of a filesystem */
	Instance = AllocateZeroPool(sizeof(EFI_FS));
	if (Instance == NULL) {
		Status = EFI_OUT_OF_RESOURCES;
		PrintStatusError(Status, L"Could not allocate a new file system instance");
		return Status;
	}
	Instance->FileIoInterface.Revision = EFI_FILE_IO_INTERFACE_REVISION;
	Instance->FileIoInterface.OpenVolume = FileOpenVolume,

	/* Fill the device path for our instance */
	DevicePath = DevicePathFromHandle(ControllerHandle);
	if (DevicePath == NULL) {
		Status = EFI_NO_MAPPING;
		PrintStatusError(Status, L"Could not get Device Path");
		goto error;
	}

	Instance->DevicePathString = ConvertDevicePathToText(DevicePath, FALSE, FALSE);
	if (Instance->DevicePathString == NULL) {
		Status = EFI_OUT_OF_RESOURCES;
		PrintStatusError(Status, L"Could not allocate Device Path string");
		goto error;
	}

	/* Get access to the Block IO protocol for this controller */
	Status = BS->OpenProtocol(ControllerHandle,
                              &gEfiBlockIo2ProtocolGuid, (VOID **) &Instance->BlockIo2,
                              This->DriverBindingHandle, ControllerHandle,
                              /* http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES#OpenProtocol.28.29
                               * EFI_OPEN_PROTOCOL_BY_DRIVER returns Access Denied here, most likely
                               * because the disk driver has that protocol already open. So we use
                               * EFI_OPEN_PROTOCOL_GET_PROTOCOL (which doesn't require us to close it)
                               */
                              EFI_OPEN_PROTOCOL_GET_PROTOCOL);
    if (EFI_ERROR(Status))
    {
      Instance->BlockIo2 = NULL;
    }

	Status = BS->OpenProtocol(ControllerHandle,
			&gEfiBlockIoProtocolGuid, (VOID **) &Instance->BlockIo,
			This->DriverBindingHandle, ControllerHandle,
			/* http://wiki.phoenix.com/wiki/index.php/EFI_BOOT_SERVICES#OpenProtocol.28.29
			 * EFI_OPEN_PROTOCOL_BY_DRIVER returns Access Denied here, most likely
			 * because the disk driver has that protocol already open. So we use
			 * EFI_OPEN_PROTOCOL_GET_PROTOCOL (which doesn't require us to close it)
			 */
			EFI_OPEN_PROTOCOL_GET_PROTOCOL);
	if (EFI_ERROR(Status)) {
		PrintStatusError(Status, L"Could not access BlockIO protocol");
		goto error;
	}

	/* Get exclusive access to the Disk IO protocol */
	Status = BS->OpenProtocol(ControllerHandle,
                              &gEfiDiskIo2ProtocolGuid, (VOID**) &Instance->DiskIo2,
                              This->DriverBindingHandle, ControllerHandle,
                              EFI_OPEN_PROTOCOL_BY_DRIVER);
    if (EFI_ERROR(Status))
    {
        Instance->DiskIo2 = NULL;
    }

	Status = BS->OpenProtocol(ControllerHandle,
			&gEfiDiskIoProtocolGuid, (VOID**) &Instance->DiskIo,
			This->DriverBindingHandle, ControllerHandle,
			EFI_OPEN_PROTOCOL_BY_DRIVER);
	if (EFI_ERROR(Status)) {
		PrintStatusError(Status, L"Could not access the DiskIo protocol");
		goto error;
	}

	/* Go through GRUB target init */
	Status = GrubDeviceInit(Instance);
	if (EFI_ERROR(Status)) {
		PrintStatusError(Status, L"Could not init grub device");
		goto error;
	}

	Status = FSInstall(Instance, ControllerHandle);
	/* Unless we close the DiskIO protocol in case of error, no other
	 * FS driver will be able to access this partition.
	 */
	if (EFI_ERROR(Status)) {
		GrubDeviceExit(Instance);
		BS->CloseProtocol(ControllerHandle, &gEfiDiskIo2ProtocolGuid,
                          This->DriverBindingHandle, ControllerHandle);
		BS->CloseProtocol(ControllerHandle, &gEfiDiskIoProtocolGuid,
			This->DriverBindingHandle, ControllerHandle);
	}

error:
	if (EFI_ERROR(Status))
		FreeFsInstance(Instance);
	return Status;
}