# fatfs.h

    00001 /*
    00002 ** The Sleuth Kit
    00003 **
    00004 ** $Date: 2007/04/19 19:01:34 $
    00005 **
    00006 ** Brian Carrier [carrier@sleuthkit.org]
    00007 ** Copyright (c) 2003-2005 Brian Carrier.  All rights reserved
    00008 **
    00009 ** TASK
    00010 ** Copyright (c) 2002 @stake Inc.  All rights reserved
    00011 **
    00012 ** This software is distributed under the Common Public License 1.0
    00013 **
    00014 */
    00015
    00016 #ifndef _FATFS_H
    00017 #define _FATFS_H
    00018
    00019 #ifdef __cplusplus
    00020 extern "C" {
    00021 #endif
    00022
    00023 /*
    00024 ** Constants
    00025 */
    00026 #define FATFS_ROOTINO   2       /* location of root directory inode */
    00027 #define FATFS_FIRSTINO  2
    00028
    00029 /* The following two values do not have the same meaning as they do in
    00030  * TSK_FS_INFO_TYPE_EXT_2 and FFS because there is no notion of indirect pointers.
    00031  * we will assign the first cluster to direct_addr[0] and that is it
    00032  */
    00033 #define FATFS_NDADDR    2
    00034 #define FATFS_NIADDR    0
    00035 #define FATFS_DEV_BSIZE 512
    00036 #define FATFS_SBOFF             0
    00037 #define FATFS_FS_MAGIC  0xaa55
    00038 #define FATFS_MAXNAMLEN 256
    00039 #define FATFS_MAXNAMLEN_UTF8    1024
    00040
    00041 /* size of FAT to read into FATFS_INFO each time */
    00042 /* This must be at least 1024 bytes or else fat12 will get messed up */
    00043 #define FAT_CACHE_N             4       // number of caches
    00044 #define FAT_CACHE_B             4096
    00045 #define FAT_CACHE_S             8       // number of sectors in cache
    00046
    00047 /* MASK values for FAT entries */
    00048 #define FATFS_12_MASK   0x00000fff
    00049 #define FATFS_16_MASK   0x0000ffff
    00050 #define FATFS_32_MASK   0x0fffffff
    00051
    00052 /* Constants for the FAT entry */
    00053 #define FATFS_UNALLOC   0
    00054 #define FATFS_BAD               0x0ffffff7
    00055 #define FATFS_EOFS              0x0ffffff8
    00056 #define FATFS_EOFE              0x0fffffff
    00057
    00058
    00059
    00060 /* macro to identify if the FAT value is End of File
    00061  * returns 1 if it is and 0 if it is not
    00062  */
    00063 #define FATFS_ISEOF(val, mask)  \
    00064         ((val >= (FATFS_EOFS & mask)) && (val <= (FATFS_EOFE)))
    00065
    00066
    00067 #define FATFS_ISBAD(val, mask) \
    00068         ((val) == (FATFS_BAD & mask))
    00069
    00070
    00071 #define FATFS_CLUST_2_SECT(fatfs, c)    \
    00072         (DADDR_T)(fatfs->firstclustsect + ((((c) & fatfs->mask) - 2) * fatfs->csize))
    00073
    00074 #define FATFS_SECT_2_CLUST(fatfs, s)    \
    00075         (DADDR_T)(2 + ((s)  - fatfs->firstclustsect) / fatfs->csize)
    00076
    00077
    00078
    00079 /* given an inode address, determine in which sector it is located
    00080  * i must be larger than 3 (2 is the root and it doesn't have a sector)
    00081  */
    00082 #define FATFS_INODE_2_SECT(fatfs, i)    \
    00083     (DADDR_T)((i - 3)/(fatfs->dentry_cnt_se) + fatfs->firstdatasect)
    00084
    00085 #define FATFS_INODE_2_OFF(fatfs, i)     \
    00086     (unsigned int)(((i - 3) % fatfs->dentry_cnt_se) * sizeof(fatfs_dentry))
    00087
    00088
    00089
    00090 /* given a sector IN THE DATA AREA, return the base inode for it */
    00091 #define FATFS_SECT_2_INODE(fatfs, s)    \
    00092     (INUM_T)((s - fatfs->firstdatasect) * fatfs->dentry_cnt_se + 3)
    00093
    00094
    00095
    00096 /*
    00097  * Boot Sector Structure for TSK_FS_INFO_TYPE_FAT_12, TSK_FS_INFO_TYPE_FAT_16, and TSK_FS_INFO_TYPE_FAT_32
    00098  */
    00099     typedef struct {
    00100         uint8_t f1[3];
    00101         char oemname[8];
    00102         uint8_t ssize[2];       /* sector size in bytes */
    00103         uint8_t csize;          /* cluster size in sectors */
    00104         uint8_t reserved[2];    /* number of reserved sectors for boot sectors */
    00105         uint8_t numfat;         /* Number of FATs */
    00106         uint8_t numroot[2];     /* Number of Root dentries */
    00107         uint8_t sectors16[2];   /* number of sectors in FS */
    00108         uint8_t f2[1];
    00109         uint8_t sectperfat16[2];        /* size of FAT */
    00110         uint8_t f3[4];
    00111         uint8_t prevsect[4];    /* number of sectors before FS partition */
    00112         uint8_t sectors32[4];   /* 32-bit value of number of FS sectors */
    00113
    00114         /* The following are different for fat12/fat16 and fat32 */
    00115         union {
    00116             struct {
    00117                 uint8_t f5[3];
    00118                 uint8_t vol_id[4];
    00119                 uint8_t vol_lab[11];
    00120                 uint8_t fs_type[8];
    00121                 uint8_t f6[448];
    00122             } f16;
    00123             struct {
    00124                 uint8_t sectperfat32[4];
    00125                 uint8_t ext_flag[2];
    00126                 uint8_t fs_ver[2];
    00127                 uint8_t rootclust[4];   /* cluster where root directory is stored */
    00128                 uint8_t fsinfo[2];      /* TSK_FS_INFO Location */
    00129                 uint8_t bs_backup[2];   /* sector of backup of boot sector */
    00130                 uint8_t f5[12];
    00131                 uint8_t drvnum;
    00132                 uint8_t f6[2];
    00133                 uint8_t vol_id[4];
    00134                 uint8_t vol_lab[11];
    00135                 uint8_t fs_type[8];
    00136                 uint8_t f7[420];
    00137             } f32;
    00138         } a;
    00139
    00140         uint8_t magic[2];       /* MAGIC for all versions */
    00141
    00142     } fatfs_sb;
    00143
    00144     typedef struct {
    00145         uint8_t magic1[4];      /* 41615252 */
    00146         uint8_t f1[480];
    00147         uint8_t magic2[4];      /* 61417272 */
    00148         uint8_t freecnt[4];     /* free clusters 0xfffffffff if unknown */
    00149         uint8_t nextfree[4];    /* next free cluster */
    00150         uint8_t f2[12];
    00151         uint8_t magic3[4];      /* AA550000 */
    00152     } fatfs_fsinfo;
    00153
    00154
    00155
    00156 /* directory entry short name structure */
    00157     typedef struct {
    00158         uint8_t name[8];
    00159         uint8_t ext[3];
    00160         uint8_t attrib;
    00161         uint8_t lowercase;
    00162         uint8_t ctimeten;       /* create times */
    00163         uint8_t ctime[2];
    00164         uint8_t cdate[2];
    00165         uint8_t adate[2];       /* access time */
    00166         uint8_t highclust[2];
    00167         uint8_t wtime[2];       /* last write time */
    00168         uint8_t wdate[2];
    00169         uint8_t startclust[2];
    00170         uint8_t size[4];
    00171     } fatfs_dentry;
    00172
    00173
    00174 /* Macro to combine the upper and lower 2-byte parts of the starting
    00175  * cluster
    00176  */
    00177 #define FATFS_DENTRY_CLUST(fsi, de)     \
    00178         (DADDR_T)((tsk_getu16(fsi->endian, de->startclust)) | (tsk_getu16(fsi->endian, de->highclust)<<16))
    00179
    00180 /* constants for first byte of name[] */
    00181 #define FATFS_SLOT_EMPTY        0x00
    00182 #define FATFS_SLOT_E5           0x05    /* actual value is 0xe5 */
    00183 #define FATFS_SLOT_DELETED      0xe5
    00184
    00185 /*
    00186  *Return 1 if c is an valid charactor for a short file name
    00187  *
    00188  * NOTE: 0x05 is allowed in name[0], and 0x2e (".") is allowed for name[0]
    00189  * and name[1] and 0xe5 is allowed for name[0]
    00190  */
    00191
    00192 #define FATFS_IS_83_NAME(c)             \
    00193         ((((c) < 0x20) || \
    00194           ((c) == 0x22) || \
    00195           (((c) >= 0x2a) && ((c) <= 0x2c)) || \
    00196           ((c) == 0x2e) || \
    00197           ((c) == 0x2f) || \
    00198           (((c) >= 0x3a) && ((c) <= 0x3f)) || \
    00199           (((c) >= 0x5b) && ((c) <= 0x5d)) || \
    00200           ((c) == 0x7c)) == 0)
    00201
    00202
    00203
    00204 /* flags for attributes field */
    00205 #define FATFS_ATTR_NORMAL       0x00    /* normal file */
    00206 #define FATFS_ATTR_READONLY     0x01    /* file is readonly */
    00207 #define FATFS_ATTR_HIDDEN       0x02    /* file is hidden */
    00208 #define FATFS_ATTR_SYSTEM       0x04    /* file is a system file */
    00209 #define FATFS_ATTR_VOLUME       0x08    /* entry is a volume label */
    00210 #define FATFS_ATTR_DIRECTORY    0x10    /* entry is a directory name */
    00211 #define FATFS_ATTR_ARCHIVE      0x20    /* file is new or modified */
    00212 #define FATFS_ATTR_LFN          0x0f    /* A long file name entry */
    00213 #define FATFS_ATTR_ALL          0x3f    /* all flags set */
    00214
    00215 /* flags for lowercase field */
    00216 #define FATFS_CASE_LOWER_BASE   0x08    /* base is lower case */
    00217 #define FATFS_CASE_LOWER_EXT    0x10    /* extension is lower case */
    00218 #define FATFS_CASE_LOWER_ALL    0x18    /* both are lower */
    00219
    00220 #define FATFS_SEC_MASK          0x1f    /* number of seconds div by 2 */
    00221 #define FATFS_SEC_SHIFT         0
    00222 #define FATFS_SEC_MIN           0
    00223 #define FATFS_SEC_MAX           29
    00224 #define FATFS_MIN_MASK          0x7e0   /* number of minutes 0-59 */
    00225 #define FATFS_MIN_SHIFT         5
    00226 #define FATFS_MIN_MIN           0
    00227 #define FATFS_MIN_MAX           59
    00228 #define FATFS_HOUR_MASK         0xf800  /* number of hours 0-23 */
    00229 #define FATFS_HOUR_SHIFT        11
    00230 #define FATFS_HOUR_MIN          0
    00231 #define FATFS_HOUR_MAX          23
    00232
    00233 /* return 1 if x is a valid FAT time */
    00234 #define FATFS_ISTIME(x) \
    00235         (((((x & FATFS_SEC_MASK) >> FATFS_SEC_SHIFT) > FATFS_SEC_MAX) || \
    00236           (((x & FATFS_MIN_MASK) >> FATFS_MIN_SHIFT) > FATFS_MIN_MAX) || \
    00237           (((x & FATFS_HOUR_MASK) >> FATFS_HOUR_SHIFT) > FATFS_HOUR_MAX) ) == 0)
    00238
    00239 #define FATFS_DAY_MASK          0x1f    /* day of month 1-31 */
    00240 #define FATFS_DAY_SHIFT         0
    00241 #define FATFS_DAY_MIN           1
    00242 #define FATFS_DAY_MAX           31
    00243 #define FATFS_MON_MASK          0x1e0   /* month 1-12 */
    00244 #define FATFS_MON_SHIFT         5
    00245 #define FATFS_MON_MIN           1
    00246 #define FATFS_MON_MAX           12
    00247 #define FATFS_YEAR_MASK         0xfe00  /* year, from 1980 0-127 */
    00248 #define FATFS_YEAR_SHIFT        9
    00249 #define FATFS_YEAR_MIN          0
    00250 #define FATFS_YEAR_MAX          127
    00251
    00252 /* return 1 if x is a valid FAT date */
    00253 #define FATFS_ISDATE(x) \
    00254          (((((x & FATFS_DAY_MASK) >> FATFS_DAY_SHIFT) > FATFS_DAY_MAX) || \
    00255            (((x & FATFS_DAY_MASK) >> FATFS_DAY_SHIFT) < FATFS_DAY_MIN) || \
    00256            (((x & FATFS_MON_MASK) >> FATFS_MON_SHIFT) > FATFS_MON_MAX) || \
    00257            (((x & FATFS_MON_MASK) >> FATFS_MON_SHIFT) < FATFS_MON_MIN) || \
    00258            (((x & FATFS_YEAR_MASK) >> FATFS_YEAR_SHIFT) > FATFS_YEAR_MAX) ) == 0)
    00259
    00260 /*
    00261  * Long file name support for windows
    00262  *
    00263  * Contents of this are in UNICODE, not ASCII
    00264  */
    00265     typedef struct {
    00266         uint8_t seq;
    00267         uint8_t part1[10];
    00268         uint8_t attributes;
    00269         uint8_t reserved1;
    00270         uint8_t chksum;
    00271         uint8_t part2[12];
    00272         uint8_t reserved2[2];
    00273         uint8_t part3[4];
    00274     } fatfs_dentry_lfn;
    00275
    00276 /* flags for seq field */
    00277 #define FATFS_LFN_SEQ_FIRST     0x40    /* This bit is set for the first lfn entry */
    00278 #define FATFS_LFN_SEQ_MASK      0x3f    /* These bits are a mask for the decreasing
    00279                                          * sequence number for the entries */
    00280
    00281 /* internal FATFS_INFO structure */
    00282     typedef struct {
    00283         TSK_FS_INFO fs_info;    /* super class */
    00284         //TSK_DATA_BUF *table;      /* cached section of file allocation table */
    00285
    00286         /* FAT cache */
    00287         char fatc_buf[FAT_CACHE_N][FAT_CACHE_B];
    00288         DADDR_T fatc_addr[FAT_CACHE_N];
    00289         uint8_t fatc_ttl[FAT_CACHE_N];  // ttl of 0 means is not in use
    00290
    00291
    00292         TSK_DATA_BUF *dinodes;  /* sector size buffer of inode list */
    00293         fatfs_sb *sb;
    00294
    00295         fatfs_dentry *dep;
    00296
    00297
    00298         /* FIrst sector of FAT */
    00299         DADDR_T firstfatsect;
    00300
    00301         /* First sector after FAT  - For TSK_FS_INFO_TYPE_FAT_12 and TSK_FS_INFO_TYPE_FAT_16, this is where the
    00302          * root directory entries are.  For TSK_FS_INFO_TYPE_FAT_32, this is the the first
    00303          * cluster */
    00304         DADDR_T firstdatasect;
    00305
    00306         /* The sector number were cluster 2 (the first one) is
    00307          * for TSK_FS_INFO_TYPE_FAT_32, it will be the same as firstdatasect, but for TSK_FS_INFO_TYPE_FAT_12 & 16
    00308          * it will be the first sector after the Root directory  */
    00309         DADDR_T firstclustsect;
    00310
    00311         /* size of data area in clusters, starting at firstdatasect */
    00312         DADDR_T clustcnt;
    00313
    00314         DADDR_T lastclust;
    00315
    00316         /* sector where the root directory is located */
    00317         DADDR_T rootsect;
    00318
    00319         uint32_t dentry_cnt_se; /* max number of dentries per sector */
    00320         uint32_t dentry_cnt_cl; /* max number of dentries per cluster */
    00321
    00322         uint16_t ssize;         /* size of sectors in bytes */
    00323         uint16_t ssize_sh;      /* power of 2 for size of sectors */
    00324         uint8_t csize;          /* size of clusters in sectors */
    00325         //uint16_t      reserved;       /* number of reserved sectors */
    00326         uint8_t numfat;         /* number of fat tables */
    00327         uint32_t sectperfat;    /* sectors per fat table */
    00328         uint16_t numroot;       /* number of 32-byte dentries in root dir */
    00329         uint32_t mask;          /* the mask to use for the sectors */
    00330
    00331     } FATFS_INFO;
    00332
    00333
    00334     extern int8_t is_sectalloc(FATFS_INFO *, DADDR_T);
    00335
    00336     extern uint8_t fatfs_dent_walk(TSK_FS_INFO *, INUM_T,
    00337         TSK_FS_DENT_FLAG_ENUM, TSK_FS_DENT_TYPE_WALK_CB, void *);
    00338     extern uint8_t fatfs_isdentry(FATFS_INFO *, fatfs_dentry *);
    00339     extern uint8_t fatfs_make_root(FATFS_INFO *, TSK_FS_INODE *);
    00340     extern uint8_t fatfs_dinode_copy(FATFS_INFO *, TSK_FS_INODE *,
    00341         fatfs_dentry *, DADDR_T, INUM_T);
    00342
    00343 #ifdef __cplusplus
    00344 }
    00345 #endif
    00346 #endif