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

📄 apiutil.c

📁 NUcleus plus 支持的文件系统。 是学习文件系统的很好参考资料。
💻 C
📖 第 1 页 / 共 3 页
字号:
        }
        PC_DRIVE_IO_EXIT(driveno)

        /* FSINFO
            Set to 0 when the free clusters count is unknown.
            Set to 1 when the free clusters count is known. */
        pdr->valid_fsinfo = 0;

        /* Check the signature of the file system information sector.*/
        if ( (b[0] == 'R') && (b[1] == 'R') && (b[2] == 'a') && (b[3] == 'A') &&
             (b[0x1e4] == 'r') && (b[0x1e5] == 'r') && (b[0x1e6] == 'A') && (b[0x1e7] == 'a') )
        {
            /* The count of free clusters on the drive.
                Note: Set to -1(0xffffffff) when the count is unknown. */
            SWAP32((UINT32 *)&pdr->free_clusters_count,(UINT32 *)&b[0x1e8]);

            if (pdr->free_clusters_count == (UINT32)0xffffffff)
                pdr->free_clusters_count = 0L;
            else
                pdr->valid_fsinfo = 1;

            /* The cluster number of the cluster that was most recently allocated. */
            SWAP32((UINT32 *)&pdr->free_contig_pointer,(UINT32 *)&b[0x1ec]);
        }
        else
        {
            pdr->free_clusters_count = 0L;
            pdr->free_contig_pointer = 2L;
        }
    }

    /*  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.
        Note: Max cluster number  = Number of clusters + 1 */
    pdr->maxfindex = (UINT32)
            (1 + (pdr->numsecs - pdr->firstclblock)/pdr->secpalloc);

    /* Check the number of next free cluster  */
    if (pdr->free_contig_pointer > pdr->maxfindex)
        pdr->free_contig_pointer = 2L;

    if (pdr->fasize == 3)
    {
        if (pdr->maxfindex > 0x0ff6L)
        {
            pdr->opencount = 0;
            return(NUF_FORMAT);
        }
    }
    else if (pdr->fasize == 4)
    {
        if (pdr->maxfindex > 0xfff6L)
        {
            pdr->opencount = 0;
            return(NUF_FORMAT);
        }
    }
    else    /* FAT32 */
    {
        if (pdr->maxfindex > 0x0ffffff6L)
        {
            pdr->opencount = 0;
            return(NUF_FORMAT);
        }
    }

    if (NUF_Drive_Fat_Size[driveno] < min_needed)
    {
        pc_report_error(PCERR_FATCORE);
        pdr->opencount = 0;
        return(NUF_FATCORE);
    }

    if (NUF_Drive_Fat_Size[driveno] >  (INT)pdr->secpfat)
    {
        NUF_Drive_Fat_Size[driveno] = (INT)pdr->secpfat;
    }


    /* Allocate FAT cache buffer */
    pdr->fat_swap_structure.data_array =
                    (UINT8 FAR *)NUF_Alloc(NUF_Drive_Fat_Size[driveno] << 9 );

    if (!pdr->fat_swap_structure.data_array)
    {
        pdr->opencount = 0;
        return(NUF_NO_MEMORY);
    }

    /* Remember how many blocks we alloced */


    pdr->fat_swap_structure.n_blocks_total = (UINT16)NUF_Drive_Fat_Size[driveno];
    if (NUF_Drive_Fat_Size[driveno] == (INT)pdr->secpfat)
        pdr->use_fatbuf = 0;
    else
        pdr->use_fatbuf = 1;




#ifdef DEBUG0

        DEBUG_PRINT ("Oem NAME  %8s\n",pdr->oemname);
        DEBUG_PRINT ("Bytspsec  %d\n",pdr->bytspsector);
        DEBUG_PRINT ("secpallc  %d\n",pdr->secpalloc);
        DEBUG_PRINT ("secres    %d\n",pdr->fatblock);
        DEBUG_PRINT ("numfat    %d\n",pdr->numfats);
        DEBUG_PRINT ("numrot    %d\n",pdr->numroot);
        DEBUG_PRINT ("numsec    %d\n",pdr->numsecs);
        DEBUG_PRINT ("mediac    %d\n",pdr->mediadesc);
        DEBUG_PRINT ("secfat    %d\n",pdr->secpfat);
        DEBUG_PRINT ("sectrk    %d\n",pdr->secptrk);
        DEBUG_PRINT ("numhed    %d\n",pdr->numhead);
        DEBUG_PRINT ("numhide   %d\n",pdr->numhide);
#endif

    /* Clear the current working directory */
    fs_user->lcwd[driveno] = NULL;

    pdr->bytespcluster = (UINT16) (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 = (UINT32) pdr->bytespcluster;
    pdr->byte_into_cl_mask -= 1L;

    /* save away log of sectors per alloc */
    pdr->log2_secpalloc = pc_log_base_2((UINT16)pdr->secpalloc);

    /* Number of maximum file clusters */
    pdr->maxfsize_cluster = MAXFILE_SIZE >> pdr->log2_secpalloc;

    /* Initialize the fat management code */

    /* Set driveno now becuse the drive structure is valid */  
    pdr->driveno = driveno;

    if (pdr->use_fatbuf)
    {
        /* Swap in item 0. (ie read the first page of the FAT) */
        ret_stat = pc_pfswap(&pdata, pdr, (UINT32)0, NO);
        if (ret_stat != NU_SUCCESS)
        {
            pc_report_error(PCERR_FATREAD);
            NU_Deallocate_Memory((VOID *)pdr->fat_swap_structure.data_array);
            pdr->opencount = 0;
            return(ret_stat);
        }
    }
    else
    {
        /* No fat swapping. We use  drive.fat_swap_structure elements
           to implement an in memory caching scheme. data_map[255] is used
           to indicate which blocks are dirty and data_array points to
           the buffer to hold the in memory fat */

        ltemp = pdr->secpfat;
        pdata = pdr->fat_swap_structure.data_array;
        fatoffset = pdr->fatblock;
        while (ltemp)
        {
            if (ltemp > MAXSECTORS)
                nblocks = MAXSECTORS;
            else
                nblocks = (UINT16) ltemp;

            /* The dirty blocks table data_map[255] was zeroed when we zeroed
               the drive structure */
            /* Now read the fat */
            PC_DRIVE_IO_ENTER(driveno)
            if ( !pc_bdevsw[driveno].io_proc(driveno, (UINT32)fatoffset, pdata, nblocks, YES) )
            {
                PC_DRIVE_IO_EXIT(driveno)
                pc_report_error(PCERR_FATREAD);
                NU_Deallocate_Memory((VOID *)pdr->fat_swap_structure.data_array);
                pdr->opencount = 0;
                return(NUF_IO_ERROR);
            }
            PC_DRIVE_IO_EXIT(driveno)

            ltemp -= nblocks;
            fatoffset += nblocks;
            pdata += (nblocks << 9);
        }
    }
    return(NU_SUCCESS);
}


/************************************************************************
* FUNCTION                                                              
*                                                                       
*       pc_idskclose                                                    
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*       Given a valid drive number. Flush the file allocation table and 
*       purge any buffers or objects associated with the drive.         
*                                                                       
* AUTHOR                                                                
*                                                                       
*       Kyoichiro Toda                             
*                                                                       
* INPUTS                                                                
*                                                                       
*       driveno                             Drive number                
*                                                                       
* OUTPUTS                                                               
*                                                                       
*       NU_SUCCESS                          Unmount successful.         
*       NUF_BADDRIVE                        Invalid drive specified.    
*       NUF_IO_ERROR                        Driver returned error.      
*       NUF_INTERNAL                        Nucleus FILE internal error.
*                                                                       
*************************************************************************/
STATUS pc_idskclose(INT16 driveno)
{
DDRIVE      *pdr;
STATUS      ret_val;
UINT8       b[512];
UINT32      fstemp;
INT         i;
UINT16      signature;


    pdr = pc_drno2dr(driveno);

    /* Check drive number */
    if (pdr)
    {
        PC_FAT_ENTER(driveno)
        ret_val = pc_flushfat(pdr);
        PC_FAT_EXIT(driveno)

        if (ret_val == NU_SUCCESS)
        {
            if (pdr->fasize == 8)
            {
                /* Build up a Partition FSINFO(File System INFOrmation)
                    Note: PBR include a BIOS Parameter Block(BPB) */
                pc_memfill(&b[0], 512, '\0');

                /* FSI signature offset 0 */
                pc_cppad(&b[0], (UINT8 *)"RRaA", 4);

                /* FSI signature offset 0x1E0 */
                pc_cppad(&b[0x1e4], (UINT8 *)"rrAa", 4);

                if (!pdr->valid_fsinfo)   /* Set the free cluster count. */
                    pdr->free_clusters_count = pc_ifree(driveno);

                SWAP32((UINT32 *)&(b[0x1e8]), (UINT32 *)&pdr->free_clusters_count);

                SWAP32((UINT32 *)&(b[0x1ec]), (UINT32 *)&pdr->free_contig_pointer);

                /* Signature word */
                signature = 0xAA55;
                SWAP16((UINT16 *)&(b[0x1fe]), (UINT16 *)&signature);

                /* Update FSINFO */
                fstemp = (UINT32) pdr->fsinfo;
                for (i = 0; i < 2; i++)
                {
                    if ( !pc_bdevsw[driveno].io_proc(driveno, fstemp, &(b[0]), (UINT16) 1, NO) )
                    {
                        pc_report_error(PCERR_FMTWBZERO);
                        ret_val = NUF_IO_ERROR;
                        break;
                    }
                    fstemp += 6;
                }
            }
            if (ret_val == NU_SUCCESS)
            {
                /* Release the drive if opencount == 0 */
                ret_val = pc_dskfree(driveno, NO);
            }
        }
    }
    else
    {
        ret_val = NUF_NOT_OPENED;
    }
    return(ret_val);
}


/************************************************************************
* FUNCTION                                                              
*                                                                       
*       pc_fd2file                                                      
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*       Map a file descriptor to a file structure. Return null if the   
*       file is not open. If an error has occured on the file return    
*       NULL unless allow_err is true.                                  
*                                                                       
* AUTHOR                                                                
*                                                                       
*       Takahiro Takahashi                         
*                                                                       
* INPUTS                                                                
*                                                                       
*       fd                                  File descriptor             
*                                                                       
* OUTPUTS                                                               
*                                                                       
*       File representation.丂                                          
*       NULL                                Invalid FD.                 
*                                                                       
*************************************************************************/
PC_FILE *pc_fd2file(INT fd)
{
PC_FILE     *pfile;


    /* Is this descriptor value in correct range ? */
    if (0 <= fd && fd <= NUSERFILES)
    {
        /* Get PFILE memory pool pointer */
        pfile = mem_file_pool+fd;
        if (pfile && !pfile->is_free)
        {
            return(pfile);

⌨️ 快捷键说明

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