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

📄 chkdsk.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * EBS - RTFS (Real Time File Manager)
 *
 * Copyright Peter Van Oudenaren , 1993
 * All rights reserved.
 * This code may not be redistributed in source or linkable object form
 * without the consent of its author.
 */
/****************************************************************************
    CHKDSK.C   - Check Files System Integrity
                       
Summary

    CHKDSK 

 Description
    This program scans the disk searching for crosslinked chains and 
    and lost clusters. If the -f argument is present it converts lost
    chains to FILE???.CHK in the root, and file sizes are adjusted if
    they are not correct.
    
    If -v is specified every file on the disk is listed. If crossed cluster
    chains are found the files/directories containing them are printed.

    NOTE: This program is portable except for calls to exit.

Bugs:
    This routine does not recognize bad directories as well as it could.
    While travesring directories it calls pc_fndnode(). This in itself is 
    good but we have to add validation code to fndnode and makenode (soon). 
    
Returns:

Example:


****************************************************************************/
/* Tips for usage:

      A. First run chkdsk without the "save lost clusters" option.
      B. If there are any crossed files make copies of them. Chances are all 
          copies will end up fine since copy will copy only file_size bytes. 
          Delete the original files.
      C. If there are crossed chains in a directory first recreate the 
          directory in another subdirectory. Then delete all files 
          and subdirectories inside the bad subdirectory. If the dir is
          crossed with a file treat the file as in part B.
      D. You will probably not be able to delete the bad directory
          because it is non-empty. There is no API call similar to the
          icheck -p call in unix. A very slightly modified version of
          pc_unlink() could provide this service (don't check for 
          ADIRENT).
      E. If any files are reported to have the wrong size make a copy of them.
      F. run chkdsk with "save lost clusters" on to fix up the file system.

*/

#if (defined(ERTFS_SA))
#include <pcdisk.h>
#else
/* load RTIP configuration settings */
#include "xnconf.h"
#include "drvconf.h"
#include <rtfsapi.h>
#include "demo.h"
#define tm_printf_2(X,Y) tm_printf(X,Y)
#define tm_printf_3(X,Y,Z) tm_printf(X,Y,Z)
#endif


// 10-24-2000 added LBA formatting. Submit to main tree

typedef CLUSTERTYPE CLTYPE;

/************************************************************************
 *                                                                      *
 * Function prototypes                                                  *
 *                                                                      *
 ************************************************************************/

  void app_entry(void);
  void print_statistics(void);
  void print_crossed_files(void);
 short allocate_chkdsk_core(CLTYPE maxfindex);
  void free_chkdsk_core(void);
 short write_lost_chains(void);
 short build_chk_file(long bad_chain_no, long current_file_no, long *ret_file_no);
 short scan_all_files(char *dir_name);
 short process_used_map(DROBJ *pobj, char *filename);
 dword scan_for_bad_lfns(DROBJ *pmom);
 short scan_crossed_files(char *dir_name);
 short process_crossed_file(DROBJ *pobj, char *filename);
 short add_cluster_to_lost_list(DDRIVE  *pdr , CLTYPE cluster);
 short check_lost_clusters(DDRIVE  *pdr);
 dword count_lost_clusters(DDRIVE *pdr);
 short add_cluster_to_crossed(CLTYPE cluster);
CLTYPE chain_size(CLTYPE cluster);
  void clr_bit(byte *bitmap, dword index);
  byte get_bit(byte *bitmap, dword index);
  void set_bit(byte *bitmap, dword index);


/************************************************************************
 *                                                                      *
 * Programmer modifiable constants                                      *
 *                                                                      *
 ************************************************************************/

#define NCROSSED_ALLOWED 50                                               
    /* For controlling how much to alloc. You may change it . */

#define NLOST_ALLOWED 50     
    /* For controlling how much to alloc. You may change it . */

