⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.c

📁 ST5518机顶盒系统文件系统源代码!绝对超值!
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (NULL != FileHandleTable[Handle].Read.Buffer)        {            Tmp = stavfs_DiscardRWBuffer(FileHandleTable[Handle].Device_p, &(FileHandleTable[Handle].Read.Buffer));             if (Tmp != ST_NO_ERROR) Error = Tmp;        }         if (NULL != FileHandleTable[Handle].Write.Buffer)        {            Tmp = stavfs_DiscardRWBuffer(FileHandleTable[Handle].Device_p, &(FileHandleTable[Handle].Write.Buffer));             if (Tmp != ST_NO_ERROR) Error = Tmp;        }        /* Mark the handle as closed */                FileHandleTable[Handle].Device_p    = CLOSED_FILE; /* Marking the handle released */        FileHandleTable[Handle].DirEntry_p  = NULL;                /* If the file is open for write */                if (DirEntry_p->Flags & FILE_FLAG_OPEN_FOR_WRITE)        {            /* Look for other handles that are open for write */                        for (Handle = 0; (Handle < MAX_OPEN_FILES); Handle++)            {                if ((FileHandleTable[Handle].Device_p   == Device_p)   &&                    (FileHandleTable[Handle].DirEntry_p == DirEntry_p) &&                    (FileHandleTable[Handle].Mode & STAVFS_WRITE_MODE))                {                    /* We have a write handle on this file */                    break;                }            }                        if (Handle >= MAX_OPEN_FILES)            {                /* Closing the final writing handle - must flush MCAT first                  incase we have allocated clusters */                                if (ST_NO_ERROR != (Tmp = stavfs_FlushCat(Device_p)))                {                    Error = Tmp;                }                DirEntry_p->Flags &= ~FILE_FLAG_OPEN_FOR_WRITE;                stavfs_ModifyDirEntry(Device_p, DirEntry_p);            }                                    /* Flush directory entry in all cases where we wrote data, like a sync */                        if (ST_NO_ERROR != (Tmp = stavfs_FlushDir(Device_p, NULL)))            {                Error = Tmp;            }        }         /* Free the directory reference */                if (DirEntry_p != NULL)        {            stavfs_ReleaseFileEntry (Device_p, DirEntry_p);        }    }     return (Error);}/******************************************************************************Function Name : stavfs_DeleteFile  Description : Delete the named file. The files must be closed to delete.   Parameters :******************************************************************************/static ST_ErrorCode_t stavfs_DeleteFile (stavfs_Device_t * Device_p, char *Name){    ST_ErrorCode_t     Error      = ST_NO_ERROR;    ST_ErrorCode_t     TmpErr     = ST_NO_ERROR;    stavfs_DirEntry_t *DirEntry_p = NULL;        int i;            assert (Device_p != NULL);    assert (Name     != NULL);        /* Find the directory entry */        Error = stavfs_FindFileEntry(Device_p, NULL, Name, &DirEntry_p);     if (DirEntry_p == NULL)    {        /* No such file */        STTBX_Print(("No such file\n"));        Error = STAVFS_ERROR_NO_SUCH_FILE;    }        /* Check to see if it is open */        for (i = 0; (Error == ST_NO_ERROR) && (i < MAX_OPEN_FILES); i++)    {        if ((FileHandleTable[i].DirEntry_p == DirEntry_p) &&            (FileHandleTable[i].Device_p   == Device_p))        {            STTBX_Print(("File in use\n"));            Error = STAVFS_ERROR_FILE_IN_USE;        }    }        /* Delete the file */        if (Error == ST_NO_ERROR)    {        Error = stavfs_DeleteFileEntry(Device_p, DirEntry_p);    }        /* Update the MCAT and then the directory (which finally marks the file as deleted) */        if (ST_NO_ERROR != (TmpErr = stavfs_FlushCat(Device_p)))    {        Error = TmpErr;    }    if (ST_NO_ERROR != (TmpErr = stavfs_FlushDir(Device_p, NULL)))    {        Error = TmpErr;    }        /* Release our temporary reference */        if (DirEntry_p != NULL)    {        /* Release the reference */        stavfs_ReleaseFileEntry (Device_p, DirEntry_p);    }        return (Error);}/******************************************************************************Function Name : stavfs_DeleteFileEntry  Description : Delete the file entry.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_DeleteFileEntry (stavfs_Device_t * Device_p, stavfs_DirEntry_t *DirEntry_p){    ST_ErrorCode_t     Error      = ST_NO_ERROR;        U64 EndLBA = NullLBA;            assert (Device_p   != NULL);    assert (DirEntry_p != NULL);        /* Mark the entry as being deleted */        DirEntry_p->Flags  |= FILE_FLAG_BEING_DELETED;    EndLBA              = DirEntry_p->EndLBA;    DirEntry_p->EndLBA  = DirEntry_p->StartLBA;        stavfs_ModifyDirEntry(Device_p, DirEntry_p);    Error = stavfs_FlushDir(Device_p, NULL);        /* Free up the allocated space */        if (Error == ST_NO_ERROR)    {        U32 FreeClusters =  stavfs_FreeClusterChain(Device_p, &EndLBA);                    /* Correct the allocated size */                stavfs_ModifyDirEntry(Device_p, DirEntry_p);        INT_I64_SubLit(DirEntry_p->AllocSize, FreeClusters, DirEntry_p->AllocSize);                if (INT_I64_AreNotEqual(EndLBA, NullLBA))        {            /* We have failed to release the chain */                        Error = ST_ERROR_BAD_PARAMETER;        }    }        /* Free up the directory entry */        if (Error == ST_NO_ERROR)    {        /* Mark the entry as unused */                DirEntry_p->Flags = FILE_FLAG_ENTRY_UNUSED;        stavfs_ModifyDirEntry(Device_p, DirEntry_p);    }    else    {        stavfs_RootSector_t RootSector;                /* Failed to delete properly - flag partition as bad */        if (ST_NO_ERROR != stavfs_ReadRootSector (Device_p, &RootSector))        {            STTBX_Print (("Error reading the root sector\n"));            Error = STAVFS_ERROR_UNREADABLE_DISK;        }        else        {            RootSector.StateFlags |= ROOT_PARTITION_FLAG_BAD;             if (ST_NO_ERROR != stavfs_WriteRootSector (Device_p, &RootSector))            {                STTBX_Print (("Error writing the root sector\n"));                Error = STAVFS_ERROR_UNWRITABLE_DISK;            }        }    }        return (Error);}/******************************************************************************Function Name : stavfs_WriteFile  Description :    Parameters :******************************************************************************/static ST_ErrorCode_t stavfs_WriteFile (int Handle, U32 Size, char const *Address, U32 *BytesWritten){    ST_ErrorCode_t     Error       =   ST_NO_ERROR;        stavfs_OpenFileHandle_t *FileHandle_p =   FileHandleTable+Handle;    stavfs_Device_t         *Device_p     =   FileHandle_p->Device_p;    stavfs_DirEntry_t       *DirEntry_p   =   FileHandle_p->DirEntry_p;    stavfs_FilePos_t        *Pos_p        = &(FileHandle_p->Write);        U32                Offset      = 0;    U32                WrittenData = 0;    U64                FilePos;    BOOL StreamFile = (DirEntry_p->Flags & FILE_FLAG_STREAM_MODE);    BOOL ReachedEOF = FALSE;        /* Check for file overflow */        assert(Device_p   != NULL);    assert(DirEntry_p != NULL);    assert(Pos_p      != NULL);        /* Check for file overflow */        if (DirEntry_p->Flags & FILE_FLAG_CYCLIC_FILE)    {        /* Cyclic file */                U32 TopDiff  = 0;        U64 TopPos;                U32 ReadDiff = 0;        U64 ReadPos;                /* Get the distance to the top of file */                stavfs_GetPos(Device_p, Pos_p, &TopPos);                if (TopPos.LSW > DirEntry_p->Size.Cyclic.TopOffset)        {            TopDiff = DirEntry_p->AllocSize.LSW * Device_p->ClusterSize * DISK_SECTOR_SIZE;                        TopDiff -= TopPos.LSW;            TopDiff += DirEntry_p->Size.Cyclic.TopOffset;        }        else        {            TopDiff  = DirEntry_p->Size.Cyclic.TopOffset;            TopDiff -= TopPos.LSW;        }                /* Get the distance from the top of file to the read position */                stavfs_GetPos(Device_p, &(FileHandle_p->Read), &ReadPos);                if (ReadPos.LSW <= DirEntry_p->Size.Cyclic.TopOffset)        {            ReadDiff = DirEntry_p->AllocSize.LSW * Device_p->ClusterSize * DISK_SECTOR_SIZE;                        ReadDiff -= DirEntry_p->Size.Cyclic.TopOffset;            ReadDiff += ReadPos.LSW;        }        else        {            ReadDiff  = ReadPos.LSW;            ReadDiff -= DirEntry_p->Size.Cyclic.TopOffset;        }                /* The vailable space is the sum of TopDiff and ReadDiff -1 */        /* But this may be > 2^32 and therefore wrap                */                /* Check that we have space for the read */                if ((ReadDiff <=  Size) &&            (TopDiff  <= (Size - ReadDiff)))        {            /* We have overflowed */                        ReachedEOF = TRUE;        }    }        /* If there is any data to write then write it to disk */        if ((Size > 0) && (Error == ST_NO_ERROR))    {        U32 WriteSectors = 0;        U32 ThisSize;        U64 LBA;                /* Write within the first sector */                if (0 != (Offset = Pos_p->Offset%DISK_SECTOR_SIZE))        {            /* Get the Sectors LBA */                        INT_I64_AddLit(Pos_p->BlockLBA, Pos_p->Offset/DISK_SECTOR_SIZE, LBA);                        /* Are we reading only part of the sector */                        ThisSize = DISK_SECTOR_SIZE - Pos_p->Offset%DISK_SECTOR_SIZE;                        if (Size < ThisSize)            {                ThisSize = Size;            }                        /* Read the data */                    if (ST_NO_ERROR != stavfs_SetRWBuffer(Device_p, &LBA, &(Pos_p->Buffer), StreamFile))            {                Error = STAVFS_ERROR_UNREADABLE_DISK;            }            else if (ST_NO_ERROR != stavfs_RWBufferWrite(Device_p, Pos_p->Buffer, Offset, ThisSize, Address, FALSE))            {                Error = STAVFS_ERROR_UNWRITABLE_DISK;            }            else            {                  Size          -= ThisSize;                Address       += ThisSize;                Pos_p->Offset += ThisSize;                WrittenData   += ThisSize;            }        }                /* Write Blocks */                WriteSectors = Size/DISK_SECTOR_SIZE;                if ((WriteSectors > 0) && (Error == ST_NO_ERROR))        {            /* We no longer need the buffer */                        if (ST_NO_ERROR != stavfs_DiscardRWBuffer(Device_p, &(Pos_p->Buffer)))            {                Error = STAVFS_ERROR_UNWRITABLE_DISK;            }        }                while ((WriteSectors > 0) && (Error == ST_NO_ERROR))        {            U32 ThisSectors;                        /* Ensure that we have space to write to */                        Error = stavfs_MoreDiskSpace(FileHandle_p, Pos_p, TRUE, Size);                       if (Error == ST_NO_ERROR)            {                /* Get the Sectors LBA */                 ThisSectors = Pos_p->BlockSize*Device_p->ClusterSize - Pos_p->Offset/DISK_SECTOR_SIZE;                INT_I64_AddLit(Pos_p->BlockLBA, Pos_p->Offset/DISK_SECTOR_SIZE, LBA);                 /* Are we reading only part of the sectors */                 if (WriteSectors < ThisSectors)                {                    ThisSectors = WriteSectors;                }                 /* Read the data */                 if (ST_NO_ERROR != stavfs_RWCacheBlockWrite (Device_p, &LBA, ThisSectors, Address, StreamFile))                {                    Error = STAVFS_ERROR_UNWRITABLE_DISK;                }                else                {                    WriteSectors  -= ThisSectors;                     Size          -= ThisSectors*DISK_SECTOR_SIZE;                    Address       += ThisSectors*DISK_SECTOR_SIZE;                    Pos_p->Offset += ThisSectors*DISK_SECTOR_SIZE;                    WrittenData   += ThisSectors*DISK_SECTOR_SIZE;                }            }        }                /* Read within the last sector */                if ((Size > 0) && (Error == ST_NO_ERROR))        {            BOOL EndOfFile = FALSE;                        if (!(DirEntry_p->Flags & FILE_FLAG_CYCLIC_FILE))            {                /* Only for regular files */                stavfs_GetPos(Device_p, Pos_p, &FilePos);                            EndOfFile = I64_IsLessThan(DirEntry_p->Size.File, FilePos);            }            

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -