ReactOS  0.4.14-dev-98-gb0d4763
check.c File Reference
#include "vfatlib.h"
#include <debug.h>
Include dependency graph for check.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define PATH_NAME_MAX   1023
 
#define FSTART(p, fs)
 
#define MODIFY(p, i, v)
 
#define MODIFY_START(p, v, fs)
 

Functions

off_t alloc_rootdir_entry (DOS_FS *fs, DIR_ENT *de, const char *pattern, int gen_name)
 
static charpath_name (DOS_FILE *file)
 
static time_t date_dos2unix (unsigned short time, unsigned short date)
 
static charfile_stat (DOS_FILE *file)
 
static int bad_name (DOS_FILE *file)
 
static void lfn_remove (off_t from, off_t to)
 
static void drop_file (DOS_FS *fs, DOS_FILE *file)
 
static void truncate_file (DOS_FS *fs, DOS_FILE *file, uint32_t clusters)
 
static void auto_rename (DOS_FILE *file)
 
static void rename_file (DOS_FILE *file)
 
static int handle_dot (DOS_FS *fs, DOS_FILE *file, int dots)
 
static int check_file (DOS_FS *fs, DOS_FILE *file)
 
static int check_files (DOS_FS *fs, DOS_FILE *start)
 
static int check_dir (DOS_FS *fs, DOS_FILE **root, int dots)
 
static void test_file (DOS_FS *fs, DOS_FILE *file, int read_test)
 
static void undelete (DOS_FS *fs, DOS_FILE *file)
 
static void new_dir (void)
 
static void add_file (DOS_FS *fs, DOS_FILE ***chain, DOS_FILE *parent, off_t offset, FDSC **cp)
 
static int subdirs (DOS_FS *fs, DOS_FILE *parent, FDSC **cp)
 
static int scan_dir (DOS_FS *fs, DOS_FILE *this, FDSC **cp)
 
int scan_root (DOS_FS *fs)
 

Variables

static DOS_FILEroot
 
static const int day_n []
 

Macro Definition Documentation

◆ FSTART

#define FSTART (   p,
  fs 
)
Value:
((uint32_t)le16toh(p->dir_ent.start) | \
(fs->fat_bits == 32 ? le16toh(p->dir_ent.starthi) << 16 : 0))
Definition: fs.h:235
GLfloat GLfloat p
Definition: glext.h:8902
#define uint32_t
Definition: nsiface.idl:61

Definition at line 40 of file check.c.

◆ MODIFY

#define MODIFY (   p,
  i,
  v 
)
Value:
do { \
if (p->offset) { \
p->dir_ent.i = v; \
fs_write(p->offset+offsetof(DIR_ENT,i), \
sizeof(p->dir_ent.i),&p->dir_ent.i); \
} \
} while(0)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define offsetof(TYPE, MEMBER)
const GLdouble * v
Definition: gl.h:2040
GLfloat GLfloat p
Definition: glext.h:8902

Definition at line 44 of file check.c.

◆ MODIFY_START

#define MODIFY_START (   p,
  v,
  fs 
)
Value:
do { \
uint32_t __v = (v); \
if (!p->offset) { \
/* writing to fake entry for FAT32 root dir */ \
if (!__v) die("Oops, deleting FAT32 root dir!"); \
fs->root_cluster = __v; \
p->dir_ent.start = htole16(__v&0xffff); \
p->dir_ent.starthi = htole16(__v>>16); \
__v = htole32(__v); \
fs_write(offsetof(struct boot_sector,root_cluster), \
sizeof(((struct boot_sector *)0)->root_cluster), \
&__v); \
} \
else { \
MODIFY(p,start,htole16((__v)&0xffff)); \
if (fs->fat_bits == 32) \
MODIFY(p,starthi,htole16((__v)>>16)); \
} \
} while(0)
#define htole16(x)
Definition: storage32.h:546
Definition: fs.h:235
#define offsetof(TYPE, MEMBER)
#define htole32(x)
Definition: storage32.h:543
__u16 starthi
Definition: mkdosfs.c:365
const GLdouble * v
Definition: gl.h:2040
GLuint start
Definition: gl.h:1545
uint32_t root_cluster
Definition: fsck.fat.h:55
#define die(str)
Definition: mkdosfs.c:347
GLfloat GLfloat p
Definition: glext.h:8902

Definition at line 53 of file check.c.

◆ NDEBUG

#define NDEBUG

Definition at line 30 of file check.c.

◆ PATH_NAME_MAX

#define PATH_NAME_MAX   1023

Definition at line 35 of file check.c.

Function Documentation

◆ add_file()

static void add_file ( DOS_FS fs,
DOS_FILE ***  chain,
DOS_FILE parent,
off_t  offset,
FDSC **  cp 
)
static

Create a description for a referenced dentry and insert it in our dentry tree. Then, go check the dentry's cluster chain for bad clusters and cluster loops.

Parameters
[in,out]fsInformation about the filesystem
[out]chain
[in]parentInformation about parent directory of this file NULL == no parent ('file' is root directory)
[in]offsetPartition-relative byte offset of directory entry of interest 0 == Root directory
cp

Definition at line 1117 of file check.c.

1119 {
1120  DOS_FILE *new;
1121  DIR_ENT de;
1122  FD_TYPE type;
1123 
1124  if (offset)
1125  fs_read(offset, sizeof(DIR_ENT), &de);
1126  else {
1127  /* Construct a DIR_ENT for the root directory */
1128  memset(&de, 0, sizeof de);
1129  memcpy(de.name, " ", MSDOS_NAME);
1130  de.attr = ATTR_DIR;
1131  de.start = htole16(fs->root_cluster & 0xffff);
1132  de.starthi = htole16((fs->root_cluster >> 16) & 0xffff);
1133  }
1134  if ((type = file_type(cp, (char *)de.name)) != fdt_none) {
1135  if (type == fdt_undelete && (de.attr & ATTR_DIR))
1136  die("Can't undelete directories.");
1137  file_modify(cp, (char *)de.name);
1138  fs_write(offset, 1, &de);
1139  }
1140  if (IS_FREE(de.name)) {
1142  return;
1143  }
1144  if (de.attr == VFAT_LN_ATTR) {
1145  lfn_add_slot(&de, offset);
1146  return;
1147  }
1148  new = qalloc(&mem_queue, sizeof(DOS_FILE));
1149  new->lfn = lfn_get(&de, &new->lfn_offset);
1150  new->offset = offset;
1151  memcpy(&new->dir_ent, &de, sizeof(de));
1152  new->next = new->first = NULL;
1153  new->parent = parent;
1154  if (type == fdt_undelete)
1155  undelete(fs, new);
1156  **chain = new;
1157  *chain = &new->next;
1158  if (list) {
1159  printf("Checking file %s", path_name(new));
1160  if (new->lfn)
1161  printf(" (%s)", file_name(new->dir_ent.name)); /* (8.3) */
1162  printf("\n");
1163  }
1164  /* Don't include root directory, '.', or '..' in the total file count */
1165  if (offset &&
1166  strncmp((const char *)de.name, MSDOS_DOT, MSDOS_NAME) != 0 &&
1167  strncmp((const char *)de.name, MSDOS_DOTDOT, MSDOS_NAME) != 0)
1168  ++n_files;
1169  test_file(fs, new, test); /* Bad cluster check */
1170 }
char * name
Definition: wpp.c:36
static void undelete(DOS_FS *fs, DOS_FILE *file)
Definition: check.c:1065
#define new(TYPE, numElems)
Definition: treelist.c:54
unsigned n_files
GLintptr offset
Definition: glext.h:5920
#define htole16(x)
Definition: storage32.h:546
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
FD_TYPE
Definition: file.h:28
#define test
Definition: rosglue.h:37
void * qalloc(void **root, int size)
Definition: common.c:139
Definition: fs.h:235
void fs_write(off_t pos, int size, void *data)
Definition: io.c:344
void * mem_queue
smooth NULL
Definition: ftsmooth.c:416
struct sock * chain
Definition: tcpcore.h:1164
Definition: file.h:28
char * lfn_get(DIR_ENT *de, off_t *lfn_offset)
Definition: lfn.c:418
#define IS_FREE(n)
Definition: msdos_fs.h:44
#define MSDOS_NAME
Definition: msdos_fs.h:46
r parent
Definition: btrfs.c:2897
static char * path_name(DOS_FILE *file)
Definition: check.c:208
void fs_read(off_t pos, int size, void *data)
Definition: io.c:282
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
FD_TYPE file_type(FDSC **curr, char *fixed)
Definition: file.c:221
#define MSDOS_DOTDOT
Definition: msdos_fs.h:48
void lfn_check_orphaned(void)
Definition: lfn.c:517
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: _list.h:228
static void test_file(DOS_FS *fs, DOS_FILE *file, int read_test)
Definition: check.c:1005
void file_modify(FDSC **curr, char *fixed)
Definition: file.c:230
static LPCWSTR file_name
Definition: protocol.c:146
#define ATTR_DIR
Definition: mkdosfs.c:370
POINT cp
Definition: magnifier.c:59
void lfn_add_slot(DIR_ENT *de, off_t dir_offset)
Definition: lfn.c:206
#define MSDOS_DOT
Definition: msdos_fs.h:47
#define die(str)
Definition: mkdosfs.c:347
#define memset(x, y, z)
Definition: compat.h:39
#define VFAT_LN_ATTR
Definition: fsck.fat.h:78
#define printf
Definition: config.h:203

