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

📄 chkdsk.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 4 页
字号:
 * User I/O functions                                                   *
 *                                                                      *
 ************************************************************************/

void print_statistics()                                             /*__fn__*/
{
    dword ltemp;
                             
    tm_printf_3("       %ld user files in %ld directories\n", (dword)gl.n_user_files, (dword)gl.n_user_directories);
    ltemp = gl.drive_structure->numsecs;
    tm_printf_2("    %10.10ld KBytes total disk space\n", (dword)(ltemp/2));

    ltemp =  (dword) gl.n_hidden_clusters;
    ltemp *= (dword) gl.drive_structure->secpalloc;
    tm_printf_3("    %10.10ld KBytes in %ld hidden files\n", (dword)(ltemp/2), (dword)gl.n_hidden_files);

    ltemp =  (dword) gl.n_dir_clusters;
    ltemp *= (dword) gl.drive_structure->secpalloc;
    ltemp += (dword) gl.drive_structure->secproot;
    tm_printf_3("    %10.10ld KBytes in %ld directories\n", (dword)(ltemp/2), (dword)gl.n_user_directories);

    ltemp =  (dword) gl.n_file_clusters;
    ltemp *= (dword) gl.drive_structure->secpalloc;
    tm_printf_3("    %10.10ld KBytes in %ld user files\n", (dword)(ltemp/2), (dword)gl.n_user_files);

    ltemp =  (dword) gl.n_bad_clusters;
    ltemp *= (dword) gl.drive_structure->secpalloc;
    tm_printf_2("    %10.10ld KBytes in bad sectors\n", (dword)(ltemp/2));

    ltemp =  (dword) gl.n_free_clusters;
    ltemp *= (dword) gl.drive_structure->secpalloc;
    tm_printf_2("    %10.10ld KBytes available on disk\n", (dword)(ltemp/2));

    tm_printf_2("\n    %6.6u Bytes Per Allocation Unit\n", gl.drive_structure->secpalloc * 512);
    tm_printf_2("    %8.8ld Total Allocation Units On Disk\n", (dword)(gl.drive_structure->maxfindex - 1));
    tm_printf_2("    %8.8ld Available Allocation Units On Disk\n", (dword)gl.n_free_clusters);

    tm_printf("\n");
    if (gl.n_lost_chains)
    {
        tm_printf_3 ("        %6.6ld lost clusters found in %6.6ld lost chains\n", (dword)gl.n_lost_clusters, (dword)gl.n_lost_chains);
    }

#if (VFAT)
    if (gl.n_bad_lfns)
    {
        if (gl.delete_bad_lfn)                  
            tm_printf_2 ("%6.6ld bad long file name chains found and deleted\n", (dword)gl.n_bad_lfns);
        else
            tm_printf_2 ("%6.6ld bad long file name chains found\n", (dword)gl.n_bad_lfns);
    }
#endif /* VFAT */
}

/* Print the names of all files that we were able to determine were crossed */
void print_crossed_files()                                          /*__fn__*/
{
    short i;
    CROSSED_FILE *pcross;
    short n_printed;

    for (i = 0; i < (short) gl.n_crossed_points; i++)
    {
        tm_printf_2("      Chains Crossed at Cluster %ld\n", (long) gl.crossed_points[i].cluster);
        pcross = gl.crossed_points[i].plist;
        n_printed = 0;
        while (pcross)
        {
            tm_printf_2("             %s\n", pcross->file_name);
            pcross = pcross->pnext;
            n_printed += 1;
        }
        if (!n_printed)
            tm_printf("       Lost Chains\n");
        else if (n_printed == 1)
            tm_printf("       A Lost Chain\n");
    }
}


/************************************************************************
 *                                                                      *
 * Init/exit functions                                                  *
 *                                                                      *
 ************************************************************************/

/* Allocate core for bitmaps, lost chains and crossed files. */
short allocate_chkdsk_core(CLTYPE maxfindex)                        /*__fn__*/
{
    long i;
    
    gl.recursion_depth = 0;

    tc_memset((PFBYTE)gl.bm_used, 0, CL_BITMAP_SIZE);
    tc_memset((PFBYTE)gl.crossed_points, 0, NCROSSED_ALLOWED*sizeof(CROSSING_POint));
    tc_memset((PFBYTE)gl.lost_chain_list, 0, NLOST_ALLOWED * sizeof(CLTYPE));
    /* Build a freelist we can use for crossed files */
    gl.crossed_file_freelist = crossed_file_core;
    for (i = 0; i < NCROSSED_ALLOWED-1; i++)
    {
        gl.crossed_file_freelist->pnext = gl.crossed_file_freelist+1;        
        gl.crossed_file_freelist++;
    }
    gl.crossed_file_freelist->pnext = 0;
    gl.crossed_file_freelist = crossed_file_core;
    return(TRUE);
}

