📄 file.c
字号:
/****************************************************************************** File Name : file.c Description : File operations.******************************************************************************//* Includes ---------------------------------------------------------------- */#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <assert.h>#include <string.h>#include "stddefs.h"#include "file.h"#include "dir.h"#include "hal.h"#include "cat.h"#include "sttbx.h"#include "rwbuffer.h"#include "stavfs.h"#include "root.h"/* Private Types ----------------------------------------------------------- */typedef struct{ U64 PrevLBA; /* Prev block LBA (last cluster) */ U64 NextLBA; /* Next block LBA (first cluster) */ U64 BlockLBA; /* First LBA in Block */ U32 BlockOffset; /* Offset in file - in Cluster */ U32 BlockSize; /* Size of block - in Clusters */ U32 Offset; /* Offset in block - in bytes */ stavfs_RWBufferRef_t Buffer;}stavfs_FilePos_t;/* This structure contains all the open files */typedef struct stavfs_OpenFileHandle_s{ stavfs_Device_t *Device_p; /* Device of open handle or NULL for closed handle */ stavfs_DirEntry_t *DirEntry_p; /* Reference to the cached directory entry */ STAVFS_OpenMode_t Mode; /* Mode of the handle i.e. read/write */ U32 LoopCount; /* A Count of the times the cyclic file has looped */ stavfs_FilePos_t Read; stavfs_FilePos_t Write;}stavfs_OpenFileHandle_t;/* Private Constants ------------------------------------------------------- *//* Private Variables ------------------------------------------------------- */static stavfs_OpenFileHandle_t FileHandleTable[MAX_OPEN_FILES];static U64 const NullLBA = {NULL_LBA, NULL_LBA};static U64 const InvalidLBA = {INVALID_LBA, INVALID_LBA};/* Private Macros ---------------------------------------------------------- *//* Private Function Prototypes --------------------------------------------- */static ST_ErrorCode_t stavfs_DeleteFile(stavfs_Device_t *Device_p, char *FullPathName);static ST_ErrorCode_t stavfs_OpenFile (stavfs_Device_t *Device_p, char *FullPathName, STAVFS_OpenMode_t Mode, U64 MaxSizeOfTSFile, int *FileId);static ST_ErrorCode_t stavfs_CloseFile (int handle);static ST_ErrorCode_t stavfs_WriteFile (int handle, U32 Size, char const *Address, U32 *BytesWritten);static ST_ErrorCode_t stavfs_ReadFile (int handle, U32 Size, char *Address, U32 *BytesRead);static ST_ErrorCode_t stavfs_GetFilePosition (stavfs_OpenFileHandle_t *FileHandle_p, BOOL WritePosition, U64 * Position_p);static ST_ErrorCode_t stavfs_AllocDiskSpace(stavfs_Device_t *Device_p, stavfs_DirEntry_t *DirEntry_p, U64 Size);/* File Position Functions */static ST_ErrorCode_t stavfs_InitPos (stavfs_FilePos_t *Pos_p);static ST_ErrorCode_t stavfs_MoreDiskSpace(stavfs_OpenFileHandle_t *FileHandle_p, stavfs_FilePos_t *Pos_p, BOOL DoWrite, U32 MoreBytes);static ST_ErrorCode_t stavfs_SetPos (stavfs_Device_t *Device_p, stavfs_DirEntry_t *DirEntry_p, U64 const *Offset, stavfs_FilePos_t *Pos_p);static ST_ErrorCode_t stavfs_GetPos (stavfs_Device_t *Device_p, stavfs_FilePos_t *Pos_p, U64 *Index_p);static ST_ErrorCode_t stavfs_NextFileBlock(stavfs_Device_t *Device_p, stavfs_FilePos_t *Pos_p);static ST_ErrorCode_t stavfs_PrevFileBlock(stavfs_Device_t *Device_p, stavfs_FilePos_t *Pos_p);ST_ErrorCode_t stavfs_SeekRegularFile (STAVFS_FileHandle_t Handle, S64 Position, STAVFS_TypePosition_t Mode, BOOL WritePosition);ST_ErrorCode_t stavfs_SeekCyclicFile (STAVFS_FileHandle_t Handle, S64 Position, STAVFS_TypePosition_t Mode, BOOL WritePosition);/* Functions --------------------------------------------------------------- *//******************************************************************************Function Name : Description : Parameters :******************************************************************************/ST_ErrorCode_t STAVFS_CloseFile (STAVFS_FileHandle_t Handle){ ST_ErrorCode_t Error = ST_NO_ERROR; int FileId = (int)Handle; stavfs_Device_t *Device_p = FileHandleTable[FileId].Device_p; /* Check for a valid file Id */ if ((FileId >= TABLE_LEN(FileHandleTable)) || (0 > FileId)) { STTBX_Print (("Invalid Id\n")); Error = ST_ERROR_INVALID_HANDLE; } else if (ST_NO_ERROR != (Error = stavfs_ValidateDevice(Device_p))) { STTBX_Print (("Invalid Device\n")); Error = ST_ERROR_INVALID_HANDLE; } else { /* Lock the driver */ semaphore_wait(&(Device_p->DeviceLock)); Error = stavfs_CloseFile(FileId); /* Release the driver */ semaphore_signal(&(Device_p->DeviceLock)); } return (Error);}/******************************************************************************Function Name : STAVFS_DeleteFile Description : Deletes a file (must be closed) Parameters : device handle, current directory handle, path name******************************************************************************/ST_ErrorCode_t STAVFS_DeleteFile (STAVFS_Handle_t Handle, STAVFS_FileHandle_t CurrentDirectory, char * FullPathName){ ST_ErrorCode_t Error = ST_NO_ERROR; stavfs_Device_t *Device_p = (stavfs_Device_t*)Handle; /* Check that the driver is initialised */ if (ST_NO_ERROR != (Error = stavfs_ValidateDevice(Device_p))) { STTBX_Print (("Invalid Device\n")); Error = ST_ERROR_INVALID_HANDLE; } else if (STAVFS_NULL_FILE_HANDLE != CurrentDirectory) { /* We don't support directories yet */ STTBX_Print (("Directories not yet supported\n")); Error = ST_ERROR_FEATURE_NOT_SUPPORTED; } else if (FullPathName == NULL) { STTBX_Print (("NULL path name\n")); Error = ST_ERROR_BAD_PARAMETER; } else { /* Lock the driver */ semaphore_wait(&(Device_p->DeviceLock)); /* Delete the file */ Error = stavfs_DeleteFile (Device_p, FullPathName); /* Release the driver */ semaphore_signal(&(Device_p->DeviceLock)); } return (Error);}/******************************************************************************Function Name : STAVFS_GetFilePosition Description : Return the current position within the file relative to the start of file. Parameters :******************************************************************************/ST_ErrorCode_t STAVFS_GetFilePosition (STAVFS_FileHandle_t Handle, BOOL WritePosition, U64 * Position_p){ ST_ErrorCode_t Error = ST_NO_ERROR; int FileId = (int)Handle; stavfs_OpenFileHandle_t *FileHandle_p = FileHandleTable +FileId; stavfs_Device_t *Device_p = FileHandle_p->Device_p; /* Check for a valid file Id */ if (Position_p == NULL) { Error = ST_ERROR_BAD_PARAMETER; } else if ((FileId >= TABLE_LEN(FileHandleTable)) || (0 > FileId)) { Error = ST_ERROR_INVALID_HANDLE; } else if (ST_NO_ERROR != (Error = stavfs_ValidateDevice(Device_p))) { STTBX_Print (("Invalid Device\n")); Error = ST_ERROR_INVALID_HANDLE; } else { /* Lock the driver */ semaphore_wait(&(Device_p->DeviceLock)); /* Check for valid handle */ if (WritePosition) { /* Check we have a write poition */ if (!(FileHandle_p->Mode & STAVFS_WRITE_MODE)) { Error = ST_ERROR_BAD_PARAMETER; } } else { /* Check we have a read poition */ if (!(FileHandle_p->Mode & STAVFS_READ_MODE)) { Error = ST_ERROR_BAD_PARAMETER; } } if (Error == ST_NO_ERROR) { Error = stavfs_GetFilePosition(FileHandle_p, WritePosition, Position_p); } /* Release the driver */ semaphore_signal(&(Device_p->DeviceLock)); } return (Error);}/******************************************************************************Function Name : STAVFS_OpenFile Description : Parameters :******************************************************************************/ST_ErrorCode_t STAVFS_OpenFile(STAVFS_Handle_t Handle, STAVFS_FileHandle_t CurrentDirectory, char * PathName, STAVFS_OpenMode_t Mode, U64 Size, STAVFS_FileHandle_t * FHandle){ ST_ErrorCode_t Error = ST_NO_ERROR; stavfs_Device_t *Device_p = (stavfs_Device_t*)Handle; int FileId = (int)STAVFS_NULL_FILE_HANDLE; /* Default - invalid id */ if (FHandle == NULL) { STTBX_Print (("NULL handle destination\n")); Error = ST_ERROR_BAD_PARAMETER; /* in all other failure cases, we write STAVFS_NULL_FILE_HANDLE below */ } else if ((PathName == NULL) || (PathName[0] == '\0') || (MAX_FILE_NAME_LEN <= strlen(PathName))) { STTBX_Print (("Bad file name\n")); Error = ST_ERROR_BAD_PARAMETER; /* in all other failure cases, we write STAVFS_NULL_FILE_HANDLE below */ } /* Check that the driver is initialised */ else if (ST_NO_ERROR != (Error = stavfs_ValidateDevice(Device_p))) { STTBX_Print (("Invalid Device\n")); Error = ST_ERROR_INVALID_HANDLE; } else if (CurrentDirectory != STAVFS_NULL_FILE_HANDLE) { STTBX_Print (("Directories are not supported yet\n")); Error = ST_ERROR_FEATURE_NOT_SUPPORTED; } else if ((Mode & STAVFS_DIRECTORY_FILE) && (Mode & (STAVFS_STREAM_FILE | STAVFS_CYCLIC_FILE | STAVFS_WRITE_MODE))) { STTBX_Print (("DIRECTORY specified with STREAM, CYCLIC, or WRITE\n")); Error = ST_ERROR_BAD_PARAMETER; } else if (Mode & (STAVFS_DIRECTORY_FILE | STAVFS_PATH_MODE)) { STTBX_Print (("Directories are not supported yet\n")); Error = ST_ERROR_FEATURE_NOT_SUPPORTED; } else if (NULL != strpbrk(PathName, RESERVED_FILE_CHAR)) { /* Do not permit path separators */ Error = ST_ERROR_BAD_PARAMETER; } else { /* Lock the driver */ semaphore_wait(&(Device_p->DeviceLock)); Error = stavfs_OpenFile (Device_p, PathName, Mode, Size, &FileId); /* Release the driver */ semaphore_signal(&(Device_p->DeviceLock)); } *FHandle = (STAVFS_FileHandle_t)FileId; return (Error);}/******************************************************************************Function Name : STAVFS_ReadFile Description : Parameters :******************************************************************************/ST_ErrorCode_t STAVFS_ReadFile (STAVFS_FileHandle_t Handle, void *Address, U32 Size, U32 * ReadData){ ST_ErrorCode_t Error = ST_NO_ERROR; int FileId = (int)Handle; stavfs_Device_t *Device_p = FileHandleTable[FileId].Device_p; /* Check for a valid file Id */ if (Address == NULL) { Error = ST_ERROR_BAD_PARAMETER; } else if ((FileId >= TABLE_LEN(FileHandleTable)) || (0 > FileId)) { Error = ST_ERROR_INVALID_HANDLE; } else if (ST_NO_ERROR != (Error = stavfs_ValidateDevice(Device_p))) { STTBX_Print (("Invalid Device\n")); Error = ST_ERROR_INVALID_HANDLE; } else if (!(FileHandleTable[FileId].Mode & STAVFS_READ_MODE)) { /* Make sure file handles valid */ STTBX_Print(("Not a valid file")); Error = STAVFS_ERROR_NOT_READ_HANDLE; } else { /* Lock the driver */ semaphore_wait(&(Device_p->DeviceLock)); Error = stavfs_ReadFile(FileId, Size, Address, ReadData); /* Release the driver */ semaphore_signal(&(Device_p->DeviceLock)); } return (Error);}/******************************************************************************Function Name : STAVFS_SeekFile Description : Parameters :******************************************************************************/ST_ErrorCode_t STAVFS_SeekFile (STAVFS_FileHandle_t Handle, S64 Position, STAVFS_TypePosition_t Mode, BOOL WritePosition){ ST_ErrorCode_t Error = ST_NO_ERROR; int FileId = (int)Handle; stavfs_OpenFileHandle_t *FileHandle_p = FileHandleTable+FileId; stavfs_Device_t *Device_p = FileHandle_p->Device_p; /* Check for a valid file Id */ if ((FileId >= TABLE_LEN(FileHandleTable)) || (0 > FileId)) { Error = ST_ERROR_INVALID_HANDLE; } else if (ST_NO_ERROR != (Error = stavfs_ValidateDevice(Device_p))) { STTBX_Print (("Invalid Device\n")); Error = ST_ERROR_INVALID_HANDLE; } else { /* Lock the driver */ semaphore_wait(&(Device_p->DeviceLock)); /* Check for valid handle */ if (WritePosition) { /* Check we have a write poition */ if (!(FileHandle_p->Mode & STAVFS_WRITE_MODE)) { Error = ST_ERROR_BAD_PARAMETER; } } else { /* Check we have a read poition */ if (!(FileHandle_p->Mode & STAVFS_READ_MODE)) { Error = ST_ERROR_BAD_PARAMETER; } } if (Error == ST_NO_ERROR) { if (FileHandle_p->DirEntry_p->Flags & FILE_FLAG_CYCLIC_FILE) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -