pmt: initial 3.0.2 update

This commit is contained in:
2024-12-14 11:17:56 +03:00
parent bbf76e4925
commit a6c9feb4d6
1292 changed files with 500838 additions and 2817 deletions

View File

@@ -0,0 +1,271 @@
/*
libparted
Copyright (C) 1998-2000, 2002, 2004, 2007, 2009-2014, 2019-2023 Free
Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
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 "fat.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
/* Reads in the boot sector (superblock), and does a minimum of sanity
* checking. The goals are:
* - to detect fat file systems, even if they are damaged [i.e. not
* return an error / throw an exception]
* - to fail detection if there's not enough information for
* fat_boot_sector_probe_type() to work (or possibly crash on a divide-by-zero)
*/
int
fat_boot_sector_read (FatBootSector** bsp, const PedGeometry *geom)
{
PED_ASSERT (bsp != NULL);
PED_ASSERT (geom != NULL);
if (!ped_geometry_read_alloc (geom, (void **)bsp, 0, 1))
return 0;
FatBootSector *bs = *bsp;
if (PED_LE16_TO_CPU (bs->boot_sign) != 0xAA55) {
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
_("File system has an invalid signature for a FAT "
"file system."));
return 0;
}
if (!bs->sector_size
|| PED_LE16_TO_CPU (bs->sector_size) % PED_SECTOR_SIZE_DEFAULT) {
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
_("File system has an invalid sector size for a FAT "
"file system."));
return 0;
}
if (!bs->cluster_size) {
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
_("File system has an invalid cluster size for a FAT "
"file system."));
return 0;
}
if (!bs->reserved) {
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
_("File system has an invalid number of reserved "
"sectors for a FAT file system."));
return 0;
}
if (bs->fats < 1 || bs->fats > 4) {
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
_("File system has an invalid number of FATs."));
return 0;
}
return 1;
}
/*
Don't trust the FAT12, FAT16 or FAT32 label string.
*/
FatType _GL_ATTRIBUTE_PURE
fat_boot_sector_probe_type (const FatBootSector* bs, const PedGeometry* geom)
{
PedSector logical_sector_size;
PedSector first_cluster_sector;
FatCluster cluster_count;
if (!PED_LE16_TO_CPU (bs->dir_entries))
return FAT_TYPE_FAT32;
logical_sector_size = PED_LE16_TO_CPU (bs->sector_size) / 512;
first_cluster_sector
= PED_LE16_TO_CPU (bs->reserved) * logical_sector_size
+ 2 * PED_LE16_TO_CPU (bs->fat_length) * logical_sector_size
+ PED_LE16_TO_CPU (bs->dir_entries)
/ (512 / sizeof (FatDirEntry));
cluster_count = (geom->length - first_cluster_sector)
/ bs->cluster_size / logical_sector_size;
if (cluster_count > MAX_FAT12_CLUSTERS)
return FAT_TYPE_FAT16;
else
return FAT_TYPE_FAT12;
}
static int
_fat_table_entry_size (FatType fat_type)
{
switch (fat_type) {
case FAT_TYPE_FAT12:
return 2; /* FIXME: how? */
case FAT_TYPE_FAT16:
return 2;
case FAT_TYPE_FAT32:
return 4;
}
return 0;
}
/* Analyses the boot sector, and sticks appropriate numbers in
fs->type_specific.
Note: you need to subtract (2 * cluster_sectors) off cluster offset,
because the first cluster is number 2. (0 and 1 are not real clusters,
and referencing them is a bug)
*/
int
fat_boot_sector_analyse (FatBootSector* bs, PedFileSystem* fs)
{
FatSpecific* fs_info = FAT_SPECIFIC (fs);
int fat_entry_size;
PED_ASSERT (bs != NULL);
fs_info->logical_sector_size = PED_LE16_TO_CPU (bs->sector_size) / 512;
fs_info->sectors_per_track = PED_LE16_TO_CPU (bs->secs_track);
fs_info->heads = PED_LE16_TO_CPU (bs->heads);
if (fs_info->sectors_per_track < 1 || fs_info->sectors_per_track > 63
|| fs_info->heads < 1 || fs_info->heads > 255) {
PedCHSGeometry* bios_geom = &fs->geom->dev->bios_geom;
int cyl_count = 0;
if (fs_info->heads > 0 && fs_info->sectors_per_track > 0)
cyl_count = fs->geom->dev->length / fs_info->heads
/ fs_info->sectors_per_track;
switch (ped_exception_throw (
PED_EXCEPTION_ERROR,
PED_EXCEPTION_IGNORE_CANCEL,
_("The file system's CHS geometry is (%d, %d, %d), "
"which is invalid. The partition table's CHS "
"geometry is (%d, %d, %d)."),
cyl_count, fs_info->heads, fs_info->sectors_per_track,
bios_geom->cylinders, bios_geom->heads,
bios_geom->sectors)) {
case PED_EXCEPTION_CANCEL:
return 0;
case PED_EXCEPTION_IGNORE:
break;
default:
break;
}
}
if (bs->sectors)
fs_info->sector_count = PED_LE16_TO_CPU (bs->sectors)
* fs_info->logical_sector_size;
else
fs_info->sector_count = PED_LE32_TO_CPU (bs->sector_count)
* fs_info->logical_sector_size;
fs_info->fat_table_count = bs->fats;
fs_info->root_dir_entry_count = PED_LE16_TO_CPU (bs->dir_entries);
fs_info->fat_offset = PED_LE16_TO_CPU (bs->reserved)
* fs_info->logical_sector_size;
fs_info->cluster_sectors = bs->cluster_size
* fs_info->logical_sector_size;
fs_info->cluster_size = fs_info->cluster_sectors * 512;
if (fs_info->logical_sector_size == 0) {
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
_("FAT boot sector says logical sector size is 0. "
"This is weird. "));
return 0;
}
if (fs_info->fat_table_count == 0) {
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
_("FAT boot sector says there are no FAT tables. This "
"is weird. "));
return 0;
}
if (fs_info->cluster_sectors == 0) {
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
_("FAT boot sector says clusters are 0 sectors. This "
"is weird. "));
return 0;
}
fs_info->fat_type = fat_boot_sector_probe_type (bs, fs->geom);
if (fs_info->fat_type == FAT_TYPE_FAT12) {
ped_exception_throw (
PED_EXCEPTION_NO_FEATURE,
PED_EXCEPTION_CANCEL,
_("File system is FAT12, which is unsupported."));
return 0;
}
if (fs_info->fat_type == FAT_TYPE_FAT16) {
fs_info->fat_sectors = PED_LE16_TO_CPU (bs->fat_length)
* fs_info->logical_sector_size;
fs_info->serial_number
= PED_LE32_TO_CPU (bs->u.fat16.serial_number);
fs_info->root_cluster = 0;
fs_info->root_dir_offset
= fs_info->fat_offset
+ fs_info->fat_sectors * fs_info->fat_table_count;
fs_info->root_dir_sector_count
= fs_info->root_dir_entry_count * sizeof (FatDirEntry)
/ (512 * fs_info->logical_sector_size);
fs_info->cluster_offset
= fs_info->root_dir_offset
+ fs_info->root_dir_sector_count;
}
if (fs_info->fat_type == FAT_TYPE_FAT32) {
fs_info->fat_sectors = PED_LE32_TO_CPU (bs->u.fat32.fat_length)
* fs_info->logical_sector_size;
fs_info->serial_number
= PED_LE32_TO_CPU (bs->u.fat32.serial_number);
fs_info->info_sector_offset
= PED_LE16_TO_CPU (fs_info->boot_sector->u.fat32.info_sector)
* fs_info->logical_sector_size;
fs_info->boot_sector_backup_offset
= PED_LE16_TO_CPU (fs_info->boot_sector->u.fat32.backup_sector)
* fs_info->logical_sector_size;
fs_info->root_cluster
= PED_LE32_TO_CPU (bs->u.fat32.root_dir_cluster);
fs_info->root_dir_offset = 0;
fs_info->root_dir_sector_count = 0;
fs_info->cluster_offset
= fs_info->fat_offset
+ fs_info->fat_sectors * fs_info->fat_table_count;
}
fs_info->cluster_count
= (fs_info->sector_count - fs_info->cluster_offset)
/ fs_info->cluster_sectors;
fat_entry_size = _fat_table_entry_size (fs_info->fat_type);
if (fs_info->cluster_count + 2
> fs_info->fat_sectors * 512 / fat_entry_size)
fs_info->cluster_count
= fs_info->fat_sectors * 512 / fat_entry_size - 2;
fs_info->dir_entries_per_cluster
= fs_info->cluster_size / sizeof (FatDirEntry);
return 1;
}

View File

@@ -0,0 +1,126 @@
/*
libparted
Copyright (C) 1998-2000, 2007, 2009-2014, 2019-2023 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
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/>.
*/
#ifndef PED_FAT_BOOTSECTOR_H
#define PED_FAT_BOOTSECTOR_H
typedef struct _FatBootSector FatBootSector;
typedef struct _FatInfoSector FatInfoSector;
#include "fat.h"
#define FAT32_INFO_MAGIC1 0x41615252
#define FAT32_INFO_MAGIC2 0x61417272
#define FAT32_INFO_MAGIC3 0xaa55
/* stolen from mkdosfs, by Dave Hudson */
#define FAT_BOOT_MESSAGE \
"This partition does not have an operating system loader installed on it.\n\r"\
"Press a key to reboot..."
#define FAT_BOOT_JUMP "\xeb\x58\x90" /* jmp +5a */
#define FAT_BOOT_CODE "\x0e" /* push cs */ \
"\x1f" /* pop ds */ \
"\xbe\x74\x7e" /* mov si, offset message */ \
/* write_msg_loop: */ \
"\xac" /* lodsb */ \
"\x22\xc0" /* and al, al */ \
"\x74\x06" /* jz done (+8) */ \
"\xb4\x0e" /* mov ah, 0x0e */ \
"\xcd\x10" /* int 0x10 */ \
"\xeb\xf5" /* jmp write_msg_loop */ \
/* done: */ \
"\xb4\x00" /* mov ah, 0x00 */ \
"\xcd\x16" /* int 0x16 */ \
"\xb4\x00" /* mov ah, 0x00 */ \
"\xcd\x19" /* int 0x19 */ \
"\xeb\xfe" /* jmp +0 - in case int 0x19 */ \
/* doesn't work */ \
/* message: */ \
FAT_BOOT_MESSAGE
#define FAT_BOOT_CODE_LENGTH 128
struct __attribute__ ((packed)) _FatBootSector {
uint8_t boot_jump[3]; /* 00: Boot strap short or near jump */
uint8_t system_id[8]; /* 03: system name */
uint16_t sector_size; /* 0b: bytes per logical sector */
uint8_t cluster_size; /* 0d: sectors/cluster */
uint16_t reserved; /* 0e: reserved sectors */
uint8_t fats; /* 10: number of FATs */
uint16_t dir_entries; /* 11: number of root directory entries */
uint16_t sectors; /* 13: if 0, total_sect supersedes */
uint8_t media; /* 15: media code */
uint16_t fat_length; /* 16: sectors/FAT for FAT12/16 */
uint16_t secs_track; /* 18: sectors per track */
uint16_t heads; /* 1a: number of heads */
uint32_t hidden; /* 1c: hidden sectors (partition start) */
uint32_t sector_count; /* 20: no. of sectors (if sectors == 0) */
union __attribute__ ((packed)) {
/* FAT16 fields */
struct __attribute__ ((packed)) {
uint8_t drive_num; /* 24: */
uint8_t empty_1; /* 25: */
uint8_t ext_signature; /* 26: always 0x29 */
uint32_t serial_number; /* 27: */
uint8_t volume_name [11]; /* 2b: */
uint8_t fat_name [8]; /* 36: */
uint8_t boot_code[448]; /* 3f: Boot code (or message) */
} fat16;
/* FAT32 fields */
struct __attribute__ ((packed)) {
uint32_t fat_length; /* 24: size of FAT in sectors */
uint16_t flags; /* 28: bit8: fat mirroring, low4: active fat */
uint16_t version; /* 2a: minor * 256 + major */
uint32_t root_dir_cluster; /* 2c: */
uint16_t info_sector; /* 30: */
uint16_t backup_sector; /* 32: */
uint8_t empty_1 [12]; /* 34: */
uint16_t drive_num; /* 40: */
uint8_t ext_signature; /* 42: always 0x29 */
uint32_t serial_number; /* 43: */
uint8_t volume_name [11]; /* 47: */
uint8_t fat_name [8]; /* 52: */
uint8_t boot_code[420]; /* 5a: Boot code (or message) */
} fat32;
} u;
uint16_t boot_sign; /* 1fe: always 0xAA55 */
};
struct __attribute__ ((packed)) _FatInfoSector {
uint32_t signature_1; /* should be 0x41615252 */
uint8_t unused [480];
uint32_t signature_2; /* should be 0x61417272 */
uint32_t free_clusters;
uint32_t next_cluster; /* most recently allocated cluster */
uint8_t unused2 [0xe];
uint16_t signature_3; /* should be 0xaa55 */
};
int fat_boot_sector_read (FatBootSector** bs, const PedGeometry* geom);
FatType fat_boot_sector_probe_type (const FatBootSector* bs,
const PedGeometry* geom);
int fat_boot_sector_analyse (FatBootSector* bs, PedFileSystem* fs);
#endif /* PED_FAT_BOOTSECTOR_H */

