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

📄 apiutil.c

📁 NUcleus plus 支持的文件系统。 是学习文件系统的很好参考资料。
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************************
*                                                                       
*       Copyright (c) 2001 by Accelerated Technology, Inc.              
*                                                                       
*  PROPRIETARY RIGHTS of Accelerated Technology are  involved in        
*  the subject matter of this material.  All manufacturing,             
*  reproduction, use, and sales rights pertaining to this subject       
*  matter are  governed by the license agreement.  The recipient of     
*     this software implicitly accepts the terms of the license.        
*                                                                       
*                                                                       
*************************************************************************

*************************************************************************
* FILE NAME                                     VERSION                 
*                                                                       
*       APIUTIL.C                               FILE  2.3              
*                                                                       
* COMPONENT                                                             
*                                                                       
*       Nucleus File                                                    
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*       Contains support code for user api level source code.           
*                                                                       
* DATA STRUCTURES                                                       
*                                                                       
*       None.                                                           
*                                                                       
* FUNCTIONS                                                             
*                                                                       
*       pc_dskinit                          Mount a disk.               
*       pc_idskclose                        Unmount a disk.             
*       pc_fd2file                          Map a file descriptor to a  
*                                           丂file structure.           
*       pc_allocfile                        Allocate a file structure.  
*       pc_freefile                         Release a file structure.   
*       pc_free_all_fil                     Release all file structures 
*                                            for a drive.               
*       pc_log_base_2                       Calculate log2(N).          
*       pc_get_cwd                          Determine cwd string from   
*                                            current directory inode.   
*       pc_upstat                           Copy directory entry info   
*                                            to a user's stat buffer.   
* DEPENDENCIES                                                          
*                                                                       
*       pcdisk.h                            File common definitions     
*                                                                       
*************************************************************************/

#include        "file\pcdisk.h"

extern PC_FILE          *mem_file_pool;
extern _PC_BDEVSW       pc_bdevsw[];
extern UNSIGNED         *NUF_Drive_Pointers[];
extern INT              NUF_Fat_Type[];
extern INT              NUF_Drive_Fat_Size[];


/************************************************************************
* FUNCTION                                                              
*                                                                       
*       pc_dskinit                                                      
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*       Given a valid drive number, read block zero and convert its     
*       contents to File syste drive information.                       
*                                                                       
* AUTHOR                                                                
*                                                                       
*       Takahiro Takahashi                         
*                                                                       
* INPUTS                                                                
*                                                                       
*       driveno                             Drive number                
*                                                                       
* OUTPUTS                                                               
*                                                                       
*       NU_SUCCESS                          Mount successful.           
*       NUF_FATCORE                         Fat cache table too small.  
*       NUF_NO_PARTITION                    No partition in disk.       
*       NUF_FORMAT                          Not formatted this disk.    
*       NUF_NO_MEMORY                       Can't allocate internal     
*                                            buffer.                    
*       NUF_IO_ERROR                        Driver returned error.      
*       NUF_INTERNAL                        Nucleus FILE internal error.
*                                                                       
*************************************************************************/
STATUS pc_dskinit(INT16 driveno)
{
STATUS      ret_stat;
UINT8       b[512];
DDRIVE      *pdr;
UINT16      min_needed;
FATSWAP     *pfr;
UINT16      nblocks;
UINT8 FAR   *pdata;
UINT32      fatoffset;
INT         i;
UINT16      wvalue;
UINT32      ltemp;


   /* get 1 block starting at 0 from driveno */
   /* READ */
    PC_DRIVE_IO_ENTER(driveno)
    if ( !pc_bdevsw[driveno].io_proc(driveno, 0L, &b[0], (UINT16) 1, YES) )
    {
        PC_DRIVE_IO_EXIT(driveno)
        pc_report_error(PCERR_INITREAD);
        return(NUF_IO_ERROR);
    }
    PC_DRIVE_IO_EXIT(driveno)

    pdr = (DDRIVE *)NUF_Drive_Pointers[driveno];
    if (!pdr)
    {
        /* Allocate Drive memory */
        pdr = (DDRIVE *)NUF_Alloc(sizeof(DDRIVE));
        if (!pdr)
        {
            pc_report_error(PCERR_DRVALLOC);
            return(NUF_NO_MEMORY);
        }
        /* Zero the structure so all of our initial values are right */
        pc_memfill(pdr, sizeof(DDRIVE), (UINT8) 0);

        pfr = &pdr->fat_swap_structure;

        if (NUF_Drive_Fat_Size[driveno] < 256)
        {
            pfr->data_map_size = 256;
        }
        else
        {
            pfr->data_map_size = NUF_Drive_Fat_Size[driveno];
        }

        pfr->data_map = (UINT16 *)NUF_Alloc(sizeof(UINT16) * pfr->data_map_size);
        if (!pfr->data_map)
        {
            pc_report_error(PCERR_DRVALLOC);
            return(NUF_NO_MEMORY);
        }

        pfr->pdirty = (UINT8 *)NUF_Alloc(pfr->data_map_size >> 3 );
        if (!pfr->pdirty)
        {
            pc_report_error(PCERR_DRVALLOC);
            return(NUF_NO_MEMORY);
        }

        for (i = 0; i < pfr->data_map_size; i++)
        {
            pfr->data_map[i] = 0;
            pfr->pdirty[i >> 3] = 0;
        }
        pfr->block_0_is_valid = 0;
        pfr->base_block = 0;
        pdr->opencount = 1;
        NUF_Drive_Pointers[driveno] = (UNSIGNED *)pdr;
    }

    /* Verify that we have a good dos formatted disk */
    if ( (b[0] != (UINT8) 0xE9) && (b[0] !=(UINT8) 0xEB) )
    {
        pc_report_error(PCERR_INITMEDI);
        pdr->opencount = 0;
        return(NUF_FORMAT);
    }

    /* This drive is FAT file system */
    pdr->fs_type  = FAT_FILE_SYSTEM;

    /* Now load the structure from the buffer */
    copybuff(&pdr->oemname[0],&b[3],8);
    SWAP16((UINT16 *)&pdr->bytspsector, (UINT16 *)&b[0xb]);
    pdr->secpalloc = b[0xd];
    SWAP16((UINT16 *)&pdr->fatblock,(UINT16 *)&b[0xe]);
    pdr->numfats = b[0x10];
    SWAP16((UINT16 *)&pdr->numroot,(UINT16 *)&b[0x11]);
    SWAP16(&wvalue,(UINT16 *)&b[0x13]);
    pdr->numsecs = wvalue;
    pdr->mediadesc = b[0x15];
    SWAP16(&wvalue,(UINT16 *)&b[0x16]);
    pdr->secpfat = wvalue;
    SWAP16((UINT16 *)&pdr->secptrk,(UINT16 *)&b[0x18]);
    SWAP16((UINT16 *)&pdr->numhead,(UINT16 *)&b[0x1a]);
    SWAP32((UINT32 *)&pdr->numhide,(UINT32 *)&b[0x1c]);
    SWAP32((UINT32 *)&pdr->bignumsecs,(UINT32 *)&b[0x20]); 
              /* # secs if > 32M (4.0) */

    /******************************************************************
            Driver set drive fat type information from MBR
        PART_UNKNOWN(00h)   Unknown.  
        PART_DOS2_FAT(01h)  12-bit FAT.  
        PART_DOS3_FAT(04h)  16-bit FAT. Partition smaller than 32MB.  
        PART_EXTENDED(05h)  Extended MS-DOS Partition.  
        PART_DOS4_FAT(06h)  16-bit FAT. Partition larger than or equal to 32MB.  
        PART_DOS32(0Bh)     32-bit FAT. Partition up to 2047GB.  
        PART_DOS32X(0Ch)    Same as PART_DOS32(0Bh), but uses Logical Block Address 
                            Int 13h extensions.  
        PART_DOSX13(0Eh)    Same as PART_DOS4_FAT(06h), but uses Logical Block Address 
                            Int 13h extensions.  
        PART_DOSX13X(0Fh)  Same as PART_EXTENDED(05h), but uses Logical Block Address 
                            Int 13h extensions.  
     ******************************************************************/
    switch (NUF_Fat_Type[driveno])
    {
    case 1:
        pdr-> fasize = 3;
        break;
    case 4:
    case 6:
    case 0x0e:
        pdr-> fasize = 4;
        break;
    case 0x0b:
    case 0x0c:
        pdr-> fasize = 8;
        break;
    default:
        if ( (b[0x36] == 'F') && (b[0x37] == 'A') && (b[0x38] == 'T') && (b[0x39] == '1') )
        {
            if (b[0x3a] == '2')
                pdr-> fasize = 3;
            if (b[0x3a] == '6')
                pdr-> fasize = 4;
        }
        else if ( (b[0x52] == 'F') && (b[0x53] == 'A') && (b[0x54] == 'T') )
        {
            if ( (b[0x55] == '1') && (b[0x56] == '6') )
                pdr-> fasize = 4;
            if ( (b[0x55] == '3') && (b[0x56] == '2') )
                pdr-> fasize = 8;
        }
    }

    /* 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 = pdr->bignumsecs;

    /* Not set the NUF_Fat_Type */
    if (pdr->fasize == 0)
    {
        /* On trial calculate the clusters */
        pdr->maxfindex = (UINT32)
                (1 + (pdr->numsecs)/pdr->secpalloc);

        if (pdr->maxfindex < 0x0fff)
            pdr->fasize = 3;
        else if (pdr->maxfindex < 0xffff)
            pdr->fasize = 4;
        else
        {
            pdr->opencount = 0;
            return(NUF_FORMAT);
        }
    }

    if (pdr->fasize <= 4)
    {   /* FAT12/FAT16 */
        pdr->phys_num = b[0x24];
        pdr->xtbootsig = b[0x26];
        SWAP16((UINT16 *)&pdr->volid,(UINT16 *)&b[0x27]);   /* Unique number per volume (4.0) */
        copybuff(&pdr->vollabel[0],&b[0x2b],11); /* Volume label (4.0) */

        /* The first block of the root is just past the fat copies */
        pdr->rootblock = pdr->fatblock + pdr->secpfat * pdr->numfats;

        /* 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;

        if (pdr->fasize == 3)
            min_needed =(UINT16)(pdr->secpfat & 0x00FFFFL);
        else
            min_needed = 12;

         /* 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 = 2L;

         /* Keep track of how much free space is on the drive. (This will
            speed up pc_free()) when calculating free space */
        pdr->free_clusters_count = 0L;
    }
    else
    {   /* FAT32 */
        SWAP32((UINT32 *)&pdr->bigsecpfat,(UINT32 *)&b[0x24]);
        SWAP16((UINT16 *)&pdr->fat_flag,(UINT16 *)&b[0x28]);
        SWAP16((UINT16 *)&pdr->file_version,(UINT16 *)&b[0x2a]);
        SWAP32((UINT32 *)&pdr->rootdirstartcl,(UINT32 *)&b[0x2c]);  /* Root dir start cluster */
        SWAP32((UINT32 *)&pdr->volid,(UINT32 *)&b[0x43]); /* Unique number per volume (4.0) */
        copybuff(&pdr->vollabel[0],&b[0x47],11); /* Volume label (4.0) */

        /* The first block of the root is given */
        pdr->rootblock = pdr->fatblock + pdr->bigsecpfat * pdr->numfats;
        if (pdr->rootdirstartcl != 2L)
        {
            if (pdr->rootdirstartcl > 2L)
                pdr->rootblock += ((pdr->rootdirstartcl - 2L) * pdr->secpalloc);
            else
            {
                pdr->opencount = 0;
                return(NUF_FORMAT);
            }
        }

        /* The first block of the cluster area is the root dir */
        pdr->firstclblock = pdr->rootblock;

        min_needed = 16;
        pdr->secpfat = pdr->bigsecpfat;

        SWAP16((UINT16 *)&pdr->fsinfo,(UINT16 *)&b[0x30]);
        /* Read the File System INFOmation */
        PC_DRIVE_IO_ENTER(driveno)
        if ( !pc_bdevsw[driveno].io_proc(driveno, (UINT32) pdr->fsinfo, &b[0], (UINT16) 1, YES) )
        {
            PC_DRIVE_IO_EXIT(driveno)
            pc_report_error(PCERR_INITREAD);
            pdr->opencount = 0;
            return(NUF_IO_ERROR);

⌨️ 快捷键说明

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