summaryrefslogtreecommitdiffstats
path: root/src/fat.h
blob: 2ec58c775942830eb9a987263777171e993c26cf (plain)
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*

    File: fat.h

    Copyright (C) 1998-2004,2007-2008 Christophe GRENIER <grenier@cgsecurity.org>
  
    This software 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 2 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, write the Free Software Foundation, Inc., 51
    Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

 */

#ifndef _FAT_H
#define _FAT_H
#ifdef __cplusplus
extern "C" {
#endif

#define FAT1X_PART_NAME 0x2B
#define FAT32_PART_NAME 0x47
#define FAT_NAME1       0x36
#define FAT_NAME2       0x52    /* FAT32 only */
#define NTFS_NAME       0x03
#define OS2_NAME        0x03

/*
 * FAT partition boot sector information, taken from the Linux
 * kernel sources.
 */

struct fat_boot_sector {
	uint8_t	ignored[3];	/* 0x00 Boot strap short or near jump */
	int8_t	system_id[8];	/* 0x03 Name - can be used to special case
				   partition manager volumes */
	uint8_t	sector_size[2];	/* 0x0B bytes per logical sector */
	uint8_t	sectors_per_cluster;	/* 0x0D sectors/cluster */
	uint16_t	reserved;	/* 0x0E reserved sectors */
	uint8_t	fats;		/* 0x10 number of FATs */
	uint8_t	dir_entries[2];	/* 0x11 root directory entries */
	uint8_t	sectors[2];	/* 0x13 number of sectors */
	uint8_t	media;		/* 0x15 media code (unused) */
	uint16_t	fat_length;	/* 0x16 sectors/FAT */
	uint16_t	secs_track;	/* 0x18 sectors per track */
	uint16_t	heads;		/* 0x1A number of heads */
	uint32_t	hidden;		/* 0x1C hidden sectors (unused) */
	uint32_t	total_sect;	/* 0x20 number of sectors (if sectors == 0) */

	/* The following fields are only used by FAT32 */
	uint32_t	fat32_length;	/* 0x24=36 sectors/FAT */
	uint16_t	flags;		/* 0x28 bit 8: fat mirroring, low 4: active fat */
	uint8_t	version[2];	/* 0x2A major, minor filesystem version */
	uint32_t	root_cluster;	/* 0x2C first cluster in root directory */
	uint16_t	info_sector;	/* 0x30 filesystem info sector */
	uint16_t	backup_boot;	/* 0x32 backup boot sector */
	uint8_t	BPB_Reserved[12];	/* 0x34 Unused */
	uint8_t	BS_DrvNum;		/* 0x40 */
	uint8_t	BS_Reserved1;		/* 0x41 */
	uint8_t	BS_BootSig;		/* 0x42 */
	uint8_t	BS_VolID[4];		/* 0x43 */
	uint8_t	BS_VolLab[11];		/* 0x47 */
	uint8_t	BS_FilSysType[8];	/* 0x52=82*/

	/* */
	uint8_t	nothing[420];	/* 0x5A */
	uint16_t	marker;
} __attribute__ ((gcc_struct, __packed__));

struct fat_fsinfo {
  uint32_t leadsig;		/* 0x41615252 */
  uint8_t reserved1[480];
  uint32_t strucsig;		/* 0x61417272 */
  uint32_t freecnt;     	/* free clusters 0xfffffffff if unknown */
  uint32_t nextfree;		/* next free cluster */
  uint8_t reserved3[12];
  uint32_t magic3;		/* 0xAA550000 */
} __attribute__ ((gcc_struct, __packed__));

struct msdos_dir_entry {
	int8_t	name[8],ext[3];		/* 00 name and extension */
	uint8_t	attr;			/* 0B attribute bits */
	uint8_t    lcase;		/* 0C Case for base and extension */
	uint8_t	        ctime_ms;	/* 0D Creation time, milliseconds */
	uint16_t	ctime;		/* 0E Creation time */
	uint16_t	cdate;		/* 10 Creation date */
	uint16_t	adate;		/* 12 Last access date */
	uint16_t        starthi;	/* 14 High 16 bits of cluster in FAT32 */
	uint16_t	time;           /* 16 time, date and first cluster */
        uint16_t        date;		/* 18 */
        uint16_t        start;		/* 1A */
	uint32_t	size;		/* 1C file size (in bytes) */
} __attribute__ ((gcc_struct, __packed__));

/* Up to 13 characters of the name */
struct msdos_dir_slot {
	uint8_t    id;			/* 00 sequence number for slot */
	uint8_t    name0_4[10];		/* 01 first 5 characters in name */
	uint8_t    attr;		/* 0B attribute byte */
	uint8_t    reserved;		/* 0C always 0 */
	uint8_t    alias_checksum;	/* 0D checksum for 8.3 alias */
	uint8_t    name5_10[12];	/* 0E 6 more characters in name */
	uint16_t   start;		/* 1A starting cluster number, 0 in long slots */
	uint8_t    name11_12[4];	/* 1C last 2 characters in name */
};


int comp_FAT(disk_t *disk,const partition_t *partition, const unsigned long int fat_size, const unsigned long int sect_res);
int log_fat2_info(const struct fat_boot_sector*fh1, const struct fat_boot_sector*fh2, const upart_type_t upart_type, const unsigned int sector_size);

unsigned int get_next_cluster(disk_t *disk,const partition_t *partition, const upart_type_t upart_type,const int offset, const unsigned int cluster);
int set_next_cluster(disk_t *disk,const partition_t *partition, const upart_type_t upart_type,const int offset, const unsigned int cluster, const unsigned int next_cluster);

int is_fat(const partition_t *partition);
int is_part_fat(const partition_t *partition);
int is_part_fat12(const partition_t *partition);
int is_part_fat16(const partition_t *partition);
int is_part_fat32(const partition_t *partition);
unsigned int fat32_get_prev_cluster(disk_t *disk,const partition_t *partition, const unsigned int fat_offset, const unsigned int cluster, const unsigned int no_of_cluster);
int fat32_free_info(disk_t *disk,const partition_t *partition, const unsigned int fat_offset, const unsigned int no_of_cluster, unsigned int *next_free, unsigned int*free_count);
unsigned long int fat32_get_free_count(const unsigned char *boot_fat32, const unsigned int sector_size);
unsigned long int fat32_get_next_free(const unsigned char *boot_fat32, const unsigned int sector_size);

#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */
#define IS_FREE(n) (!*(n) || *(const unsigned char *) (n) == DELETED_FLAG)
#define ATTR_RO      1  /* read-only */
#define ATTR_HIDDEN  2  /* hidden */
#define ATTR_SYS     4  /* system */
#define ATTR_VOLUME  8  /* volume label */
#define ATTR_DIR     16 /* directory */
#define ATTR_ARCH    32 /* archived */

#define ATTR_NONE    0 /* no attribute bits */
#define ATTR_UNUSED  (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
	/* attribute bits that are copied "as is" */
#define ATTR_EXT     (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
#define ATTR_EXT_MASK     (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME | ATTR_DIR | ATTR_ARCH)
	/* bits that are used by the Windows 95/Windows NT extended FAT */
#define FAT12_BAD	0x0FF7
#define FAT12_EOC	0x0FF8
#define FAT16_BAD	0xFFF7
#define FAT16_EOC	0xFFF8
#define FAT32_BAD	0x0FFFFFF7
#define FAT32_EOC	0x0FFFFFF8
#define FAT1x_BOOT_SECTOR_SIZE 0x200

int recover_FAT(disk_t *disk, const struct fat_boot_sector*fat_header, partition_t *partition, const int verbose, const int dump_ind, const int backup);
int check_FAT(disk_t *disk, partition_t *partition, const int verbose);
int test_FAT(disk_t *disk, const struct fat_boot_sector *fat_header, const partition_t *partition, const int verbose, const int dump_ind);
int recover_OS2MB(const disk_t *disk, const struct fat_boot_sector*fat_header, partition_t *partition, const int verbose, const int dump_ind);
int check_OS2MB(disk_t *disk, partition_t *partition, const int verbose);
int check_VFAT_volume_name(const char *name, const unsigned int max_size);
#ifdef __cplusplus
} /* closing brace for extern "C" */
#endif
#endif