diff --git a/reactos/lib/fslib/vfatlib/check/boot.c b/reactos/lib/fslib/vfatlib/check/boot.c index 4f60c182230..302fa050aad 100644 --- a/reactos/lib/fslib/vfatlib/check/boot.c +++ b/reactos/lib/fslib/vfatlib/check/boot.c @@ -57,20 +57,14 @@ static char *get_media_descr( unsigned char media ) static void dump_boot(DOS_FS *fs,struct boot_sector *b,unsigned lss) { unsigned short sectors; + char id[9]; VfatPrint("Boot sector contents:\n"); - if (!atari_format) { - char id[9]; + strncpy(id,(char*)b->system_id,8); id[8] = 0; VfatPrint("System ID \"%s\"\n",id); - } - else { - /* On Atari, a 24 bit serial number is stored at offset 8 of the boot - * sector */ - VfatPrint("Serial number 0x%x\n", - b->system_id[5] | (b->system_id[6]<<8) | (b->system_id[7]<<16)); - } + VfatPrint("Media byte 0x%02x (%s)\n",b->media,get_media_descr(b->media)); VfatPrint("%10d bytes per logical sector\n",GET_UNALIGNED_W(b->sector_size)); VfatPrint("%10d bytes per cluster\n",fs->cluster_size); @@ -99,12 +93,7 @@ static void dump_boot(DOS_FS *fs,struct boot_sector *b,unsigned lss) (__u64)fs->clusters*fs->cluster_size); VfatPrint("%u sectors/track, %u heads\n",CF_LE_W(b->secs_track), CF_LE_W(b->heads)); - VfatPrint("%10u hidden sectors\n", - atari_format ? - /* On Atari, the hidden field is only 16 bit wide and unused */ - (((unsigned char *)&b->hidden)[0] | - ((unsigned char *)&b->hidden)[1] << 8) : - CF_LE_L(b->hidden)); + VfatPrint("%10u hidden sectors\n", CF_LE_L(b->hidden)); sectors = GET_UNALIGNED_W( b->sectors ); VfatPrint("%10u sectors total\n", sectors ? sectors : CF_LE_L(b->total_sect)); } @@ -320,27 +309,12 @@ void read_boot(DOS_FS *fs) read_fsinfo(fs,&b,logical_sector_size); } - else if (!atari_format) { + else { /* On real MS-DOS, a 16 bit FAT is used whenever there would be too - * much clusers otherwise. */ + * much clusters otherwise. */ fs->fat_bits = (fs->clusters > MSDOS_FAT12) ? 16 : 12; } - else { - /* On Atari, things are more difficult: GEMDOS always uses 12bit FATs - * on floppies, and always 16 bit on harddisks. */ - fs->fat_bits = 16; /* assume 16 bit FAT for now */ - /* If more clusters than fat entries in 16-bit fat, we assume - * it's a real MSDOS FS with 12-bit fat. */ - if (fs->clusters+2 > fat_length*logical_sector_size*8/16 || - /* if it's a floppy disk --> 12bit fat */ - device_no == 2 || - /* if it's a ramdisk or loopback device and has one of the usual - * floppy sizes -> 12bit FAT */ - ((device_no == 1 || device_no == 7) && - (total_sectors == 720 || total_sectors == 1440 || - total_sectors == 2880))) - fs->fat_bits = 12; - } + /* On FAT32, the high 4 bits of a FAT entry are reserved */ fs->eff_fat_bits = (fs->fat_bits == 32) ? 28 : fs->fat_bits; fs->fat_size = fat_length*logical_sector_size; @@ -356,7 +330,7 @@ void read_boot(DOS_FS *fs) die("Logical sector size (%d bytes) is not a multiple of the physical " "sector size.",logical_sector_size); /* ++roman: On Atari, these two fields are often left uninitialized */ - if (!atari_format && (!b.secs_track || !b.heads)) + if ((!b.secs_track || !b.heads)) die("Invalid disk format in boot sector."); if (FsCheckFlags & FSCHECK_VERBOSE) dump_boot(fs,&b,logical_sector_size); } diff --git a/reactos/lib/fslib/vfatlib/check/check.c b/reactos/lib/fslib/vfatlib/check/check.c index bc7ca7946ed..3153f706f20 100644 --- a/reactos/lib/fslib/vfatlib/check/check.c +++ b/reactos/lib/fslib/vfatlib/check/check.c @@ -153,7 +153,7 @@ loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern) } vffree(root); } - ++n_files; + ++FsCheckTotalFiles; return offset; } @@ -221,7 +221,7 @@ static char *file_stat(DOS_FILE *file) static int bad_name(unsigned char *name) { int i, spc, suspicious = 0; - char *bad_chars = atari_format ? "*?\\/:" : "*?<>|\"\\/:"; + char *bad_chars = "*?<>|\"\\/:"; /* Do not complain about (and auto-correct) the extended attribute files * of OS/2. */ @@ -260,10 +260,6 @@ static int bad_name(unsigned char *name) return 1; } - /* Under GEMDOS, chars >= 128 are never allowed. */ - if (atari_format && suspicious) - return 1; - /* Only complain about too much suspicious chars in interactive mode, * never correct them automatically. The chars are all basically ok, so we * shouldn't auto-correct such names. */ @@ -281,7 +277,7 @@ static void drop_file(DOS_FS *fs,DOS_FILE *file) for (cluster = FSTART(file,fs); cluster > 0 && cluster < fs->clusters+2; cluster = next_cluster(fs,cluster)) set_owner(fs,cluster,NULL); - --n_files; + --FsCheckTotalFiles; } @@ -780,7 +776,7 @@ static void add_file(DOS_FS *fs,DOS_FILE ***chain,DOS_FILE *parent, lfn_add_slot(&de,offset); return; } - new = qalloc(&mem_queue,sizeof(DOS_FILE)); + new = qalloc(&FsCheckMemQueue,sizeof(DOS_FILE)); new->lfn = lfn_get(&de); new->offset = offset; memcpy(&new->dir_ent,&de,sizeof(de)); @@ -798,7 +794,7 @@ static void add_file(DOS_FS *fs,DOS_FILE ***chain,DOS_FILE *parent, if (offset && strncmp((char*)de.name,MSDOS_DOT,MSDOS_NAME) != 0 && strncmp((char*)de.name,MSDOS_DOTDOT,MSDOS_NAME) != 0) - ++n_files; + ++FsCheckTotalFiles; test_file(fs,new,FsCheckFlags & FSCHECK_TEST_READ); } diff --git a/reactos/lib/fslib/vfatlib/check/dosfsck.h b/reactos/lib/fslib/vfatlib/check/dosfsck.h index 0134996c75b..0ddbf2ba35e 100644 --- a/reactos/lib/fslib/vfatlib/check/dosfsck.h +++ b/reactos/lib/fslib/vfatlib/check/dosfsck.h @@ -165,18 +165,17 @@ typedef struct { #define FSCHECK_IMMEDIATE_WRITE 0x10 extern ULONG FsCheckFlags; -extern int atari_format; -extern unsigned n_files; -extern void *mem_queue; +extern ULONG FsCheckTotalFiles; +extern void *FsCheckMemQueue; /* value to use as end-of-file marker */ -#define FAT_EOF(fs) ((atari_format ? 0xfff : 0xff8) | FAT_EXTD(fs)) +#define FAT_EOF(fs) (0xff8 | FAT_EXTD(fs)) #define FAT_IS_EOF(fs,v) ((unsigned long)(v) >= (0xff8|FAT_EXTD(fs))) /* value to mark bad clusters */ #define FAT_BAD(fs) (0xff7 | FAT_EXTD(fs)) /* range of values used for bad clusters */ -#define FAT_MIN_BAD(fs) ((atari_format ? 0xff0 : 0xff7) | FAT_EXTD(fs)) -#define FAT_MAX_BAD(fs) ((atari_format ? 0xff7 : 0xff7) | FAT_EXTD(fs)) +#define FAT_MIN_BAD(fs) (0xff7 | FAT_EXTD(fs)) +#define FAT_MAX_BAD(fs) (0xff7 | FAT_EXTD(fs)) #define FAT_IS_BAD(fs,v) ((v) >= FAT_MIN_BAD(fs) && (v) <= FAT_MAX_BAD(fs)) /* return -16 as a number with fs->fat_bits bits */ diff --git a/reactos/lib/fslib/vfatlib/check/fat.c b/reactos/lib/fslib/vfatlib/check/fat.c index ba7ee9bd65b..7e2ad9c1d62 100644 --- a/reactos/lib/fslib/vfatlib/check/fat.c +++ b/reactos/lib/fslib/vfatlib/check/fat.c @@ -97,7 +97,7 @@ void read_fat(DOS_FS *fs) //exit(1); } } - fs->fat = qalloc(&mem_queue,sizeof(FAT_ENTRY)*(fs->clusters+2)); + fs->fat = qalloc(&FsCheckMemQueue,sizeof(FAT_ENTRY)*(fs->clusters+2)); for (i = 2; i < fs->clusters+2; i++) get_fat(&fs->fat[i],use,i,fs); for (i = 2; i < fs->clusters+2; i++) if (fs->fat[i].value >= fs->clusters+2 && diff --git a/reactos/lib/fslib/vfatlib/check/io.c b/reactos/lib/fslib/vfatlib/check/io.c index b266cad069d..cea6654d56e 100644 --- a/reactos/lib/fslib/vfatlib/check/io.c +++ b/reactos/lib/fslib/vfatlib/check/io.c @@ -17,6 +17,8 @@ #define NDEBUG #include +#define FSCTL_IS_VOLUME_DIRTY CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 30, METHOD_BUFFERED, FILE_ANY_ACCESS) + typedef struct _change { void *data; loff_t pos; @@ -76,6 +78,63 @@ void fs_open(PUNICODE_STRING DriveRoot,int rw) did_change = 0; } +BOOLEAN fs_isdirty(PUNICODE_STRING DriveRoot) +{ + OBJECT_ATTRIBUTES ObjectAttributes; + ULONG DirtyMask = 0; + WCHAR TempRootBuf[128]; + UNICODE_STRING TempRoot; + HANDLE FileSystem; + IO_STATUS_BLOCK IoSb; + NTSTATUS Status; + + /* Add backslash to the end, so FS will be opened */ + TempRoot.Length = 0; + TempRoot.MaximumLength = sizeof(TempRootBuf); + TempRoot.Buffer = TempRootBuf; + RtlCopyUnicodeString(&TempRoot, DriveRoot); + if (TempRoot.Length == (TempRoot.MaximumLength-1)) return FALSE; + wcscat(TempRoot.Buffer, L"\\"); + TempRoot.Length += sizeof(WCHAR); + + InitializeObjectAttributes(&ObjectAttributes, + &TempRoot, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileSystem, + FILE_GENERIC_READ, + &ObjectAttributes, + &IoSb, + 0, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile() failed with status 0x%.08x\n", Status); + return FALSE; + } + + /* Check if volume is dirty */ + Status = NtFsControlFile(FileSystem, + NULL, NULL, NULL, &IoSb, + FSCTL_IS_VOLUME_DIRTY, + NULL, 0, &DirtyMask, sizeof(DirtyMask)); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtFsControlFile() failed with Status 0x%08x\n", Status); + /* Close FS handle */ + NtClose(FileSystem); + return FALSE; + } + + /* Close FS handle */ + NtClose(FileSystem); + + return (DirtyMask & 1); +} + void fs_read(loff_t pos,int size,void *data) { diff --git a/reactos/lib/fslib/vfatlib/check/io.h b/reactos/lib/fslib/vfatlib/check/io.h index a53e8749004..6c6675f0f9b 100644 --- a/reactos/lib/fslib/vfatlib/check/io.h +++ b/reactos/lib/fslib/vfatlib/check/io.h @@ -21,6 +21,10 @@ void fs_open(PUNICODE_STRING DriveRoot,int rw); /* Opens the file system PATH. If RW is zero, the file system is opened read-only, otherwise, it is opened read-write. */ +BOOLEAN fs_isdirty(PUNICODE_STRING DriveRoot); + +/* Checks if filesystem is dirty */ + void fs_read(loff_t pos,int size,void *data); /* Reads SIZE bytes starting at POS into DATA. Performs all applicable diff --git a/reactos/lib/fslib/vfatlib/check/lfn.c b/reactos/lib/fslib/vfatlib/check/lfn.c index 0aad9ae3055..d57901bd7fd 100644 --- a/reactos/lib/fslib/vfatlib/check/lfn.c +++ b/reactos/lib/fslib/vfatlib/check/lfn.c @@ -81,7 +81,7 @@ static char *cnv_unicode( const unsigned char *uni, int maxlen, int use_q ) else len += 4; } - cp = out = use_q ? qalloc( &mem_queue, len+1 ) : vfalloc( len+1 ); + cp = out = use_q ? qalloc( &FsCheckMemQueue, len+1 ) : vfalloc( len+1 ); for( up = uni; (up-uni)/2 < maxlen && (up[0] || up[1]); up += 2 ) { if (UNICODE_CONVERTABLE(up[0],up[1]))