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

📄 api.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright EBS Inc. 1996
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*/
/* API.C - Contains user api level source code.

    The following routines are included:

    po_open         - Open a file.
    po_read         - Read bytes from a file.
    po_write        - Write Bytes to a file.
    po_lseek        - Move the file pointer.
    po_close        - Close a file and flush the file allocation table.
    po_flush        - Flush an open file
    po_trunc        - Truncate an open file
    pc_mv           - Rename a file.
    pc_unlink       - Delete a file.
    pc_mkdir        - Create a directory.
    pc_rmdir        - Delete a directory.
    pc_deltree      - Delete an entire directory tree.
    pc_fat_size     - Calculate blocks required for a volume's Allocation Table.
    pc_free         - Calculate and return the free space on a disk.
    pc_gfirst       - Get stats on the first file to match a pattern.
    pc_gnext        - Get stats on the next file to match a pattern.
    pc_gdone        - Free resources used by pc_gfirst/pc_gnext.
    pc_set_default_drive - Set the default drive number.
    pc_setdfltdrvno - Set the default drive number.
    pc_getdfltdrvno - Get the default drive number.
    pc_set_cwd      - Set the current working directory.
    pc_isdir        -   Determine if a path is a directory.
    pc_isvol        -   Determine if a path is a volume
    pc_pwd          - Get string representation of current working dir.
    pc_cluster_size - Get the cluster size of a drive
    po_extend_file  - Extend a file by N contiguous clusters.
    pc_find_contig_clusters  - Find at least MIN_CLUSTER clusters.
*/

#include <pcdisk.h>

RTFS_FILE(dskopen.c, pc_dskopen)

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

/******************************************************************************
    PC_I_DSKOPEN -  Open a disk for business.

 Description
    Called by lower level code in chkmedia to open the disk
    
    THIS ROUTINE MUST BE CALLED BEFORE ANY OTHERS.

 Returns
    Returns TRUE if the disk was successfully initialized.
****************************************************************************/

int pc_log_base_2(word n)                                   /*__fn__*/
{
int log;

    log = 0;
    if (n <= 1)
        return(log);

    while(n)
    {
        log += 1;
        n >>= 1;
    }
    return((int)(log-1));
}


