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

📄 chkdsk.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 4 页
字号:
 *      . updates gl.n_hidden_clusters     or ..
 *       . updates gl.n_file_clusters
 *  It then checks the bit map of already accounted for clusters, if the 
 *  cluster is accounted for it adds the cluster to the list of lost
 *  chains by calling add_cluster_to_crossed(), if another cluster in the
 *  chain was already found to be crossed we don't call add_cluster_to_crossed()
 *  since it works with the whole chain.
 *
 *  After the chain has been traversed its size is compared with the size 
 *  recorded in the directory. If they differ the file is printed and if -f
 *  was specified the size is adjusted.     
 */

short process_used_map(DROBJ *pobj, char *filename)                 /*__fn__*/
{
    CLTYPE cluster;
    CLTYPE n_clusters;
    CLTYPE proper_size;
    CLTYPE true_size;
    short is_dir;
    short is_hidden;
    short found_an_intersection;

    if (pc_isroot(pobj))
#if (!FAT32)
        return(TRUE);
#else   
    /* FAT32 stores the root directory as a cluster chain */
    {
        if (pobj->pdrive->fasize == 8) /* FAT32 volume */
        {
            cluster = pc_sec2cluster(pobj->pdrive,pobj->pdrive->rootblock);
            is_dir = TRUE;
        }
        else
            return(TRUE);
    }
#endif /* FAT32 */
    else
    {
        /* For tracking crossed chains. We only want to note the intersection
           points of lost chains not every cluster in the chain. */

        if (pobj->finode->fattribute & ADIRENT)
            is_dir = TRUE;
        else
        {
            if (pobj->finode->fattribute & AHIDDEN)
                is_hidden = TRUE;
            else
                is_hidden = FALSE;
            is_dir = FALSE;
        }
        cluster = pc_finode_cluster(pobj->pdrive, pobj->finode);
    }
    found_an_intersection = FALSE;
    n_clusters = 0;
    while (cluster)
    {
        n_clusters += 1;

        if ( (gl.cl_start <= cluster) && (cluster < gl.cl_end) )
        {
            /* If the cluster is already in use we have a problem it's 
               a crossed chain */
            if ( get_bit(gl.bm_used, cluster - gl.cl_start) )
            {
                if (!found_an_intersection)
                {
                    if (!add_cluster_to_crossed(cluster))
                        return(FALSE);
                    found_an_intersection = TRUE;
                }
            }
            set_bit(gl.bm_used, cluster - gl.cl_start);
        }

        cluster = pc_clnext(pobj->pdrive, cluster); 
    }

    if (gl.on_first_pass)
    {
        if (is_dir)
            gl.n_dir_clusters += n_clusters;
        else
        {
            if (is_hidden)
                gl.n_hidden_clusters += n_clusters;
            else
                gl.n_file_clusters += n_clusters;

            /* Check the file size here */
            /* Re-use the true size variable to save a little stack (we're 
               inside a recursive algorithm here */
#define cl_size_minus_1 true_size
            cl_size_minus_1 = pobj->pdrive->secpalloc;
            cl_size_minus_1 <<= 9; /* *= 512 */
            cl_size_minus_1 -=1; 
            /* This is how many bytes the file should occupy in the FAT. */
            proper_size = (pobj->finode->fsize + cl_size_minus_1) & ~cl_size_minus_1;
#undef cl_size_minus_1
            true_size = n_clusters;
            true_size <<= pobj->pdrive->log2_secpalloc;
            true_size <<= 9; /* *= 512 */
            if (proper_size != true_size)
            {
                /* Size in the directory entry doesn't match the size of the
                   chain. If -f was specified update the file size in the directory  */
                if (gl.write_chains)
                {
                    pobj->finode->fsize = true_size;
                    if (!pc_update_inode(pobj, TRUE, TRUE))
                    {
                        tm_printf_2("Failed Writing Adusted File:    %s\n", filename);
                        return(FALSE);
                    }
                    tm_printf_2("Size Adusted, File:    %s\n", filename);
                }
                else
                {
                    tm_printf_2("Size Needs Adusting, File:    %s\n", filename);
                }
            }
        }   
    } /* if (on_first_pass) */
    return(TRUE);
}