Referenced by scan_dir(), and scan_root().

◆ alloc_rootdir_entry()

off_t alloc_rootdir_entry ( DOS_FS fs,
DIR_ENT *  de,
const char pattern,
int  gen_name 
)

Definition at line 74 of file check.c.

75 {
76  static int curr_num = 0;
77  off_t offset;
78 
79  if (fs->root_cluster) {
80  DIR_ENT d2;
81  int i = 0, got = 0;
82  uint32_t clu_num, prev = 0;
83  off_t offset2;
84 
85  clu_num = fs->root_cluster;
86  offset = cluster_start(fs, clu_num);
87  while (clu_num > 0 && clu_num != -1) {
88  fs_read(offset, sizeof(DIR_ENT), &d2);
89  if (IS_FREE(d2.name) && d2.attr != VFAT_LN_ATTR) {
90  got = 1;
91  break;
92  }
93  i += sizeof(DIR_ENT);
94  offset += sizeof(DIR_ENT);
95  if ((i % fs->cluster_size) == 0) {
96  prev = clu_num;
97  if ((clu_num = next_cluster(fs, clu_num)) == 0 || clu_num == -1)
98  break;
99  offset = cluster_start(fs, clu_num);
100  }
101  }
102  if (!got) {
103  /* no free slot, need to extend root dir: alloc next free cluster
104  * after previous one */
105  if (!prev)
106  die("Root directory has no cluster allocated!");
107  for (clu_num = prev + 1; clu_num != prev; clu_num++) {
109 
110  if (clu_num >= fs->data_clusters + 2)
111  clu_num = 2;
112  get_fat(&entry, fs->fat, clu_num, fs);
113  if (!entry.value)
114  break;
115  }
116  if (clu_num == prev)
117  die("Root directory full and no free cluster");
118  set_fat(fs, prev, clu_num);
119  set_fat(fs, clu_num, -1);
120  set_owner(fs, clu_num, get_owner(fs, fs->root_cluster));
121  /* clear new cluster */
122  memset(&d2, 0, sizeof(d2));
123  offset = cluster_start(fs, clu_num);
124  for (i = 0; i < fs->cluster_size; i += sizeof(DIR_ENT))
125  fs_write(offset + i, sizeof(d2), &d2);
126  }
127  memset(de, 0, sizeof(DIR_ENT));
128  if (gen_name) {
129  while (1) {
130  char expanded[12];
131  sprintf(expanded, pattern, curr_num);
132  memcpy(de->name, expanded, MSDOS_NAME);
133  clu_num = fs->root_cluster;
134  i = 0;
135  offset2 = cluster_start(fs, clu_num);
136  while (clu_num > 0 && clu_num != -1) {
137  fs_read(offset2, sizeof(DIR_ENT), &d2);
138  if (offset2 != offset &&
139  !strncmp((const char *)d2.name, (const char *)de->name,
140  MSDOS_NAME))
141  break;
142  i += sizeof(DIR_ENT);
143  offset2 += sizeof(DIR_ENT);
144  if ((i % fs->cluster_size) == 0) {
145  if ((clu_num = next_cluster(fs, clu_num)) == 0 ||
146  clu_num == -1)
147  break;
148  offset2 = cluster_start(fs, clu_num);
149  }
150  }
151  if (clu_num == 0 || clu_num == -1)
152  break;
153  if (++curr_num >= 10000)
154  die("Unable to create unique name");
155  }
156  } else {
157  memcpy(de->name, pattern, MSDOS_NAME);
158  }
159  } else {
160  DIR_ENT *root;
161  int next_free = 0, scan;
162 
163  root = alloc(fs->root_entries * sizeof(DIR_ENT));
164  fs_read(fs->root_start, fs->root_entries * sizeof(DIR_ENT), root);
165 
166  while (next_free < fs->root_entries)
167  if (IS_FREE(root[next_free].name) &&
168  root[next_free].attr != VFAT_LN_ATTR)
169  break;
170  else
171  next_free++;
172  if (next_free == fs->root_entries)
173  die("Root directory is full.");
174  offset = fs->root_start + next_free * sizeof(DIR_ENT);
175  memset(de, 0, sizeof(DIR_ENT));
176  if (gen_name) {
177  while (1) {
178  char expanded[12];
179  sprintf(expanded, pattern, curr_num);
180  memcpy(de->name, expanded, MSDOS_NAME);
181  for (scan = 0; scan < fs->root_entries; scan++)
182  if (scan != next_free &&
183  !strncmp((const char *)root[scan].name,
184  (const char *)de->name, MSDOS_NAME))
185  break;
186  if (scan == fs->root_entries)
187  break;
188  if (++curr_num >= 10000)
189  die("Unable to create unique name");
190  }
191  } else {
192  memcpy(de->name, pattern, MSDOS_NAME);
193  }
194  free(root);
195  }
196  ++n_files;
197  return offset;
198 }
unsigned n_files
static HRESULT get_owner(VARIANT *user, VARIANT *domain, VARIANT *retval)
Definition: process.c:35
#define free
Definition: debug_ros.c:5
__kernel_off_t off_t
Definition: linux.h:201
GLintptr offset
Definition: glext.h:5920
void set_fat(DOS_FS *fs, uint32_t cluster, int32_t new)
Definition: fat.c:189
Definition: fs.h:235
void fs_write(off_t pos, int size, void *data)
Definition: io.c:344
#define sprintf(buf, format,...)
Definition: sprintf.c:55
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
uint32_t next_cluster(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:276
#define IS_FREE(n)
Definition: msdos_fs.h:44
#define MSDOS_NAME
Definition: msdos_fs.h:46
static char * gen_name(void)
Definition: parser.tab.c:6236
void fs_read(off_t pos, int size, void *data)
Definition: io.c:282
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
void set_owner(DOS_FS *fs, uint32_t cluster, DOS_FILE *owner)
Definition: fat.c:303
Definition: cookie.c:170
const char * root_entries[]
Definition: netreg.cpp:25
Definition: fsck.fat.h:192
uint32_t entry
Definition: isohybrid.c:63
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define alloc
Definition: rosglue.h:13
static DOS_FILE * root
Definition: check.c:37
UINT32 uint32_t
Definition: types.h:75
off_t cluster_start(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:289
Definition: name.c:36
#define die(str)
Definition: mkdosfs.c:347
#define memset(x, y, z)
Definition: compat.h:39
#define VFAT_LN_ATTR
Definition: fsck.fat.h:78
GLubyte * pattern
Definition: glext.h:7787
WCHAR * name
Definition: name.c:40
void get_fat(FAT_ENTRY *entry, void *fat, uint32_t cluster, DOS_FS *fs)
Definition: fat.c:41

Referenced by reclaim_file(), and write_volume_label().

◆ auto_rename()

static void auto_rename ( DOS_FILE file)
static

Definition at line 419 of file check.c.

420 {
421  DOS_FILE *first, *walk;
423 
424  if (!file->offset)
425  return; /* cannot rename FAT32 root dir */
426  first = file->parent ? file->parent->first : root;
427  number = 0;
428  while (1) {
429  char num[8];
430  sprintf(num, "%07lu", (unsigned long)number);
431  memcpy(file->dir_ent.name, "FSCK", 4);
432  memcpy(file->dir_ent.name + 4, num, 7);
433  for (walk = first; walk; walk = walk->next)
434  if (walk != file
435  && !strncmp((const char *)walk->dir_ent.name,
436  (const char *)file->dir_ent.name, MSDOS_NAME))
437  break;
438  if (!walk) {
439  if (file->dir_ent.lcase & FAT_NO_83NAME) {
440  /* as we only assign a new 8.3 filename, reset flag that 8.3 name is not
441  present */
442  file->dir_ent.lcase &= ~FAT_NO_83NAME;
443  /* reset the attributes, only keep DIR and VOLUME */
444  file->dir_ent.attr &= ~(ATTR_DIR | ATTR_VOLUME);
445  fs_write(file->offset, MSDOS_NAME + 2, &file->dir_ent);
446  } else {
447  fs_write(file->offset, MSDOS_NAME, file->dir_ent.name);
448  }
449  if (file->lfn)
450  lfn_fix_checksum(file->lfn_offset, file->offset,
451  (const char *)file->dir_ent.name);
452  return;
453  }
454  number++;
455  if (number > 9999999) {
456  die("Too many files need repair.");
457  }
458  }
459  die("Can't generate a unique name.");
460 }
void lfn_fix_checksum(off_t from, off_t to, const char *short_name)
Definition: lfn.c:181
#define ATTR_VOLUME
Definition: mkdosfs.c:369
const GLint * first
Definition: glext.h:5794
DIR_ENT dir_ent
Definition: fsck.fat.h:183
void fs_write(off_t pos, int size, void *data)
Definition: io.c:344
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define FAT_NO_83NAME
Definition: fsck.fat.h:238
char name[1]
Definition: fci.c:135
static size_t double number
Definition: printf.c:64
#define MSDOS_NAME
Definition: msdos_fs.h:46
struct _dos_file * next
Definition: fsck.fat.h:188
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
GLuint GLuint num
Definition: glext.h:9618
cab_ULONG offset
Definition: fci.c:130
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static DOS_FILE * root
Definition: check.c:37
UINT32 uint32_t
Definition: types.h:75
#define ATTR_DIR
Definition: mkdosfs.c:370
#define die(str)
Definition: mkdosfs.c:347
Definition: fci.c:126

Referenced by check_dir(), and handle_dot().

◆ bad_name()

static int bad_name ( DOS_FILE file)
static

Definition at line 296 of file check.c.

297 {
298  int i, spc, suspicious = 0;
299  const char *bad_chars = atari_format ? "*?\\/:" : "*?<>|\"\\/:";
300  const unsigned char *name = file->dir_ent.name;
301  const unsigned char *ext = name + 8;
302 
303  /* Do not complain about (and auto-correct) the extended attribute files
304  * of OS/2. */
305  if (strncmp((const char *)name, "EA DATA SF", 11) == 0 ||
306  strncmp((const char *)name, "WP ROOT SF", 11) == 0)
307  return 0;
308 
309  /* check if we have neither a long filename nor a short name */
310  if ((file->lfn == NULL) && (file->dir_ent.lcase & FAT_NO_83NAME)) {
311  return 1;
312  }
313 
314  /* don't complain about the dummy 11 bytes used by patched Linux
315  kernels */
316  if (file->dir_ent.lcase & FAT_NO_83NAME)
317  return 0;
318 
319  for (i = 0; i < MSDOS_NAME; i++) {
320  if (name[i] < ' ' || name[i] == 0x7f)
321  return 1;
322  if (name[i] > 0x7f)
323  ++suspicious;
324  if (strchr(bad_chars, name[i]))
325  return 1;
326  }
327 
328  spc = 0;
329  for (i = 0; i < 8; i++) {
330  if (name[i] == ' ')
331  spc = 1;
332  else if (spc)
333  /* non-space after a space not allowed, space terminates the name
334  * part */
335  return 1;
336  }
337 
338  spc = 0;
339  for (i = 0; i < 3; i++) {
340  if (ext[i] == ' ')
341  spc = 1;
342  else if (spc)
343  /* non-space after a space not allowed, space terminates the ext
344  * part */
345  return 1;
346  }
347 
348  /* Under GEMDOS, chars >= 128 are never allowed. */
349  if (atari_format && suspicious)
350  return 1;
351 
352 #ifdef __REACTOS__ // Old !!!!!!!!!!!!!!!
353 
354  /* Only complain about too much suspicious chars in interactive mode,
355  * never correct them automatically. The chars are all basically ok, so we
356  * shouldn't auto-correct such names. */
357  if (interactive && suspicious > 6)
358  return 1;
359  return 0;
360 
361 #else
362 
363  /* Under MS-DOS and Windows, chars >= 128 in short names are valid
364  * (but these characters can be visualised differently depending on
365  * local codepage: CP437, CP866, etc). The chars are all basically ok,
366  * so we shouldn't auto-correct such names. */
367  return 0;
368 
369 #endif
370 }
#define interactive
Definition: rosglue.h:34
#define FAT_NO_83NAME
Definition: fsck.fat.h:238
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
char name[1]
Definition: fci.c:135
smooth NULL
Definition: ftsmooth.c:416
char ext[3]
Definition: mkdosfs.c:358
int atari_format
#define MSDOS_NAME
Definition: msdos_fs.h:46
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strchr(const char *String, int ch)
Definition: utclib.c:501
Definition: name.c:36
Definition: fci.c:126

Referenced by check_dir().

◆ check_dir()

static int check_dir ( DOS_FS fs,
DOS_FILE **  root,
int  dots 
)
static

Definition at line 826 of file check.c.

827 {
828  DOS_FILE *parent, **walk, **scan;
829  int dot, dotdot, skip, redo;
830  int good, bad;
831 
832  if (!*root)
833  return 0;
834  parent = (*root)->parent;
835  good = bad = 0;
836  for (walk = root; *walk; walk = &(*walk)->next)
837  if (bad_name(*walk))
838  bad++;
839  else
840  good++;
841  if (*root && parent && good + bad > 4 && bad > good / 2) {
842  printf("%s\n Has a large number of bad entries. (%d/%d)\n",
843  path_name(parent), bad, good + bad);
844  if (!dots)
845  printf(" Not dropping root directory.\n");
846 #ifndef __REACTOS__
847  else if (!interactive)
848 #else
849  else if (!interactive || !rw)
850 #endif
851  printf(" Not dropping it in auto-mode.\n");
852  else if (get_key("yn", "Drop directory ? (y/n)") == 'y') {
853  truncate_file(fs, parent, 0);
855  /* buglet: deleted directory stays in the list. */
856  return 1;
857  }
858  }
859  dot = dotdot = redo = 0;
860  walk = root;
861  while (*walk) {
862  if (!strncmp
863  ((const char *)((*walk)->dir_ent.name), MSDOS_DOT, MSDOS_NAME)
864  || !strncmp((const char *)((*walk)->dir_ent.name), MSDOS_DOTDOT,
865  MSDOS_NAME)) {
866  if (handle_dot(fs, *walk, dots)) {
867  *walk = (*walk)->next;
868  continue;
869  }
870  if (!strncmp
871  ((const char *)((*walk)->dir_ent.name), MSDOS_DOT, MSDOS_NAME))
872  dot++;
873  else
874  dotdot++;
875  }
876  if (!((*walk)->dir_ent.attr & ATTR_VOLUME) && bad_name(*walk)) {
877 #ifndef __REACTOS__
878  puts(path_name(*walk));
879  printf(" Bad short file name (%s).\n",
880  file_name((*walk)->dir_ent.name));
881 #else
882  printf("%s\n Bad short file name (%s).\n",
883  path_name(*walk), file_name((*walk)->dir_ent.name));
884 #endif
885  if (interactive)
886  printf("1) Drop file\n2) Rename file\n3) Auto-rename\n"
887  "4) Keep it\n");
888  else
889 #ifdef __REACTOS__
890  if (rw)
891 #endif
892  printf(" Auto-renaming it.\n");
893 #ifdef __REACTOS__
894  if (rw || interactive) {
895 #endif
896  switch (interactive ? get_key("1234", "?") : '3') {
897  case '1':
898  drop_file(fs, *walk);
899  walk = &(*walk)->next;
900  continue;
901  case '2':
902  rename_file(*walk);
903  redo = 1;
904  break;
905  case '3':
906  auto_rename(*walk);
907  printf(" Renamed to %s\n", file_name((*walk)->dir_ent.name));
908  break;
909  case '4':
910  break;
911 #ifdef __REACTOS__
912  }
913 #endif
914  }
915  }
916  /* don't check for duplicates of the volume label */
917  if (!((*walk)->dir_ent.attr & ATTR_VOLUME)) {
918  scan = &(*walk)->next;
919  skip = 0;
920  while (*scan && !skip) {
921  if (!((*scan)->dir_ent.attr & ATTR_VOLUME) &&
922  !memcmp((*walk)->dir_ent.name, (*scan)->dir_ent.name,
923  MSDOS_NAME)) {
924  printf("%s\n Duplicate directory entry.\n First %s\n",
925  path_name(*walk), file_stat(*walk));
926  printf(" Second %s\n", file_stat(*scan));
927  if (interactive)
928  printf
929  ("1) Drop first\n2) Drop second\n3) Rename first\n"
930  "4) Rename second\n5) Auto-rename first\n"
931  "6) Auto-rename second\n");
932  else
933 #ifdef __REACTOS__
934  if (rw)
935 #endif
936  printf(" Auto-renaming second.\n");
937 #ifdef __REACTOS__
938  if (rw || interactive) {
939 #endif
940  switch (interactive ? get_key("123456", "?") : '6') {
941  case '1':
942  drop_file(fs, *walk);
943  *walk = (*walk)->next;
944  skip = 1;
945  break;
946  case '2':
947  drop_file(fs, *scan);
948  *scan = (*scan)->next;
949  continue;
950  case '3':
951  rename_file(*walk);
952  printf(" Renamed to %s\n", path_name(*walk));
953  redo = 1;
954  break;
955  case '4':
956  rename_file(*scan);
957  printf(" Renamed to %s\n", path_name(*walk));
958  redo = 1;
959  break;
960  case '5':
961  auto_rename(*walk);
962  printf(" Renamed to %s\n",
963  file_name((*walk)->dir_ent.name));
964  break;
965  case '6':
966  auto_rename(*scan);
967  printf(" Renamed to %s\n",
968  file_name((*scan)->dir_ent.name));
969  break;
970 #ifdef __REACTOS__
971  }
972 #endif
973  }
974  }
975  scan = &(*scan)->next;
976  }
977  if (skip)
978  continue;
979  }
980  if (!redo)
981  walk = &(*walk)->next;
982  else {
983  walk = root;
984  dot = dotdot = redo = 0;
985  }
986  }
987  if (dots && !dot)
988  printf("%s\n \".\" is missing. Can't fix this yet.\n",
989  path_name(parent));
990  if (dots && !dotdot)
991  printf("%s\n \"..\" is missing. Can't fix this yet.\n",
992  path_name(parent));
993  return 0;
994 }
#define DELETED_FLAG
Definition: msdos_fs.h:43
#define ATTR_VOLUME
Definition: mkdosfs.c:369
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static void truncate_file(DOS_FS *fs, DOS_FILE *file, uint32_t clusters)
Definition: check.c:401
#define MODIFY(p, i, v)
Definition: check.c:44
static void auto_rename(DOS_FILE *file)
Definition: check.c:419
#define interactive
Definition: rosglue.h:34
Definition: fs.h:235
static void drop_file(DOS_FS *fs, DOS_FILE *file)
Definition: check.c:388
static int handle_dot(DOS_FS *fs, DOS_FILE *file, int dots)
Definition: check.c:511
static void rename_file(DOS_FILE *file)
Definition: check.c:462
static int bad_name(DOS_FILE *file)
Definition: check.c:296
char get_key(const char *valid, const char *prompt)
Definition: common.c:184
#define MSDOS_NAME
Definition: msdos_fs.h:46
r parent
Definition: btrfs.c:2897
static char * path_name(DOS_FILE *file)
Definition: check.c:208
struct _dos_file * next
Definition: fsck.fat.h:188
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
int rw
#define MSDOS_DOTDOT
Definition: msdos_fs.h:48
int puts(const char *string)
Definition: crtsupp.c:23
static char * file_stat(DOS_FILE *file)
Definition: check.c:279
static DOS_FILE * root
Definition: check.c:37
static LPCWSTR file_name
Definition: protocol.c:146
#define skip(...)
Definition: atltest.h:64
Definition: name.c:36
#define MSDOS_DOT
Definition: msdos_fs.h:47
#define printf
Definition: config.h:203

Referenced by check_directory(), scan_dir(), and scan_root().

◆ check_file()

static int check_file ( DOS_FS fs,
DOS_FILE file 
)
static

Definition at line 560 of file check.c.

561 {
562  DOS_FILE *owner;
563  int restart;
564  uint32_t expect, curr, this, clusters, prev, walk, clusters2;
565 
566  if (file->dir_ent.attr & ATTR_DIR) {
567  if (le32toh(file->dir_ent.size)) {
568 #ifndef __REACTOS__
569  printf("%s\n Directory has non-zero size. Fixing it.\n",
570  path_name(file));
571 #else
572  printf("%s\n Directory has non-zero size.%s\n",
573  path_name(file), (rw) ? " Fixing it." : "");
574  if (rw)
575 #endif
576  MODIFY(file, size, htole32(0));
577  }
578  if (file->parent
579  && !strncmp((const char *)file->dir_ent.name, MSDOS_DOT,
580  MSDOS_NAME)) {
581  expect = FSTART(file->parent, fs);
582  if (FSTART(file, fs) != expect) {
583  printf("%s\n Start (%lu) does not point to parent (%lu)\n",
584  path_name(file), (unsigned long)FSTART(file, fs), (long)expect);
585 #ifdef __REACTOS__
586  if (rw)
587 #endif
589  }
590  return 0;
591  }
592  if (file->parent
593  && !strncmp((const char *)file->dir_ent.name, MSDOS_DOTDOT,
594  MSDOS_NAME)) {
595  expect =
596  file->parent->parent ? FSTART(file->parent->parent, fs) : 0;
597  if (fs->root_cluster && expect == fs->root_cluster)
598  expect = 0;
599  if (FSTART(file, fs) != expect) {
600  printf("%s\n Start (%lu) does not point to .. (%lu)\n",
601  path_name(file), (unsigned long)FSTART(file, fs), (unsigned long)expect);
602 #ifdef __REACTOS__
603  if (rw)
604 #endif
606  }
607  return 0;
608  }
609  if (FSTART(file, fs) == 0) {
610 #ifndef __REACTOS__
611  printf("%s\n Start does point to root directory. Deleting dir. \n",
612  path_name(file));
613 #else
614  printf("%s\n Start does point to root directory.%s\n",
615  path_name(file), (rw) ? " Deleting dir. " : "");
616  if (rw)
617 #endif
619  return 0;
620  }
621  }
622  if (FSTART(file, fs) == 1) {
623  printf("%s\n Bad start cluster 1. Truncating file.\n",
624  path_name(file));
625  if (!file->offset)
626  die("Bad FAT32 root directory! (bad start cluster 1)\n");
627 #ifdef __REACTOS__
628  if (rw)
629 #endif
630  MODIFY_START(file, 0, fs);
631  }
632  if (FSTART(file, fs) >= fs->data_clusters + 2) {
633  printf
634 #ifndef __REACTOS__
635  ("%s\n Start cluster beyond limit (%lu > %lu). Truncating file.\n",
636  path_name(file), (unsigned long)FSTART(file, fs),
637  (unsigned long)(fs->data_clusters + 1));
638 #else
639  ("%s\n Start cluster beyond limit (%lu > %lu).%s\n",
640  path_name(file), (unsigned long)FSTART(file, fs),
641  (unsigned long)(fs->data_clusters + 1),
642  (rw) ? " Truncating file." : "");
643 #endif
644  if (!file->offset)
645  die("Bad FAT32 root directory! (start cluster beyond limit: %lu > %lu)\n",
646  (unsigned long)FSTART(file, fs),
647  (unsigned long)(fs->data_clusters + 1));
648 #ifdef __REACTOS__
649  if (rw)
650 #endif
651  MODIFY_START(file, 0, fs);
652  }
653  clusters = prev = 0;
654  for (curr = FSTART(file, fs) ? FSTART(file, fs) :
655  -1; curr != -1; curr = next_cluster(fs, curr)) {
656  FAT_ENTRY curEntry;
657  get_fat(&curEntry, fs->fat, curr, fs);
658 
659  if (!curEntry.value || bad_cluster(fs, curr)) {
660 #ifndef __REACTOS__
661  printf("%s\n Contains a %s cluster (%lu). Assuming EOF.\n",
662  path_name(file), curEntry.value ? "bad" : "free", (unsigned long)curr);
663 #else
664  printf("%s\n Contains a %s cluster (%lu).%s\n",
665  path_name(file), curEntry.value ? "bad" : "free", (unsigned long)curr,
666  (rw) ? " Assuming EOF." : "");
667 #endif
668  if (prev)
669 #ifdef __REACTOS__
670  {
671  if (rw)
672 #endif
673  set_fat(fs, prev, -1);
674 #ifdef __REACTOS__
675  }
676 #endif
677  else if (!file->offset)
678  die("FAT32 root dir starts with a bad cluster!");
679  else
680 #ifdef __REACTOS__
681  if (rw)
682 #endif
683  MODIFY_START(file, 0, fs);
684  break;
685  }
686  if (!(file->dir_ent.attr & ATTR_DIR) && le32toh(file->dir_ent.size) <=
687  (uint64_t)clusters * fs->cluster_size) {
688 #ifdef __REACTOS__
689  if (rw) {
690 #endif
691  printf
692  ("%s\n File size is %u bytes, cluster chain length is > %llu "
693  "bytes.\n Truncating file to %u bytes.\n", path_name(file),
694  le32toh(file->dir_ent.size),
695  (unsigned long long)clusters * fs->cluster_size,
696  le32toh(file->dir_ent.size));
697  truncate_file(fs, file, clusters);
698 #ifdef __REACTOS__
699  } else {
700  printf
701  ("%s\n File size is %u bytes, cluster chain length is > %llu "
702  "bytes.\n", path_name(file),
703  le32toh(file->dir_ent.size),
704  (unsigned long long)clusters * fs->cluster_size);
705  }
706 #endif
707  break;
708  }
709  if ((owner = get_owner(fs, curr))) {
710  int do_trunc = 0;
711  printf("%s and\n", path_name(owner));
712  printf("%s\n share clusters.\n", path_name(file));
713  clusters2 = 0;
714  for (walk = FSTART(owner, fs); walk > 0 && walk != -1; walk =
715  next_cluster(fs, walk))
716  if (walk == curr)
717  break;
718  else
719  clusters2++;
720  restart = file->dir_ent.attr & ATTR_DIR;
721 #ifndef __REACTOS__
722  if (!owner->offset) {
723 #else
724  if (!owner->offset && rw) {
725 #endif
726  printf(" Truncating second to %llu bytes because first "
727  "is FAT32 root dir.\n",
728  (unsigned long long)clusters * fs->cluster_size);
729  do_trunc = 2;
730 #ifndef __REACTOS__
731  } else if (!file->offset) {
732 #else
733  } else if (!file->offset && rw) {
734 #endif
735  printf(" Truncating first to %llu bytes because second "
736  "is FAT32 root dir.\n",
737  (unsigned long long)clusters2 * fs->cluster_size);
738  do_trunc = 1;
739  } else if (interactive)
740  printf("1) Truncate first to %llu bytes%s\n"
741  "2) Truncate second to %llu bytes\n",
742  (unsigned long long)clusters2 * fs->cluster_size,
743  restart ? " and restart" : "",
744  (unsigned long long)clusters * fs->cluster_size);
745  else
746 #ifdef __REACTOS__
747  if (rw)
748 #endif
749  printf(" Truncating second to %llu bytes.\n",
750  (unsigned long long)clusters * fs->cluster_size);
751 #ifndef __REACTOS__
752  if (do_trunc != 2
753  && (do_trunc == 1
754 #else
755  if ((do_trunc != 2 && rw)
756  && ((do_trunc == 1 && rw)
757 #endif
758  || (interactive && get_key("12", "?") == '1'))) {
759  prev = 0;
760  clusters = 0;
761  for (this = FSTART(owner, fs); this > 0 && this != -1; this =
762  next_cluster(fs, this)) {
763  if (this == curr) {
764  if (prev)
765  set_fat(fs, prev, -1);
766  else
767  MODIFY_START(owner, 0, fs);
768  MODIFY(owner, size,
769  htole32((uint64_t)clusters *
770  fs->cluster_size));
771  if (restart)
772  return 1;
773  while (this > 0 && this != -1) {
774  set_owner(fs, this, NULL);
775  this = next_cluster(fs, this);
776  }
777  this = curr;
778  break;
779  }
780  clusters++;
781  prev = this;
782  }
783  if (this != curr)
784  die("Internal error: didn't find cluster %d in chain"
785  " starting at %d", curr, FSTART(owner, fs));
786  } else {
787  if (prev)
788  set_fat(fs, prev, -1);
789  else
790  MODIFY_START(file, 0, fs);
791  break;
792  }
793  }
794  set_owner(fs, curr, file);
795  clusters++;
796  prev = curr;
797  }
798  if (!(file->dir_ent.attr & ATTR_DIR) && le32toh(file->dir_ent.size) >
799 #ifndef __REACTOS__
800  (uint64_t)clusters * fs->cluster_size) {
801 #else
802  (uint64_t)clusters * fs->cluster_size && rw) {
803 #endif
804  printf
805  ("%s\n File size is %u bytes, cluster chain length is %llu bytes."
806  "\n Truncating file to %llu bytes.\n", path_name(file),
807  le32toh(file->dir_ent.size),
808  (unsigned long long)clusters * fs->cluster_size,
809  (unsigned long long)clusters * fs->cluster_size);
810  MODIFY(file, size,
811  htole32((uint64_t)clusters * fs->cluster_size));
812  }
813  return 0;
814 }
#define DELETED_FLAG
Definition: msdos_fs.h:43
off_t offset
Definition: fsck.fat.h:185
static void truncate_file(DOS_FS *fs, DOS_FILE *file, uint32_t clusters)
Definition: check.c:401
static HRESULT get_owner(VARIANT *user, VARIANT *domain, VARIANT *retval)
Definition: process.c:35
#define MODIFY(p, i, v)
Definition: check.c:44
void set_fat(DOS_FS *fs, uint32_t cluster, int32_t new)
Definition: fat.c:189
#define interactive
Definition: rosglue.h:34
Definition: fs.h:235
char name[1]
Definition: fci.c:135
smooth NULL
Definition: ftsmooth.c:416
#define htole32(x)
Definition: storage32.h:543
uint32_t next_cluster(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:276
void restart(int argc, const char *argv[])
Definition: cmds.c:2115
GLsizeiptr size
Definition: glext.h:5919
char get_key(const char *valid, const char *prompt)
Definition: common.c:184
#define MSDOS_NAME
Definition: msdos_fs.h:46
static char * path_name(DOS_FILE *file)
Definition: check.c:208
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
void set_owner(DOS_FS *fs, uint32_t cluster, DOS_FILE *owner)
Definition: fat.c:303
cab_ULONG offset
Definition: fci.c:130
cab_ULONG size
Definition: fci.c:129
int rw
#define MSDOS_DOTDOT
Definition: msdos_fs.h:48
Definition: fsck.fat.h:192
#define uint64_t
Definition: nsiface.idl:62
int bad_cluster(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:258
UINT64 uint64_t
Definition: types.h:77
#define long
Definition: qsort.c:33
uint32_t value
Definition: fsck.fat.h:193
#define expect(expected, got)
Definition: combo.c:36
UINT32 uint32_t
Definition: types.h:75
#define MODIFY_START(p, v, fs)
Definition: check.c:53
#define ATTR_DIR
Definition: mkdosfs.c:370
Definition: name.c:36
#define MSDOS_DOT
Definition: msdos_fs.h:47
#define die(str)
Definition: mkdosfs.c:347
#define FSTART(p, fs)
Definition: check.c:40
void get_fat(FAT_ENTRY *entry, void *fat, uint32_t cluster, DOS_FS *fs)
Definition: fat.c:41
#define printf
Definition: config.h:203
Definition: fci.c:126

Referenced by check_files().

◆ check_files()

static int check_files ( DOS_FS fs,
DOS_FILE start 
)
static

Definition at line 816 of file check.c.

817 {
818  while (start) {
819  if (check_file(fs, start))
820  return 1;
821  start = start->next;
822  }
823  return 0;
824 }
static int check_file(DOS_FS *fs, DOS_FILE *file)
Definition: check.c:560
Definition: fs.h:235
GLuint start
Definition: gl.h:1545

Referenced by scan_dir(), and scan_root().

◆ date_dos2unix()

static time_t date_dos2unix ( unsigned short  time,
unsigned short  date 
)
static

Definition at line 235 of file check.c.

236 {
237  int month, year;
238  time_t secs;
239 
240  month = ((date >> 5) & 15) - 1;
241  if (month < 0) {
242  /* make sure that nothing bad happens if the month bits were zero */
243  month = 0;
244  }
245  year = date >> 9;
246  secs =
247  (time & 31) * 2 + 60 * ((time >> 5) & 63) + (time >> 11) * 3600 +
248  86400 * ((date & 31) - 1 + day_n[month] + (year / 4) + year * 365 -
249  ((year & 3) == 0 && month < 2 ? 1 : 0) + 3653);
250  /* days since 1.1.70 plus 80's leap day */
251  return secs;
252 }
__u16 time
Definition: mkdosfs.c:366
__kernel_time_t time_t
Definition: linux.h:252
__u16 date
Definition: mkdosfs.c:366
static const int day_n[]
Definition: check.c:229
int month[12]
Definition: systime.c:13

Referenced by file_stat().

◆ drop_file()

static void drop_file ( DOS_FS fs,
DOS_FILE file 
)
static

Definition at line 388 of file check.c.

389 {
390  uint32_t cluster;
391 
393  if (file->lfn)
394  lfn_remove(file->lfn_offset, file->offset);
395  for (cluster = FSTART(file, fs); cluster > 0 && cluster <
396  fs->data_clusters + 2; cluster = next_cluster(fs, cluster))
397  set_owner(fs, cluster, NULL);
398  --n_files;
399 }
#define DELETED_FLAG
Definition: msdos_fs.h:43
unsigned n_files
#define MODIFY(p, i, v)
Definition: check.c:44
Definition: fs.h:235
smooth NULL
Definition: ftsmooth.c:416
static void lfn_remove(off_t from, off_t to)
Definition: check.c:372
uint32_t next_cluster(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:276
void set_owner(DOS_FS *fs, uint32_t cluster, DOS_FILE *owner)
Definition: fat.c:303
cab_ULONG offset
Definition: fci.c:130
UINT32 uint32_t
Definition: types.h:75
Definition: name.c:36
#define FSTART(p, fs)
Definition: check.c:40
Definition: fci.c:126

Referenced by check_dir(), and handle_dot().

◆ file_stat()

static char* file_stat ( DOS_FILE file)
static

Definition at line 279 of file check.c.

280 {
281  static char temp[100];
282  struct tm *tm;
283  char tmp[100];
284  time_t date;
285 
286  date =
287  date_dos2unix(le16toh(file->dir_ent.time), le16toh(file->dir_ent.date));
288  tm = localtime(&date);
289  strftime(tmp, 99, "%H:%M:%S %b %d %Y", tm);
290  sprintf(temp, " Size %u bytes, date %s", le32toh(file->dir_ent.size), tmp);
291  return temp;
292 }
static time_t date_dos2unix(unsigned short time, unsigned short date)
Definition: check.c:235
cab_UWORD date
Definition: fci.c:132
#define sprintf(buf, format,...)
Definition: sprintf.c:55
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
Definition: strftime.c:293
cab_ULONG size
Definition: fci.c:129
Definition: time.h:76
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:424
cab_UWORD time
Definition: fci.c:133
__kernel_time_t time_t
Definition: linux.h:252
static calc_node_t temp
Definition: rpn_ieee.c:38
__u16 date
Definition: mkdosfs.c:366
Definition: fci.c:126

Referenced by check_dir(), and File::length().

◆ handle_dot()

static int handle_dot ( DOS_FS fs,
DOS_FILE file,
int  dots 
)
static

Definition at line 511 of file check.c.

512 {
513  const char *name;
514 
515  name =
516  strncmp((const char *)file->dir_ent.name, MSDOS_DOT,
517  MSDOS_NAME) ? ".." : ".";
518  if (!(file->dir_ent.attr & ATTR_DIR)) {
519  printf("%s\n Is a non-directory.\n", path_name(file));
520  if (interactive)
521  printf("1) Drop it\n2) Auto-rename\n3) Rename\n"
522  "4) Convert to directory\n");
523 #ifndef __REACTOS__
524  else
525 #else
526  else if (rw)
527 #endif
528  printf(" Auto-renaming it.\n");
529 #ifdef __REACTOS__
530  if (rw || interactive) {
531 #endif
532  switch (interactive ? get_key("1234", "?") : '2') {
533  case '1':
534  drop_file(fs, file);
535  return 1;
536  case '2':
537  auto_rename(file);
538  printf(" Renamed to %s\n", file_name(file->dir_ent.name));
539  return 0;
540  case '3':
541  rename_file(file);
542  return 0;
543  case '4':
544  MODIFY(file, size, htole32(0));
545  MODIFY(file, attr, file->dir_ent.attr | ATTR_DIR);
546  break;
547 #ifdef __REACTOS__
548  }
549 #endif
550  }
551  }
552  if (!dots) {
553  printf("Root contains directory \"%s\". Dropping it.\n", name);
554  drop_file(fs, file);
555  return 1;
556  }
557  return 0;
558 }
#define MODIFY(p, i, v)
Definition: check.c:44
static void auto_rename(DOS_FILE *file)
Definition: check.c:419
#define interactive
Definition: rosglue.h:34
Definition: fs.h:235
static void drop_file(DOS_FS *fs, DOS_FILE *file)
Definition: check.c:388
char name[1]
Definition: fci.c:135
#define htole32(x)
Definition: storage32.h:543
static void rename_file(DOS_FILE *file)
Definition: check.c:462
GLsizeiptr size
Definition: glext.h:5919
char get_key(const char *valid, const char *prompt)
Definition: common.c:184
#define MSDOS_NAME
Definition: msdos_fs.h:46
static char * path_name(DOS_FILE *file)
Definition: check.c:208
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
Definition: cookie.c:170
int rw
static LPCWSTR file_name
Definition: protocol.c:146
#define ATTR_DIR
Definition: mkdosfs.c:370
Definition: name.c:36
#define MSDOS_DOT
Definition: msdos_fs.h:47
#define printf
Definition: config.h:203
Definition: fci.c:126
GLuint const GLchar * name
Definition: glext.h:6031

Referenced by check_dir().

◆ lfn_remove()

static void lfn_remove ( off_t  from,
off_t  to 
)
static

Definition at line 372 of file check.c.

373 {
374  DIR_ENT empty;
375 
376  /* New dir entry is zeroed except first byte, which is set to 0xe5.
377  * This is to avoid that some FAT-reading OSes (not Linux! ;) stop reading
378  * a directory at the first zero entry...
379  */
380  memset(&empty, 0, sizeof(empty));
381  empty.name[0] = DELETED_FLAG;
382 
383  for (; from < to; from += sizeof(empty)) {
384  fs_write(from, sizeof(DIR_ENT), &empty);
385  }
386 }
#define DELETED_FLAG
Definition: msdos_fs.h:43
static const WCHAR empty[]
Definition: main.c:49
void fs_write(off_t pos, int size, void *data)
Definition: io.c:344
CardRegion * from
Definition: spigame.cpp:19
#define memset(x, y, z)
Definition: compat.h:39

Referenced by drop_file().

◆ new_dir()

static void new_dir ( void  )
static

Definition at line 1099 of file check.c.

1100 {
1101  lfn_reset();
1102 }
void lfn_reset(void)
Definition: lfn.c:193

Referenced by BookmarkList::import_IE_favorites(), scan_dir(), and scan_root().

◆ path_name()

static char* path_name ( DOS_FILE file)
static

Construct a full path (starting with '/') for the specified dentry, relative to the partition. All components are "long" names where possible.

Parameters
[in]fileInformation about dentry (file or directory) of interest

return Pointer to static string containing file's full path

Definition at line 208 of file check.c.

209 {
210  static char path[PATH_NAME_MAX * 2];
211 
212  if (!file)
213  *path = 0; /* Reached the root directory */
214  else {
215  if (strlen(path_name(file->parent)) > PATH_NAME_MAX)
216  die("Path name too long.");
217  if (strcmp(path, "/") != 0)
218  strcat(path, "/");
219 
220  /* Append the long name to the path,
221  * or the short name if there isn't a long one
222  */
223  strcpy(strrchr(path, 0),
224  file->lfn ? file->lfn : file_name(file->dir_ent.name));
225  }
226  return path;
227 }
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLsizei const GLchar ** path
Definition: glext.h:7234
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
char name[1]
Definition: fci.c:135
static char * path_name(DOS_FILE *file)
Definition: check.c:208
#define PATH_NAME_MAX
Definition: check.c:35
Definition: services.c:325
static LPCWSTR file_name
Definition: protocol.c:146
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define die(str)
Definition: mkdosfs.c:347
Definition: fci.c:126

Referenced by add_file(), check_dir(), check_file(), do_parent(), handle_dot(), ok_path(), test_comctl32_classes(), test_file(), and test_GetVolumePathNameA().

◆ rename_file()

static void rename_file ( DOS_FILE file)
static

Definition at line 462 of file check.c.

463 {
464 #ifndef __REACTOS__
465  unsigned char name[46];
466  unsigned char *walk, *here;
467 #endif
468 
469  if (!file->offset) {
470 #ifndef __REACTOS__
471  printf("Cannot rename FAT32 root dir\n");
472 #else
473  VfatPrint( "Cannot rename FAT32 root dir\n" );
474 #endif
475  return; /* cannot rename FAT32 root dir */
476  }
477  while (1) {
478 #ifndef __REACTOS__
479  printf("New name: ");
480  fflush(stdout);
481  if (fgets((char *)name, 45, stdin)) {
482  if ((here = (unsigned char *)strchr((const char *)name, '\n')))
483  *here = 0;
484  for (walk = (unsigned char *)strrchr((const char *)name, 0);
485  walk >= name && (*walk == ' ' || *walk == '\t'); walk--) ;
486  walk[1] = 0;
487  for (walk = name; *walk == ' ' || *walk == '\t'; walk++) ;
488  if (file_cvt(walk, file->dir_ent.name)) {
489  if (file->dir_ent.lcase & FAT_NO_83NAME) {
490  /* as we only assign a new 8.3 filename, reset flag that 8.3 name is not
491  present */
492  file->dir_ent.lcase &= ~FAT_NO_83NAME;
493  /* reset the attributes, only keep DIR and VOLUME */
494  file->dir_ent.attr &= ~(ATTR_DIR | ATTR_VOLUME);
495  fs_write(file->offset, MSDOS_NAME + 2, &file->dir_ent);
496  } else {
497  fs_write(file->offset, MSDOS_NAME, file->dir_ent.name);
498  }
499  if (file->lfn)
500  lfn_fix_checksum(file->lfn_offset, file->offset,
501  (const char *)file->dir_ent.name);
502  return;
503  }
504  }
505 #else
506  return;
507 #endif
508  }
509 }
void lfn_fix_checksum(off_t from, off_t to, const char *short_name)
Definition: lfn.c:181
#define ATTR_VOLUME
Definition: mkdosfs.c:369
VOID VfatPrint(PCHAR Format,...)
Definition: vfatlib.c:363
FILE * stdin
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
FILE * stdout
void fs_write(off_t pos, int size, void *data)
Definition: io.c:344
#define FAT_NO_83NAME
Definition: fsck.fat.h:238
char name[1]
Definition: fci.c:135
#define MSDOS_NAME
Definition: msdos_fs.h:46
cab_ULONG offset
Definition: fci.c:130
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define ATTR_DIR
Definition: mkdosfs.c:370
Definition: name.c:36
int file_cvt(unsigned char *name, unsigned char *fixed)
Definition: file.c:84
#define printf
Definition: config.h:203
Definition: fci.c:126

Referenced by check_dir(), and handle_dot().

◆ scan_dir()

static int scan_dir ( DOS_FS fs,
DOS_FILE this,
FDSC **  cp 
)
static

Definition at line 1174 of file check.c.

1175 {
1176  DOS_FILE **chain;
1177  int i;
1178  uint32_t clu_num;
1179 
1180  chain = &this->first;
1181  i = 0;
1182  clu_num = FSTART(this, fs);
1183  new_dir();
1184  while (clu_num > 0 && clu_num != -1) {
1185  add_file(fs, &chain, this,
1186  cluster_start(fs, clu_num) + (i % fs->cluster_size), cp);
1187  i += sizeof(DIR_ENT);
1188  if (!(i % fs->cluster_size))
1189  if ((clu_num = next_cluster(fs, clu_num)) == 0 || clu_num == -1)
1190  break;
1191  }
1193  if (check_dir(fs, &this->first, this->offset))
1194  return 0;
1195  if (check_files(fs, this->first))
1196  return 1;
1197  return subdirs(fs, this, cp);
1198 }
static int subdirs(DOS_FS *fs, DOS_FILE *parent, FDSC **cp)
Definition: check.c:1210
const GLint * first
Definition: glext.h:5794
GLintptr offset
Definition: glext.h:5920
static void add_file(DOS_FS *fs, DOS_FILE ***chain, DOS_FILE *parent, off_t offset, FDSC **cp)
Definition: check.c:1117
Definition: fs.h:235
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct sock * chain
Definition: tcpcore.h:1164
uint32_t next_cluster(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:276
void lfn_check_orphaned(void)
Definition: lfn.c:517
static int check_files(DOS_FS *fs, DOS_FILE *start)
Definition: check.c:816
static int check_dir(DOS_FS *fs, DOS_FILE **root, int dots)
Definition: check.c:826
static void new_dir(void)
Definition: check.c:1099
UINT32 uint32_t
Definition: types.h:75
off_t cluster_start(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:289
POINT cp
Definition: magnifier.c:59
#define FSTART(p, fs)
Definition: check.c:40

Referenced by subdirs().

◆ scan_root()

int scan_root ( DOS_FS fs)

Scan all directory and file information for errors.

Parameters
[in,out]fsInformation about the filesystem
Returns
0 Success
1 Error

Definition at line 1232 of file check.c.

1233 {
1234  DOS_FILE **chain;
1235  int i;
1236 
1237  root = NULL;
1238  chain = &root;
1239  new_dir();
1240  if (fs->root_cluster) {
1241  add_file(fs, &chain, NULL, 0, &fp_root);
1242  } else {
1243  for (i = 0; i < fs->root_entries; i++)
1244  add_file(fs, &chain, NULL, fs->root_start + i * sizeof(DIR_ENT),
1245  &fp_root);
1246  }
1248  (void)check_dir(fs, &root, 0);
1249  if (check_files(fs, root))
1250  return 1;
1251  return subdirs(fs, NULL, &fp_root);
1252 }
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
static int subdirs(DOS_FS *fs, DOS_FILE *parent, FDSC **cp)
Definition: check.c:1210
static void add_file(DOS_FS *fs, DOS_FILE ***chain, DOS_FILE *parent, off_t offset, FDSC **cp)
Definition: check.c:1117
Definition: fs.h:235
FDSC * fp_root
Definition: file.c:32
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
struct sock * chain
Definition: tcpcore.h:1164
void lfn_check_orphaned(void)
Definition: lfn.c:517
static int check_files(DOS_FS *fs, DOS_FILE *start)
Definition: check.c:816
static int check_dir(DOS_FS *fs, DOS_FILE **root, int dots)
Definition: check.c:826
static DOS_FILE * root
Definition: check.c:37
static void new_dir(void)
Definition: check.c:1099

Referenced by VfatChkdsk().

◆ subdirs()

static int subdirs ( DOS_FS fs,
DOS_FILE parent,
FDSC **  cp 
)
static

Recursively scan subdirectories of the specified parent directory.

Parameters
[in,out]fsInformation about the filesystem
[in]parentIdentifies the directory to scan
[in]cp
Returns
0 Success
1 Error

Definition at line 1210 of file check.c.

1211 {
1212  DOS_FILE *walk;
1213 
1214  for (walk = parent ? parent->first : root; walk; walk = walk->next)
1215  if (walk->dir_ent.attr & ATTR_DIR)
1216  if (strncmp((const char *)walk->dir_ent.name, MSDOS_DOT, MSDOS_NAME)
1217  && strncmp((const char *)walk->dir_ent.name, MSDOS_DOTDOT,
1218  MSDOS_NAME))
1219  if (scan_dir(fs, walk, file_cd(cp, (char *)walk->dir_ent.name)))
1220  return 1;
1221  return 0;
1222 }
static int scan_dir(DOS_FS *fs, DOS_FILE *this, FDSC **cp)
Definition: check.c:1174
Definition: fs.h:235
DIR_ENT dir_ent
Definition: fsck.fat.h:183
FDSC ** file_cd(FDSC **curr, char *fixed)
Definition: file.c:186
#define MSDOS_NAME
Definition: msdos_fs.h:46
r parent
Definition: btrfs.c:2897
struct _dos_file * next
Definition: fsck.fat.h:188
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define MSDOS_DOTDOT
Definition: msdos_fs.h:48
#define ATTR_DIR
Definition: mkdosfs.c:370
POINT cp
Definition: magnifier.c:59
#define MSDOS_DOT
Definition: msdos_fs.h:47

Referenced by scan_dir(), and scan_root().

◆ test_file()

static void test_file ( DOS_FS fs,
DOS_FILE file,
int  read_test 
)
static

Check a dentry's cluster chain for bad clusters. If requested, we verify readability and mark unreadable clusters as bad.

Parameters
[in,out]fsInformation about the filesystem
[in]filedentry to check
[in]read_testNonzero == verify that dentry's clusters can be read

Definition at line 1005 of file check.c.

1006 {
1007  DOS_FILE *owner;
1008  uint32_t walk, prev, clusters, next_clu;
1009 
1010  prev = clusters = 0;
1011  for (walk = FSTART(file, fs); walk > 1 && walk < fs->data_clusters + 2;
1012  walk = next_clu) {
1013  next_clu = next_cluster(fs, walk);
1014 
1015  /* In this stage we are checking only for a loop within our own
1016  * cluster chain.
1017  * Cross-linking of clusters is handled in check_file()
1018  */
1019  if ((owner = get_owner(fs, walk))) {
1020  if (owner == file) {
1021  printf("%s\n Circular cluster chain. Truncating to %lu "
1022  "cluster%s.\n", path_name(file), (unsigned long)clusters,
1023  clusters == 1 ? "" : "s");
1024  if (prev)
1025  set_fat(fs, prev, -1);
1026  else if (!file->offset)
1027  die("Bad FAT32 root directory! (bad start cluster)\n");
1028  else
1029  MODIFY_START(file, 0, fs);
1030  }
1031  break;
1032  }
1033  if (bad_cluster(fs, walk))
1034  break;
1035  if (read_test) {
1036  if (fs_test(cluster_start(fs, walk), fs->cluster_size)) {
1037  prev = walk;
1038  clusters++;
1039  } else {
1040  printf("%s\n Cluster %lu (%lu) is unreadable. Skipping it.\n",
1041  path_name(file), (unsigned long)clusters, (unsigned long)walk);
1042  if (prev)
1043  set_fat(fs, prev, next_cluster(fs, walk));
1044  else
1045  MODIFY_START(file, next_cluster(fs, walk), fs);
1046  set_fat(fs, walk, -2);
1047  }
1048  } else {
1049  prev = walk;
1050  clusters++;
1051  }
1052  set_owner(fs, walk, file);
1053  }
1054  /* Revert ownership (for now) */
1055  for (walk = FSTART(file, fs); walk > 1 && walk < fs->data_clusters + 2;
1056  walk = next_cluster(fs, walk))
1057  if (bad_cluster(fs, walk))
1058  break;
1059  else if (get_owner(fs, walk) == file)
1060  set_owner(fs, walk, NULL);
1061  else
1062  break;
1063 }
static HRESULT get_owner(VARIANT *user, VARIANT *domain, VARIANT *retval)
Definition: process.c:35
static const struct notification read_test[]
Definition: notification.c:903
void set_fat(DOS_FS *fs, uint32_t cluster, int32_t new)
Definition: fat.c:189
Definition: fs.h:235
int fs_test(off_t pos, int size)
Definition: io.c:322
smooth NULL
Definition: ftsmooth.c:416
uint32_t next_cluster(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:276
static char * path_name(DOS_FILE *file)
Definition: check.c:208
const char file[]
Definition: icontest.c:11
void set_owner(DOS_FS *fs, uint32_t cluster, DOS_FILE *owner)
Definition: fat.c:303
cab_ULONG offset
Definition: fci.c:130
int bad_cluster(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:258
UINT32 uint32_t
Definition: types.h:75
off_t cluster_start(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:289
#define MODIFY_START(p, v, fs)
Definition: check.c:53
#define die(str)
Definition: mkdosfs.c:347
#define FSTART(p, fs)
Definition: check.c:40
#define printf
Definition: config.h:203
Definition: fci.c:126

Referenced by add_file().

◆ truncate_file()

static void truncate_file ( DOS_FS fs,
DOS_FILE file,
uint32_t  clusters 
)
static

Definition at line 401 of file check.c.

402 {
403  int deleting;
404  uint32_t walk, next;
405 
406  walk = FSTART(file, fs);
407  if ((deleting = !clusters))
408  MODIFY_START(file, 0, fs);
409  while (walk > 0 && walk != -1) {
410  next = next_cluster(fs, walk);
411  if (deleting)
412  set_fat(fs, walk, 0);
413  else if ((deleting = !--clusters))
414  set_fat(fs, walk, -1);
415  walk = next;
416  }
417 }
void set_fat(DOS_FS *fs, uint32_t cluster, int32_t new)
Definition: fat.c:189
Definition: fs.h:235
uint32_t next_cluster(DOS_FS *fs, uint32_t cluster)
Definition: fat.c:276
static unsigned __int64 next
Definition: rand_nt.c:6
UINT32 uint32_t
Definition: types.h:75
#define MODIFY_START(p, v, fs)
Definition: check.c:53
#define FSTART(p, fs)
Definition: check.c:40
Definition: fci.c:126

Referenced by check_dir(), and check_file().

◆ undelete()

static void undelete ( DOS_FS fs,
DOS_FILE file 
)
static

Definition at line 1065 of file check.c.

1066 {
1067  uint32_t clusters, left, prev, walk;
1068 
1069  clusters = left = (le32toh(file->dir_ent.size) + fs->cluster_size - 1) /
1070  fs->cluster_size;
1071  prev = 0;
1072 
1073  walk = FSTART(file, fs);
1074 
1075  while (left && (walk >= 2) && (walk < fs->data_clusters + 2)) {
1076 
1077  FAT_ENTRY curEntry;
1078  get_fat(&curEntry, fs->fat, walk, fs);
1079 
1080  if (!curEntry.value)
1081  break;
1082 
1083  left--;
1084  if (prev)
1085  set_fat(fs, prev, walk);
1086  prev = walk;
1087  walk++;
1088  }
1089  if (prev)
1090  set_fat(fs, prev, -1);
1091  else
1092  MODIFY_START(file, 0, fs);
1093  if (left)
1094  printf("Warning: Did only undelete %lu of %lu cluster%s.\n",
1095  (unsigned long)clusters - left, (unsigned long)clusters, clusters == 1 ? "" : "s");
1096 
1097 }
void set_fat(DOS_FS *fs, uint32_t cluster, int32_t new)
Definition: fat.c:189
Definition: fs.h:235
GLint left
Definition: glext.h:7726
cab_ULONG size
Definition: fci.c:129
Definition: fsck.fat.h:192
uint32_t value
Definition: fsck.fat.h:193
UINT32 uint32_t
Definition: types.h:75
#define MODIFY_START(p, v, fs)
Definition: check.c:53
#define FSTART(p, fs)
Definition: check.c:40
void get_fat(FAT_ENTRY *entry, void *fat, uint32_t cluster, DOS_FS *fs)
Definition: fat.c:41
#define printf
Definition: config.h:203
Definition: fci.c:126

Referenced by add_file().

Variable Documentation

◆ day_n

const int day_n[]
static
Initial value:
=
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0 }

Definition at line 229 of file check.c.

Referenced by date_dos2unix().

◆ root

DOS_FILE* root
static

Definition at line 37 of file check.c.

Referenced by alloc_rootdir_entry(), auto_rename(), check_dir(), and scan_root().