EFI_STATUS FileSetPosition ( IN EFI_FILE *File, IN UINT64 Position ) { SEMIHOST_FCB *Fcb = NULL; UINTN Length; EFI_STATUS Status; Fcb = SEMIHOST_FCB_FROM_THIS(File); if (!Fcb->IsRoot) { Status = SemihostFileLength (Fcb->SemihostHandle, &Length); if (!EFI_ERROR(Status) && (Length < Position)) { Position = Length; } Status = SemihostFileSeek (Fcb->SemihostHandle, (UINT32)Position); if (!EFI_ERROR(Status)) { Fcb->Position = Position; } } else { Fcb->Position = Position; Status = EFI_SUCCESS; } return Status; }
/** Worker function that extends the size of an open file. The extension is filled with zeros. @param[in] Fcb Internal description of the opened file @param[in] Size The number of bytes, the file has to be extended. @retval EFI_SUCCESS The file was extended. @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed. **/ STATIC EFI_STATUS ExtendFile ( IN SEMIHOST_FCB *Fcb, IN UINTN Size ) { RETURN_STATUS Return; UINTN Remaining; CHAR8 WriteBuffer[128]; UINTN WriteNb; UINTN WriteSize; Return = SemihostFileSeek (Fcb->SemihostHandle, Fcb->Info.FileSize); if (RETURN_ERROR (Return)) { return EFI_DEVICE_ERROR; } Remaining = Size; SetMem (WriteBuffer, 0, sizeof(WriteBuffer)); while (Remaining > 0) { WriteNb = MIN (Remaining, sizeof(WriteBuffer)); WriteSize = WriteNb; Return = SemihostFileWrite (Fcb->SemihostHandle, &WriteSize, WriteBuffer); if (RETURN_ERROR (Return)) { return EFI_DEVICE_ERROR; } Remaining -= WriteNb; } return EFI_SUCCESS; }
/** Set a file's current position. @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that is the file handle to set the requested position on. @param[in] Position The byte position from the start of the file to set. @retval EFI_SUCCESS The position was set. @retval EFI_DEVICE_ERROR The semi-hosting positionning operation failed. @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open directories. @retval EFI_INVALID_PARAMETER The parameter "This" is NULL. **/ EFI_STATUS FileSetPosition ( IN EFI_FILE *This, IN UINT64 Position ) { SEMIHOST_FCB *Fcb; RETURN_STATUS Return; if (This == NULL) { return EFI_INVALID_PARAMETER; } Fcb = SEMIHOST_FCB_FROM_THIS (This); if (Fcb->IsRoot) { if (Position != 0) { return EFI_UNSUPPORTED; } } else { // // UEFI Spec section 12.5: // "Seeking to position 0xFFFFFFFFFFFFFFFF causes the current position to // be set to the end of the file." // if (Position == 0xFFFFFFFFFFFFFFFF) { Position = Fcb->Info.FileSize; } Return = SemihostFileSeek (Fcb->SemihostHandle, MIN (Position, Fcb->Info.FileSize)); if (RETURN_ERROR (Return)) { return EFI_DEVICE_ERROR; } } Fcb->Position = Position; return EFI_SUCCESS; }