35 #define PATH_NAME_MAX 1023 40 #define FSTART(p,fs) \ 41 ((uint32_t)le16toh(p->dir_ent.start) | \ 42 (fs->fat_bits == 32 ? le16toh(p->dir_ent.starthi) << 16 : 0)) 44 #define MODIFY(p,i,v) \ 48 fs_write(p->offset+offsetof(DIR_ENT,i), \ 49 sizeof(p->dir_ent.i),&p->dir_ent.i); \ 53 #define MODIFY_START(p,v,fs) \ 58 if (!__v) die("Oops, deleting FAT32 root dir!"); \ 59 fs->root_cluster = __v; \ 60 p->dir_ent.start = htole16(__v&0xffff); \ 61 p->dir_ent.starthi = htole16(__v>>16); \ 63 fs_write(offsetof(struct boot_sector,root_cluster), \ 64 sizeof(((struct boot_sector *)0)->root_cluster), \ 68 MODIFY(p,start,htole16((__v)&0xffff)); \ 69 if (fs->fat_bits == 32) \ 70 MODIFY(p,starthi,htole16((__v)>>16)); \ 76 static int curr_num = 0;
79 if (
fs->root_cluster) {
85 clu_num =
fs->root_cluster;
87 while (clu_num > 0 && clu_num != -1) {
95 if ((
i %
fs->cluster_size) == 0) {
106 die(
"Root directory has no cluster allocated!");
107 for (clu_num = prev + 1; clu_num != prev; clu_num++) {
110 if (clu_num >=
fs->data_clusters + 2)
117 die(
"Root directory full and no free cluster");
122 memset(&d2, 0,
sizeof(d2));
124 for (
i = 0;
i <
fs->cluster_size;
i +=
sizeof(DIR_ENT))
127 memset(de, 0,
sizeof(DIR_ENT));
133 clu_num =
fs->root_cluster;
136 while (clu_num > 0 && clu_num != -1) {
137 fs_read(offset2,
sizeof(DIR_ENT), &d2);
139 !
strncmp((
const char *)d2.name, (
const char *)de->name,
142 i +=
sizeof(DIR_ENT);
143 offset2 +=
sizeof(DIR_ENT);
144 if ((
i %
fs->cluster_size) == 0) {
151 if (clu_num == 0 || clu_num == -1)
153 if (++curr_num >= 10000)
154 die(
"Unable to create unique name");
161 int next_free = 0, scan;
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));
181 for (scan = 0; scan <
fs->root_entries; scan++)
182 if (scan != next_free &&
186 if (scan ==
fs->root_entries)
188 if (++curr_num >= 10000)
189 die(
"Unable to create unique name");
216 die(
"Path name too long.");
230 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, 0 };
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);
254 #ifdef __REACTOS__ // Old version! 258 static char temp[100];
269 _snprintf(tmp,
sizeof(tmp),
"%d:%d:%d %d.%d.%d",
281 static char temp[100];
298 int i, spc, suspicious = 0;
299 const char *bad_chars =
atari_format ?
"*?\\/:" :
"*?<>|\"\\/:";
301 const unsigned char *
ext =
name + 8;
305 if (
strncmp((
const char *)
name,
"EA DATA SF", 11) == 0 ||
306 strncmp((
const char *)
name,
"WP ROOT SF", 11) == 0)
329 for (
i = 0;
i < 8;
i++) {
339 for (
i = 0;
i < 3;
i++) {
352 #ifdef __REACTOS__ // Old !!!!!!!!!!!!!!! 395 for (cluster =
FSTART(
file,
fs); cluster > 0 && cluster <
407 if ((deleting = !clusters))
409 while (walk > 0 && walk != -1) {
413 else if ((deleting = !--clusters))
433 for (walk =
first; walk; walk = walk->
next)
456 die(
"Too many files need repair.");
459 die(
"Can't generate a unique name.");
465 unsigned char name[46];
466 unsigned char *walk, *here;
471 printf(
"Cannot rename FAT32 root dir\n");
473 VfatPrint(
"Cannot rename FAT32 root dir\n" );
482 if ((here = (
unsigned char *)
strchr((
const char *)
name,
'\n')))
484 for (walk = (
unsigned char *)
strrchr((
const char *)
name, 0);
485 walk >=
name && (*walk ==
' ' || *walk ==
'\t'); walk--) ;
487 for (walk =
name; *walk ==
' ' || *walk ==
'\t'; walk++) ;
521 printf(
"1) Drop it\n2) Auto-rename\n3) Rename\n" 522 "4) Convert to directory\n");
528 printf(
" Auto-renaming it.\n");
553 printf(
"Root contains directory \"%s\". Dropping it.\n",
name);
569 printf(
"%s\n Directory has non-zero size. Fixing it.\n",
572 printf(
"%s\n Directory has non-zero size.%s\n",
583 printf(
"%s\n Start (%lu) does not point to parent (%lu)\n",
597 if (
fs->root_cluster &&
expect ==
fs->root_cluster)
600 printf(
"%s\n Start (%lu) does not point to .. (%lu)\n",
611 printf(
"%s\n Start does point to root directory. Deleting dir. \n",
614 printf(
"%s\n Start does point to root directory.%s\n",
623 printf(
"%s\n Bad start cluster 1. Truncating file.\n",
626 die(
"Bad FAT32 root directory! (bad start cluster 1)\n");
635 (
"%s\n Start cluster beyond limit (%lu > %lu). Truncating file.\n",
637 (
unsigned long)(
fs->data_clusters + 1));
639 (
"%s\n Start cluster beyond limit (%lu > %lu).%s\n",
641 (
unsigned long)(
fs->data_clusters + 1),
642 (
rw) ?
" Truncating file." :
"");
645 die(
"Bad FAT32 root directory! (start cluster beyond limit: %lu > %lu)\n",
647 (
unsigned long)(
fs->data_clusters + 1));
661 printf(
"%s\n Contains a %s cluster (%lu). Assuming EOF.\n",
664 printf(
"%s\n Contains a %s cluster (%lu).%s\n",
666 (
rw) ?
" Assuming EOF." :
"");
678 die(
"FAT32 root dir starts with a bad cluster!");
692 (
"%s\n File size is %u bytes, cluster chain length is > %llu " 695 (
unsigned long long)clusters *
fs->cluster_size,
701 (
"%s\n File size is %u bytes, cluster chain length is > %llu " 704 (
unsigned long long)clusters *
fs->cluster_size);
714 for (walk =
FSTART(owner,
fs); walk > 0 && walk != -1; walk =
726 printf(
" Truncating second to %llu bytes because first " 727 "is FAT32 root dir.\n",
728 (
unsigned long long)clusters *
fs->cluster_size);
735 printf(
" Truncating first to %llu bytes because second " 736 "is FAT32 root dir.\n",
737 (
unsigned long long)clusters2 *
fs->cluster_size);
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,
744 (
unsigned long long)clusters *
fs->cluster_size);
749 printf(
" Truncating second to %llu bytes.\n",
750 (
unsigned long long)clusters *
fs->cluster_size);
755 if ((do_trunc != 2 &&
rw)
756 && ((do_trunc == 1 &&
rw)
761 for (
this =
FSTART(owner,
fs);
this > 0 &&
this != -1;
this =
773 while (
this > 0 &&
this != -1) {
784 die(
"Internal error: didn't find cluster %d in chain" 785 " starting at %d", curr,
FSTART(owner,
fs));
805 (
"%s\n File size is %u bytes, cluster chain length is %llu bytes." 808 (
unsigned long long)clusters *
fs->cluster_size,
809 (
unsigned long long)clusters *
fs->cluster_size);
829 int dot, dotdot,
skip, redo;
836 for (walk =
root; *walk; walk = &(*walk)->
next)
841 if (*
root &&
parent && good + bad > 4 && bad > good / 2) {
842 printf(
"%s\n Has a large number of bad entries. (%d/%d)\n",
845 printf(
" Not dropping root directory.\n");
851 printf(
" Not dropping it in auto-mode.\n");
852 else if (
get_key(
"yn",
"Drop directory ? (y/n)") ==
'y') {
859 dot = dotdot = redo = 0;
867 *walk = (*walk)->
next;
879 printf(
" Bad short file name (%s).\n",
882 printf(
"%s\n Bad short file name (%s).\n",
886 printf(
"1) Drop file\n2) Rename file\n3) Auto-rename\n" 892 printf(
" Auto-renaming it.\n");
899 walk = &(*walk)->
next;
918 scan = &(*walk)->
next;
920 while (*scan && !
skip) {
922 !
memcmp((*walk)->dir_ent.name, (*scan)->dir_ent.name,
924 printf(
"%s\n Duplicate directory entry.\n First %s\n",
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");
936 printf(
" Auto-renaming second.\n");
943 *walk = (*walk)->
next;
948 *scan = (*scan)->
next;
962 printf(
" Renamed to %s\n",
967 printf(
" Renamed to %s\n",
975 scan = &(*scan)->
next;
981 walk = &(*walk)->
next;
984 dot = dotdot = redo = 0;
988 printf(
"%s\n \".\" is missing. Can't fix this yet.\n",
991 printf(
"%s\n \"..\" is missing. Can't fix this yet.\n",
1008 uint32_t walk, prev, clusters, next_clu;
1010 prev = clusters = 0;
1011 for (walk =
FSTART(
file,
fs); walk > 1 && walk <
fs->data_clusters + 2;
1020 if (owner ==
file) {
1021 printf(
"%s\n Circular cluster chain. Truncating to %lu " 1023 clusters == 1 ?
"" :
"s");
1027 die(
"Bad FAT32 root directory! (bad start cluster)\n");
1040 printf(
"%s\n Cluster %lu (%lu) is unreadable. Skipping it.\n",
1041 path_name(
file), (
unsigned long)clusters, (
unsigned long)walk);
1055 for (walk =
FSTART(
file,
fs); walk > 1 && walk <
fs->data_clusters + 2;
1069 clusters =
left = (le32toh(
file->dir_ent.
size) +
fs->cluster_size - 1) /
1075 while (
left && (walk >= 2) && (walk <
fs->data_clusters + 2)) {
1080 if (!curEntry.
value)
1094 printf(
"Warning: Did only undelete %lu of %lu cluster%s.\n",
1095 (
unsigned long)clusters -
left, (
unsigned long)clusters, clusters == 1 ?
"" :
"s");
1128 memset(&de, 0,
sizeof de);
1131 de.start =
htole16(
fs->root_cluster & 0xffff);
1132 de.starthi =
htole16((
fs->root_cluster >> 16) & 0xffff);
1136 die(
"Can't undelete directories.");
1152 new->next =
new->first =
NULL;
1157 *
chain = &
new->next;
1184 while (clu_num > 0 && clu_num != -1) {
1187 i +=
sizeof(DIR_ENT);
1188 if (!(
i %
fs->cluster_size))
1240 if (
fs->root_cluster) {
1243 for (
i = 0;
i <
fs->root_entries;
i++)
void lfn_fix_checksum(off_t from, off_t to, const char *short_name)
static void undelete(DOS_FS *fs, DOS_FILE *file)
off_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern, int gen_name)
static time_t date_dos2unix(unsigned short time, unsigned short date)
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
#define new(TYPE, numElems)
char * strcat(char *DstString, const char *SrcString)
static int check_file(DOS_FS *fs, DOS_FILE *file)
static void truncate_file(DOS_FS *fs, DOS_FILE *file, uint32_t clusters)
static int subdirs(DOS_FS *fs, DOS_FILE *parent, FDSC **cp)
static int scan_dir(DOS_FS *fs, DOS_FILE *this, FDSC **cp)
ACPI_SIZE strlen(const char *String)
GLsizei const GLchar ** path
NTSYSAPI VOID NTAPI RtlSecondsSince1970ToTime(_In_ ULONG SecondsSince1970, _Out_ PLARGE_INTEGER Time)
static HRESULT get_owner(VARIANT *user, VARIANT *domain, VARIANT *retval)
static const struct notification read_test[]
void set_fat(DOS_FS *fs, uint32_t cluster, int32_t new)
static void add_file(DOS_FS *fs, DOS_FILE ***chain, DOS_FILE *parent, off_t offset, FDSC **cp)
VOID VfatPrint(PCHAR Format,...)
static void auto_rename(DOS_FILE *file)
void * qalloc(void **root, int size)
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
static void drop_file(DOS_FS *fs, DOS_FILE *file)
void fs_write(off_t pos, int size, void *data)
#define sprintf(buf, format,...)
int fs_test(off_t pos, int size)
static size_t double number
int scan_root(DOS_FS *fs)
static int handle_dot(DOS_FS *fs, DOS_FILE *file, int dots)
static void lfn_remove(off_t from, off_t to)
FDSC ** file_cd(FDSC **curr, char *fixed)
static void rename_file(DOS_FILE *file)
char * lfn_get(DIR_ENT *de, off_t *lfn_offset)
uint32_t next_cluster(DOS_FS *fs, uint32_t cluster)
void restart(int argc, const char *argv[])
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
static int bad_name(DOS_FILE *file)
BOOLEAN RtlTimeToTimeFields(IN PLARGE_INTEGER Time, IN PTIME_FIELDS TimeFields)
char get_key(const char *valid, const char *prompt)
static char * path_name(DOS_FILE *file)
void fs_read(off_t pos, int size, void *data)
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
void set_owner(DOS_FS *fs, uint32_t cluster, DOS_FILE *owner)
FD_TYPE file_type(FDSC **curr, char *fixed)
void lfn_check_orphaned(void)
const char * root_entries[]
#define memcpy(s1, s2, n)
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
int puts(const char *string)
static void test_file(DOS_FS *fs, DOS_FILE *file, int read_test)
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
static char * file_stat(DOS_FILE *file)
int bad_cluster(DOS_FS *fs, uint32_t cluster)
static unsigned __int64 next
static int check_files(DOS_FS *fs, DOS_FILE *start)
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
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
static int check_dir(DOS_FS *fs, DOS_FILE **root, int dots)
void file_modify(FDSC **curr, char *fixed)
#define expect(expected, got)
static void new_dir(void)
off_t cluster_start(DOS_FS *fs, uint32_t cluster)
char * strchr(const char *String, int ch)
#define MODIFY_START(p, v, fs)
void lfn_add_slot(DIR_ENT *de, off_t dir_offset)
char * strcpy(char *DstString, const char *SrcString)
int strcmp(const char *String1, const char *String2)
GLuint GLuint GLsizei GLenum type
int file_cvt(unsigned char *name, unsigned char *fixed)
void get_fat(FAT_ENTRY *entry, void *fat, uint32_t cluster, DOS_FS *fs)
GLuint const GLchar * name