#if (VFAT)
/* scan_for_bad_lfns(DROBJ *pmom)
 *
 *  Scan through a directory and count all Win95 long file name errors. 
 *
 *  Errors detected:
 *      Bad lfn checksums
 *      Bad lfn sequence numbers
 *      Stray lfn chains
 *      Incomplete lfn chains
 * 
 *  If gl.delete_bad_lfn is set, free up the directory space used up by 
 *  invalid long file name information by deleting invalid chains
 *
 *  Returns: number of invalid lfn chains found
 *
 *  This fn is based on pc_findin (drobj.c)
 */

dword scan_for_bad_lfns(DROBJ *pmom)                                /*__fn__*/
{
DROBJ    *pobj;
BLKBUFF  *rbuf;
DIRBLK   *pd;
DOSINODE *pi;
LFNINODE *lfn_node;
SEGDESC  s;
byte     lastsegorder;
dword    bad_lfn_count;

    pc_zeroseglist(&s);
    lastsegorder = 0;

    /* pobj will be used to scan through the directory */
    pobj = pc_mkchild(pmom);
    if (!pobj)
        return(0);

    bad_lfn_count = 0;

    /* For convenience. We want to get at block info here   */
    pd = &pobj->blkinfo;
    
    /* Read the data   */
    pobj->pblkbuff = rbuf = pc_read_blk(pobj->pdrive, pobj->blkinfo.my_block);

    while (rbuf)
    {
        pi = (DOSINODE *) &rbuf->data[0];

        /* Look at the current inode   */
        pi += pd->my_index;

        while ( pd->my_index < INOPBLOCK )
        {
            /* End of dir if name is 0   */
            if (!pi->fname[0])
            {
                pc_free_buf(rbuf,FALSE);
                pc_freeobj(pobj);
                return(bad_lfn_count);
            }

            if (pi->fname[0] == PCDELETE)
            {
                if (s.nsegs)
                {
                    /* lfn chain interrupted by empty dir entry */
                    bad_lfn_count++;
                    if (gl.delete_bad_lfn)                  
                        pc_deleteseglist(pobj->pdrive, &s);
                    pc_zeroseglist(&s);
                    lastsegorder = 0;
                }
            }
            else
            {
                if (pi->fattribute == CHICAGO_EXT)
                {
                    /* Found a piece of an lfn */
                    lfn_node = (LFNINODE *) pi;
  
                    if (lfn_node->lfnorder & FIRST_NAMESEG)
                    {  
                        if (s.nsegs) /* if a chain already exists */
                        {
                            /* lfn chain begins in the middle of another one;
                               Delete the one that was interrupted, keep the
                               new one. */
                            bad_lfn_count++;
                            if (gl.delete_bad_lfn)                  
                                pc_deleteseglist(pobj->pdrive, &s);
                            pc_zeroseglist(&s);
                        }
                        lastsegorder = lfn_node->lfnorder;
                        pc_addtoseglist(&s, pd->my_block, pd->my_index);
                        s.ncksum = lfn_node->lfncksum;
                    } 
                    else
                    { 
                        /* optimization - the current segment should first be
                           linked onto the chain in each of the branches 
                           below */
                        pc_addtoseglist(&s, pd->my_block, pd->my_index);
                        if ((s.nsegs - 1) && 
                            (lfn_node->lfnorder & NAMESEG_ORDER) == (lastsegorder & NAMESEG_ORDER) - 1 &&
                            lfn_node->lfncksum == s.ncksum )
                        {
                            /* Sequence number and checksum match; Add new
                               segment to lfn chain   */
                            lastsegorder = lfn_node->lfnorder;
                        }
                        else
                        {
                            /* New segment has a checksum or sequence number
                               that doesn't match the current chain; Delete
                               the whole chain plus new segment */
                            bad_lfn_count++;
                            if (gl.delete_bad_lfn)                  
                                pc_deleteseglist(pobj->pdrive, &s);
                            pc_zeroseglist(&s);
                            lastsegorder = 0;
                        }
                    }
                }    
                else 
             /* if (pi->fattribute != CHICAGO_EXT) */
                {
                    /* Found a file entry - make sure our lfn chain matches
                       (if we have one) */
                    if (s.nsegs) /* if a chain has been built up */
                    {
                        if (pc_cksum((byte*)pi) != s.ncksum ||
                            (lastsegorder & NAMESEG_ORDER) != 1)
                        {
                            /* chain's checksum doesn't match the DOSINODE,
                               or the last sequence number isn't 1; Delete
                               the lfn chain */
                            bad_lfn_count++;
                            if (gl.delete_bad_lfn)                  
                                pc_deleteseglist(pobj->pdrive, &s);
                        }
                        /* We want to release this chain, whether good or bad */
                        pc_zeroseglist(&s); 
                        lastsegorder = 0;
                    }
                }       /* if (!CHICAGO_EXT) */            
            }           /* if (!PCDELETE) */
            pd->my_index++;
            pi++;
        }
        /* Current block is clean; go to next one */
        pc_free_buf(rbuf,FALSE);
        /* Update the objects block pointer */
        if (!pc_next_block(pobj))
            break;
        pd->my_index = 0;
        pobj->pblkbuff = rbuf = pc_read_blk(pobj->pdrive, pobj->blkinfo.my_block);
    }
    
    pc_freeobj(pobj);
    return (bad_lfn_count);
}
#endif /* VFAT */


/************************************************************************
 *                                                                      *
 * Lost cluster fns                                                     *
 *                                                                      *
 ************************************************************************/

/* check_lost_clusters(DDRIVE *pdr)
 *
 * This routine is called by (app_entry()) after scan_all_files() was called
 * to produce the bm_used bitmap of clusters cliamed by files and 
 * sub-direcories.
 * It scans the FILE allocation table. A cluster is lost if it
 * is allocated in the FAT but not in the bm_used bitmap we built up while
 * scanning the file system (scan_all_files()). We maintain an array of 
 * chain heads of lost clusters. 
 */

short check_lost_clusters(DDRIVE  *pdr)                             /*__fn__*/
{
    CLTYPE cluster;
    CLTYPE nxt;

    for (cluster = gl.cl_start ; cluster < gl.cl_end; cluster++)
    {

        if (!pc_faxx(pdr, cluster, &nxt))
        {
            return(FALSE);
        }
        if (nxt != 0)
        {
            /* If we didn't see the cluster during the directory scan */
            if ( !get_bit(gl.bm_used, cluster - gl.cl_start) )
            {
                /* ff(f)7 marks a bad cluster if it is not already in 
                   a chain. */
                if ( ((pdr->fasize == 3) && (nxt ==  0xff7)) || 
                     ((pdr->fasize == 4) && (nxt == 0xfff7)) 
#if (FAT32)
                     && ((pdr->fasize == 8) && (nxt == 0xfffffff7ul))
#endif /* FAT32 */      
                    )
                    gl.n_bad_clusters += 1;

                if ( ((pdr->fasize == 3) && ((nxt < 0xff0) || (nxt > 0xff8))) || 
                     ((pdr->fasize == 4) && ((nxt < 0xfff0) || (nxt > 0xfff8))) 
#if (FAT32)
                    || ((pdr->fasize == 8) && ((nxt < 0xfffffff0ul) || (nxt > 0xfffffff8ul)))
#endif /* FAT32 */
                    )
                {
                    /* And if it is not a bad or reserved cluster */
                    /* Add it to the lost list */
                    tm_printf_3("Add lost cluster %ld sector == %ld\n", (dword) cluster, pc_cl2sector(pdr, cluster));

                    if (!add_cluster_to_lost_list(pdr, cluster))
                        return(FALSE);
                }
            }

⌨️ 快捷键说明

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