void free_chkdsk_core()                                             /*__fn__*/
{
}


/************************************************************************
 *                                                                      *
 * Functions for saving lost chains to CHK files                        *
 *                                                                      *
 ************************************************************************/

/* Create a FILEXXXX.CHK file for each found lost chain */
short write_lost_chains()                                           /*__fn__*/
{
long current_chk_file;
long i;
    current_chk_file = 0;
    for (i = 0; i < (long) gl.n_lost_chains; i++)
    {
        if (!build_chk_file(i, current_chk_file, &current_chk_file))
            return(FALSE);
    }
    return(TRUE);
}

/* Given a lost chain number and a likely starting point for the 
   FILE???.CHK file create the file from the lost chain. */
short build_chk_file(long bad_chain_no, long current_file_no, long *ret_file_no)    /*__fn__*/
{
char filename[13];
long remainder;
long temp;
short fd;
PC_FILE *pfile;

    for ( ; current_file_no < 999;  current_file_no++)
    {
        /* Create a file name */
        tc_strcpy(filename, "\\FILE000.CHK");
        temp = (short) (current_file_no/100);
        filename[5] = (char) ('0' + temp);
        remainder = (short) (current_file_no - (temp * 100));
        temp = (short) (remainder/10);
        filename[6] = (char) ('0' + (char) temp);
        remainder = (short) (remainder - (temp * 10));
        filename[7] = (char) ('0' + remainder);

        /* Try to open it exclusive. This will fail if the file exists */
        fd = (short)po_open(filename, (word)PO_CREAT|PO_EXCL|PO_WRONLY, (word)PS_IREAD|PS_IWRITE);
        if (fd >= 0)
        {
            /* Get underneath the file and set the first cluster to the
               beginning of the lost_chain. */
            pfile = pc_fd2file(fd, FALSE);
            pc_pfinode_cluster(pfile->pobj->pdrive,pfile->pobj->finode,
                                         gl.lost_chain_list[bad_chain_no]);
            /* Update the size. */
            pfile->pobj->finode->fsize = chain_size(pc_finode_cluster(pfile->pobj->pdrive,pfile->pobj->finode));
            pfile->needs_flush = TRUE;
            /* Close the file. This will write everything out. */
            po_close(fd);
            break;
        }
    }

    /* If we get here it didn't work */
    if (current_file_no == 999)
        return(FALSE);

    /* Return the next ??? for FILE???.CHK that will probably work */
    *ret_file_no =  (short) (current_file_no + 1);
    return(TRUE);
}



/************************************************************************
 *                                                                      *
 * File/Directory Scanning                                              *
 *                                                                      *
 ************************************************************************/

/* Scan all files/directories on the drive - 
 *  Mark all used clusterd in the used bit map.
 *  Note any crossed cluster chains
 *  Adjust any incorrect file sizes
 */


/* int scan_all_files(char *dir_name)
 *
 *  This routine scans all subdirectories and does the following:
 *   . calculates gl.n_user_directories
 *   . calculates gl.n_hidden_files
 *   . calculates gl.n_user_files
 *       Then it calls process_used_map for each file in the directory and
 *       for the directory itself .
 *     process_used_map does the following:
 *   .       calculates gl.n_dir_clusters
 *   .       calculates gl.n_hidden_clusters
 *   .       calculates gl.n_file_clusters
 *   .       notes and if writing adjusts incorrect filesizes
 *   .       finds crossed chains
 *   . calls scan_for_bad_lfns (if VFAT is enabled)
 *   .
 *   . scan_all_files calls itself recursively for each subdirectory it
 *   . encounters.
 *   .    
 *   .
 */

