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

📄 lowl.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* If fat32 is not defined the nxt is always <= 0xffff. picky compilers
       notice this and emit a warning */
        if (nxt >= (CLUSTERTYPE)0xfff7)
#endif
            nxt = 0;                            /* end of chain */
    }
    return(nxt);
}

RTFS_FILE(clreleas.c, pc_clrelease)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)

/****************************************************************************
    PC_CLRELEASE - Return a cluster to the pool of free space on a disk

 Description
    Given a DDRIVE and a cluster, mark the cluster in the file allocation
    table as free. It will be used again by calls to pc_clalloc().

 Returns
    Nothing



***************************************************************************/
 

/* Return a cluster to the free list                             */
/* Note: The caller locks the fat before calling this routine    */
void pc_clrelease(DDRIVE    *pdr, CLUSTERTYPE  clno)                        /*__fn__*/
{
    if (clno < 2)
        return;

    /* Don't catch any lower level errors here. You'll catch them soon enough   */
#if (FAT32)
    if (pc_pfaxx(pdr, clno, 0x00000000))    /* Mark it as free */
#else
    if (pc_pfaxx(pdr, clno, 0x0000))        /* Mark it as free */
#endif
    {
        /* If freeing in the "contiguous" region reset the "hint" if we
            free space earlier than it. */
        if (clno >= pdr->free_contig_base && clno <= pdr->free_contig_pointer)
            pdr->free_contig_pointer = clno;

        if (pdr->known_free_clusters)
#if (FAT32)
            pdr->known_free_clusters = (long) (pdr->known_free_clusters + (long)1);
#else
            pdr->known_free_clusters = (word) (pdr->known_free_clusters + (word)1);
#endif
    }
}
#endif
RTFS_FILE(faxx.c, pc_faxx)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif

/***************************************************************************
    PC_FAXX - Get the value store in the FAT at clno.

 Description
    Given a DDRIVE and a cluster number. Get the value in the fat at clusterno
    (the next cluster in a chain.) Handle 16 and 12 bit fats correctly.

 Returns
    Returns the the value at clno. In pvalue. 
    If any error occured while FAT swapping return FALSE else return TRUE.
***************************************************************************/
 