View File

@@ -0,0 +1,46 @@
/*
libparted
Copyright (C) 1999-2000, 2007-2014, 2019-2023 Free Software Foundation,
Inc.
This program is free software; you can redistribute it and/or modify
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/>.
*/
#ifndef COUNT_H_INCLUDED
#define COUNT_H_INCLUDED
typedef enum _FatClusterFlag FatClusterFlag;
typedef struct _FatClusterInfo FatClusterInfo;
enum _FatClusterFlag {
FAT_FLAG_FREE=0,
FAT_FLAG_FILE=1,
FAT_FLAG_DIRECTORY=2,
FAT_FLAG_BAD=3
};
struct __attribute__ ((packed)) _FatClusterInfo {
unsigned int units_used:6; /* 1 unit = cluster_size / 64 */
FatClusterFlag flag:2;
};
extern int fat_collect_cluster_info (PedFileSystem *fs);
extern FatClusterFlag fat_get_cluster_flag (PedFileSystem* fs,
FatCluster cluster);
extern PedSector fat_get_cluster_usage (PedFileSystem* fs, FatCluster cluster);
extern FatClusterFlag fat_get_fragment_flag (PedFileSystem* fs,
FatFragment frag);
extern int fat_is_fragment_active (PedFileSystem* fs, FatFragment frag);
#endif /* COUNT_H_INCLUDED */

