diff options
Diffstat (limited to 'minfo.c')
-rw-r--r-- | minfo.c | 246 |
1 files changed, 167 insertions, 79 deletions
@@ -24,13 +24,14 @@ #include "vfat.h" #include "mtools.h" #include "nameclash.h" +#include "fsP.h" static void usage(int ret) NORETURN; static void usage(int ret) { - fprintf(stderr, + fprintf(stderr, "Mtools version %s, dated %s\n", mversion, mdate); - fprintf(stderr, + fprintf(stderr, "Usage: %s [-v] drive\n", progname); exit(ret); } @@ -44,9 +45,9 @@ static void displayInfosector(Stream_t *Stream, union bootsector *boot) return; infosec = (InfoSector_t *) safe_malloc(WORD(secsiz)); - force_read(Stream, (char *) infosec, - (mt_off_t) WORD(secsiz) * WORD(ext.fat32.infoSector), - WORD(secsiz)); + force_pread(Stream, (char *) infosec, + (mt_off_t) WORD(secsiz) * WORD(ext.fat32.infoSector), + WORD(secsiz)); printf("\nInfosector:\n"); printf("signature=0x%08x\n", _DWORD(infosec->signature1)); if(_DWORD(infosec->count) != MAX32) @@ -55,6 +56,12 @@ static void displayInfosector(Stream_t *Stream, union bootsector *boot) printf("last allocated cluster=%u\n", _DWORD(infosec->pos)); } +/* + * Number of hidden sector is only a 4 byte quantity if number of sectors is + */ +static uint32_t getHidden(union bootsector *boot) { + return WORD(psect) ? WORD(nhs) : DWORD(nhs); +} static void displayBPB(Stream_t *Stream, union bootsector *boot) { struct label_blk_t *labelBlock; @@ -66,15 +73,16 @@ static void displayBPB(Stream_t *Stream, union bootsector *boot) { printf("cluster size: %d sectors\n", boot->boot.clsiz); printf("reserved (boot) sectors: %d\n", WORD(nrsvsect)); printf("fats: %d\n", boot->boot.nfat); - printf("max available root directory slots: %d\n", + printf("max available root directory slots: %d\n", WORD(dirents)); printf("small size: %d sectors\n", WORD(psect)); printf("media descriptor byte: 0x%x\n", boot->boot.descr); printf("sectors per fat: %d\n", WORD(fatlen)); printf("sectors per track: %d\n", WORD(nsect)); printf("heads: %d\n", WORD(nheads)); - printf("hidden sectors: %d\n", DWORD(nhs)); - printf("big size: %d sectors\n", DWORD(bigsect)); + printf("hidden sectors: %d\n", getHidden(boot)); + if(!WORD(psect)) + printf("big size: %u sectors\n", DWORD(bigsect)); if(WORD(fatlen)) { labelBlock = &boot->boot.ext.old.labelBlock; @@ -83,20 +91,20 @@ static void displayBPB(Stream_t *Stream, union bootsector *boot) { } if(has_BPB4) { - printf("physical drive id: 0x%x\n", + printf("physical drive id: 0x%x\n", labelBlock->physdrive); - printf("reserved=0x%x\n", + printf("reserved=0x%x\n", labelBlock->reserved); - printf("dos4=0x%x\n", + printf("dos4=0x%x\n", labelBlock->dos4); - printf("serial number: %08X\n", + printf("serial number: %08X\n", _DWORD(labelBlock->serial)); - printf("disk label=\"%11.11s\"\n", + printf("disk label=\"%11.11s\"\n", labelBlock->label); - printf("disk type=\"%8.8s\"\n", + printf("disk type=\"%8.8s\"\n", labelBlock->fat_type); } - + if(!WORD(fatlen)){ printf("Big fatlen=%u\n", DWORD(ext.fat32.bigFat)); @@ -116,27 +124,144 @@ static void displayBPB(Stream_t *Stream, union bootsector *boot) { } } +static int try(uint32_t tot_sectors, Fs_t *masterFs, Fs_t *tryFs, + struct device *master_dev, struct device *try_dev, + uint8_t *bootDescr) { + *tryFs = *masterFs; + *try_dev = *master_dev; + return calc_fs_parameters(try_dev, 0, tot_sectors, + tryFs, bootDescr); +} + +static void print_mformat_commandline(const char *imgFile, + char drive, + struct device *dev, + union bootsector *boot, + int media, + int haveBPB) { + uint8_t size_code; + uint32_t sect_per_track; + uint32_t hidden; + uint32_t tot_sectors; + int tracks_match=0; + Fs_t masterFs, tryFs, actual; + struct device used_dev; + uint8_t tryMedia; + int bad; + + sect_per_track = dev->sectors * dev->heads; + if(sect_per_track == 0) + return; + + tot_sectors = parseFsParams(&actual, boot, + media | (haveBPB ? 0x100:0), + sect_per_track); + if(tot_sectors == 0) + return; + + printf("mformat command line:\n mformat "); + + if(haveBPB) { + if(media == 0xf0) + hidden = getHidden(boot); + else + hidden = 0; + size_code = (uint8_t) actual.sectorShift-7; + } else { + size_code=2; + hidden = 0; + } + + if(tot_sectors == + dev->tracks * sect_per_track - hidden % sect_per_track) { + tracks_match=1; + printf("-t %d ", dev->tracks); + } else { + printf("-T %d ", tot_sectors); + } + printf ("-h %d -s %d ", dev->heads, dev->sectors); + if(haveBPB && (hidden || !tracks_match)) + printf("-H %d ", hidden); + used_dev=*dev; + if(size_code != 2) { + printf("-S %d ",size_code); + used_dev.ssize = size_code; + } + + initFsForFormat(&masterFs); + setFsSectorSize(&masterFs, &used_dev, 0); + + if(actual.num_fat != 2) { + masterFs.num_fat = actual.num_fat; + printf("-d %d ", actual.num_fat); + } + + bad=try(tot_sectors, &masterFs, &tryFs, dev , &used_dev, &tryMedia); + + if(bad || actual.dir_len != tryFs.dir_len) { + masterFs.dir_len = actual.dir_len; + printf("-r %d ", actual.dir_len); + bad = try(tot_sectors, + &masterFs, &tryFs, dev , &used_dev, + &tryMedia); + } + + if(bad || actual.cluster_size != tryFs.cluster_size) { + masterFs.cluster_size = actual.cluster_size; + printf("-c %d ", actual.cluster_size); + bad = try(tot_sectors, + &masterFs, &tryFs, dev , &used_dev, + &tryMedia); + } + + if(bad || actual.fat_start != tryFs.fat_start) { + masterFs.fat_start = actual.fat_start; + printf("-R %d ", actual.fat_start); + bad = try(tot_sectors, + &masterFs, &tryFs, dev , &used_dev, + &tryMedia); + } + + if(bad || actual.fat_len != tryFs.fat_len) { + masterFs.fat_len = actual.fat_len; + printf("-L %d ", actual.fat_len); + bad = try(tot_sectors, + &masterFs, &tryFs, dev , &used_dev, + &tryMedia); + } +#ifdef HAVE_ASSERT_H + assert(!bad); +#endif + if((media & 0xff) != (tryMedia & 0xff)) + printf("-m %d ", (media & 0xff)); + + if(actual.fat_bits == 32) { + if(actual.backupBoot != tryFs.backupBoot) + printf("-K %d ", actual.backupBoot); + } + + if(imgFile != NULL) + printf("-i \"%s\" ", imgFile); + printf("%c:\n", ch_tolower(drive)); + printf("\n"); +} + + void minfo(int argc, char **argv, int type UNUSEDP) NORETURN; void minfo(int argc, char **argv, int type UNUSEDP) { union bootsector boot; char name[EXPAND_BUF]; - int media; - int haveBPB; - int size_code; - int i; struct device dev; char drive; int verbose=0; int c; Stream_t *Stream; int have_drive = 0; - - unsigned long sect_per_track; - + int ex=0; char *imgFile=NULL; - + if(helpFlag(argc, argv)) usage(0); while ((c = getopt(argc, argv, "i:vh")) != EOF) { @@ -156,6 +281,9 @@ void minfo(int argc, char **argv, int type UNUSEDP) } for(;optind <= argc; optind++) { + int media; + int haveBPB; + if(optind == argc) { if(have_drive) break; @@ -167,13 +295,16 @@ void minfo(int argc, char **argv, int type UNUSEDP) } have_drive = 1; - if(! (Stream = find_device(drive, O_RDONLY, &dev, &boot, - name, &media, 0, NULL))) - exit(1); + if(! (Stream = find_device(drive, O_RDONLY, &dev, &boot, + name, &media, 0, NULL))) { + fprintf(stderr, "Could not open drive %c:\n", drive); + ex=1; + continue; + } haveBPB = media >= 0x100; media = media & 0xff; - + printf("device information:\n"); printf("===================\n"); printf("filename=\"%s\"\n", name); @@ -182,78 +313,35 @@ void minfo(int argc, char **argv, int type UNUSEDP) printf("cylinders: %d\n\n", dev.tracks); printf("media byte: %02x\n\n", media & 0xff); - sect_per_track = dev.sectors * dev.heads; - if(sect_per_track != 0) { - unsigned int hidden; - unsigned long tot_sectors; - int tracks_match=0; - printf("mformat command line: mformat "); - - if(haveBPB) { - int sector_size; - tot_sectors = DWORD_S(bigsect); - SET_INT(tot_sectors, WORD_S(psect)); - sector_size = WORD_S(secsiz); - size_code=2; - for(i=0; i<7; i++) { - if(sector_size == 128 << i) { - size_code = i; - break; - } - } - if(media == 0xf0) - hidden = DWORD_S(nhs); - else - hidden = 0; - } else { - tot_sectors = dev.tracks * sect_per_track; - size_code=2; - hidden = 0; - } - - if(tot_sectors == - dev.tracks * sect_per_track - hidden % sect_per_track) { - tracks_match=1; - printf("-t %d ", dev.tracks); - } else { - printf("-T %ld ", tot_sectors); - } - printf ("-h %d -s %d ", dev.heads, dev.sectors); - if(haveBPB && (hidden || !tracks_match)) - printf("-H %d ", hidden); - if(size_code != 2) - printf("-S %d ",size_code); - if(imgFile != NULL) - printf("-i \"%s\" ", imgFile); - printf("%c:\n", ch_tolower(drive)); - printf("\n"); - } + print_mformat_commandline(imgFile, drive, + &dev, &boot, media, haveBPB); if(haveBPB || verbose) displayBPB(Stream, &boot); if(verbose) { - int size; + uint16_t size; + ssize_t ssize; unsigned char *buf; printf("\n"); size = WORD_S(secsiz); - + buf = (unsigned char *) malloc(size); if(!buf) { fprintf(stderr, "Out of memory error\n"); exit(1); } - size = READS(Stream, buf, (mt_off_t) 0, size); - if(size < 0) { + ssize = PREADS(Stream, buf, 0, size); + if(ssize < 0) { perror("read boot sector"); exit(1); } - print_sector("Boot sector hexdump", buf, size); + print_sector("Boot sector hexdump", buf, (uint16_t)ssize); } } FREE(&Stream); - exit(0); + exit(ex); } |