/* Retrieve a value from the fat   */
BOOLEAN pc_faxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE *pvalue)             /*__fn__*/
{
    CLUSTERTYPE  nibble,index, offset, result;
    byte    c;
    union align1 {
        byte    wrdbuf[4];          /* Temp storage area */
        word  fill[2];
    } u;
    union align2 {
    byte    wrdbuf2[4];         /* Temp storage area */
    word  fill[2];
    } u2;

    result = 0;
    if (pdr->fasize == 3)       /* 3 nibble ? */
    {
        nibble = (word)(clno * 3);
        index  = (word)(nibble >> 2);
        offset = (word)(clno & 0x03);
        /* Read the first word   */
        if (!pc_fword( pdr, index, (word *) &u.wrdbuf[0], FALSE ))
            return(FALSE);
/*
        |   W0      |   W1      |   W2  |
        A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
        xx xx   xx
*/
        if (offset == 0) /* (A2 << 8) | A1 A2 */
        {
            /* BYTE 0 =='s Low byte, byte 1 low nibble =='s high byte   */
            u.wrdbuf[1] &= 0x0f;
            result = u.wrdbuf[1];
            result <<= 8;
            result |= u.wrdbuf[0];
        }
/*
        |   W0      |   W1      |   W2  |
        A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
                xx  xx xx 
*/
    
        else if (offset == 1) /* (B1 B2 << 4) | B0 */
        {
            /* BYTE 2 == High byte Byte 1 high nibb == low nib   */
            if (!pc_fword( pdr, (word)(index+1), (word *) &u2.wrdbuf2[0], FALSE ))
                return(FALSE);
            c = (byte) (u.wrdbuf[1] >> 4);
            result = u2.wrdbuf2[0];
            result <<= 4;
            result |= c;
        }
/*
        |   W0      |   W1      |   W2  |
        A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
                            xx xx   xx 
*/
        else if (offset == 2) /*(C2 << 8) | C1 C2 */
        {
            if (!pc_fword( pdr, (word)(index+1), (word *) &u2.wrdbuf2[0], FALSE ))
                return(FALSE);
            /* BYTE 1 =='s Low byte, byte 2 low nibble =='s high byte   */
            result = (word) (u2.wrdbuf2[0] & 0x0f);
            result <<= 8;
            result |= u.wrdbuf[1];
        }
/*
        |   W0      |   W1      |   W2  |
        A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
                                xx  xx xx
*/
    
        else if (offset == 3) /* (D2 D1) << 4 | D0 */   
        {
            result = u.wrdbuf[1];
            result <<= 4;
            c = u.wrdbuf[0];
            c >>= 4;
            result |= c;
        }
    }
    else if (pdr->fasize == 8) /* 32 BIT fat. ret the value at 4 * clno */
    {
#if (FAT32)
#if KS_LITTLE_ENDIAN
            if (!pc_pfgdword( pdr, clno, (dword *) &result ))
                return (FALSE);
#else
            if ( pc_pfgdword( pdr, clno, (dword *) &u.wrdbuf[0] ))
                result = (CLUSTERTYPE) to_DWORD(&u.wrdbuf[0]); 
            else
                return (FALSE);
#endif
#else
        return (FALSE); /* no FAT32 */
#endif /* FAT32 */
    }
    else    /* 16 BIT fat. ret the value at 2 * clno */
    {
            if ( pc_fword( pdr, clno, (word *) &u.wrdbuf[0], FALSE ))
                result = (CLUSTERTYPE) to_WORD(&u.wrdbuf[0]); /*X*/ /* And use the product as index */
            else
                return (FALSE);
    }
    *pvalue = result;
    return (TRUE);
}

RTFS_FILE(flushfat.c, pc_flushfat)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)

/****************************************************************************
    PC_FLUSHFAT -  Write any dirty FAT blocks to disk

 Description
    Given a valid drive number. Write any fat blocks to disk that
    have been modified. Updates all copies of the fat.

 Returns
    Returns FALSE if driveno is not an open drive. Or a write failed.

****************************************************************************/

#if (FAT32)
/* Update a fat32 voulme's info sector   */
BOOLEAN pc_flushinfo(DDRIVE *pdr)                                      /*__fn__*/
{
    byte KS_FAR *pf;
    int j;      /*FAT32*/
    BLKBUFF *buf;

    if (pdr->fasize == 8)
    {
        buf = pc_scratch_blk();
        if (!buf)
        {
            pc_report_error(PCERR_FAT_FLUSH);
            return(FALSE);
        }
        else
        {
            pf = buf->data;      /* Now we don't have to use the stack */

            /* READ IT   */
            if(!devio_read(pdr->driveno,(BLOCKT)(pdr->infosec) ,pf , 1, FALSE))
                goto info_error;

            /* Merge in the new values   */
#if KS_LITTLE_ENDIAN
            for (j=0; *((dword*)pf)!=FSINFOSIG && j<512; pf++,j++);
            ((struct fat32_info *)pf)->free_alloc = pdr->known_free_clusters;
            ((struct fat32_info *)pf)->next_alloc = pdr->free_contig_pointer;
#else
            for (j=0; to_DWORD(pf)!=FSINFOSIG && j<512; pf++,j++);
            fr_DWORD((byte *) (&((struct fat32_info *)pf)->free_alloc), pdr->known_free_clusters );
            fr_DWORD((byte *) (&((struct fat32_info *)pf)->next_alloc), pdr->free_contig_pointer );
#endif
            pf = buf->data;      /* Now we don't have to use the stack */
            /* WRITE IT   */
            if(!devio_write(pdr->driveno,(BLOCKT)(pdr->infosec) ,pf , 1, FALSE))
            {
info_error:
                pc_free_buf(buf, TRUE);
                pc_report_error(PCERR_FAT_FLUSH);
                return(FALSE);
            }
            pc_free_buf(buf, TRUE);
        }
    }
    return (TRUE);
}
#endif /* FAT32 */


