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

📄 fatlite.c

📁 truefs for vxworks, make fs on flash or rom
💻 C
📖 第 1 页 / 共 5 页
字号:
                unsigned nextCluster;                if(file->currentCluster == 0)                    nextCluster = LE2(getDirEntry(file)->startingCluster);                else                    nextCluster = getFATentry(&vol,file->currentCluster);                if(nextCluster < 2 || nextCluster > vol.maxCluster)                    /* We have a bad file size, or the FAT is bad */                    return flInvalidFATchain;                file->currentCluster = nextCluster;            }        }    }    *offsetInSector = offsetInCluster & (SECTOR_SIZE - 1);    if(file->flags & FILE_IS_ROOT_DIR)        *sectorNo = vol.rootDirectorySectorNo +                    (SectorNo) (file->currentPosition >> SECTOR_SIZE_BITS);    else        *sectorNo = firstSectorOfCluster(&vol,file->currentCluster) +                    (SectorNo) (offsetInCluster >> SECTOR_SIZE_BITS);    return flOK;}/*----------------------------------------------------------------------*//*              c l o s e F i l e               *//*                                  *//* Closes an open file, records file size and dates in directory and    *//* releases file handle.                        *//*                                                                      *//* Parameters:                                                          *//*  vol     : Pointer identifying drive         *//*  file        : File to close.                        *//*                                                                      *//* Returns:                                                             *//*  FLStatus    : 0 on success, otherwise failed                *//*----------------------------------------------------------------------*/static FLStatus closeFile(File *file){    if((file->flags & FILE_MODIFIED) && !(file->flags & FILE_IS_ROOT_DIR))    {        DirectoryEntry *dirEntry;        checkStatus(getDirEntryForUpdate(file,&dirEntry));        dirEntry->attributes |= ATTR_ARCHIVE;        if(!(file->flags & FILE_IS_DIRECTORY))            toLE4(dirEntry->fileSize,file->fileSize);        setCurrentDateTime(dirEntry);    }    file->flags = 0;      /* no longer open */    return flOK;}#ifdef SUB_DIRECTORY/*----------------------------------------------------------------------*//*              e x t e n d D i r e c t o r y           *//*                                  *//* Extends a directory, writing empty entries and the mandatory '.' and *//* '..' entries.                            *//*                                                                      *//* Parameters:                                                          *//*  vol     : Pointer identifying drive         *//*  file        : Directory file to extend. On entry,           *//*            currentPosition == fileSize. On exit, fileSize*//*            is updated.                   *//*  ownerDir    : Cluster no. of owner directory        *//*                                                                      *//* Returns:                                                             *//*  FLStatus    : 0 on success, otherwise failed                *//*----------------------------------------------------------------------*/static FLStatus extendDirectory(File *file, unsigned ownerDir){    Volume vol = file->fileVol;    unsigned i;    SectorNo sectorOfDir;    unsigned offsetInSector;    /* Assuming the current position is at the end-of-file, this will     */    /* extend the directory.                        */    checkStatus(getSectorAndOffset(file,&sectorOfDir,&offsetInSector));    for(i = 0; i < vol.sectorsPerCluster; i++)    {        /* Write binary zeroes to indicate never-used entries */        checkStatus(updateSector(&vol,sectorOfDir + i,FALSE));        buffer.checkPoint = TRUE;        if(file->currentPosition == 0 && i == 0)        {            /* Add the mandatory . and .. entries */            tffscpy(directory[0].name,".          ",sizeof directory[0].name);            directory[0].attributes = ATTR_ARCHIVE | ATTR_DIRECTORY;            toLE2(directory[0].startingCluster,file->currentCluster);            toLE4(directory[0].fileSize,0);            setCurrentDateTime(&directory[0]);            tffscpy(&directory[1],&directory[0],sizeof directory[0]);            directory[1].name[1] = '.';   /* change . to .. */            toLE2(directory[1].startingCluster,ownerDir);        }        file->fileSize += SECTOR_SIZE;    }    /* Update the parent directory by closing the file */    file->flags |= FILE_MODIFIED;    return closeFile(file);}#endif  /* SUB_DIRECTORY *//*----------------------------------------------------------------------*//*              f i n d D i r E n t r y             *//*                                  *//* Finds a directory entry by path-name, or finds an available directory*//* entry if the file does not exist.                    *//* Most fields necessary for opening a file are set by this routine.    *//*                                                                      *//* Parameters:                                                          *//*  vol     : Pointer identifying drive         *//*  path        : path to find                  *//*      file            : File in which to record directory information.*//*                        Specific fields on entry:         *//*              flags: if FILE_MUST_OPEN = 1, directory     *//*                 will be extended if necessary.   *//*            on exit:                  *//*              flags: FILE_IS_DIRECTORY and                *//*                 FILE_IS_ROOT_DIR set if true.    *//*              fileSize: Set for non-directory files.      *//*                          currentCluster: Set to 0 (unknown)      *//*              ownerDirCluster: Set to 1st cluster of      *//*                    owning directory.         *//*              directorySector: Sector of directory. If 0  *//*                    entry not found and directory full*//*              directoryEntry: Entry # in directory sector *//*              currentPosition: not set by this routine.   *//*                                  *//* Returns:                                                             *//*  FLStatus    : 0 on success and file found           *//*            flFileNotFound on success and file not found  *//*            otherwise failed.             *//*----------------------------------------------------------------------*/static FLStatus findDirEntry(Volume vol, FLSimplePath FAR1 *path, File *file){    File scanFile;        /* Internal file of search */    unsigned dirBackPointer = 0;  /* 1st cluster of previous directory */    FLStatus status = flOK;       /* root directory exists */    file->flags |= (FILE_IS_ROOT_DIR | FILE_IS_DIRECTORY);    file->fileSize = (long) (vol.sectorsInRootDirectory) << SECTOR_SIZE_BITS;    file->fileVol = &vol;#ifdef SUB_DIRECTORY    for(; path->name[0]; path++) /* while we have another path segment */#else    if(path->name[0])    /* search the root directory */#endif    {        status = flFileNotFound;        /* not yet */        if(!(file->flags & FILE_IS_DIRECTORY))            return flPathNotFound;  /* if we don't have a directory,                         we have no business here */        scanFile = *file;       /* the previous file found becomes the scan file */        scanFile.currentPosition = 0;        file->directorySector = 0;  /* indicate no entry found yet */        file->flags &= ~(FILE_IS_ROOT_DIR | FILE_IS_DIRECTORY);        file->ownerDirCluster = dirBackPointer;        file->fileSize = 0;        file->currentCluster = 0;        /* Scan directory */        while(scanFile.currentPosition < scanFile.fileSize)        {            int i;            DirectoryEntry FAR0 *dirEntry;            SectorNo sectorOfDir;            unsigned offsetInSector;            FLStatus readStatus = getSectorAndOffset(&scanFile,&sectorOfDir,&offsetInSector);            if(readStatus == flInvalidFATchain)            {                scanFile.fileSize = scanFile.currentPosition;   /* now we know */                break;      /* we ran into the end of the directory file */            }            else if(readStatus != flOK)                return readStatus;            dirEntry = (DirectoryEntry FAR0 *) findSector(&vol,sectorOfDir);            if(dirEntry == NULL)                return flSectorNotFound;            scanFile.currentPosition += SECTOR_SIZE;            for(i = 0; i < DIRECTORY_ENTRIES_PER_SECTOR; i++, dirEntry++)            {                if(tffscmp(path,dirEntry->name,sizeof dirEntry->name) == 0 &&                   !(dirEntry->attributes & ATTR_VOL_LABEL))                {                    /* Found a match */                    file->directorySector = sectorOfDir;                    file->directoryIndex = i;                    file->fileSize = LE4(dirEntry->fileSize);                    if(dirEntry->attributes & ATTR_DIRECTORY)                    {                        file->flags |= FILE_IS_DIRECTORY;                        file->fileSize = 0x7fffffffl;                        /* Infinite. Directories don't have a recorded size */                    }                    if(dirEntry->attributes & ATTR_READ_ONLY)                        file->flags |= FILE_READ_ONLY;                    dirBackPointer = LE2(dirEntry->startingCluster);                    status = flOK;                    goto endOfPathSegment;                }                else if(dirEntry->name[0] == NEVER_USED_DIR_ENTRY ||                        dirEntry->name[0] == DELETED_DIR_ENTRY)                {                    /* Found a free entry. Remember it in case we don't find a match */                    if(file->directorySector == 0)                    {                        file->directorySector = sectorOfDir;                        file->directoryIndex = i;                    }                    if(dirEntry->name[0] == NEVER_USED_DIR_ENTRY)    /* end of dir */                        goto endOfPathSegment;                }            }        }        endOfPathSegment:        ;    }    if(status == flFileNotFound && (file->flags & FILE_MUST_OPEN) &&       file->directorySector == 0)    {        /* We did not find a place in the directory for this new entry. The */        /* directory should be extended. 'scanFile' refers to the directory */        /* to extend, and the current pointer is at its end         */#ifdef SUB_DIRECTORY        checkStatus(extendDirectory(&scanFile,(unsigned) file->ownerDirCluster));        file->directorySector = firstSectorOfCluster(&vol,scanFile.currentCluster);        file->directoryIndex = 0;         /* Has to be. This is a new cluster */#else        status = flRootDirectoryFull;#endif    }    return status;}/*----------------------------------------------------------------------*//*               r e a d F i l e                *//*                                  *//* Reads from the current position in the file to the user-buffer.  *//* Parameters:                                                          *//*      file        : File to read.                 *//*      ioreq->irData   : Address of user buffer            *//*  ioreq->irLength : Number of bytes to read. If the read extends  *//*            beyond the end-of-file, the read is truncated *//*            at the end-of-file.               *//*                                                                      *//* Returns:                                                             *//*  FLStatus    : 0 on success, otherwise failed                *//*  ioreq->irLength : Actual number of bytes read           *//*----------------------------------------------------------------------*/static FLStatus readFile(File *file,IOreq FAR2 *ioreq){    Volume vol = file->fileVol;    char FAR1 *userData = (char FAR1 *) ioreq->irData;   /* user buffer address */    unsigned long stillToRead = ioreq->irLength;    unsigned long remainingInFile = file->fileSize - file->currentPosition;    ioreq->irLength = 0;      /* read so far */    /* Should we return an end of file status ? */    if(stillToRead > remainingInFile)        stillToRead = (unsigned) remainingInFile;    while(stillToRead > 0)    {        SectorNo sectorToRead;        unsigned offsetInSector;        unsigned readThisTime;        const char FAR0 *sector;        checkStatus(getSectorAndOffset(file,&sectorToRead,&offsetInSector));        sector = (const char FAR0 *) findSector(&vol,sectorToRead);        readThisTime = SECTOR_SIZE - offsetInSector;        if(readThisTime > stillToRead)            readThisTime = (unsigned) stillToRead;        if(sector)            tffscpy(userData,sector + offsetInSector,readThisTime);        else            return flSectorNotFound;      /* Sector does not exist */        stillToRead -= readThisTime;        ioreq->irLength += readThisTime;        userData += readThisTime;        file->currentPosition += readThisTime;    }    return flOK;}/*----------------------------------------------------------------------*//*       f l F i n d N e x t F i l e                *//*                                                                      *//* See the description of 'flFindFirstFile'.                *//*                                                                      *//* Parameters:                                                          *//*  irHandle    : File handle returned by flFindFirstFile.  *//*  irData      : Address of user buffer to receive a       *//*            DirectoryEntry structure          *//*                                                                      *//* Returns:                  

⌨️ 快捷键说明

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