Ejemplo n.º 1
0
/**
  Set the name of a file.

  This is a helper function for SetFileInfo().

  @param[in]  Instance  A pointer to the description of the volume
                        the file belongs to.
  @param[in]  File      A pointer to the description of the file.
  @param[in]  FileName  A pointer to the new name of the file.

  @retval  EFI_SUCCESS        The name was set.
  @retval  EFI_ACCESS_DENIED  An attempt is made to change the name of a file
                              to a file that is already present.

**/
STATIC
EFI_STATUS
SetFileName (
  IN  BOOTMON_FS_INSTANCE  *Instance,
  IN  BOOTMON_FS_FILE      *File,
  IN  CONST CHAR16         *FileName
  )
{
  CHAR8            AsciiFileName[MAX_NAME_LENGTH];
  BOOTMON_FS_FILE  *SameFile;

  // If the file path start with a \ strip it. The EFI Shell may
  // insert a \ in front of the file name.
  if (FileName[0] == L'\\') {
    FileName++;
  }

  UnicodeStrToAsciiStrS (FileName, AsciiFileName, MAX_NAME_LENGTH);

  if (BootMonGetFileFromAsciiFileName (
        File->Instance,
        AsciiFileName,
        &SameFile
        ) != EFI_NOT_FOUND) {
    // A file with that name already exists.
    return EFI_ACCESS_DENIED;
  } else {
    // OK, change the filename.
    AsciiStrToUnicodeStrS (AsciiFileName, File->Info->FileName,
      (File->Info->Size - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16));
    return EFI_SUCCESS;
  }
}
/**
  Get a human readable name for an image.
  The following methods will be tried orderly:
    1. Image PDB
    2. FFS UI section
    3. Image GUID

  @param[in] ImageStruct  Point to the image structure.

  @return The resulting Ascii name string is stored in the mNameString global array.

**/
CHAR8 *
GetDriverNameString (
  IN SMM_CORE_IMAGE_DATABASE_STRUCTURE  *ImageStruct
  )
{
  EFI_STATUS                  Status;
  CHAR16                      *NameString;
  UINTN                       StringSize;

  if (ImageStruct == NULL) {
    return "???";
  }

  //
  // Method 1: Get the name string from image PDB
  //
  if (ImageStruct->PdbStringOffset != 0) {
    GetShortPdbFileName ((CHAR8 *) ((UINTN) ImageStruct + ImageStruct->PdbStringOffset), mNameString);
    return mNameString;
  }

  if (!IsZeroGuid (&ImageStruct->FileGuid)) {
    //
    // Try to get the image's FFS UI section by image GUID
    //
    NameString = NULL;
    StringSize = 0;
    Status = GetSectionFromAnyFv (
              &ImageStruct->FileGuid,
              EFI_SECTION_USER_INTERFACE,
              0,
              (VOID **) &NameString,
              &StringSize
              );
    if (!EFI_ERROR (Status)) {
      //
      // Method 2: Get the name string from FFS UI section
      //
      if (StrLen (NameString) > PROFILE_NAME_STRING_LENGTH) {
        NameString[PROFILE_NAME_STRING_LENGTH] = 0;
      }
      UnicodeStrToAsciiStrS (NameString, mNameString, sizeof (mNameString));
      FreePool (NameString);
      return mNameString;
    }
  }

  //
  // Method 3: Get the name string from image GUID
  //
  AsciiSPrint (mNameString, sizeof (mNameString), "%g", &ImageStruct->FileGuid);
  return mNameString;
}
CHAR8*
Unicode2Ascii (
  CONST CHAR16* UnicodeStr
)
{
  UINTN BufSize = StrSize (UnicodeStr) * sizeof (CHAR8);
  CHAR8* AsciiStr = AllocatePool(BufSize);
  if (AsciiStr == NULL) {
    return NULL;
  }

  UnicodeStrToAsciiStrS(UnicodeStr, AsciiStr, BufSize);

  return AsciiStr;
}
Ejemplo n.º 4
0
/**
  Embedded Boot Loader (EBL) - A simple EFI command line application for embedded
  devices. PcdEmbeddedAutomaticBootCommand is a complied in command line that
  gets executed automatically. The ; separator allows multiple commands
  for each command line.

  @param  ImageHandle   EFI ImageHandle for this application.
  @param  SystemTable   EFI system table

  @return EFI status of the application

**/
EFI_STATUS
EFIAPI
EdkBootLoaderEntry (
  IN EFI_HANDLE                            ImageHandle,
  IN EFI_SYSTEM_TABLE                      *SystemTable
  )
{
  EFI_STATUS  Status;
  CHAR8       CmdLine[MAX_CMD_LINE];
  CHAR16      *CommandLineVariable = NULL;
  CHAR16      *CommandLineVariableName = L"default-cmdline";
  UINTN       CommandLineVariableSize = 0;
  EFI_GUID    VendorGuid;

  // Initialize tables of commands
  EblInitializeCmdTable ();
  EblInitializeDeviceCmd ();
  EblInitializemdHwDebugCmds ();
  EblInitializemdHwIoDebugCmds ();
  EblInitializeDirCmd ();
  EblInitializeHobCmd ();
  EblInitializeScriptCmd ();
  EblInitializeExternalCmd ();
  EblInitializeNetworkCmd();
  EblInitializeVariableCmds ();

  if (gST->ConOut == NULL) {
    DEBUG((EFI_D_ERROR,"Error: No Console Output\n"));
    return EFI_NOT_READY;
  }

  // Disable the 5 minute EFI watchdog time so we don't get automatically reset
  gBS->SetWatchdogTimer (0, 0, 0, NULL);

  if (FeaturePcdGet (PcdEmbeddedMacBoot)) {
    // A MAC will boot in graphics mode, so turn it back to text here
    // This protocol was removed from edk2. It is only an edk thing. We need to make our own copy.
    // DisableQuietBoot ();

    // Enable the biggest output screen size possible
    gST->ConOut->SetMode (gST->ConOut, (UINTN)gST->ConOut->Mode->MaxMode - 1);

  }

  // Save current screen mode
  gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &gScreenColumns, &gScreenRows);

  EblPrintStartupBanner ();

  // Parse command line and handle commands separated by ;
  // The loop prints the prompt gets user input and saves history

  // Look for a variable with a default command line, otherwise use the Pcd
  ZeroMem(&VendorGuid, sizeof(EFI_GUID));

  Status = gRT->GetVariable(CommandLineVariableName, &VendorGuid, NULL, &CommandLineVariableSize, CommandLineVariable);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    CommandLineVariable = AllocatePool(CommandLineVariableSize);

    Status = gRT->GetVariable(CommandLineVariableName, &VendorGuid, NULL, &CommandLineVariableSize, CommandLineVariable);
    if (!EFI_ERROR(Status)) {
      UnicodeStrToAsciiStrS (CommandLineVariable, CmdLine, MAX_CMD_LINE);
    }

    FreePool(CommandLineVariable);
  }

  if (EFI_ERROR(Status)) {
    AsciiStrCpyS (CmdLine, MAX_CMD_LINE, (CHAR8 *)PcdGetPtr (PcdEmbeddedAutomaticBootCommand));
  }

  for (;;) {
    Status = ProcessCmdLine (CmdLine, MAX_CMD_LINE);
    if (Status == EFI_ABORTED) {
      // if a command returns EFI_ABORTED then exit the EBL
      EblShutdownExternalCmdTable ();
      return EFI_SUCCESS;
    }

    // get the command line from the user
    EblPrompt ();
    GetCmd (CmdLine, MAX_CMD_LINE);
    SetCmdHistory (CmdLine);

    if (FeaturePcdGet (PcdEmbeddedProbeRemovable)) {
      // Probe removable media devices to see if media has been inserted or removed.
      EblProbeRemovableMedia ();
    }
  }
}
Ejemplo n.º 5
0
/**
  Function to write a line of text to a file.
  
  If the file is a Unicode file (with UNICODE file tag) then write the unicode 
  text.
  If the file is an ASCII file then write the ASCII text.
  If the size of file is zero (without file tag at the beginning) then write 
  ASCII text as default.

  @param[in]     Handle         FileHandle to write to.
  @param[in]     Buffer         Buffer to write, if NULL the function will
                                take no action and return EFI_SUCCESS.

  @retval  EFI_SUCCESS            The data was written.
                                  Buffer is NULL.
  @retval  EFI_INVALID_PARAMETER  Handle is NULL.
  @retval  EFI_OUT_OF_RESOURCES   Unable to allocate temporary space for ASCII 
                                  string due to out of resources.

  @sa FileHandleWrite
**/
EFI_STATUS
EFIAPI
FileHandleWriteLine(
  IN EFI_FILE_HANDLE Handle,
  IN CHAR16          *Buffer
  )
{
  EFI_STATUS  Status;
  CHAR16      CharBuffer;
  UINTN       Size;
  UINTN       Index;
  UINTN       CharSize;
  UINT64      FileSize;
  UINT64      OriginalFilePosition;
  BOOLEAN     Ascii;
  CHAR8       *AsciiBuffer;

  if (Buffer == NULL) {
    return (EFI_SUCCESS);
  }

  if (Handle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }
  
  Ascii = FALSE;
  AsciiBuffer = NULL;
  
  Status = FileHandleGetPosition(Handle, &OriginalFilePosition);
  if (EFI_ERROR(Status)) {
    return Status;
  }
  
  Status = FileHandleSetPosition(Handle, 0);
  if (EFI_ERROR(Status)) {
    return Status;
  }
  
  Status = FileHandleGetSize(Handle, &FileSize);
  if (EFI_ERROR(Status)) {
    return Status;
  }
  
  if (FileSize == 0) {
    Ascii = TRUE;
  } else {
    CharSize = sizeof (CHAR16);
    Status = FileHandleRead (Handle, &CharSize, &CharBuffer);
    ASSERT_EFI_ERROR (Status);
    if (CharBuffer == gUnicodeFileTag) {
      Ascii = FALSE;
    } else {
      Ascii = TRUE;
    }
  }
  
  Status = FileHandleSetPosition(Handle, OriginalFilePosition);
  if (EFI_ERROR(Status)) {
    return Status;
  }
  
  if (Ascii) {
    Size = ( StrSize(Buffer) / sizeof(CHAR16) ) * sizeof(CHAR8);
    AsciiBuffer = (CHAR8 *)AllocateZeroPool(Size);
    if (AsciiBuffer == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    UnicodeStrToAsciiStrS (Buffer, AsciiBuffer, Size);
    for (Index = 0; Index < Size; Index++) {
      if (!((AsciiBuffer[Index] >= 0) && (AsciiBuffer[Index] < 128))){
        FreePool(AsciiBuffer);
        return EFI_INVALID_PARAMETER;
      }
    }
    
    Size = AsciiStrSize(AsciiBuffer) - sizeof(CHAR8);
    Status = FileHandleWrite(Handle, &Size, AsciiBuffer);
    if (EFI_ERROR(Status)) {
      FreePool (AsciiBuffer);
      return (Status);
    }
    Size = AsciiStrSize("\r\n") - sizeof(CHAR8);
    Status = FileHandleWrite(Handle, &Size, "\r\n");
  } else {
    if (OriginalFilePosition == 0) {
      Status = FileHandleSetPosition (Handle, sizeof(CHAR16));
      if (EFI_ERROR(Status)) {
        return Status;
      }
    }
    Size = StrSize(Buffer) - sizeof(CHAR16);
    Status = FileHandleWrite(Handle, &Size, Buffer);
    if (EFI_ERROR(Status)) {
      return (Status);
    }
    Size = StrSize(L"\r\n") - sizeof(CHAR16);
    Status = FileHandleWrite(Handle, &Size, L"\r\n");
  }
  
  if (AsciiBuffer != NULL) {
    FreePool (AsciiBuffer);
  }
  return Status;
}
Ejemplo n.º 6
0
/**
  Get devcie name through the component name protocol.

  @param[in]       AllHandlesBuffer   The handle buffer for current system.
  @param[in]       NumAllHandles      The number of handles for the handle buffer.
  @param[in]       Dev                The device which need to get name.
  @param[in]       UseComp1           Whether use component name or name2 protocol.

  @retval     TRUE        Find the name for this device.
  @retval     FALSE       Not found the name for this device.
**/
BOOLEAN
OpalDriverGetDeviceNameByProtocol(
  EFI_HANDLE             *AllHandlesBuffer,
  UINTN                  NumAllHandles,
  OPAL_DRIVER_DEVICE     *Dev,
  BOOLEAN                UseComp1
  )
{
  EFI_HANDLE*                   ProtocolHandlesBuffer;
  UINTN                         NumProtocolHandles;
  EFI_STATUS                    Status;
  EFI_COMPONENT_NAME2_PROTOCOL* Cnp1_2; // efi component name and componentName2 have same layout
  EFI_GUID                      Protocol;
  UINTN                         StrLength;
  EFI_DEVICE_PATH_PROTOCOL*     TmpDevPath;
  UINTN                         Index1;
  UINTN                         Index2;
  EFI_HANDLE                    TmpHandle;
  CHAR16                        *DevName;

  if (Dev == NULL || AllHandlesBuffer == NULL || NumAllHandles == 0) {
    return FALSE;
  }

  Protocol = UseComp1 ? gEfiComponentNameProtocolGuid : gEfiComponentName2ProtocolGuid;

  //
  // Find all EFI_HANDLES with protocol
  //
  Status = gBS->LocateHandleBuffer(
               ByProtocol,
               &Protocol,
               NULL,
               &NumProtocolHandles,
               &ProtocolHandlesBuffer
               );
  if (EFI_ERROR(Status)) {
    return FALSE;
  }


  //
  // Exit early if no supported devices
  //
  if (NumProtocolHandles == 0) {
    return FALSE;
  }

  //
  // Get printable name by iterating through all protocols
  // using the handle as the child, and iterate through all handles for the controller
  // exit loop early once found, if not found, then delete device
  // storage security protocol instances already exist, add them to internal list
  //
  Status = EFI_DEVICE_ERROR;
  for (Index1 = 0; Index1 < NumProtocolHandles; Index1++) {
    DevName = NULL;

    if (Dev->Name16 != NULL) {
      return TRUE;
    }

    TmpHandle = ProtocolHandlesBuffer[Index1];

    Status = gBS->OpenProtocol(
                 TmpHandle,
                 &Protocol,
                 (VOID**)&Cnp1_2,
                 gImageHandle,
                 NULL,
                 EFI_OPEN_PROTOCOL_GET_PROTOCOL
                 );
    if (EFI_ERROR(Status) || Cnp1_2 == NULL) {
      continue;
    }

    //
    // Use all handles array as controller handle
    //
    for (Index2 = 0; Index2 < NumAllHandles; Index2++) {
      Status = Cnp1_2->GetControllerName(
                   Cnp1_2,
                   AllHandlesBuffer[Index2],
                   Dev->Handle,
                   LANGUAGE_ISO_639_2_ENGLISH,
                   &DevName
                   );
      if (EFI_ERROR(Status)) {
        Status = Cnp1_2->GetControllerName(
                     Cnp1_2,
                     AllHandlesBuffer[Index2],
                     Dev->Handle,
                     LANGUAGE_RFC_3066_ENGLISH,
                     &DevName
                     );
      }
      if (!EFI_ERROR(Status) && DevName != NULL) {
        StrLength = StrLen(DevName) + 1;        // Add one for NULL terminator
        Dev->Name16 = AllocateZeroPool(StrLength * sizeof (CHAR16));
        ASSERT (Dev->Name16 != NULL);
        StrCpyS (Dev->Name16, StrLength, DevName);
        Dev->NameZ = (CHAR8*)AllocateZeroPool(StrLength);
        UnicodeStrToAsciiStrS (DevName, Dev->NameZ, StrLength);

        //
        // Retrieve bridge BDF info and port number or namespace depending on type
        //
        TmpDevPath = NULL;
        Status = gBS->OpenProtocol(
            Dev->Handle,
            &gEfiDevicePathProtocolGuid,
            (VOID**)&TmpDevPath,
            gImageHandle,
            NULL,
            EFI_OPEN_PROTOCOL_GET_PROTOCOL
            );
        if (!EFI_ERROR(Status)) {
          Dev->OpalDevicePath = DuplicateDevicePath (TmpDevPath);
          return TRUE;
        }

        if (Dev->Name16 != NULL) {
          FreePool(Dev->Name16);
          Dev->Name16 = NULL;
        }
        if (Dev->NameZ != NULL) {
          FreePool(Dev->NameZ);
          Dev->NameZ = NULL;
        }
      }
    }
  }

  return FALSE;
}
Ejemplo n.º 7
0
/**
  Get password input from the popup windows, and unlock the device.

  @param[in]       Dev          The device which need to be unlock.
  @param[out]      PressEsc     Whether user escape function through Press ESC.

  @retval   Password string if success. NULL if failed.

**/
CHAR8 *
OpalDriverPopUpHddPassword (
  IN  OPAL_DRIVER_DEVICE         *Dev,
  OUT BOOLEAN                    *PressEsc
  )
{
  EFI_INPUT_KEY                InputKey;
  UINTN                        InputLength;
  CHAR16                       Mask[MAX_PASSWORD_SIZE + 1];
  CHAR16                       Unicode[MAX_PASSWORD_SIZE + 1];
  CHAR8                        *Ascii;
  CHAR16                       *PopUpString;
  UINTN                        StrLength;

  ZeroMem(Unicode, sizeof(Unicode));
  ZeroMem(Mask, sizeof(Mask));

  StrLength = StrLen(Dev->Name16);
  PopUpString = (CHAR16*) AllocateZeroPool ((8 + StrLength) * 2);
  *PressEsc = FALSE;

  if (Dev->Name16 == NULL) {
    UnicodeSPrint(PopUpString, StrLen(L"Unlock Disk") + 1, L"Unlock Disk");
  } else {
    UnicodeSPrint(PopUpString, StrLen(L"Unlock ") + StrLength + 1, L"Unlock %s", Dev->Name16);
  }

  gST->ConOut->ClearScreen(gST->ConOut);

  InputLength = 0;
  while (TRUE) {
    Mask[InputLength] = L'_';
    CreatePopUp(
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &InputKey,
        PopUpString,
        L"---------------------",
        Mask,
        NULL
    );

    //
    // Check key.
    //
    if (InputKey.ScanCode == SCAN_NULL) {
      //
      // password finished
      //
      if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {
        //
        // Add the null terminator.
        //
        Unicode[InputLength] = 0;
        InputLength++;
        break;
      } else if ((InputKey.UnicodeChar == CHAR_NULL) ||
                 (InputKey.UnicodeChar == CHAR_TAB) ||
                 (InputKey.UnicodeChar == CHAR_LINEFEED)
                ) {
        continue;
      } else {
        //
        // delete last key entered
        //
        if (InputKey.UnicodeChar == CHAR_BACKSPACE) {
          if (InputLength > 0) {
            Unicode[InputLength] = 0;
            Mask[InputLength] = 0;
            InputLength--;
          }
        } else {
          //
          // add Next key entry
          //
          Unicode[InputLength] = InputKey.UnicodeChar;
          Mask[InputLength] = L'*';
          InputLength++;
          if (InputLength == MAX_PASSWORD_SIZE) {
            //
            // Add the null terminator.
            //
            Unicode[InputLength] = 0;
            Mask[InputLength] = 0;
            break;
          }
        }
      }
    }

    //
    // exit on ESC
    //
    if (InputKey.ScanCode == SCAN_ESC) {
      *PressEsc = TRUE;
      break;
    }
  }

  gST->ConOut->ClearScreen(gST->ConOut);

  if (InputLength == 0 || InputKey.ScanCode == SCAN_ESC) {
    return NULL;
  }

  Ascii = AllocateZeroPool (MAX_PASSWORD_SIZE + 1);
  if (Ascii == NULL) {
    return NULL;
  }

  UnicodeStrToAsciiStrS (Unicode, Ascii, MAX_PASSWORD_SIZE + 1);
  ZeroMem (Unicode, sizeof (Unicode));

  return Ascii;
}
Ejemplo n.º 8
0
Archivo: Tftp.c Proyecto: lgao4/edk2
/**
  Function for 'tftp' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).

  @return  SHELL_SUCCESS            The 'tftp' command completed successfully.
  @return  SHELL_ABORTED            The Shell Library initialization failed.
  @return  SHELL_INVALID_PARAMETER  At least one of the command's arguments is
                                    not valid.
  @return  SHELL_OUT_OF_RESOURCES   A memory allocation failed.
  @return  SHELL_NOT_FOUND          Network Interface Card not found or server
                                    error or file error.

**/
SHELL_STATUS
EFIAPI
ShellCommandRunTftp (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  SHELL_STATUS            ShellStatus;
  EFI_STATUS              Status;
  LIST_ENTRY              *CheckPackage;
  CHAR16                  *ProblemParam;
  UINTN                   ParamCount;
  CONST CHAR16            *UserNicName;
  BOOLEAN                 NicFound;
  CONST CHAR16            *ValueStr;
  CONST CHAR16            *RemoteFilePath;
  CHAR8                   *AsciiRemoteFilePath;
  UINTN                   FilePathSize;
  CONST CHAR16            *Walker;
  CONST CHAR16            *LocalFilePath;
  EFI_MTFTP4_CONFIG_DATA  Mtftp4ConfigData;
  EFI_HANDLE              *Handles;
  UINTN                   HandleCount;
  UINTN                   NicNumber;
  CHAR16                  NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH];
  EFI_HANDLE              ControllerHandle;
  EFI_HANDLE              Mtftp4ChildHandle;
  EFI_MTFTP4_PROTOCOL     *Mtftp4;
  UINTN                   FileSize;
  VOID                    *Data;
  SHELL_FILE_HANDLE       FileHandle;
  UINT16                  BlockSize;

  ShellStatus         = SHELL_INVALID_PARAMETER;
  ProblemParam        = NULL;
  NicFound            = FALSE;
  AsciiRemoteFilePath = NULL;
  Handles             = NULL;
  FileSize            = 0;
  BlockSize           = MTFTP_DEFAULT_BLKSIZE;

  //
  // Initialize the Shell library (we must be in non-auto-init...)
  //
  Status = ShellInitialize ();
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return SHELL_ABORTED;
  }

  //
  // Parse the command line.
  //
  Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE);
  if (EFI_ERROR (Status)) {
    if ((Status == EFI_VOLUME_CORRUPTED) &&
        (ProblemParam != NULL) ) {
      ShellPrintHiiEx (
        -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellTftpHiiHandle,
        L"tftp", ProblemParam
        );
      FreePool (ProblemParam);
    } else {
      ASSERT (FALSE);
    }
    goto Error;
  }

  //
  // Check the number of parameters
  //
  ParamCount = ShellCommandLineGetCount (CheckPackage);
  if (ParamCount > 4) {
    ShellPrintHiiEx (
      -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY),
      gShellTftpHiiHandle, L"tftp"
      );
    goto Error;
  }
  if (ParamCount < 3) {
    ShellPrintHiiEx (
      -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW),
      gShellTftpHiiHandle, L"tftp"
      );
    goto Error;
  }

  Mtftp4ConfigData = DefaultMtftp4ConfigData;

  //
  // Check the host IPv4 address
  //
  ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1);
  Status = NetLibStrToIp4 (ValueStr, &Mtftp4ConfigData.ServerIp);
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx (
      -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),
      gShellTftpHiiHandle, L"tftp", ValueStr
    );
    goto Error;
  }

  RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2);
  ASSERT(RemoteFilePath != NULL);
  FilePathSize = StrLen (RemoteFilePath) + 1;
  AsciiRemoteFilePath = AllocatePool (FilePathSize);
  if (AsciiRemoteFilePath == NULL) {
    ShellStatus = SHELL_OUT_OF_RESOURCES;
    goto Error;
  }
  UnicodeStrToAsciiStrS (RemoteFilePath, AsciiRemoteFilePath, FilePathSize);

  if (ParamCount == 4) {
    LocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3);
  } else {
    Walker = RemoteFilePath + StrLen (RemoteFilePath);
    while ((--Walker) >= RemoteFilePath) {
      if ((*Walker == L'\\') ||
          (*Walker == L'/' )    ) {
        break;
      }
    }
    LocalFilePath = Walker + 1;
  }

  //
  // Get the name of the Network Interface Card to be used if any.
  //
  UserNicName = ShellCommandLineGetValue (CheckPackage, L"-i");

  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l");
  if (ValueStr != NULL) {
    if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.LocalPort)) {
      goto Error;
    }
  }

  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-r");
  if (ValueStr != NULL) {
    if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.InitialServerPort)) {
      goto Error;
    }
  }

  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-c");
  if (ValueStr != NULL) {
    if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TryCount)) {
      goto Error;
    }
  }

  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t");
  if (ValueStr != NULL) {
    if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TimeoutValue)) {
      goto Error;
    }
    if (Mtftp4ConfigData.TimeoutValue == 0) {
      ShellPrintHiiEx (
        -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),
        gShellTftpHiiHandle, L"tftp", ValueStr
      );
      goto Error;
    }
  }

  ValueStr = ShellCommandLineGetValue (CheckPackage, L"-s");
  if (ValueStr != NULL) {
    if (!StringToUint16 (ValueStr, &BlockSize)) {
      goto Error;
    }
    if (BlockSize < MTFTP_MIN_BLKSIZE || BlockSize > MTFTP_MAX_BLKSIZE) {
      ShellPrintHiiEx (
        -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV),
        gShellTftpHiiHandle, L"tftp", ValueStr
      );
      goto Error;
    }
  }

  //
  // Locate all MTFTP4 Service Binding protocols
  //
  ShellStatus = SHELL_NOT_FOUND;
  Status = gBS->LocateHandleBuffer (
                 ByProtocol,
                 &gEfiManagedNetworkServiceBindingProtocolGuid,
                 NULL,
                 &HandleCount,
                 &Handles
                 );
  if (EFI_ERROR (Status) || (HandleCount == 0)) {
    ShellPrintHiiEx (
      -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NO_NIC),
      gShellTftpHiiHandle
    );
    goto Error;
  }

  for (NicNumber = 0;
       (NicNumber < HandleCount) && (ShellStatus != SHELL_SUCCESS);
       NicNumber++) {
    ControllerHandle = Handles[NicNumber];
    Data = NULL;

    Status = GetNicName (ControllerHandle, NicNumber, NicName);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NAME),
        gShellTftpHiiHandle, NicNumber, Status
      );
      continue;
    }

    if (UserNicName != NULL) {
      if (StrCmp (NicName, UserNicName) != 0) {
        continue;
      }
      NicFound = TRUE;
    }

    Status = CreateServiceChildAndOpenProtocol (
               ControllerHandle,
               &gEfiMtftp4ServiceBindingProtocolGuid,
               &gEfiMtftp4ProtocolGuid,
               &Mtftp4ChildHandle,
               (VOID**)&Mtftp4
               );
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL),
        gShellTftpHiiHandle, NicName, Status
      );
      continue;
    }

    Status = Mtftp4->Configure (Mtftp4, &Mtftp4ConfigData);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_CONFIGURE),
        gShellTftpHiiHandle, NicName, Status
      );
      goto NextHandle;
    }

    Status = GetFileSize (Mtftp4, AsciiRemoteFilePath, &FileSize);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_FILE_SIZE),
        gShellTftpHiiHandle, RemoteFilePath, NicName, Status
      );
      goto NextHandle;
    }

    Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, &Data);
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD),
        gShellTftpHiiHandle, RemoteFilePath, NicName, Status
      );
      goto NextHandle;
    }

    if (!EFI_ERROR (ShellFileExists (LocalFilePath))) {
      ShellDeleteFileByName (LocalFilePath);
    }

    Status = ShellOpenFileByName (
               LocalFilePath,
               &FileHandle,
               EFI_FILE_MODE_CREATE |
               EFI_FILE_MODE_WRITE  |
               EFI_FILE_MODE_READ,
               0
               );
    if (EFI_ERROR (Status)) {
      ShellPrintHiiEx (
        -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL),
        gShellTftpHiiHandle, L"tftp", LocalFilePath
      );
      goto NextHandle;
    }

    Status = ShellWriteFile (FileHandle, &FileSize, Data);
    if (!EFI_ERROR (Status)) {
      ShellStatus = SHELL_SUCCESS;
    } else {
      ShellPrintHiiEx (
        -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_WRITE),
        gShellTftpHiiHandle, LocalFilePath, Status
      );
    }
    ShellCloseFile (&FileHandle);

    NextHandle:

    if (Data != NULL) {
      gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Data, EFI_SIZE_TO_PAGES (FileSize));
    }

    CloseProtocolAndDestroyServiceChild (
      ControllerHandle,
      &gEfiMtftp4ServiceBindingProtocolGuid,
      &gEfiMtftp4ProtocolGuid,
      Mtftp4ChildHandle
      );
  }

  if ((UserNicName != NULL) && (!NicFound)) {
    ShellPrintHiiEx (
      -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND),
      gShellTftpHiiHandle, UserNicName
    );
  }

  Error:

  ShellCommandLineFreeVarList (CheckPackage);
  if (AsciiRemoteFilePath != NULL) {
    FreePool (AsciiRemoteFilePath);
  }
  if (Handles != NULL) {
    FreePool (Handles);
  }

  return ShellStatus;
}
Ejemplo n.º 9
0
/**
  Installs the Device Recovery Module PPI, Initialize BlockIo Ppi
  installation notification

  @param  FileHandle            The file handle of the image.
  @param  PeiServices           General purpose services available to every PEIM.

  @retval EFI_SUCCESS           The function completed successfully.
  @retval EFI_OUT_OF_RESOURCES  There is not enough system memory.

**/
EFI_STATUS
EFIAPI
CdExpressPeimEntry (
  IN EFI_PEI_FILE_HANDLE       FileHandle,
  IN CONST EFI_PEI_SERVICES    **PeiServices
  )
{
  EFI_STATUS                  Status;
  PEI_CD_EXPRESS_PRIVATE_DATA *PrivateData;

  if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
    return EFI_SUCCESS;
  }

  PrivateData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (*PrivateData)));
  if (PrivateData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  mRecoveryFileNameSize = PcdGetSize(PcdRecoveryFileName) / sizeof(CHAR16);
  mRecoveryFileName = AllocatePool(mRecoveryFileNameSize);
  if (mRecoveryFileName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  Status = UnicodeStrToAsciiStrS(PcdGetPtr(PcdRecoveryFileName), mRecoveryFileName, mRecoveryFileNameSize);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  //
  // Initialize Private Data (to zero, as is required by subsequent operations)
  //
  ZeroMem (PrivateData, sizeof (*PrivateData));
  PrivateData->Signature    = PEI_CD_EXPRESS_PRIVATE_DATA_SIGNATURE;

  PrivateData->BlockBuffer  = AllocatePages (EFI_SIZE_TO_PAGES (PEI_CD_BLOCK_SIZE));
  if (PrivateData->BlockBuffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  PrivateData->CapsuleCount = 0;
  Status = UpdateBlocksAndVolumes (PrivateData, TRUE);
  Status = UpdateBlocksAndVolumes (PrivateData, FALSE);

  //
  // Installs Ppi
  //
  PrivateData->DeviceRecoveryPpi.GetNumberRecoveryCapsules  = GetNumberRecoveryCapsules;
  PrivateData->DeviceRecoveryPpi.GetRecoveryCapsuleInfo     = GetRecoveryCapsuleInfo;
  PrivateData->DeviceRecoveryPpi.LoadRecoveryCapsule        = LoadRecoveryCapsule;

  PrivateData->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
  PrivateData->PpiDescriptor.Guid  = &gEfiPeiDeviceRecoveryModulePpiGuid;
  PrivateData->PpiDescriptor.Ppi   = &PrivateData->DeviceRecoveryPpi;

  Status = PeiServicesInstallPpi (&PrivateData->PpiDescriptor);
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // PrivateData is allocated now, set it to the module variable
  //
  mPrivateData = PrivateData;

  //
  // Installs Block Io Ppi notification function
  //
  PrivateData->NotifyDescriptor.Flags =
    (
      EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
    );
  PrivateData->NotifyDescriptor.Guid    = &gEfiPeiVirtualBlockIoPpiGuid;
  PrivateData->NotifyDescriptor.Notify  = BlockIoNotifyEntry;

  PrivateData->NotifyDescriptor2.Flags =
    (
      EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
      EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
    );
  PrivateData->NotifyDescriptor2.Guid    = &gEfiPeiVirtualBlockIo2PpiGuid;
  PrivateData->NotifyDescriptor2.Notify  = BlockIoNotifyEntry;

  return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor);

}