/** Function to determine if a FILE_HANDLE is at the end of the file. This will NOT work on directories. If Handle is NULL, then return False. @param[in] Handle the file handle @retval TRUE the position is at the end of the file @retval FALSE the position is not at the end of the file **/ BOOLEAN EFIAPI FileHandleEof( IN EFI_FILE_HANDLE Handle ) { EFI_FILE_INFO *Info; UINT64 Pos; BOOLEAN RetVal; if (Handle == NULL) { return (FALSE); } FileHandleGetPosition(Handle, &Pos); Info = FileHandleGetInfo (Handle); if (Info == NULL) { return (FALSE); } FileHandleSetPosition(Handle, Pos); if (Pos == Info->FileSize) { RetVal = TRUE; } else { RetVal = FALSE; } FreePool (Info); return (RetVal); }
/** 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 begining 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); }
STATIC CHAR8* IniReaderEfiFile ( CHAR8 *String, INT32 Size, VOID *Stream ) { EFI_FILE_PROTOCOL *File = (EFI_FILE_PROTOCOL*) Stream; EFI_STATUS Status; UINTN BufferSize; UINT64 Position; UINTN Index; // stop here if we reached EOF already if (FileHandleEof(File)) { return NULL; } // get current position Status = FileHandleGetPosition(File, &Position); if (EFI_ERROR(Status)) return NULL; // read data BufferSize = Size-1; Status = FileHandleRead(File, &BufferSize, String); if (EFI_ERROR(Status)) { return NULL; } // EOF or error if (BufferSize==0) { return NULL; } // terminate buffer String[BufferSize] = '\0'; // search for newline for(Index=0; Index<BufferSize; Index++) { CHAR8 c = String[Index]; if(c=='\n' || c=='\r') { String[Index+1] = '\0'; // seek back file position Status = FileHandleSetPosition(File, Position+Index+1); if (EFI_ERROR(Status)) return NULL; break; } } return String; }
/** 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); }
/** 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; }