📄 file.c
字号:
/* Cyclic file */ Error = stavfs_SeekCyclicFile (Handle, Position, Mode, WritePosition); } else { /* Regular file */ Error = stavfs_SeekRegularFile (Handle, Position, Mode, WritePosition); } } /* Release the driver */ semaphore_signal(&(Device_p->DeviceLock)); } return (Error);}/******************************************************************************Function Name : STAVFS_WriteFile Description : Parameters :******************************************************************************/ST_ErrorCode_t STAVFS_WriteFile (STAVFS_FileHandle_t Handle, void const *Address, U32 Size, U32 * SizeWritten){ ST_ErrorCode_t Error = ST_NO_ERROR; int FileId = (int)Handle; stavfs_Device_t *Device_p = FileHandleTable[FileId].Device_p; stavfs_DirEntry_t *DirEntry_p = FileHandleTable[FileId].DirEntry_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_WRITE_MODE)) { /* Make sure file handles valid */ STTBX_Print(("Not a valid file")); Error = STAVFS_ERROR_NOT_WRITE_HANDLE; } else if ((DirEntry_p == NULL) || (DirEntry_p->Flags & FILE_FLAG_DIRECTORY)) { /* Can't write to a directory */ Error = ST_ERROR_INVALID_HANDLE; } else { /* Lock the driver */ semaphore_wait(&(Device_p->DeviceLock)); Error = stavfs_WriteFile(FileId, Size, Address, SizeWritten); /* Release the driver */ semaphore_signal(&(Device_p->DeviceLock)); } return (Error);}/******************************************************************************Function Name : STAVFS_SyncFile Description : Flush any cached data to disk. Parameters :******************************************************************************/ST_ErrorCode_t STAVFS_SyncFile (STAVFS_FileHandle_t Handle){ ST_ErrorCode_t Error = ST_NO_ERROR; int FileId = (int)Handle; stavfs_Device_t *Device_p = FileHandleTable[FileId].Device_p; 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)); /* Flush the directory data (this will flush any file buffers). We don't need to flush the MCAT, since that can be regenerated from the LCATs by fsck for a file that is marked open */ Error = stavfs_FlushDir(Device_p, NULL); /* Release the driver */ semaphore_signal(&(Device_p->DeviceLock)); } return (Error);}/******************************************************************************Function Name : stavfs_InitFileTable Description : Initialise the file table. Parameters :******************************************************************************/void stavfs_InitFileTable (){ int i; for (i = 0; (i < MAX_OPEN_FILES); i++) { FileHandleTable[i].Device_p = CLOSED_FILE; }}/******************************************************************************Function Name : stavfs_CloseAllFilesOnDevice Description : Close all files on the device. Parameters :******************************************************************************/void stavfs_CloseAllFilesOnDevice (stavfs_Device_t *Device_p){ int i; /* Find all open file handles and close them */ for (i = 0; (i < MAX_OPEN_FILES); i++) { if (FileHandleTable[i].Device_p == Device_p) { stavfs_CloseFile (i); } }}/******************************************************************************Function Name : stavfs_CountOpenFilesOnDevice Description : Count all open file handles on device Parameters :******************************************************************************/int stavfs_CountOpenFilesOnDevice (stavfs_Device_t *Device_p){ int i; int Count = 0; for (i = 0; (i < MAX_OPEN_FILES); i++) { if (FileHandleTable[i].Device_p == Device_p) { Count++; } } return (Count);}/******************************************************************************Function Name : stavfs_OpenFile Description : Open the specified file creating the file if needed. Parameters :******************************************************************************/static ST_ErrorCode_t stavfs_OpenFile (stavfs_Device_t *Device_p, char *Name, STAVFS_OpenMode_t Mode, U64 SizeOfFile, int *FileId){ ST_ErrorCode_t Error = ST_NO_ERROR; stavfs_DirEntry_t *DirEntry_p = NULL; int Handle; int i; assert (Device_p != NULL); assert (Name != NULL); assert (FileId != NULL); /* Get a free handle */ Handle = *FileId; for (i = 0; (Handle < 0) && (i < MAX_OPEN_FILES); i++) { if (FileHandleTable[i].Device_p == CLOSED_FILE) /* If released handle found... */ { Handle = i; } } if (Handle < 0) /* If no released handles then the max num of open files has been met */ { Error = ST_ERROR_NO_FREE_HANDLES; } /* Find the directory entry */ if (Error == ST_NO_ERROR) { if (0 == strcmp(THIS_DIRECTORY, Name)) { /* Open this directory */ /* Can't open a directory yet */ Error = ST_ERROR_FEATURE_NOT_SUPPORTED; } else if (0 == strcmp(PARENT_DIRECTORY, Name)) { /* Open the parent directory */ /* Can't open a directory yet */ Error = ST_ERROR_FEATURE_NOT_SUPPORTED; } else { Error = stavfs_FindFileEntry(Device_p, NULL, Name, &DirEntry_p); } if ((Error == ST_NO_ERROR) && (DirEntry_p == NULL)) { /* The file does not exist - Create it */ if (Mode & STAVFS_WRITE_MODE) { /* Create the entry */ if (Mode & STAVFS_DIRECTORY_FILE) { /* Can't create a directory yet */ Error = ST_ERROR_FEATURE_NOT_SUPPORTED; } else if ((Mode & STAVFS_CYCLIC_FILE) && (SizeOfFile.MSW != 0)) { /* We cannot handle cyclic files this size */ Error = ST_ERROR_BAD_PARAMETER; } else { /* Create the file */ Error = stavfs_FindFreeEntry(Device_p, NULL, &DirEntry_p); if (DirEntry_p == NULL) { /* Directory is full */ Error = ST_ERROR_NO_FREE_HANDLES; } else { /* Fill in the entry */ stavfs_ModifyDirEntry(Device_p, DirEntry_p); INT_I64_SetValue(0, 0, DirEntry_p->AllocSize); INT_I64_SetValue(0, 0, DirEntry_p->Size.File); strncpy((char*)DirEntry_p->Name, Name, MAX_FILE_NAME_LEN); DirEntry_p->Flags = FILE_FLAG_ENTRY_USED | FILE_FLAG_OPEN_FOR_WRITE; DirEntry_p->Unused = 0; DirEntry_p->StartLBA = NullLBA; DirEntry_p->EndLBA = NullLBA; if (Mode & STAVFS_CYCLIC_FILE) { DirEntry_p->Flags |= FILE_FLAG_CYCLIC_FILE; } if (Mode & STAVFS_STREAM_FILE) { DirEntry_p->Flags |= FILE_FLAG_STREAM_MODE; } /* Allocate disk space */ if (ST_NO_ERROR != (Error = stavfs_AllocDiskSpace(Device_p, DirEntry_p, SizeOfFile))) { /* Rewind - delete the file */ stavfs_DeleteFileEntry(Device_p, DirEntry_p); stavfs_FlushDir (Device_p, NULL); /* no need to flush MCAT since it was never flushed with space allocated */ } else { Error = stavfs_FlushDir(Device_p, NULL); } } } } else { /* No such file */ Error = STAVFS_ERROR_NO_SUCH_FILE; } } } /* Allocate a file handle */ if (DirEntry_p != NULL) { /* Check the cyclic file is not already open */ if (DirEntry_p->Flags & FILE_FLAG_CYCLIC_FILE) { for (i = 0; (i < MAX_OPEN_FILES) && (Error == ST_NO_ERROR); i++) { if ((FileHandleTable[i].DirEntry_p == DirEntry_p) && (FileHandleTable[i].Device_p == Device_p)) /* If released handle found... */ { Error = STAVFS_ERROR_FILE_IN_USE; } } } /* Flag the file open for write */ if ( (Error == ST_NO_ERROR) && (Mode & STAVFS_WRITE_MODE) && !(DirEntry_p->Flags & FILE_FLAG_OPEN_FOR_WRITE)) { DirEntry_p->Flags |= FILE_FLAG_OPEN_FOR_WRITE; stavfs_ModifyDirEntry(Device_p, DirEntry_p); Error = stavfs_FlushDir(Device_p, NULL); } /* Allocate the file handle */ if (Error == ST_NO_ERROR) { stavfs_OpenFileHandle_t *FileHandle_p = FileHandleTable+Handle; U64 Start = {0,0}; U64 End = {0,0}; /* Allocate the file handle */ FileHandle_p->Device_p = Device_p; FileHandle_p->DirEntry_p = DirEntry_p; FileHandle_p->Mode = Mode; FileHandle_p->LoopCount = 0; stavfs_InitPos(&(FileHandle_p->Read)); stavfs_InitPos(&(FileHandle_p->Write)); /* Set up the file pointers depending on what mode of openning is used */ if (DirEntry_p->Flags & FILE_FLAG_CYCLIC_FILE) { /* Reset to the start */ DirEntry_p->Size.Cyclic.LoopCount = 0; DirEntry_p->Size.Cyclic.TopOffset = 0; FileHandle_p->LoopCount = 0; stavfs_SetPos(Device_p, DirEntry_p, &Start, &(FileHandle_p->Read)); stavfs_SetPos(Device_p, DirEntry_p, &Start, &(FileHandle_p->Write)); } else { End = DirEntry_p->Size.File; /* Set read to the start and write to the end */ stavfs_SetPos(Device_p, DirEntry_p, &Start, &(FileHandle_p->Read)); stavfs_SetPos(Device_p, DirEntry_p, &End, &(FileHandle_p->Write)); } /* Return the assigned file id */ *FileId = Handle; } /* Clean up on error */ if (Error != ST_NO_ERROR) { /* Release the directory refrence */ stavfs_ReleaseFileEntry (Device_p, DirEntry_p); } } return (Error);}/******************************************************************************Function Name : stavfs_CloseFile Description : Closes the file on the HDD...updates the directory with the size of the closed file Parameters :******************************************************************************/static ST_ErrorCode_t stavfs_CloseFile (int Handle){ ST_ErrorCode_t Tmp = ST_NO_ERROR; ST_ErrorCode_t Error = ST_NO_ERROR; if (FileHandleTable[Handle].Device_p != CLOSED_FILE) { stavfs_Device_t *Device_p = FileHandleTable[Handle].Device_p; stavfs_DirEntry_t *DirEntry_p = FileHandleTable[Handle].DirEntry_p; if (Tmp != ST_NO_ERROR) Error = Tmp; /* Free the R/W Buffers */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -