📄 chkdsk.c
字号:
* 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, ¤t_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 + -