1/* Copyright 1997-2003,2006,2007,2009 Alain Knaff. 2 * This file is part of mtools. 3 * 4 * Mtools is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * Mtools is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with Mtools. If not, see <http://www.gnu.org/licenses/>. 16 * 17 * mlabel.c 18 * Make an MSDOS volume label 19 */ 20 21#include "sysincludes.h" 22#include "msdos.h" 23#include "mainloop.h" 24#include "vfat.h" 25#include "mtools.h" 26#include "nameclash.h" 27 28static void usage(int ret) NORETURN; 29static void usage(int ret) 30{ 31 fprintf(stderr, 32 "Mtools version %s, dated %s\n", mversion, mdate); 33 fprintf(stderr, 34 "Usage: %s [-v] drive\n", progname); 35 exit(ret); 36} 37 38 39static void displayInfosector(Stream_t *Stream, struct bootsector *boot) 40{ 41 InfoSector_t *infosec; 42 43 if(WORD(ext.fat32.infoSector) == MAX16) 44 return; 45 46 infosec = (InfoSector_t *) safe_malloc(WORD(secsiz)); 47 force_read(Stream, (char *) infosec, 48 (mt_off_t) WORD(secsiz) * WORD(ext.fat32.infoSector), 49 WORD(secsiz)); 50 printf("\nInfosector:\n"); 51 printf("signature=0x%08x\n", _DWORD(infosec->signature1)); 52 if(_DWORD(infosec->count) != MAX32) 53 printf("free clusters=%u\n", _DWORD(infosec->count)); 54 if(_DWORD(infosec->pos) != MAX32) 55 printf("last allocated cluster=%u\n", _DWORD(infosec->pos)); 56} 57 58 59void minfo(int argc, char **argv, int type) 60{ 61 unsigned char boot0[MAX_BOOT]; 62 struct bootsector *boot = (struct bootsector *) boot0; 63 64 char name[EXPAND_BUF]; 65 int media; 66 int tot_sectors; 67 int size_code; 68 int sector_size; 69 int i; 70 struct device dev; 71 char drive; 72 int verbose=0; 73 int c; 74 Stream_t *Stream; 75 struct label_blk_t *labelBlock; 76 77 if(helpFlag(argc, argv)) 78 usage(0); 79 while ((c = getopt(argc, argv, "i:vh")) != EOF) { 80 switch (c) { 81 case 'i': 82 set_cmd_line_image(optarg, 0); 83 break; 84 case 'v': 85 verbose = 1; 86 break; 87 case 'h': 88 usage(0); 89 default: 90 usage(1); 91 } 92 } 93 94 if(argc == optind) 95 usage(1); 96 97 for(;optind < argc; optind++) { 98 if(!argv[optind][0] || argv[optind][1] != ':') 99 usage(1); 100 drive = toupper(argv[optind][0]); 101 102 if(! (Stream = find_device(drive, O_RDONLY, &dev, boot, 103 name, &media, 0, NULL))) 104 exit(1); 105 106 tot_sectors = DWORD(bigsect); 107 SET_INT(tot_sectors, WORD(psect)); 108 sector_size = WORD(secsiz); 109 size_code=2; 110 for(i=0; i<7; i++) { 111 if(sector_size == 128 << i) { 112 size_code = i; 113 break; 114 } 115 } 116 printf("device information:\n"); 117 printf("===================\n"); 118 printf("filename=\"%s\"\n", name); 119 printf("sectors per track: %d\n", dev.sectors); 120 printf("heads: %d\n", dev.heads); 121 printf("cylinders: %d\n\n", dev.tracks); 122 printf("mformat command line: mformat -t %d -h %d -s %d ", 123 dev.tracks, dev.heads, dev.sectors); 124 if(DWORD(nhs)) 125 printf("-H %d ", DWORD(nhs)); 126 if(size_code != 2) 127 printf("-S %d ",size_code); 128 printf("%c:\n", tolower(drive)); 129 printf("\n"); 130 131 printf("bootsector information\n"); 132 printf("======================\n"); 133 printf("banner:\"%8s\"\n", boot->banner); 134 printf("sector size: %d bytes\n", WORD(secsiz)); 135 printf("cluster size: %d sectors\n", boot->clsiz); 136 printf("reserved (boot) sectors: %d\n", WORD(nrsvsect)); 137 printf("fats: %d\n", boot->nfat); 138 printf("max available root directory slots: %d\n", 139 WORD(dirents)); 140 printf("small size: %d sectors\n", WORD(psect)); 141 printf("media descriptor byte: 0x%x\n", boot->descr); 142 printf("sectors per fat: %d\n", WORD(fatlen)); 143 printf("sectors per track: %d\n", WORD(nsect)); 144 printf("heads: %d\n", WORD(nheads)); 145 printf("hidden sectors: %d\n", DWORD(nhs)); 146 printf("big size: %d sectors\n", DWORD(bigsect)); 147 148 if(WORD(fatlen)) { 149 labelBlock = &boot->ext.old.labelBlock; 150 } else { 151 labelBlock = &boot->ext.fat32.labelBlock; 152 } 153 154 printf("physical drive id: 0x%x\n", 155 labelBlock->physdrive); 156 printf("reserved=0x%x\n", 157 labelBlock->reserved); 158 printf("dos4=0x%x\n", 159 labelBlock->dos4); 160 printf("serial number: %08X\n", 161 _DWORD(labelBlock->serial)); 162 printf("disk label=\"%11.11s\"\n", 163 labelBlock->label); 164 printf("disk type=\"%8.8s\"\n", 165 labelBlock->fat_type); 166 167 if(!WORD(fatlen)){ 168 printf("Big fatlen=%u\n", 169 DWORD(ext.fat32.bigFat)); 170 printf("Extended flags=0x%04x\n", 171 WORD(ext.fat32.extFlags)); 172 printf("FS version=0x%04x\n", 173 WORD(ext.fat32.fsVersion)); 174 printf("rootCluster=%u\n", 175 DWORD(ext.fat32.rootCluster)); 176 if(WORD(ext.fat32.infoSector) != MAX16) 177 printf("infoSector location=%d\n", 178 WORD(ext.fat32.infoSector)); 179 if(WORD(ext.fat32.backupBoot) != MAX16) 180 printf("backup boot sector=%d\n", 181 WORD(ext.fat32.backupBoot)); 182 displayInfosector(Stream,boot); 183 } 184 185 if(verbose) { 186 int size; 187 unsigned char *buf; 188 189 printf("\n"); 190 size = WORD(secsiz); 191 192 buf = (unsigned char *) malloc(size); 193 if(!buf) { 194 fprintf(stderr, "Out of memory error\n"); 195 exit(1); 196 } 197 198 size = READS(Stream, buf, (mt_off_t) 0, size); 199 if(size < 0) { 200 perror("read boot sector"); 201 exit(1); 202 } 203 204 print_sector("Boot sector hexdump", buf, size); 205 } 206 } 207 FREE(&Stream); 208 exit(0); 209} 210