Ejemplo n.º 1
0
/** Retrieve first entry from a directory.

  This function takes an open directory handle and gets information from the
  first entry in the directory.  A buffer is allocated to contain
  the information and a pointer to the buffer is returned in *Buffer.  The
  caller can use FileHandleFindNextFile() to get subsequent directory entries.

  The buffer will be freed by FileHandleFindNextFile() when the last directory
  entry is read.  Otherwise, the caller must free the buffer, using FreePool,
  when finished with it.

  @param[in]  DirHandle         The file handle of the directory to search.
  @param[out] Buffer            The pointer to pointer to buffer for file's information.

  @retval EFI_SUCCESS           Found the first file.
  @retval EFI_NOT_FOUND         Cannot find the directory.
  @retval EFI_NO_MEDIA          The device has no media.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
  @return Others                status of FileHandleGetInfo, FileHandleSetPosition,
                                or FileHandleRead
**/
EFI_STATUS
EFIAPI
FileHandleFindFirstFile (
  IN EFI_FILE_HANDLE            DirHandle,
  OUT EFI_FILE_INFO             **Buffer
  )
{
  EFI_STATUS    Status;
  UINTN         BufferSize;

  if (Buffer == NULL || DirHandle == NULL) {
    return (EFI_INVALID_PARAMETER);
  }

  //
  // verify that DirHandle is a directory
  //
  Status = FileHandleIsDirectory(DirHandle);
  if (EFI_ERROR(Status)) {
    return (Status);
  }

  //
  // Allocate a buffer sized to struct size + enough for the string at the end
  //
  BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;
  *Buffer = AllocateZeroPool(BufferSize);
  if (*Buffer == NULL){
    return (EFI_OUT_OF_RESOURCES);
  }

  //
  // reset to the beginning of the directory
  //
  Status = FileHandleSetPosition(DirHandle, 0);
  if (EFI_ERROR(Status)) {
    FreePool(*Buffer);
    *Buffer = NULL;
    return (Status);
  }

  //
  // read in the info about the first file
  //
  Status = FileHandleRead (DirHandle, &BufferSize, *Buffer);
  ASSERT(Status != EFI_BUFFER_TOO_SMALL);
  if (EFI_ERROR(Status) || BufferSize == 0) {
    FreePool(*Buffer);
    *Buffer = NULL;
    if (BufferSize == 0) {
      return (EFI_NOT_FOUND);
    }
    return (Status);
  }
  return (EFI_SUCCESS);
}
Ejemplo n.º 2
0
static char *
GetData(FileHandle *In, unsigned long Length)
{
	char *Ptr;

	if ((Ptr = malloc(Length + 1)) != NULL) {
		if (FileHandleRead(In, Ptr, Length) && SkipAndAlign(In, 0)) {
			Ptr[Length] = '\0';
			return Ptr;
		}
		free(Ptr);
	}

	return NULL;
}
Ejemplo n.º 3
0
/** Retrieve next entries from a directory.

  To use this function, the caller must first call the FileHandleFindFirstFile()
  function to get the first directory entry.  Subsequent directory entries are
  retrieved by using the FileHandleFindNextFile() function.  This function can
  be called several times to get each entry from the directory.  If the call of
  FileHandleFindNextFile() retrieved the last directory entry, the next call of
  this function will set *NoFile to TRUE and free the buffer.

  @param[in]  DirHandle         The file handle of the directory.
  @param[out] Buffer            The pointer to buffer for file's information.
  @param[out] NoFile            The pointer to boolean when last file is found.

  @retval EFI_SUCCESS           Found the next file, or reached last file
  @retval EFI_NO_MEDIA          The device has no media.
  @retval EFI_DEVICE_ERROR      The device reported an error.
  @retval EFI_VOLUME_CORRUPTED  The file system structures are corrupted.
**/
EFI_STATUS
EFIAPI
FileHandleFindNextFile(
  IN EFI_FILE_HANDLE          DirHandle,
  OUT EFI_FILE_INFO          *Buffer,
  OUT BOOLEAN                *NoFile
  )
{
  EFI_STATUS    Status;
  UINTN         BufferSize;

  //
  // ASSERTs for DirHandle or Buffer or NoFile poitners being NULL
  //
  ASSERT (DirHandle != NULL);
  ASSERT (Buffer    != NULL);
  ASSERT (NoFile    != NULL);

  //
  // This BufferSize MUST stay equal to the originally allocated one in GetFirstFile
  //
  BufferSize = FIND_XXXXX_FILE_BUFFER_SIZE;

  //
  // read in the info about the next file
  //
  Status = FileHandleRead (DirHandle, &BufferSize, Buffer);
  ASSERT(Status != EFI_BUFFER_TOO_SMALL);
  if (EFI_ERROR(Status)) {
    return (Status);
  }

  //
  // If we read 0 bytes (but did not have erros) we already read in the last file.
  //
  if (BufferSize == 0) {
    FreePool(Buffer);
    *NoFile = TRUE;
  }

  return (EFI_SUCCESS);
}
Ejemplo n.º 4
0
EFI_STATUS
UtilReadFileToMemory (
  EFI_FILE_PROTOCOL *File,
  VOID              **OutBuffer,
  UINTN             *OutSize
)
{
  EFI_STATUS Status;
  UINT64     FileSize = 0;
  VOID       *Buffer = NULL;
  UINTN      ReadSize;

  if(!File)
    return EFI_INVALID_PARAMETER;

  // get size
  Status = FileHandleGetSize(File, &FileSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // allocate buffer
  Buffer = AllocatePool(FileSize);
  if (Buffer==NULL)
    return EFI_OUT_OF_RESOURCES;

  // read data
  ReadSize = (UINTN) FileSize;
  Status = FileHandleRead(File, &ReadSize, Buffer);
  if (EFI_ERROR (Status)) {
    FreePool (Buffer);
    return Status;
  }

  *OutBuffer = Buffer;
  *OutSize   = ReadSize;

  return EFI_SUCCESS;
}
Ejemplo n.º 5
0
static bool
WriteFile(FileHandle *in, char *name, mode_t mode, unsigned long length,
    const char *link_target)
{
	int		outfd;
	struct stat	sb;
	char		buffer[1 << 16];

	if ((lstat(name, &sb) == 0) &&
	    (!S_ISREG(sb.st_mode) || (unlink(name) < 0))) {
		return false;
	}

	if (link_target != NULL) {
		if (link(link_target, name) < 0)
			return false;
		outfd = open(name, O_WRONLY, mode);
	 } else {
		outfd = open(name, O_WRONLY|O_CREAT, mode);
	}
	if (outfd < 0)
		return false;

	while (length > 0) {
		ssize_t	chunk;

		chunk = (length > sizeof(buffer)) ? sizeof(buffer) : length;
		if (!FileHandleRead(in, buffer, chunk) ||
		    write(outfd, buffer, chunk) != chunk)
			break;
		length -= chunk;
	}

	if (close(outfd) == 0 && length == 0)
		return SkipAndAlign(in, 0);

	(void)unlink(name);
	return false;
}
Ejemplo n.º 6
0
/**
  Function to read a single line (up to but not including the \n) from a file.

  If the position upon start is 0, then the Ascii Boolean will be set.  This should be
  maintained and not changed for all operations with the same file.
  The function will not return the \r and \n character in buffer. When an empty line is
  read a CHAR_NULL character will be returned in buffer.

  @param[in]       Handle        FileHandle to read from.
  @param[in, out]  Buffer        The pointer to buffer to read into.
  @param[in, out]  Size          The pointer to number of bytes in Buffer.
  @param[in]       Truncate      If the buffer is large enough, this has no effect.
                                 If the buffer is is too small and Truncate is TRUE,
                                 the line will be truncated.
                                 If the buffer is is too small and Truncate is FALSE,
                                 then no read will occur.

  @param[in, out]  Ascii         Boolean value for indicating whether the file is
                                 Ascii (TRUE) or UCS2 (FALSE).

  @retval EFI_SUCCESS           The operation was successful.  The line is stored in
                                Buffer.
  @retval EFI_INVALID_PARAMETER Handle was NULL.
  @retval EFI_INVALID_PARAMETER Size was NULL.
  @retval EFI_BUFFER_TOO_SMALL  Size was not large enough to store the line.
                                Size was updated to the minimum space required.
  @sa FileHandleRead
**/
EFI_STATUS
EFIAPI
FileHandleReadLine(
  IN EFI_FILE_HANDLE            Handle,
  IN OUT CHAR16                 *Buffer,
  IN OUT UINTN                  *Size,
  IN BOOLEAN                    Truncate,
  IN OUT BOOLEAN                *Ascii
  )
{
  EFI_STATUS  Status;
  CHAR16      CharBuffer;
  UINT64      FileSize;
  UINTN       CharSize;
  UINTN       CountSoFar;
  UINTN       CrCount;
  UINT64      OriginalFilePosition;

  if (Handle == NULL
    ||Size   == NULL
    ||(Buffer==NULL&&*Size!=0)
   ){
    return (EFI_INVALID_PARAMETER);
  } 
  
  if (Buffer != NULL && *Size != 0) {
    *Buffer = CHAR_NULL;
  } 
  
  Status = FileHandleGetSize (Handle, &FileSize);
  if (EFI_ERROR (Status)) {
    return Status;
  } else if (FileSize == 0) {
    *Ascii = TRUE;
    return EFI_SUCCESS;
  }  
  
  FileHandleGetPosition(Handle, &OriginalFilePosition);
  if (OriginalFilePosition == 0) {
    CharSize = sizeof(CHAR16);
    Status = FileHandleRead(Handle, &CharSize, &CharBuffer);
    ASSERT_EFI_ERROR(Status);
    if (CharBuffer == gUnicodeFileTag) {
      *Ascii = FALSE;
    } else {
      *Ascii = TRUE;
      FileHandleSetPosition(Handle, OriginalFilePosition);
    }
  }

  CrCount = 0;
  for (CountSoFar = 0;;CountSoFar++){
    CharBuffer = 0;
    if (*Ascii) {
      CharSize = sizeof(CHAR8);
    } else {
      CharSize = sizeof(CHAR16);
    }
    Status = FileHandleRead(Handle, &CharSize, &CharBuffer);
    if (  EFI_ERROR(Status)
       || CharSize == 0
       || (CharBuffer == L'\n' && !(*Ascii))
       || (CharBuffer ==  '\n' && *Ascii)
     ){
      break;
    } else if (
        (CharBuffer == L'\r' && !(*Ascii)) ||
        (CharBuffer ==  '\r' && *Ascii)
      ) {
      CrCount++;
      continue;
    }
    //
    // if we have space save it...
    //
    if ((CountSoFar+1-CrCount)*sizeof(CHAR16) < *Size){
      ASSERT(Buffer != NULL);
      ((CHAR16*)Buffer)[CountSoFar-CrCount] = CharBuffer;
      ((CHAR16*)Buffer)[CountSoFar+1-CrCount] = CHAR_NULL;
    }
  }

  //
  // if we ran out of space tell when...
  //
  if ((CountSoFar+1-CrCount)*sizeof(CHAR16) > *Size){
    *Size = (CountSoFar+1-CrCount)*sizeof(CHAR16);
    if (!Truncate) {
      if (Buffer != NULL && *Size != 0) {
        ZeroMem(Buffer, *Size);
      }
      FileHandleSetPosition(Handle, OriginalFilePosition);
      return (EFI_BUFFER_TOO_SMALL);
    } else {
      DEBUG((DEBUG_WARN, "The line was truncated in FileHandleReadLine"));
      return (EFI_SUCCESS);
    }
  }

  return (Status);
}
Ejemplo n.º 7
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.º 8
0
/**
  Dump capsule information from disk.

  @param[in] Fs                  The device path of disk.
  @param[in] DumpCapsuleInfo     The flag to indicate whether to dump the capsule inforomation.

  @retval EFI_SUCCESS            The capsule information is dumped.

**/
EFI_STATUS
DumpCapsuleFromDisk (
  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL            *Fs,
  IN BOOLEAN                                    DumpCapsuleInfo
  )
{
  EFI_STATUS                                    Status;
  EFI_FILE                                      *Root;
  EFI_FILE                                      *DirHandle;
  EFI_FILE                                      *FileHandle;
  UINTN                                         Index;
  UINTN                                         FileSize;
  VOID                                          *FileBuffer;
  EFI_FILE_INFO                                 **FileInfoBuffer;
  EFI_FILE_INFO                                 *FileInfo;
  UINTN                                         FileCount;
  BOOLEAN                                       NoFile;

  DirHandle       = NULL;
  FileHandle      = NULL;
  Index           = 0;
  FileInfoBuffer  = NULL;
  FileInfo        = NULL;
  FileCount       = 0;
  NoFile          = FALSE;

  Status = Fs->OpenVolume (Fs, &Root);
  if (EFI_ERROR (Status)) {
    Print (L"Cannot open volume. Status = %r\n", Status);
    goto Done;
  }

  Status = Root->Open (Root, &DirHandle, EFI_CAPSULE_FILE_DIRECTORY, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE , 0);
  if (EFI_ERROR (Status)) {
    Print (L"Cannot open %s. Status = %r\n", EFI_CAPSULE_FILE_DIRECTORY, Status);
    goto Done;
  }

  //
  // Get file count first
  //
  do {
    Status = FileHandleFindFirstFile (DirHandle, &FileInfo);
    if (EFI_ERROR (Status) || FileInfo == NULL) {
      Print (L"Get File Info Fail. Status = %r\n", Status);
      goto Done;
    }

    if ((FileInfo->Attribute & (EFI_FILE_SYSTEM | EFI_FILE_ARCHIVE)) != 0) {
      FileCount++;
    }

    Status = FileHandleFindNextFile (DirHandle, FileInfo, &NoFile);
    if (EFI_ERROR (Status)) {
      Print (L"Get Next File Fail. Status = %r\n", Status);
      goto Done;
    }
  } while (!NoFile);

  if (FileCount == 0) {
    Print (L"Error: No capsule file found!\n");
    Status = EFI_NOT_FOUND;
    goto Done;
  }

  FileInfoBuffer = AllocateZeroPool (sizeof (FileInfo) * FileCount);
  if (FileInfoBuffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }
  NoFile = FALSE;

  //
  // Get all file info
  //
  do {
    Status = FileHandleFindFirstFile (DirHandle, &FileInfo);
    if (EFI_ERROR (Status) || FileInfo == NULL) {
      Print (L"Get File Info Fail. Status = %r\n", Status);
      goto Done;
    }

    if ((FileInfo->Attribute & (EFI_FILE_SYSTEM | EFI_FILE_ARCHIVE)) != 0) {
      FileInfoBuffer[Index++] = AllocateCopyPool ((UINTN)FileInfo->Size, FileInfo);
    }

    Status = FileHandleFindNextFile (DirHandle, FileInfo, &NoFile);
    if (EFI_ERROR (Status)) {
      Print (L"Get Next File Fail. Status = %r\n", Status);
      goto Done;
    }
  } while (!NoFile);

  //
  // Sort FileInfoBuffer by alphabet order
  //
  PerformQuickSort (
    FileInfoBuffer,
    FileCount,
    sizeof (FileInfo),
    (SORT_COMPARE) CompareFileNameInAlphabet
    );

  Print (L"The capsules will be performed by following order:\n");

  for (Index = 0; Index < FileCount; Index++) {
    Print (L"  %d.%s\n", Index + 1, FileInfoBuffer[Index]->FileName);
  }

  if (!DumpCapsuleInfo) {
    Status = EFI_SUCCESS;
    goto Done;
  }

  Print(L"The infomation of the capsules:\n");

  for (Index = 0; Index < FileCount; Index++) {
    FileHandle = NULL;
    Status = DirHandle->Open (DirHandle, &FileHandle, FileInfoBuffer[Index]->FileName, EFI_FILE_MODE_READ, 0);
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    Status = FileHandleGetSize (FileHandle, (UINT64 *) &FileSize);
    if (EFI_ERROR (Status)) {
      Print (L"Cannot read file %s. Status = %r\n", FileInfoBuffer[Index]->FileName, Status);
      FileHandleClose (FileHandle);
      goto Done;
    }

    FileBuffer = AllocatePool (FileSize);
    if (FileBuffer == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Done;
    }

    Status = FileHandleRead (FileHandle, &FileSize, FileBuffer);
    if (EFI_ERROR (Status)) {
      Print (L"Cannot read file %s. Status = %r\n", FileInfoBuffer[Index]->FileName, Status);
      FileHandleClose (FileHandle);
      FreePool (FileBuffer);
      goto Done;
    }

    Print (L"**************************\n");
    Print (L"  %d.%s:\n", Index + 1, FileInfoBuffer[Index]->FileName);
    Print (L"**************************\n");
    DumpCapsuleFromBuffer ((EFI_CAPSULE_HEADER *) FileBuffer);
    FileHandleClose (FileHandle);
    FreePool (FileBuffer);
  }

Done:
  if (FileInfoBuffer != NULL) {
    for (Index = 0; Index < FileCount; Index++) {
      if (FileInfoBuffer[Index] != NULL) {
        FreePool (FileInfoBuffer[Index]);
      }
    }
    FreePool (FileInfoBuffer);
  }

  return Status;
}
Ejemplo n.º 9
0
STATIC
EFI_STATUS
ReadFileData (
  IN  CHAR16   *FileName,
  OUT UINT8    **Buffer,
  OUT UINT32   *BufferSize
  )
{
  EFI_STATUS             Status;
  SHELL_FILE_HANDLE      FileHandle;
  UINT64                 Size;
  VOID                   *NewBuffer;
  UINTN                  ReadSize;

  FileHandle = NULL;
  NewBuffer = NULL;
  Size = 0;

  Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = FileHandleIsDirectory (FileHandle);
  if (!EFI_ERROR (Status)) {
    Status = EFI_NOT_FOUND;
    goto Done;
  }

  Status = FileHandleGetSize (FileHandle, &Size);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  NewBuffer = AllocatePool ((UINTN) Size);

  ReadSize = (UINTN) Size;
  Status = FileHandleRead (FileHandle, &ReadSize, NewBuffer);
  if (EFI_ERROR (Status)) {
    goto Done;
  } else if (ReadSize != (UINTN) Size) {
    Status = EFI_INVALID_PARAMETER;
    goto Done;
  }

Done:
  if (FileHandle != NULL) {
    ShellCloseFile (&FileHandle);
  }

  if (EFI_ERROR (Status)) {
    if (NewBuffer != NULL) {
      FreePool (NewBuffer);
    }
  } else {
    *Buffer = NewBuffer;
    *BufferSize = (UINT32) Size;
  }

  return Status;
}