#define MAX_RECURSION_DEPTH 8 
    /* For controlling how deep you will allow the directory traversal to 
    go. This guards against stack overflow in systems with deeply nested 
    subdirectories. Each recursion chews up around 160 bytes if EMAXPATH 
    is 145. Less if EMAXPATH is smaller. */

#define CL_WINDOW_SIZE 0x10000L 
    /* This is the size of the largest number of clusters that can be 
    scanned for crossed and lost chains on a single pass:
    (# of passes) = (# of clusters)/CL_WINDOW_SIZE */

#define CL_BITMAP_SIZE (int) ((CL_WINDOW_SIZE+7)/8)
    /* Size of the bitmap needed to process CL_WINDOW_SIZE clusters on a
    single pass */


/************************************************************************
 *                                                                      *
 * CHKDSK parameters - set parameters here if no console input is       *
 *  available                                                           *
 *                                                                      *
 ************************************************************************/

#define DRIVE_TO_CHECK "A:" 
    /* Drive letter to scan */

#define VERBOSE TRUE 
    /* Set to TRUE for verbose mode; FALSE for silent mode */

#define WRITE_CHAINS FALSE 
    /* Will save lost clusters in FILE???.CHK */

#if (VFAT)
#define DELETE_BAD_LFNS FALSE 
    /* Will delete any invalid long file name information lying around */
#endif /* VFAT */


/************************************************************************
 *                                                                      *
 * CHKDSK data structures                                               *
 *                                                                      *
 ************************************************************************/

typedef struct crossed_file {
    char  file_name[EMAXPATH];
    struct crossed_file *pnext;
} CROSSED_FILE;

typedef struct crossing_point {
    CLTYPE cluster;
    struct crossed_file *plist;
} CROSSING_POint;

/* The program uses a lot of global data. To keep it manageable we put
   it all in one big structure. */

typedef struct chk_global {
    short  write_chains;                    /* TRUE if -f flag  */
    DDRIVE *drive_structure;                /* The drive we are working on */
    dword  n_user_files;                    /* Total #user files found */
    dword  n_hidden_files;                  /* Total #hidden files found */
    dword  n_user_directories;              /* Total #directories found */
    CLTYPE n_free_clusters;                 /* # free available clusters */
    CLTYPE n_bad_clusters;                  /* # clusters marked bad */
    CLTYPE n_file_clusters;                 /* Clusters in non hidden files */
    CLTYPE n_hidden_clusters;               /* Clusters in hidden files */
    CLTYPE n_dir_clusters;                  /* Clusters in directories */
    CROSSED_FILE *crossed_file_freelist;    /* Freelist of crossed file structures */
    CROSSING_POint crossed_points[NCROSSED_ALLOWED]; /* Array: containing 
                                               cluster number and a list of 
                                               files crossed at that cluster. */
    dword  n_crossed_points;                /* Number of crossed chains. */
    CLTYPE lost_chain_list[NLOST_ALLOWED];  /* Array listheads of lost chains */
    dword  n_lost_chains;                   /* # lost chains */
    dword  n_lost_clusters;                 /* # lost clusters */
    byte  bm_used[CL_BITMAP_SIZE];          /* Bitmap of all clusters used
                                               by directories/files */
    short be_verbose;                       /* BE_VERBOSE */
    /* Use a global buffer so we don't load the stack up during recursion */
    char gl_file_name[13];
    char gl_file_path[EMAXPATH];
    short recursion_depth;                  /* how deep in the stack we are */

#if (VFAT)
    dword n_bad_lfns;               /* # corrupt/disjoint win95 lfn chains */
    short delete_bad_lfn;
#endif /* VFAT */

    /* These fields bound the cluster map processing so we can process 
       disks with very large FATs by making multiple passes */
    dword cl_start;     
    dword cl_end;       
    short on_first_pass;
} CHK_GLOBAL;


/************************************************************************
 *                                                                      *
 * GLOBAL DATA                                                          *
 *                                                                      *
 ************************************************************************/

/* This is where all the globals are kept. */
CHK_GLOBAL KS_FAR gl;
CROSSED_FILE KS_FAR crossed_file_core[NCROSSED_ALLOWED]; /* Base of the list */


/************************************************************************
 *                                                                      *
 * MAIN PROGRAM                                                         *
 *                                                                      *
 ************************************************************************/


void check_disk(char *drive_id, int write_chains)
{
    char drive_to_check[8];
    short drive_number;

    tc_memset((PFBYTE)&gl, 0, sizeof(gl));
    pc_str2upper(drive_to_check, drive_id);
    gl.write_chains = write_chains;
    gl.be_verbose = VERBOSE;
#if (VFAT)
    gl.delete_bad_lfn = DELETE_BAD_LFNS;
#endif /* VFAT */

    /* Initialize filesystem memory */
    VOID_CHECK_MEM()    /* Make sure memory is initted */

    /* "Mount" the disk */
    drive_number = (short) check_drive(drive_to_check);
    if (drive_number < 0)
    {
        goto ex_it;
    }
    
    gl.drive_structure = pc_drno2dr(drive_number);
    if (!pc_setdfltdrvno(drive_number))
    {
        tm_printf_2("Error Accessing: %s\n", drive_to_check);
        goto ex_it;
    }

    /* Allocate the bit maps and data structures we'll need we pass in
       the size of the fat so we know how many bits we'll need to allocate
       in our "used" bitmap. */
    if (!allocate_chkdsk_core(gl.drive_structure->maxfindex))
    {
        tm_printf("Failed Allocating Core To Run\n");
        goto ex_it;
    }

    gl.on_first_pass = 1;
    gl.cl_start = 2;
    gl.cl_end = CL_WINDOW_SIZE + 2;
    if (gl.cl_end > gl.drive_structure->maxfindex+1)
        gl.cl_end = gl.drive_structure->maxfindex+1;

    while (gl.cl_start < gl.drive_structure->maxfindex)
    {
        gl.n_user_files = 0;
        gl.n_hidden_files = 0;
        gl.n_user_directories = 0;

        /* Build a "used" map plus get statistics on cluster usage */    
        if (!scan_all_files("\\"))
        {
            tm_printf("Failed Scanning Disk Files\n");
            goto ex_it;
        }
        
        /* Now check if any allocated clusters are unaccounted for */
        if (!check_lost_clusters(gl.drive_structure))
        {
            tm_printf("Failed Scanning FAT\n");
            goto ex_it;
        }

        /* Advance the active cluster window */
        gl.cl_start = gl.cl_end;
        gl.cl_end += CL_WINDOW_SIZE;
        if (gl.cl_end > gl.drive_structure->maxfindex+1)
            gl.cl_end = gl.drive_structure->maxfindex+1;
        gl.on_first_pass = 0;

        /* Clear the used cluster table */
        tc_memset((PFBYTE)gl.bm_used,0,CL_BITMAP_SIZE);
    }

    
    /* If there are lost chains count the clusters inside. */
    if (gl.n_lost_chains)
        count_lost_clusters(gl.drive_structure);

    /* Now recover lost chains into .CHK files */
    if (gl.n_lost_chains)
    {
        if (gl.write_chains)
        {
            tm_printf("      Creating .CHK Files\n");
            if (!write_lost_chains())
            {
                tm_printf("Failed creating .CHK Files\n");
                goto ex_it;
            }
        }
        else
           tm_printf("      Use -f option to create .CHK files\n");
    }

    /* If there are crossed chains we have to rescan the whole file
       system looking for the files that contain he crossed chains. */
    if (gl.n_crossed_points)
    {
        if (!scan_crossed_files("\\"))
        {
            tm_printf("Failed Scanning Crossed Files\n");
            goto ex_it;
        }
    }
    
    /* Now print the statistics */
    print_statistics();

    /* print the names of files with crossed chains. */
    if (gl.n_crossed_points)
    {
        tm_printf("      Crossed Chains Were Found\n");
        print_crossed_files();
    }

ex_it:
    return;
}

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

⌨️ 快捷键说明

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