162
jni/parted/libparted/fs/fat/fat.c Executable file
View File

@@ -0,0 +1,162 @@
/*
libparted
Copyright (C) 1998-2001, 2007-2014, 2019-2023 Free Software Foundation,
Inc.
This program is free software; you can redistribute it and/or modify
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 <uuid/uuid.h>
#include "fat.h"
PedFileSystem*
fat_alloc (const PedGeometry* geom)
{
PedFileSystem* fs;
fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
if (!fs)
goto error;
fs->type_specific = (FatSpecific*) ped_malloc (sizeof (FatSpecific));
if (!fs->type_specific)
goto error_free_fs;
FatSpecific* fs_info = (FatSpecific*) fs->type_specific;
fs_info->boot_sector = NULL;
fs_info->info_sector = NULL;
fs->geom = ped_geometry_duplicate (geom);
if (!fs->geom)
goto error_free_type_specific;
fs->checked = 0;
return fs;
error_free_type_specific:
free (fs->type_specific);
error_free_fs:
free (fs);
error:
return NULL;
}
void
fat_free (PedFileSystem* fs)
{
FatSpecific* fs_info = (FatSpecific*) fs->type_specific;
free (fs_info->boot_sector);
ped_geometry_destroy (fs->geom);
free (fs->type_specific);
free (fs);
}
PedGeometry*
fat_probe (PedGeometry* geom, FatType* fat_type)
{
PedFileSystem* fs;
FatSpecific* fs_info;
PedGeometry* result;
fs = fat_alloc (geom);
if (!fs)
goto error;
fs_info = (FatSpecific*) fs->type_specific;
if (!fat_boot_sector_read (&fs_info->boot_sector, geom))
goto error_free_fs;
if (!fat_boot_sector_analyse (fs_info->boot_sector, fs))
goto error_free_fs;
*fat_type = fs_info->fat_type;
result = ped_geometry_new (geom->dev, geom->start,
fs_info->sector_count);
fat_free (fs);
return result;
error_free_fs:
fat_free (fs);
error:
return NULL;
}
PedGeometry*
fat_probe_fat16 (PedGeometry* geom)
{
FatType fat_type;
PedGeometry* probed_geom = fat_probe (geom, &fat_type);
if (probed_geom) {
if (fat_type == FAT_TYPE_FAT16)
return probed_geom;
ped_geometry_destroy (probed_geom);
}
return NULL;
}
PedGeometry*
fat_probe_fat32 (PedGeometry* geom)
{
FatType fat_type;
PedGeometry* probed_geom = fat_probe (geom, &fat_type);
if (probed_geom) {
if (fat_type == FAT_TYPE_FAT32)
return probed_geom;
ped_geometry_destroy (probed_geom);
}
return NULL;
}
static PedFileSystemOps fat16_ops = {
probe: fat_probe_fat16,
};
static PedFileSystemOps fat32_ops = {
probe: fat_probe_fat32,
};
PedFileSystemType fat16_type = {
next: NULL,
ops: &fat16_ops,
name: "fat16",
};
PedFileSystemType fat32_type = {
next: NULL,
ops: &fat32_ops,
name: "fat32",
};
void
ped_file_system_fat_init ()
{
if (sizeof (FatBootSector) != 512) {
ped_exception_throw (PED_EXCEPTION_BUG, PED_EXCEPTION_CANCEL,
_("GNU Parted was miscompiled: the FAT boot sector "
"should be 512 bytes. FAT support will be disabled."));
} else {
ped_file_system_type_register (&fat16_type);
ped_file_system_type_register (&fat32_type);
}
}
void
ped_file_system_fat_done ()
{
ped_file_system_type_unregister (&fat16_type);
ped_file_system_type_unregister (&fat32_type);
}

163
jni/parted/libparted/fs/fat/fat.h Executable file
View File

@@ -0,0 +1,163 @@
/*
libparted
Copyright (C) 1998-2001, 2007, 2009-2014, 2019-2023 Free Software
Foundation, Inc.
This program is free software; you can redistribute it and/or modify
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/>.
*/
#ifndef FAT_H_INCLUDED
#define FAT_H_INCLUDED
#include <parted/parted.h>
#include <parted/endian.h>
#include <parted/debug.h>
#if ENABLE_NLS
# include <libintl.h>
# define _(String) dgettext (PACKAGE, String)
#else
# define _(String) (String)
#endif /* ENABLE_NLS */
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUFFER_SIZE 1024 /* buffer size in sectors (512 bytes) */
typedef uint32_t FatCluster;
typedef int32_t FatFragment;
enum _FatType {
FAT_TYPE_FAT12,
FAT_TYPE_FAT16,
FAT_TYPE_FAT32
};
typedef enum _FatType FatType;
typedef struct _FatSpecific FatSpecific;
typedef struct _FatDirEntry FatDirEntry;
#include "bootsector.h"
#include "count.h"
struct _FatTable {
void* table;
FatCluster size;
int raw_size;
FatType fat_type;
FatCluster cluster_count;
FatCluster free_cluster_count;
FatCluster bad_cluster_count;
FatCluster last_alloc;
};
typedef struct _FatTable FatTable;
struct __attribute__ ((packed)) _FatDirEntry {
char name[8];
uint8_t extension[3];
uint8_t attributes;
uint8_t is_upper_case_name;
uint8_t creation_time_low; /* milliseconds */
uint16_t creation_time_high;
uint16_t creation_date;
uint16_t access_date;
uint16_t first_cluster_high; /* for FAT32 */
uint16_t time;
uint16_t date;
uint16_t first_cluster;
uint32_t length;
};
struct _FatSpecific {
FatBootSector *boot_sector; /* structure of boot sector */
FatInfoSector *info_sector; /* fat32-only information sector */
int logical_sector_size; /* illogical sector size :-) */
PedSector sector_count;
int sectors_per_track; /* BIOS CHS stuff (S) */
int heads; /* BIOS CHS stuff (H) */
int cluster_size;
PedSector cluster_sectors;
FatCluster cluster_count;
int dir_entries_per_cluster;
FatType fat_type;
int fat_table_count;
PedSector fat_sectors;
uint32_t serial_number;
PedSector info_sector_offset; /* FAT32 only */
PedSector fat_offset;
PedSector root_dir_offset; /* non-FAT32 */
PedSector cluster_offset;
PedSector boot_sector_backup_offset;
FatCluster root_cluster; /* FAT32 only */
int root_dir_entry_count; /* non-FAT32 */
PedSector root_dir_sector_count; /* non-FAT32 */
FatCluster total_dir_clusters;
FatTable* fat;
FatClusterInfo* cluster_info;
PedSector buffer_sectors;
char* buffer;
int frag_size;
PedSector frag_sectors;
FatFragment frag_count;
FatFragment buffer_frags;
FatFragment cluster_frags;
};
#define FAT_SPECIFIC(fs) ((FatSpecific*) fs->type_specific)
#define FAT_ROOT 0
#define DELETED_FLAG 0xe5
#define READONLY_ATTR 0x01
#define HIDDEN_ATTR 0x02
#define SYSTEM_ATTR 0x04
#define VOLUME_LABEL_ATTR 0x08
#define VFAT_ATTR 0x0f
#define DIRECTORY_ATTR 0x10
#define ARCH_ATTR 0x20
#define MAX_FAT12_CLUSTERS 4086
#define MAX_FAT16_CLUSTERS 65526
#define MAX_FAT32_CLUSTERS 2000000
#define FAT_ROOT_DIR_ENTRY_COUNT 512
extern PedFileSystemType fat16_type;
extern PedFileSystemType fat32_type;
extern void fat_print (const PedFileSystem* fs);
extern PedFileSystem* fat_alloc (const PedGeometry* geom);
extern void fat_free (PedFileSystem* fs);
extern int fat_alloc_buffers (PedFileSystem* fs);
extern int fat_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer);
#endif /* FAT_H_INCLUDED */