/* Consult the dirty fat block list and write any. write all copies
    of the fat */
/* Note: The caller locks the fat before calling this routine   */
BOOLEAN pc_flushfat(int driveno)                                        /*__fn__*/
{
    DDRIVE *pdr;

    pdr = pc_drno2dr(driveno);

    if (!pdr)
    {
        return(FALSE);
    }

    if (!pdr->fat_is_dirty)
        return(TRUE);
#if (FAT32)
    /* write the alloc hints into the info block   */
    if (!pc_flushinfo(pdr))
        return(FALSE);
#endif


    if (pc_pfflush(pdr))
    {
        pdr->fat_is_dirty = FALSE;
        return(TRUE);
    }
    else
        return(FALSE);
}
#endif
RTFS_FILE(freech.c, pc_freechain)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)

/****************************************************************************
    PC_FREECHAIN - Free a cluster chain associated with an inode.

 Description
    Trace the cluster chain starting at cluster and return all the clusters to
    the free state for re-use. The FAT is not flushed.

 Returns
    Nothing.

****************************************************************************/
/* Note: The caller locks the fat before calling this routine   */
void pc_freechain(DDRIVE *pdr, CLUSTERTYPE cluster)                     /*__fn__*/
{
    CLUSTERTYPE nextcluster;
    nextcluster = pc_clnext(pdr , cluster);
    while (cluster)
    {
        pc_clrelease(pdr , cluster);
        cluster = nextcluster;
        nextcluster = pc_clnext(pdr , nextcluster);
    }
}
#endif
RTFS_FILE(cltrunc.c, pc_cl_truncate)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif
#if (RTFS_WRITE)
#if (RTFS_SUBDIRS)
/****************************************************************************
    PC_CL_TRUNCATE - Truncate a cluster chain.

 Description
    Trace the cluster chain starting at cluster until l_cluster is reached.
    Then terminate the chain and free from l_cluster on.
    The FAT is not flushed.

    If cluster == l_cluster does nothing. This condition should be handled
    higher up by updating dirents appropriately and then calling pc_freechain.

 Returns
    The last cluster in the chain after truncation.
****************************************************************************/
/* Note: The caller locks the fat before calling this routine   */
CLUSTERTYPE  pc_cl_truncate(DDRIVE *pdr, CLUSTERTYPE cluster, CLUSTERTYPE l_cluster)/*__fn__*/
{
    CLUSTERTYPE nextcluster;
    nextcluster = pc_clnext(pdr , cluster);
    while (nextcluster)
    {
        if (nextcluster == l_cluster)
        {
            if (!pc_pfaxxterm(pdr, cluster))    /* Terminate the chain */ /* FAT32 */
                break;                              /* Error break to ret 0 */
            pc_freechain(pdr, l_cluster);
            return(cluster);
        }
        else
        {
            cluster = nextcluster;
            nextcluster = pc_clnext(pdr , nextcluster);
        }
    }
    return(0);
}
#endif
#endif
RTFS_FILE(getchain.c, pc_get_chain)

#ifndef __PCDISK__  /* This allows us to build the lib with subroutines split */
#include <pcdisk.h>
#endif

/******************************************************************************
    PC_GET_CHAIN  -  Return as many contiguous clusters as possible.


 Description
        Starting at start_cluster return the number of contiguous clusters
        allocated in the chain containing start_cluster or n_clusters,
        whichever is less.
    
 Returns
    Returns the number of contiguous clusters found. Or zero on an error.
    This function should always return at least one. (start_cluster). Unless
    an error occurs.

    The word at *pnext_cluster is filled with on of the following:
        . If we went beyond a contiguous section it contains
        the first cluster in the next segment of the chain.
        . If we are still in a section it contains
        the next cluster in the current segment of the chain.
        . If we are at the end of the chain it contains the last cluster 
        in the chain.

⌨️ 快捷键说明

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