/* 
* Note: This routine is called with the drive already locked so
*   in several cases there is no need for critical section code handling
*   This is a helper function for pc_i_dskopen()
*/
BOOLEAN pc_dskinit(int driveno)                         /*__fn__*/
{
    DDRIVE *pdr;
    struct pcblk0 bl0;

    /* Check drive number   */
    if (!pc_validate_driveno(driveno))
    {
        pc_report_error(PCERR_INITDRNO);
        return(FALSE);
    }

    if (!mem_drives_structures)
    {
        /* Failed: pc_meminit() must not have been called   */
        pc_report_error(PCERR_INITCORE);
        return (FALSE);
    }

    pdr = pc_drno_to_drive_struct(driveno);

    /* Don't do anything on reopens   */
    if (pdr->mount_valid)
    {
        return(TRUE);
    }
    else
    {
        /* Zero the structure so all of our initial values are right   */
        OS_CLAIM_FSCRITICAL()
        {
            PFBYTE p1, p2;
            p1 = (PFBYTE) pdr;
            p2 = (PFBYTE) &pdr->begin_user_area;
            while(p1 < p2) *p1++ = 0;
        }
        OS_RELEASE_FSCRITICAL()
    }

    /* Set this to true now so check media doesn't try to mount */
    pdr->mount_valid = TRUE;
    if (pdr->drive_flags & DRIVE_FLAGS_PARTITIONED)
    {
        if (pc_read_partition_table(driveno, pdr) != READ_PARTION_OK)
        {
            pc_report_error(PCERR_INITDEV);
 return_error:
            pdr->mount_valid = FALSE;
            return(FALSE);
        }
    }
     
    /* Read block 0   */
    if (!pc_gblk0((word) driveno, &bl0 ))
    {
        pc_report_error(PCERR_INITREAD);
        goto return_error;
    }

    /* Verify that we have a good dos formatted disk   */
    if ( (bl0.jump != (byte) 0xE9) && (bl0.jump !=(byte) 0xEB) )
    {
        pc_report_error(PCERR_INITMEDI);
        goto return_error;
    }

    /* set up the drive structur from block 0   */
    pdr->bytspsector = bl0.bytspsector; /* bytes/sector */
    pdr->secpalloc = bl0.secpalloc; /* sectors / cluster */
    pdr->secpfat = (CLUSTERTYPE) bl0.secpfat;   /* sectors / fat */
    pdr->numfats = bl0.numfats; /* Number of fat copies */
    pdr->numroot = bl0.numroot; /* Maximum number of root entries */
    pdr->numsecs = (BLOCKT) bl0.numsecs;    /* Total sectors on the disk */
    pdr->mediadesc =    bl0.mediadesc;  /* Media descriptor byte */
    pdr->secreserved = bl0.secreserved; /* sectors reserved */
    pdr->secptrk    = bl0.secptrk;  /* sectors per track */
    pdr->numhead    = bl0.numhead;  /* number of heads */
    pdr->numhide    =bl0.numhide;   /* # hidden sectors */

/* Check if running on a DOS (4.0) huge partition                           */
    /* If traditional total # sectors is zero, use value in extended BPB    */
    if (pdr->numsecs == 0L)
        pdr->numsecs = bl0.numsecs2;                            /* (4.0) */

    /* derive some things   */

            /* beginning of fat is just past reserved sectors   */
#if (FAT32)
    if (pdr->secpfat == 0L)
        pdr->secpfat = bl0.secpfat2;
     
    if (bl0.flags & NOFATMIRROR)
    {                                                   
        pdr->fatblock = (BLOCKT) bl0.secreserved + 
                        ((bl0.flags & ACTIVEFAT) * pdr->secpfat);
        pdr->numfats = 1;
    }   
    else    
        pdr->fatblock = (BLOCKT) bl0.secreserved;
#else
    pdr->fatblock = (BLOCKT) bl0.secreserved;
#endif
        /* The first block of the root is just past the fat copies   */
#if (FAT32)
     if (pdr->numroot==0) /* Drive must be FAT32 */
     {
          pdr->firstclblock = pdr->fatblock + pdr->secpfat * pdr->numfats;
/* DM: 7-6-99: BUG FIX: */
          pdr->rootblock = (bl0.rootbegin-2) * pdr->secpalloc + pdr->firstclblock;
/* WRONG: pdr->rootblock = bl0.rootbegin-2 + pdr->firstclblock; */
     }
     else 
#endif
    {
        pdr->rootblock = pdr->fatblock + pdr->secpfat * pdr->numfats;
        pdr->secproot =  (word)((pdr->numroot + INOPBLOCK - 1)/INOPBLOCK);
        /* The first block of the cluster area is just past the root   */
        /* Round up if we have to                                      */
        pdr->firstclblock = pdr->rootblock +
                            (pdr->numroot + INOPBLOCK - 1)/INOPBLOCK;

    }
    pdr->bytespcluster = (word) (512 * pdr->secpalloc);

    /* bits to mask in to calculate byte offset in cluster from file pointer.
        AND file pointer with this to get byte offset in cluster a shift right
        9 to get block offset in cluster */
    pdr->byte_into_cl_mask = (dword) pdr->bytespcluster;
    pdr->byte_into_cl_mask -= 1L;

    /* save away log of sectors per alloc   */
    pdr->log2_secpalloc = (word)pc_log_base_2((word)pdr->secpalloc);
    
    /*  Calculate the largest index in the file allocation table.
        Total # block in the cluster area)/Blockpercluster =='s total
        Number of clusters. Entries 0 & 1 are reserved so the highest
        valid fat index is 1 + total # clusters.
    */
    pdr->maxfindex = (CLUSTERTYPE)  /* FAT32 */
            (1 + ((pdr->numsecs - pdr->firstclblock)/pdr->secpalloc));
#if (!FAT32)
     /* if calculated size > fff0 set it to one less. fff0 to ffff are
        reserved values. */
    if (pdr->maxfindex >= 0xfff0)
        pdr->maxfindex = 0xffef;
#endif

    /* Create a hint for where we should write file data. We do this 
        because directories are allocated in one cluster chunks while
        file may allocate larger chunks. We Try to put directory 
        data at the beginning of the disk in a seperate region so we
        don't break the contiguous space further out */

    /* guess that 1/32nd of the disk will store directory info and the
        rest will be data. */
#if (FAT32)
    if (pdr->maxfindex > (CLUSTERTYPE)65526ul)
    {
        pdr->known_free_clusters = bl0.free_alloc;
        pdr->free_contig_base = bl0.next_alloc;
        pdr->free_contig_pointer = pdr->free_contig_base;
        pdr->infosec = bl0.infosec;
    }
    else
#endif
    {
    pdr->free_contig_base = (word) (pdr->maxfindex >> 5);
    if (pdr->free_contig_base < 2)
        pdr->free_contig_base = 2;
     /* set the pointer to where to look for free clusters to the contiguous
        area. On the first call to write this will hunt for the real free
        blocks. */
    pdr->free_contig_pointer = pdr->free_contig_base;

     /* Keep track of how much free space is on the drive. (This will
        speed up pc_free()) when calculating free space */
    pdr->known_free_clusters = 0;
    }

    /* Initialize the fat management code   */

        /* Nibbles/fat entry if < 4087 clusters then 12 bit else 16   */
    pdr->fasize = (word) ((pdr->maxfindex < 4087) ? 3 : 4);
#if (FAT32)
    pdr->fasize = (word) ((pdr->maxfindex > (CLUSTERTYPE)65526ul) ? 
        8 : pdr->fasize);
#endif   

    if (driveno == 0)
        pdr->fat_swap_structure.data_array = (PFBYTE)fat_drive_0;
#if (NDRIVES > 1)   /* B: */
    if (driveno == 1)
        pdr->fat_swap_structure.data_array = (PFBYTE)fat_drive_1;
#endif
#if (NDRIVES > 2)   /* C: */
    if (driveno == 2)
        pdr->fat_swap_structure.data_array = (PFBYTE)fat_drive_2;
#endif

#if (NDRIVES > 3)   /* D: */
    if (driveno == 3)
        pdr->fat_swap_structure.data_array = (PFBYTE)fat_drive_3;
#endif

#if (NDRIVES > 4)   /* E: */
    if (driveno == 4)
        pdr->fat_swap_structure.data_array = (PFBYTE)fat_drive_4;
#endif

#if (NDRIVES > 5)   /* E: */
    if (driveno == 5)
        pdr->fat_swap_structure.data_array = (PFBYTE)fat_drive_5;
#endif

#if (NDRIVES > 6)   /* E: */
    if (driveno == 6)
        pdr->fat_swap_structure.data_array = (PFBYTE)fat_drive_6;
#endif

#if (NDRIVES > 7)   /* E: */
    if (driveno == 7)
        pdr->fat_swap_structure.data_array = (PFBYTE)fat_drive_7;
#endif

#if (NDRIVES > 8)   /* E: */
    if (driveno == 8)
        pdr->fat_swap_structure.data_array = (PFBYTE)fat_drive_8;
#endif

#if (NDRIVES > 9)   /* E: */
    if (driveno == 9)
        pdr->fat_swap_structure.data_array = (PFBYTE)fat_drive_9;
#endif



#if (NDRIVES > 10) 
#error Please add fat_drive_10
#endif

    /* Remember how many blocks we alloced   */
    pdr->fat_swap_structure.n_blocks_total = FAT_BUFFER_SIZE;
    /* Set driveno now becuse the drive structure is valid     */
    pdr->driveno = (word)driveno; 

    /* Swap in item 0. (ie read the first page of the FAT)   */
    if (!pc_pfswap(pdr, (word) 0, FALSE))
    {
        pc_report_error(PCERR_FATREAD);
        goto return_error;
    }
    pdr->mount_valid = TRUE;
    return(TRUE);
}


