GCC toolchain cannot build ShellPkg. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Harry Liebel <Harry.Liebel@arm.com> Signed-off-by: Olivier Martin <Olivier.Martin@arm.com> Reviewed-by: Jaben Carsey <Jaben.Carsey@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14326 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			281 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			281 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Main file for attrib shell level 2 function.
 | 
						|
 | 
						|
  Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
 | 
						|
  This program and the accompanying materials
 | 
						|
  are licensed and made available under the terms and conditions of the BSD License
 | 
						|
  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
  http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "UefiShellLevel2CommandsLib.h"
 | 
						|
 | 
						|
// This function was from from the BdsLib implementation in
 | 
						|
// IntelFrameworkModulePkg\Library\GenericBdsLib\BdsConnect.c
 | 
						|
// function name: BdsLibConnectAllEfi
 | 
						|
/**
 | 
						|
  This function will connect all current system handles recursively. The
 | 
						|
  connection will finish until every handle's child handle created if it have.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           All handles and it's child handle have been
 | 
						|
                                connected
 | 
						|
  @retval EFI_STATUS            Return the status of gBS->LocateHandleBuffer().
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
ConnectAllEfi (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  UINTN       HandleCount;
 | 
						|
  EFI_HANDLE  *HandleBuffer;
 | 
						|
  UINTN       Index;
 | 
						|
 | 
						|
  Status = gBS->LocateHandleBuffer (
 | 
						|
                  AllHandles,
 | 
						|
                  NULL,
 | 
						|
                  NULL,
 | 
						|
                  &HandleCount,
 | 
						|
                  &HandleBuffer
 | 
						|
                 );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; Index < HandleCount; Index++) {
 | 
						|
    Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
 | 
						|
  }
 | 
						|
 | 
						|
  if (HandleBuffer != NULL) {
 | 
						|
    FreePool (HandleBuffer);
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  function to load a .EFI driver into memory and possible connect the driver.
 | 
						|
 | 
						|
  if FileName is NULL then ASSERT.
 | 
						|
 | 
						|
  @param[in] FileName           FileName of the driver to load
 | 
						|
  @param[in] Connect            Whether to connect or not
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           the driver was loaded and if Connect was
 | 
						|
                                true then connect was attempted. Connection may
 | 
						|
                                have failed.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES  there was insufficient memory
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
LoadDriver(
 | 
						|
  IN CONST CHAR16   *FileName,
 | 
						|
  IN CONST BOOLEAN  Connect
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_HANDLE                    LoadedDriverHandle;
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  EFI_DEVICE_PATH_PROTOCOL      *FilePath;
 | 
						|
  EFI_LOADED_IMAGE_PROTOCOL     *LoadedDriverImage;
 | 
						|
 | 
						|
  LoadedDriverImage   = NULL;
 | 
						|
  FilePath            = NULL;
 | 
						|
  LoadedDriverHandle  = NULL;
 | 
						|
  Status              = EFI_SUCCESS;
 | 
						|
 | 
						|
  ASSERT (FileName != NULL);
 | 
						|
 | 
						|
  //
 | 
						|
  // Fix local copies of the protocol pointers
 | 
						|
  //
 | 
						|
  Status = CommandInit();
 | 
						|
  ASSERT_EFI_ERROR(Status);
 | 
						|
 | 
						|
  //
 | 
						|
  // Convert to DEVICE_PATH
 | 
						|
  //
 | 
						|
  FilePath = gEfiShellProtocol->GetDevicePathFromFilePath(FileName);
 | 
						|
 | 
						|
  if (FilePath == NULL) {
 | 
						|
    ASSERT(FALSE);
 | 
						|
    return (EFI_INVALID_PARAMETER);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Use LoadImage to get it into memory
 | 
						|
  //
 | 
						|
  Status = gBS->LoadImage(
 | 
						|
    FALSE,
 | 
						|
    gImageHandle,
 | 
						|
    FilePath,
 | 
						|
    NULL,
 | 
						|
    0,
 | 
						|
    &LoadedDriverHandle);
 | 
						|
 | 
						|
  if (EFI_ERROR(Status)) {
 | 
						|
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_NOT_IMAGE), gShellLevel2HiiHandle, FileName, Status);
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // Make sure it is a driver image
 | 
						|
    //
 | 
						|
    Status = gBS->HandleProtocol (LoadedDriverHandle, &gEfiLoadedImageProtocolGuid, (VOID *) &LoadedDriverImage);
 | 
						|
 | 
						|
    ASSERT (LoadedDriverImage != NULL);
 | 
						|
 | 
						|
    if ( EFI_ERROR(Status)
 | 
						|
      || ( LoadedDriverImage->ImageCodeType != EfiBootServicesCode
 | 
						|
        && LoadedDriverImage->ImageCodeType != EfiRuntimeServicesCode)
 | 
						|
     ){
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_NOT_DRIVER), gShellLevel2HiiHandle, FileName);
 | 
						|
 | 
						|
      //
 | 
						|
      // Exit and unload the non-driver image
 | 
						|
      //
 | 
						|
      gBS->Exit(LoadedDriverHandle, EFI_INVALID_PARAMETER, 0, NULL);
 | 
						|
      Status = EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!EFI_ERROR(Status)) {
 | 
						|
    //
 | 
						|
    // Start the image
 | 
						|
    //
 | 
						|
    Status = gBS->StartImage(LoadedDriverHandle, NULL, NULL);
 | 
						|
    if (EFI_ERROR(Status)) {
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_ERROR), gShellLevel2HiiHandle, FileName, Status);
 | 
						|
    } else {
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_LOAD_LOADED), gShellLevel2HiiHandle, FileName, LoadedDriverImage->ImageBase, Status);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (!EFI_ERROR(Status) && Connect) {
 | 
						|
    //
 | 
						|
    // Connect it...
 | 
						|
    //
 | 
						|
    Status = ConnectAllEfi();
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // clean up memory...
 | 
						|
  //
 | 
						|
  if (FilePath != NULL) {
 | 
						|
    FreePool(FilePath);
 | 
						|
  }
 | 
						|
 | 
						|
  return (Status);
 | 
						|
}
 | 
						|
 | 
						|
STATIC CONST SHELL_PARAM_ITEM LoadParamList[] = {
 | 
						|
  {L"-nc", TypeFlag},
 | 
						|
  {NULL, TypeMax}
 | 
						|
  };
 | 
						|
 | 
						|
/**
 | 
						|
  Function for 'load' command.
 | 
						|
 | 
						|
  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
 | 
						|
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
 | 
						|
**/
 | 
						|
