/*
libparted
Copyright (C) 1998-2001, 2007-2010 Free Software Foundation, Inc.
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <string.h>
#include "fat.h"
#include "calc.h"
{
if (!fs)
goto error;
if (!fs->type_specific)
goto error_free_fs;
goto error_free_type_specific;
return fs;
return NULL;
}
/* Requires the boot sector to be analysed */
int
{
goto error;
if (!fs_info->cluster_info)
goto error_free_buffer;
return 1;
return 0;
}
void
{
}
void
{
}
int
{
return 0);
return 1;
}
{
if (!fs)
goto error;
goto error_free_fs;
goto error_free_fs;
return result;
return NULL;
}
{
if (probed_geom) {
if (fat_type == FAT_TYPE_FAT16)
return probed_geom;
}
return NULL;
}
{
if (probed_geom) {
if (fat_type == FAT_TYPE_FAT32)
return probed_geom;
}
return NULL;
}
#ifndef DISCOVER_ONLY
int
{
return 1;
boot_sector.system_id[0] = 0;
boot_sector.boot_sign = 0;
}
static int
{
goto error;
goto error_free_fat;
return 1;
return 0;
}
{
if (!fs)
goto error;
goto error_free_fs;
goto error_free_fs;
? &fat16_type
: &fat32_type;
goto error_free_fs;
}
if (!_init_fats (fs))
goto error_free_fs;
if (!fat_alloc_buffers (fs))
goto error_free_fat_table;
if (!fat_collect_cluster_info (fs))
goto error_free_buffers;
return fs;
return NULL;
}
static int
{
}
/* hack: use the ext2 uuid library to generate a reasonably random (hopefully
*/
static uint32_t
_gen_new_serial_number (void)
{
union {
uint32_t i;
} uu32;
return uu32.i;
}
{
if (!fs)
goto error;
/* some initial values, to be changed later */
/ (512 / sizeof (FatDirEntry));
&fs_info->fat_sectors)) {
(fat_type == FAT_TYPE_FAT16)
: fat32_type.name);
goto error_free_fs;
}
/* FAT16 */
if (fs_info->cluster_count
}
/ (512 / sizeof (FatDirEntry));
} else {
/* FAT32 */
fs_info->root_dir_sector_count = 0;
fs_info->root_dir_entry_count = 0;
fs_info->root_dir_offset = 0;
}
goto error_free_fs;
if (!fat_alloc_buffers (fs))
goto error_free_fat_table;
return 0;
}
goto error_free_buffers;
goto error_free_buffers;
goto error_free_buffers;
goto error_free_buffers;
goto error_free_buffers;
}
goto error_free_buffers;
if (!fat_root_dir_clear (fs))
goto error_free_buffers;
}
return fs;
return NULL;
}
{
}
{
}
int
{
return 1;
}
/* Hack: just resize the file system outside of its boundaries! */
{
if (!new_fs)
goto error;
goto error_close_new_fs;
return new_fs;
return 0;
}
static int
{
int i;
if (!table_copy)
goto error;
goto error_free_table_copy;
_("The FATs don't match. If you don't know "
"what this means, then select cancel, run "
"scandisk on the file system, and then come "
"back."))
goto error_free_table_copy;
}
}
return 1;
return 0;
}
int
{
&fat_sectors)) {
_("There are no possible configurations for this FAT "
"type."))
goto error;
}
_("File system doesn't have expected sizes for "
"Windows to like it. "
"Cluster size is %dk (%dk expected); "
"number of clusters is %d (%d expected); "
"size of FATs is %d sectors (%d expected)."),
(int) cluster_sectors / 2,
(int) fs_info->cluster_count,
(int) cluster_count,
(int) fs_info->fat_sectors,
(int) fat_sectors)
goto error;
}
}
_("File system is reporting the free space as "
"%d clusters, not %d clusters."),
goto error;
}
}
if (!_compare_fats (fs))
goto error;
return 1; /* existence of fs implies consistency ;-) */
return 0;
}
/* Calculates how much space there will be in clusters in:
* old_fs intersect the-new-fs
*/
static PedSector
const PedFileSystem* old_fs,
{
}
static int
{
if (fat_calc_resize_sizes (
&geom,
>= min_data_size)
return 1;
if (fat_calc_resize_sizes (
&geom,
0,
>= min_data_size)
return 1;
return 0;
}
/* does a binary search (!) for the mininum size. Too hard to compute directly
* (see calc_sizes() for why!)
*/
static PedSector
{
max_length = length;
else
min_length = length;
}
/* adds a bit of leeway (64 sectors), for resolving extra issues, like root
* directory allocation, that aren't covered here.
*/
return max_length + 64;
}
{
return NULL;
}
{
}
/* FIXME: fat_calc_sizes() needs to say "too big" or "too small", or
* something. This is a really difficult (maths) problem to do
* nicely...
* So, this algorithm works if dev->length / 2 is a valid fat_type
* size. (Which is how I got the magic numbers below)
*/
#if 0
/* returns: -1 too small, 0 ok, 1 too big */
static int
{
return -1; // XXX: doesn't work... can't see a better way!
if (_cluster_sectors < cluster_sectors)
return -1;
if (_cluster_sectors > cluster_sectors)
return 1;
if (_cluster_count < cluster_count)
return -1;
if (_cluster_count > cluster_count)
return 1;
return 0;
}
static PedSector
{
PedSector min_length = 0;
while (1) {
cluster_count)) {
case 0: return length;
}
/* hack... won't always be able to get max cluster count
* with max cluster size, etc. */
return min_length;
}
return 0; /* shut gcc up */
}
#endif
{
return NULL;
#if 0
if (!min_size)
return NULL;
#else
min_size = 65794;
max_size = 2097153;
#endif
return ped_constraint_new (
}
{
return NULL;
#if 0
if (!min_size)
return NULL;
#else
min_size = 525224;
#endif
return ped_constraint_new (
}
#endif /* !DISCOVER_ONLY */
.probe = fat_probe_fat16,
#ifndef DISCOVER_ONLY
.clobber = fat_clobber,
.resize = fat_resize,
#else /* !DISCOVER_ONLY */
#endif /* !DISCOVER_ONLY */
};
.probe = fat_probe_fat32,
#ifndef DISCOVER_ONLY
.clobber = fat_clobber,
.resize = fat_resize,
#else /* !DISCOVER_ONLY */
#endif /* !DISCOVER_ONLY */
};
.name = "fat16",
};
.name = "fat32",
};
void
{
if (sizeof (FatBootSector) != 512) {
_("GNU Parted was miscompiled: the FAT boot sector "
"should be 512 bytes. FAT support will be disabled."));
} else {
}
}
void
{
}