RTFS_FILE(dskflush.c, pc_diskflush)

#if (RTFS_WRITE)
/****************************************************************************
    PC_DISKFLUSH -  Flush the FAT and all files on a disk

 Description

    If an application may call this functions to force all files 
    to be flushed and the fat to be flushed. After this call returns
    the disk image is synchronized with RTFS's internal view of the
    voulme.

Returns
    TRUE if the disk flushed else no

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

/* Free all resources belonging to a drive without flushing anything    */
BOOLEAN pc_diskflush(char *path)                                        /*__fn__*/
{
    int driveno;
    DDRIVE *pdrive;
    BOOLEAN ret_val;
    CHECK_MEM(BOOLEAN, 0)   /* Make sure memory is initted */
    OS_FS_ENTER()

    ret_val = FALSE;
    driveno = check_drive(path);
    if (driveno >= 0)
    {
        if (pc_parsedrive( &driveno, path ))
        {
            /* Find the drive   */
            pdrive = pc_drno2dr(driveno);
            if (pdrive)
            {
                OS_CLAIM_LOGDRIVE(driveno)      /* Grab exclusive access to the drive */
                if (pc_flush_all_fil(pdrive))
                    if (pc_flushfat(driveno))
                        ret_val = TRUE;
                OS_RELEASE_LOGDRIVE(driveno)
            }
        }
    }
    /* Restore the kernel state   */
    OS_FS_EXIT()
    return(ret_val);
}

#endif


    
RTFS_FILE(mkdir.c, pc_mkdir)

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

#if (RTFS_WRITE)
#if (RTFS_SUBDIRS)

⌨️ 快捷键说明

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