1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
package resize_fat::any;
use diagnostics;
use strict;
use vars qw($FREE $FILE $DIRECTORY $UNMOVEABLE);
use common qw(:common :constant);
use resize_fat::fat;
use resize_fat::directory;
use resize_fat::dir_entry;
use resize_fat::c_rewritten;
$FREE = 0;
$FILE = 1;
$DIRECTORY = 2;
$UNMOVEABLE = 8;
1;
#- returns the number of clusters for a given filesystem type
sub min_cluster_count($) {
my ($fs) = @_;
(1 << $ {{ FAT16 => 12, FAT32 => 12 }}{$fs->{fs_type}}) - 12;
}
sub max_cluster_count($) {
my ($fs) = @_;
2 ** $fs->{fs_type_size} - 11;
}
#- patch to get the function last_used that return the last used cluster of a fs.
sub last_used($) {
my ($fs) = @_;
#- count in negative so absolute value count back to 2.
foreach (-($fs->{nb_clusters}+1)..-2) { return -$_ if resize_fat::c_rewritten::flag(-$_) }
die "any: empty FAT table";
}
#- patch to get the function last_unmoveable that return the last unmoveable cluster of a fs.
sub last_unmoveable($) {
my ($fs) = @_;
#- count in negative so absolute value count back to 2.
foreach (-($fs->{nb_clusters}+1)..-2) { return -$_ if 0x8 & resize_fat::c_rewritten::flag(-$_) }
die "any: empty FAT table";
}
#- calculates the minimum size of a partition, in physical sectors
sub min_size($) {
my ($fs) = @_;
my $count = $fs->{clusters}{count};
#- directories are both in `used' and `dirs', so are counted twice
#- It's done on purpose since we're moving all directories. So at the worse
#- moment, 2 directories are there, but that way nothing wrong can happen :)
my $min_cluster_count = max(2 + $count->{used} + $count->{bad} + $count->{dirs}, min_cluster_count($fs));
$min_cluster_count = max($min_cluster_count, last_unmoveable($fs));
my $size = $min_cluster_count * divide($fs->{cluster_size}, $SECTORSIZE) +
divide($fs->{cluster_offset}, $SECTORSIZE) +
64*1024*1024 / $SECTORSIZE; #- help with such more sectors (ie 64Mb).
#- help zindozs again with 512Mb+ at least else partition is ignored.
if ($resize_fat::isFAT32) {
$size = max($size, 524*1024*1024 / $SECTORSIZE);
}
$size;
}
#- calculates the maximum size of a partition, in physical sectors
sub max_size($) {
my ($fs) = @_;
my $max_cluster_count = min($fs->{nb_fat_entries} - 2, max_cluster_count($fs));
$max_cluster_count * divide($fs->{cluster_size}, $SECTORSIZE) +
divide($fs->{cluster_offset}, $SECTORSIZE);
}
#- calculates used size in order to avoid modifying anything.
sub used_size($) {
my ($fs) = @_;
my $used_cluster_count = max(last_used($fs), min_cluster_count($fs));
$used_cluster_count * divide($fs->{cluster_size}, $SECTORSIZE) +
divide($fs->{cluster_offset}, $SECTORSIZE);
}
#- fills in fat_flag_map in c_rewritten.
#- Each FAT entry is flagged as either FREE, FILE or DIRECTORY.
sub flag_clusters {
my ($fs) = @_;
my ($cluster, $curr_dir_name, $entry, $type, $nb_dirs);
my $f = sub {
($curr_dir_name, $entry) = @_;
$cluster = resize_fat::dir_entry::get_cluster($entry);
if (resize_fat::dir_entry::is_file($entry)) {
$type = $FILE;
$type |= $UNMOVEABLE if resize_fat::dir_entry::is_unmoveable($entry);
} elsif (resize_fat::dir_entry::is_directory($entry)) {
$type = $DIRECTORY;
} else { return }
my $nb = resize_fat::c_rewritten::checkFat($cluster, $type, "$curr_dir_name/$entry->{name}");
$nb_dirs += $nb if $type == $DIRECTORY;
0;
};
#- this must call allocate_fat_flag that zeroes the buffer allocated.
resize_fat::c_rewritten::allocate_fat_flag($fs->{nb_clusters} + 2);
resize_fat::directory::traverse_all($fs, $f);
$fs->{clusters}{count}{dirs} = $nb_dirs;
}
|