short scan_all_files(char *dir_name)                                /*__fn__*/
{
DROBJ *directory;
DROBJ *entry;
char ldir_name[EMAXPATH];

    if (gl.recursion_depth > MAX_RECURSION_DEPTH)
    {
        tm_printf_2("Path too deep , directory %s\n", dir_name);
        return(FALSE);
    }
    gl.recursion_depth += 1;


#if (VFAT)
    /* Only do this on the first pass */
    if (gl.on_first_pass)
    {
        /* Find the directory again for scanning the dir for lfn errors */
        directory = pc_fndnode(dir_name);
        if (!directory)
        {
            tm_printf_2("Failed Scanning Directory %s on LFN Pass\n", dir_name);
            return(FALSE);
        }
        
        /* Scan through the directory looking for bad lfn data */
        gl.n_bad_lfns += scan_for_bad_lfns(directory);  
        pc_freeobj(directory);
    }
#endif /* VFAT */
        
    /* Find the directory for scanning the dir for files */
    directory = pc_fndnode(dir_name);
    if (!directory)
    {
        tm_printf_2("Failed Scanning Directory %s\n", dir_name);
        return(FALSE);
    }
    if (gl.be_verbose && gl.on_first_pass)
    {
        tm_printf_2("%s\n",dir_name);
    }
    if (!pc_isroot(directory))
        gl.n_user_directories += 1;

     /* Mark all of this Dirs clusters IN use, and look for crossed chains */
    if (!process_used_map(directory, dir_name))
    {
        pc_freeobj(directory);
        tm_printf_2("Failed Scanning Directory %s\n", dir_name);
        return(FALSE);
    }

    /* Scan through the directory looking for all files */
    entry = pc_get_inode(0,directory, (PFBYTE)"*", (PFBYTE)"*",TRUE);
    if (entry)
    {
        do 
        {
            if (!(entry->finode->fattribute & (AVOLUME | ADIRENT) ))
            {
                pc_mfile((byte*)gl.gl_file_name, (byte*)entry->finode->fname,(byte *) entry->finode->fext);
                pc_mpath((byte *)gl.gl_file_path, (byte *)dir_name, (byte *)gl.gl_file_name);
                if (gl.be_verbose && gl.on_first_pass)
                {
                    tm_printf_2("    %s\n", gl.gl_file_path);
                }
                if (entry->finode->fattribute & AHIDDEN)
                    gl.n_hidden_files += 1;
                else
                    gl.n_user_files += 1;
                /* Mark all of this File's clusters IN use, check the size
                   and look for crossed chains */
                if (!process_used_map(entry, gl.gl_file_path))
                {
                    pc_freeobj(entry);
                    pc_freeobj(directory);
                    tm_printf_2("Failed Scanning File %s\n", gl.gl_file_path);
                    return(FALSE);
                }
            }
        }     while (pc_get_inode(entry , directory, (PFBYTE)"*", (PFBYTE)"*",TRUE));
        pc_freeobj(entry);
    }
    pc_freeobj(directory);

    /* Now we call scan_all_files() for each subdirectory */
    /* Find the directory for scanning the dir for files */
    directory = pc_fndnode(dir_name);
    if (!directory)
    {
        tm_printf_2("Failed Scanning Directory %s\n", dir_name);
        return(FALSE);
    }

    /* Scan through the directory looking for all files */
    entry = pc_get_inode(0,directory, (PFBYTE)"*", (PFBYTE)"*",TRUE);
    if (entry)
    {
        do 
        {
            /* Scan it if it is a directory and not "." or ".." */
            if (entry->finode->fattribute & ADIRENT)
            {
                if ( !pc_isdot(entry->finode->fname, entry->finode->fext) && 
                     !pc_isdotdot(entry->finode->fname, entry->finode->fext) )
                {
                    pc_mfile((byte *)gl.gl_file_name, (byte *)entry->finode->fname, (byte *)entry->finode->fext);
                    pc_mpath((byte *)ldir_name, (byte *)dir_name, (byte *)gl.gl_file_name);
                    if (!scan_all_files(ldir_name))
                    {
                        pc_freeobj(directory);
                        pc_freeobj(entry);
                        return(FALSE);
                    }
                }
            }
        } while (pc_get_inode(entry , directory, (PFBYTE)"*", (PFBYTE)"*",TRUE));
        pc_freeobj(entry);
    }
    pc_freeobj(directory);
    gl.recursion_depth -= 1;

    return (TRUE);
}


/* process_used_map(DROBJ *pobj, char *filename)
 *
 *  This routine is called for each subdirectory and file in the system.
 *  It traverses the chain owned by drobj and does the following with each
 *  cluster in the chain:
 *      . updates gl.n_dir_clusters        or ..

⌨️ 快捷键说明

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