Initial import package mtools: Programs for accessing MS-DOS disks without mounting...
[profile/ivi/mtools.git] / minfo.c
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
28 static void usage(int ret) NORETURN;
29 static 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
39 static void displayInfosector(Stream_t *Stream, union 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
59 void minfo(int argc, char **argv, int type)
60 {
61         union bootsector boot;
62
63         char name[EXPAND_BUF];
64         int media;
65         int tot_sectors;
66         int size_code;
67         int sector_size;
68         int i;
69         struct device dev;
70         char drive;
71         int verbose=0;
72         int c;
73         Stream_t *Stream;
74         struct label_blk_t *labelBlock;
75         
76         if(helpFlag(argc, argv))
77                 usage(0);
78         while ((c = getopt(argc, argv, "i:vh")) != EOF) {
79                 switch (c) {
80                         case 'i':
81                                 set_cmd_line_image(optarg, 0);
82                                 break;
83                         case 'v':
84                                 verbose = 1;
85                                 break;
86                         case 'h':
87                                 usage(0);
88                         default:
89                                 usage(1);
90                 }
91         }
92
93         if(argc == optind)
94                 usage(1);
95
96         for(;optind < argc; optind++) {
97                 if(!argv[optind][0] || argv[optind][1] != ':')
98                         usage(1);
99                 drive = toupper(argv[optind][0]);
100
101                 if(! (Stream = find_device(drive, O_RDONLY, &dev, &boot, 
102                                            name, &media, 0, NULL)))
103                         exit(1);
104
105                 tot_sectors = DWORD_S(bigsect);
106                 SET_INT(tot_sectors, WORD_S(psect));
107                 sector_size = WORD_S(secsiz);
108                 size_code=2;
109                 for(i=0; i<7; i++) {
110                         if(sector_size == 128 << i) {
111                                 size_code = i;
112                                 break;
113                         }
114                 }
115                 printf("device information:\n");
116                 printf("===================\n");
117                 printf("filename=\"%s\"\n", name);
118                 printf("sectors per track: %d\n", dev.sectors);
119                 printf("heads: %d\n", dev.heads);
120                 printf("cylinders: %d\n\n", dev.tracks);
121                 printf("mformat command line: mformat -t %d -h %d -s %d ",
122                        dev.tracks, dev.heads, dev.sectors);
123                 if(DWORD_S(nhs))
124                         printf("-H %d ", DWORD_S(nhs));
125                 if(size_code != 2)
126                         printf("-S %d ",size_code);
127                 printf("%c:\n", tolower(drive));
128                 printf("\n");
129                 
130                 printf("bootsector information\n");
131                 printf("======================\n");
132                 printf("banner:\"%8s\"\n", boot.boot.banner);
133                 printf("sector size: %d bytes\n", WORD_S(secsiz));
134                 printf("cluster size: %d sectors\n", boot.boot.clsiz);
135                 printf("reserved (boot) sectors: %d\n", WORD_S(nrsvsect));
136                 printf("fats: %d\n", boot.boot.nfat);
137                 printf("max available root directory slots: %d\n", 
138                        WORD_S(dirents));
139                 printf("small size: %d sectors\n", WORD_S(psect));
140                 printf("media descriptor byte: 0x%x\n", boot.boot.descr);
141                 printf("sectors per fat: %d\n", WORD_S(fatlen));
142                 printf("sectors per track: %d\n", WORD_S(nsect));
143                 printf("heads: %d\n", WORD_S(nheads));
144                 printf("hidden sectors: %d\n", DWORD_S(nhs));
145                 printf("big size: %d sectors\n", DWORD_S(bigsect));
146
147                 if(WORD_S(fatlen)) {
148                     labelBlock = &boot.boot.ext.old.labelBlock;
149                 } else {
150                     labelBlock = &boot.boot.ext.fat32.labelBlock;
151                 }
152
153                 printf("physical drive id: 0x%x\n", 
154                        labelBlock->physdrive);
155                 printf("reserved=0x%x\n", 
156                        labelBlock->reserved);
157                 printf("dos4=0x%x\n", 
158                        labelBlock->dos4);
159                 printf("serial number: %08X\n", 
160                        _DWORD(labelBlock->serial));
161                 printf("disk label=\"%11.11s\"\n", 
162                        labelBlock->label);
163                 printf("disk type=\"%8.8s\"\n", 
164                        labelBlock->fat_type);
165
166                 if(!WORD_S(fatlen)){
167                         printf("Big fatlen=%u\n",
168                                DWORD_S(ext.fat32.bigFat));
169                         printf("Extended flags=0x%04x\n",
170                                WORD_S(ext.fat32.extFlags));
171                         printf("FS version=0x%04x\n",
172                                WORD_S(ext.fat32.fsVersion));
173                         printf("rootCluster=%u\n",
174                                DWORD_S(ext.fat32.rootCluster));
175                         if(WORD_S(ext.fat32.infoSector) != MAX16)
176                                 printf("infoSector location=%d\n",
177                                        WORD_S(ext.fat32.infoSector));
178                         if(WORD_S(ext.fat32.backupBoot) != MAX16)
179                                 printf("backup boot sector=%d\n",
180                                        WORD_S(ext.fat32.backupBoot));
181                         displayInfosector(Stream,&boot);
182                 }
183
184                 if(verbose) {
185                         int size;
186                         unsigned char *buf;
187
188                         printf("\n");
189                         size = WORD_S(secsiz);
190                         
191                         buf = (unsigned char *) malloc(size);
192                         if(!buf) {
193                                 fprintf(stderr, "Out of memory error\n");
194                                 exit(1);
195                         }
196
197                         size = READS(Stream, buf, (mt_off_t) 0, size);
198                         if(size < 0) {
199                                 perror("read boot sector");
200                                 exit(1);
201                         }
202
203                         print_sector("Boot sector hexdump", buf, size);
204                 }
205         }
206         FREE(&Stream);
207         exit(0);
208 }