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

📄 dir.c

📁 ST5518机顶盒系统文件系统源代码!绝对超值!
💻 C
字号:
/******************************************************************************    File Name   : dir.c    Description : Directory management functions******************************************************************************//* Includes ---------------------------------------------------------------- */#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <string.h>#include <assert.h>#include "sttbx.h"#include "dir.h"#include "hal.h"#include "rwbuffer.h"#include "backup.h"/* Private Types ----------------------------------------------------------- */typedef struct{    int Modified;    int TableSize;}stavfs_DirMetaData_t;typedef struct{    stavfs_DirMetaData_t Meta;                /* Cluster data - Form here on the structure must be the size of one cluster*/        /*U64 LBA; This is burried in stavfs_DirEntry_t now */    stavfs_DirEntry_t DirTable[1];}stavfs_DirCache_t;/* Private Constants ------------------------------------------------------- *//* Private Variables ------------------------------------------------------- *//* Private Macros ---------------------------------------------------------- *//* Private Function Prototypes --------------------------------------------- *//* Functions --------------------------------------------------------------- *//******************************************************************************Function Name : stavfs_InitRootDir  Description : Open and formated root directory for the file system.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_InitRootDir (stavfs_Device_t *Device_p){    ST_ErrorCode_t Error = ST_NO_ERROR;    int ClusterSize;        assert(Device_p != NULL);        if (Device_p->RootDir == NULL)    {        /* Not currently Open */                ClusterSize = Device_p->ClusterSize*DISK_SECTOR_SIZE;        Device_p->RootDir = memory_allocate(Device_p->MemoryPartition, sizeof(stavfs_DirMetaData_t) + ClusterSize);         if (Device_p->RootDir == NULL)        {            STTBX_Print (("Out of memory.\n"));            Error = ST_ERROR_NO_MEMORY;        }        else        {            stavfs_DirCache_t *Cache = (stavfs_DirCache_t*)Device_p->RootDir;                Cache->Meta.Modified  = TRUE;            Cache->Meta.TableSize = ClusterSize/sizeof(stavfs_DirEntry_t);            Error = stavfs_FormatRootDir (Device_p);        }    }        return (Error);}/******************************************************************************Function Name : stavfs_OpenRootDir  Description : Open the root directory for the file system.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_OpenRootDir (stavfs_Device_t *Device_p){    ST_ErrorCode_t Error = ST_NO_ERROR;    int ClusterSize;        assert(Device_p != NULL);        if (Device_p->RootDir == NULL)    {        /* Not currently Open */                ClusterSize = Device_p->ClusterSize*DISK_SECTOR_SIZE;        Device_p->RootDir = memory_allocate(Device_p->MemoryPartition, sizeof(stavfs_DirMetaData_t) + ClusterSize);         if (Device_p->RootDir == NULL)        {            STTBX_Print (("Out of memory.\n"));            Error = ST_ERROR_NO_MEMORY;        }        else        {            /* Read the root directory */             stavfs_DirCache_t *Cache = (stavfs_DirCache_t*)Device_p->RootDir;             Cache->Meta.Modified  = FALSE;            Cache->Meta.TableSize = ClusterSize/sizeof(stavfs_DirEntry_t);            /* Read the Directory */             if (ST_NO_ERROR != (Error = stavfs_BOWClusterRead(Device_p, &(Device_p->RootDirLBA), (U8*)(Cache->DirTable))))            {                /* Failed to read the directory */                STTBX_Print (("Failed to read the directory.\n"));                stavfs_CloseRootDir (Device_p);            }        }    }        return (Error);}/******************************************************************************Function Name : stavfs_CloseRootDir  Description : Close the root directory for the file system.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_CloseRootDir (stavfs_Device_t *Device_p){    ST_ErrorCode_t Error = ST_NO_ERROR;        if ((Device_p != NULL) && (Device_p->RootDir != NULL))    {        Error = stavfs_FlushDir (Device_p, NULL);            /* Free up any allocated space */                memory_deallocate(Device_p->MemoryPartition, Device_p->RootDir);        Device_p->RootDir = NULL;    }        return (Error);}/******************************************************************************Function Name : stavfs_FormatRootDir  Description : Format the root directory.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_FormatRootDir (stavfs_Device_t *Device_p){    ST_ErrorCode_t     Error = ST_NO_ERROR;    stavfs_DirCache_t *Cache = NULL;    int i;        assert (Device_p          != NULL);    assert (Device_p->RootDir != NULL);        Cache = (stavfs_DirCache_t*)Device_p->RootDir;        for (i = 0; (i < Cache->Meta.TableSize); i++)    {        Cache->DirTable[i].Flags = FILE_FLAG_ENTRY_UNUSED;    }        return (Error);}/******************************************************************************Function Name : stavfs_FlushDir  Description : Write the root directory back to disk.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_FlushDir (stavfs_Device_t *Device_p, stavfs_DirEntry_t *Dir_p){    ST_ErrorCode_t     Error = ST_NO_ERROR;    stavfs_DirCache_t *Cache = NULL;        assert (Dir_p             == NULL);  /* Must be root dir */    assert (Device_p          != NULL);    assert (Device_p->RootDir != NULL);        Cache = (stavfs_DirCache_t*)Device_p->RootDir;        if (Cache->Meta.Modified)    {        /* Flush any related file buffers */                stavfs_FlushRWCache(Device_p);                /* Write the data to disk */                Error = stavfs_BOWClusterWrite(Device_p, &(Device_p->RootDirLBA), (U8*)(Cache->DirTable));                if (Error == ST_NO_ERROR)        {            Cache->Meta.Modified = FALSE;        }    }        return (Error);}/******************************************************************************Function Name : stavfs_ModifyDirEntry  Description : Flag the directory entry as modified   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_ModifyDirEntry(stavfs_Device_t *Device_p, stavfs_DirEntry_t *DirEntry_p){    ST_ErrorCode_t     Error = ST_NO_ERROR;    stavfs_DirCache_t *Cache = NULL;        assert (Device_p          != NULL);    assert (DirEntry_p        != NULL);    assert (Device_p->RootDir != NULL);        Cache = (stavfs_DirCache_t*)Device_p->RootDir;        Cache->Meta.Modified = TRUE;        return (Error);}/******************************************************************************Function Name : stavfs_FindFileEntry  Description : Find a directory entry (in the root directory) with the given name.                Future implementations may copy the entry into cache with a                reference count. So stavfs_ReleaseFileEntry() must be used to                release an entry when it is no longer in use.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_FindFileEntry (stavfs_Device_t *Device_p, stavfs_DirEntry_t *Dir_p, char *Name, stavfs_DirEntry_t **Entry_p){    ST_ErrorCode_t     Error = ST_NO_ERROR;    stavfs_DirCache_t *Cache = NULL;        int i;        assert (Dir_p             == NULL);  /* Currently must be the root directory */    assert (Name              != NULL);    assert (Entry_p           != NULL);    assert (Device_p          != NULL);    assert (Device_p->RootDir != NULL);        Cache = (stavfs_DirCache_t*)Device_p->RootDir;        /* Scan looking for the file */        *Entry_p = NULL;    for (i = 0; (i < Cache->Meta.TableSize) && (*Entry_p == NULL); i++)    {        if ( (Cache->DirTable[i].Flags & FILE_FLAG_ENTRY_USED)    &&            !(Cache->DirTable[i].Flags & FILE_FLAG_BEING_DELETED) &&             (0 == strncmp(Name, (char*)Cache->DirTable[i].Name, sizeof(Cache->DirTable[i].Name))))        {            *Entry_p = Cache->DirTable+i;        }    }        return (Error);}/******************************************************************************Function Name : stavfs_NextEntry  Description : Get the next directory entry. If the current entry is a NULL pointer                then find the first directory entry. If there are no more entries                then return a NULL pointer.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_NextEntry (stavfs_Device_t *Device_p, stavfs_DirEntry_t *Dir_p, stavfs_DirEntry_t **Entry_p){    ST_ErrorCode_t     Error     = ST_NO_ERROR;    stavfs_DirCache_t *Cache     = NULL;    stavfs_DirEntry_t *ThisEntry = NULL;        assert (Dir_p             == NULL);  /* Currently must be the root directory */    assert (Entry_p           != NULL);    assert (Device_p          != NULL);    assert (Device_p->RootDir != NULL);        Cache = (stavfs_DirCache_t*)Device_p->RootDir;        /* Set the start conditions */        ThisEntry = *Entry_p;    *Entry_p  = NULL;        if (ThisEntry == NULL)    {        /* Start at the begining */                ThisEntry = Cache->DirTable;    }    else    {        /* Try the next entry */                ThisEntry++;    }        /* Scan looking for the next used entry */        for (;(ThisEntry < Cache->DirTable+Cache->Meta.TableSize) &&          (*Entry_p == NULL); ThisEntry++)    {        if (ThisEntry->Flags & FILE_FLAG_ENTRY_USED)        {            *Entry_p = ThisEntry;        }    }        return (Error);}/******************************************************************************Function Name : stavfs_FindFreeEntry  Description : Find an unused directory entry (in the root directory).                Future implementations may copy the entry into cache with a                reference count. So stavfs_ReleaseFileEntry() must be used to                release an entry when it is no longer in use.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_FindFreeEntry (stavfs_Device_t *Device_p, stavfs_DirEntry_t *Dir_p, stavfs_DirEntry_t **Entry_p){    ST_ErrorCode_t     Error = ST_NO_ERROR;    stavfs_DirCache_t *Cache = NULL;        int i;        assert (Dir_p             == NULL);  /* Currently must be the root directory */    assert (Entry_p           != NULL);    assert (Device_p          != NULL);    assert (Device_p->RootDir != NULL);        Cache = (stavfs_DirCache_t*)Device_p->RootDir;        /* Scan looking for the file */        *Entry_p = NULL;    for (i = 0; (i < Cache->Meta.TableSize) && (*Entry_p == NULL); i++)    {        if (!(Cache->DirTable[i].Flags & FILE_FLAG_ENTRY_USED))        {            *Entry_p = Cache->DirTable+i;        }    }        return (Error);}/******************************************************************************Function Name : stavfs_ReleaseFileEntry  Description : Release a file entry (posibly held in cache).                Future implementations may copy the entry into cache with a                reference count. So stavfs_ReleaseFileEntry() must be used to                release an entry when it is no longer in use.   Parameters :******************************************************************************/ST_ErrorCode_t stavfs_ReleaseFileEntry (stavfs_Device_t *Device_p, stavfs_DirEntry_t *Entry_p){    ST_ErrorCode_t Error = ST_NO_ERROR;        assert (Entry_p           != NULL);    assert (Device_p          != NULL);    assert (Device_p->RootDir != NULL);        /* There is currently no reference count - so do nothing */        return (Error);}

⌨️ 快捷键说明

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