SHELL_STATUS
 | 
						|
EFIAPI
 | 
						|
ShellCommandRunLoad (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  LIST_ENTRY          *Package;
 | 
						|
  CHAR16              *ProblemParam;
 | 
						|
  SHELL_STATUS        ShellStatus;
 | 
						|
  UINTN               ParamCount;
 | 
						|
  EFI_SHELL_FILE_INFO *ListHead;
 | 
						|
  EFI_SHELL_FILE_INFO *Node;
 | 
						|
 | 
						|
  ListHead            = NULL;
 | 
						|
  ProblemParam        = NULL;
 | 
						|
  ShellStatus         = SHELL_SUCCESS;
 | 
						|
 | 
						|
  //
 | 
						|
  // initialize the shell lib (we must be in non-auto-init...)
 | 
						|
  //
 | 
						|
  Status = ShellInitialize();
 | 
						|
  ASSERT_EFI_ERROR(Status);
 | 
						|
 | 
						|
  //
 | 
						|
  // parse the command line
 | 
						|
  //
 | 
						|
  Status = ShellCommandLineParse (LoadParamList, &Package, &ProblemParam, TRUE);
 | 
						|
  if (EFI_ERROR(Status)) {
 | 
						|
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, ProblemParam);
 | 
						|
      FreePool(ProblemParam);
 | 
						|
      ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
    } else {
 | 
						|
      ASSERT(FALSE);
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // check for "-?"
 | 
						|
    //
 | 
						|
    if (ShellCommandLineGetFlag(Package, L"-?")) {
 | 
						|
      ASSERT(FALSE);
 | 
						|
    } else if (ShellCommandLineGetRawValue(Package, 1) == NULL) {
 | 
						|
      //
 | 
						|
      // we didnt get a single file to load parameter
 | 
						|
      //
 | 
						|
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle);
 | 
						|
      ShellStatus = SHELL_INVALID_PARAMETER;
 | 
						|
    } else {
 | 
						|
      for ( ParamCount = 1
 | 
						|
          ; ShellCommandLineGetRawValue(Package, ParamCount) != NULL
 | 
						|
          ; ParamCount++
 | 
						|
         ){
 | 
						|
        Status = ShellOpenFileMetaArg((CHAR16*)ShellCommandLineGetRawValue(Package, ParamCount), EFI_FILE_MODE_READ, &ListHead);
 | 
						|
        if (!EFI_ERROR(Status)) {
 | 
						|
          for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode(&ListHead->Link)
 | 
						|
              ; !IsNull(&ListHead->Link, &Node->Link)
 | 
						|
              ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode(&ListHead->Link, &Node->Link)
 | 
						|
             ){
 | 
						|
            //
 | 
						|
            // once we have an error preserve that value, but finish the loop.
 | 
						|
            //
 | 
						|
            if (EFI_ERROR(Status)) {
 | 
						|
              LoadDriver(Node->FullName, (BOOLEAN)(ShellCommandLineGetFlag(Package, L"-nc")==FALSE));
 | 
						|
            } else {
 | 
						|
              Status = LoadDriver(Node->FullName, (BOOLEAN)(ShellCommandLineGetFlag(Package, L"-nc")==FALSE));
 | 
						|
            }
 | 
						|
          } // for loop for multi-open
 | 
						|
          if (EFI_ERROR(Status)) {
 | 
						|
            ShellCloseFileMetaArg(&ListHead);
 | 
						|
          } else {
 | 
						|
            Status = ShellCloseFileMetaArg(&ListHead);;
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          //
 | 
						|
          // no files found.
 | 
						|
          //
 | 
						|
          ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, (CHAR16*)ShellCommandLineGetRawValue(Package, ParamCount));
 | 
						|
          ShellStatus = SHELL_NOT_FOUND;
 | 
						|
        }
 | 
						|
      } // for loop for params
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    // free the command line package
 | 
						|
    //
 | 
						|
    ShellCommandLineFreeVarList (Package);
 | 
						|
  }
 | 
						|
 | 
						|
  if (EFI_ERROR(Status) && ShellStatus == SHELL_SUCCESS) {
 | 
						|
    ShellStatus = SHELL_DEVICE_ERROR;
 | 
						|
  }
 | 
						|
 | 
						|
  return (ShellStatus);
 | 
						|
}
 |