3 ###APPAUTHOR: xiaoranzzz
4 ###APPDATE: 2009-06-19 01:16:23
6 ###APPDESC: Edit MSDOS boot sector record
7 ###APPUSAGE: mbred [options] [bootsect_filename]
8 ###APPEXAMPLE: mbred -v bootsect.bin
9 ###APPOPTION: -v:Display bootsect detail|-d:Hex dump|-o:Set OEM ID|-b|Set bytes per sector|-s:Set sectors count|-S:Set disk size|-l:Set Label
12 #ENV variable MUST be defined somewhere,
13 #FOR perl to search modules from,
15 use lib
$ENV{XR_PERL_MODULE_DIR
};
17 use MyPlace
::Script
::Usage qw
/help_required help_even_empty/;
18 exit 0 if(help_required
($0,@ARGV));
21 my @field = qw
/oem bs sc rs fat re s md sf st h hs ls pdn ch sig id vol sys/;
23 $field[0]=>["OEMID","STR",0x03,8,"MSDOS5.0"],
24 $field[1]=>["Bytes Per Sector","INT",0x0B,2,512],
25 $field[2]=>["Sectors Per Cluster","INT",0x0D,1,1],
26 $field[3]=>["Reserved Sectors","INT",0x0E,2,1],
27 $field[4]=>["FATs","INT",0x10,1,2],
28 $field[5]=>["Root Entries","INT",0x11,2,224],
29 $field[6]=>["Small Sectors","INT",0x13,2,2880],
30 $field[7]=>["Media Descriptor","HEX",0x15,1,"F0"],
31 $field[8]=>["Sectors Per FAT","INT",0x16,2,9],
32 $field[9]=>["Sectors Per Track","INT",0x18,2,18],
33 $field[10]=>["Heads","INT",0x1A,2,2],
34 $field[11]=>["Hidden Sectors","INT",0x1C,4,0],
35 $field[12]=>["Large Sectors","INT",0x20,4,0],
36 $field[13]=>["Physical Drive Number","INT",0x24,1,0],
37 $field[14]=>["Current Head","INT",0x25,1,0],
38 $field[15]=>["Signature","INT",0x26,1,41],
39 $field[16]=>["ID","HEX",0x27,4,"0000"],
40 $field[17]=>["Volume Label","STR",0x2B,11,"Boot"],
41 $field[18]=>["System ID","STR",0x36,8,"FAT12"]
44 my $MINIREAD = 0x36+8;
48 my $length = scalar(@_);
49 push @result," 0 1 2 3 4 5 6 7 8 9 A B C D E F\n";;
50 for(my $i = 0;$i<$length;$i+=16) {
51 my $count = $i + 16 >= $length ?
$length - 1 : $i + 15;
52 my @lines = @_[$i..$count];
53 push @result,sprintf("%03X0 ",$i/16);
54 push @result,sprintf("%02X "x16
,@lines);
55 push @result,map {/[\p{IsGraph} ]/ ?
$_ : "." } map chr,@lines;
58 push @result," 0 1 2 3 4 5 6 7 8 9 A B C D E F\n";;
66 my $type= $mbr{$fn}->[1];
67 my $idx = $mbr{$fn}->[2];
68 my $len = $mbr{$fn}->[3];
69 # print STDERR Dumper($mbr{$fn}),"\n";
70 my @data= @
{$src}[$idx..$idx+$len-1];
75 $result = sprintf("%02X",$data[$_]) . $result;
78 elsif($type eq "STR") {
79 $result = join("",map chr,@data);
84 $result = $result + $data[$_]*(256**$_);
93 my $type= $mbr{$fn}->[1];
94 my $idx = $mbr{$fn}->[2];
95 my $len = $mbr{$fn}->[3];
96 # print STDERR Dumper($mbr{$fn}),"\n";
97 my @data= @
{$dst}[$idx..$idx+$len-1];
101 $value = hex($value);
105 @data = map ord,split("",substr($value . " "x
$len,0,$len));
110 my $low = $value % 256;
111 $value = $value / 256;
115 @
{$dst}[$idx..$idx+$len-1]=@data;
122 my $p = shift(@ARGV);
123 if($p eq '-v' or $p eq '-d') {
128 $opts{$p}=shift(@ARGV);
137 open FI
,"<",$opts{file
} or die("$!\n");
140 last if(length($bytes)>$MAXREAD);
143 $bytes = substr($bytes . "\0" x
$MINIREAD,0,$MAXREAD);
144 my @bytes = map ord,split("",$bytes);
147 my $value = getvalue
(\
@bytes,$_);
148 my $type = $mbr{$_}->[1];
149 my $def = $mbr{$_}->[4];
150 # print STDERR ("$_ = $def\n");
151 next if($value eq $def);
152 if((!$value) or $value =~ /^[\0x0,\s]+$/) {
153 # print STDERR "Assing $_ to default:",$def,"\n";
154 setvalue
(\
@bytes,$_,$def);
158 setvalue
(\
@bytes,$_,$def) if($value =~ /^0+$/);
164 setvalue
(\
@bytes,"oem",$opts{-o
}) if($opts{-o
});
165 my $secs = getvalue
(\
@bytes,"s");
166 my $bs = getvalue
(\
@bytes,"bs");
167 if($opts{-S
} && $opts{-S
} > 0) {
168 $opts{-S
} = $opts{-S
} * 1024;
169 if($opts{-b
} && $opts{-b
}>0) {
170 $bs = int($opts{-b
});
171 $secs = int($opts{-S
} / $bs);
173 elsif($opts{-s
} && $opts{-s
}) {
174 $secs = int($opts{-b
});
175 $bs = int($opts{-S
}/$secs);
178 $secs = int($opts{-S
}/$bs);
181 elsif($opts{-b
} && $opts{-b
}>0) {
182 $bs = int($opts{-b
});
184 elsif($opts{-s
} && $opts{-s
}>0) {
185 $secs = int($opts{-s
});
188 setvalue
(\
@bytes,"bs",$bs);
189 setvalue
(\
@bytes,"s",$secs);
190 my $size = int($secs * $bs / 1024);
193 setvalue
(\
@bytes,"h",1);
194 setvalue
(\
@bytes,"md","FE");
195 setvalue
(\
@bytes,"st",8);
199 setvalue
(\
@bytes,"h",1);
200 setvalue
(\
@bytes,"md","FC");
201 setvalue
(\
@bytes,"st",9);
205 setvalue
(\
@bytes,"h",1);
206 setvalue
(\
@bytes,"md","FA");
207 setvalue
(\
@bytes,"st",8);
211 setvalue
(\
@bytes,"h",2);
212 setvalue
(\
@bytes,"md","FD");
213 setvalue
(\
@bytes,"st",9);
217 setvalue
(\
@bytes,"h",2);
218 setvalue
(\
@bytes,"md","FB");
219 setvalue
(\
@bytes,"st",8);
222 setvalue
(\
@bytes,"h",2);
223 setvalue
(\
@bytes,"md","F9");
224 setvalue
(\
@bytes,"st",9);
227 setvalue
(\
@bytes,"h",2);
228 setvalue
(\
@bytes,"md","F0");
229 setvalue
(\
@bytes,"st",18);
231 elsif($size ==2880) {
232 setvalue
(\
@bytes,"h",2);
233 setvalue
(\
@bytes,"md","F0");
234 setvalue
(\
@bytes,"st",36);
235 setvalue
(\
@bytes,"sc",2);
237 elsif($size <260000) {
238 setvalue
(\
@bytes,"sc",1);
241 setvalue
(\
@bytes,"sc",4);
246 printf STDERR
"%28s : ",$mbr{$_}->[0];
247 print STDERR getvalue
(\
@bytes,$_),"\n";
251 print STDERR hexdump
(@bytes),"\n";
254 print map chr,@bytes;# unless($opts{-v} or $opts{-d});