/usr/include/tsk/fs/tsk_exfatfs.h is in libtsk-dev 4.4.2-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | /*
** The Sleuth Kit
**
** Copyright (c) 2013 Basis Technology Corp. All rights reserved
** Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
**
** This software is distributed under the Common Public License 1.0
**
*/
/*
* This code makes use of research presented in the following paper:
* "Reverse Engineering the exFAT File System" by Robert Shullich
* Retrieved May 2013 from:
* http://www.sans.org/reading_room/whitepapers/forensics/reverse-engineering-microsoft-exfat-file-system_33274
*
* Some additional details concerning TexFAT were obtained in May 2013
* from:
* http://msdn.microsoft.com/en-us/library/ee490643(v=winembedded.60).aspx
*/
/**
* \file tsk_exfatfs.h
* Contains declarations of structures and functions specific to TSK exFAT
* file system support.
*/
#ifndef _TSK_EXFATFS_H
#define _TSK_EXFATFS_H
#include "tsk_fs_i.h"
#include "tsk_fatfs.h"
/**
* \internal
* The first cluster of an exFAT cluster heap (data area) is cluster #2.
*/
#define EXFATFS_FIRST_CLUSTER 2
/**
* \internal
* An exFAT volume label should have 11 UTF-16 characters, but in practice
* the name can extend into the reserved bytes and have a length up to 15
* characters.
*/
#define EXFATFS_MAX_VOLUME_LABEL_LEN_CHAR 15
#define EXFATFS_MAX_VOLUME_LABEL_LEN_BYTE 30
/**
* \internal
* AnS exFAT file entry set consists of a file directory entry followed by a
* file stream directory entry and at least one file name directory entry.
* The file stream and file name entries are the secondary entries.
*/
#define EXFATFS_MIN_FILE_SECONDARY_DENTRIES_COUNT 2
/**
* \internal
* An exFAT file entry set consists of a file directory entry followed by a
* file stream directory entry and up to seventeen file name directory entries.
* The file stream and file name entries are the secondary entries.
*/
#define EXFATFS_MAX_FILE_SECONDARY_DENTRIES_COUNT 18
/**
* \internal
* An exFAT file name directory entry includes from 1 to 15 UTF-16 characters.
* Each character is stored in UTF-16, so the buffer is actually 30-bytes.
*/
#define EXFATFS_MAX_FILE_NAME_SEGMENT_LENGTH_UTF16_CHARS 15
#define EXFATFS_MAX_FILE_NAME_SEGMENT_LENGTH_UTF16_BYTES 30
/**
* \internal
* An exFAT file name can be a maximum of 255 UTF-16 characters.
*/
#define EXFATFS_MAX_FILE_NAME_LENGTH_UTF16_CHARS 255
/**
* \internal
* In an exFAT file stream directory entry, the second bit of the general
* secondary flags byte is set if there is no FAT chain for a file, i.e., the
* file is not fragmented.
*/
#define EXFATFS_INVALID_FAT_CHAIN_MASK 0x02
/**
* Name for an exFAT volume label directory entry that has an empty label, with
* the "$" prefix that is used to indicate "special file" directory entries and
* non-file directory entries.
*/
#define EXFATFS_EMPTY_VOLUME_LABEL_DENTRY_NAME "$EMPTY_VOLUME_LABEL"
/**
* Name for an exFAT volume GUID directory entry, with the "$" prefix that is
* used to indicate "special file" directory entries and non-file directory
* entries.
*/
#define EXFATFS_VOLUME_GUID_DENTRY_NAME "$VOLUME_GUID"
/**
* Name for an exFAT allocation bitmap directory entry, with the "$" prefix
* that is used to indicate "special file" directory entries and non-file
* directory entries.
*/
#define EXFATFS_ALLOC_BITMAP_DENTRY_NAME "$ALLOC_BITMAP"
/**
* Name for an exFAT upcase table directory entry, with the "$" prefix that is
* used to indicate "special file" directory entries and non-file directory
* entries.
*/
#define EXFATFS_UPCASE_TABLE_DENTRY_NAME "$UPCASE_TABLE"
/**
* Name for an exFAT TexFAT directory entry, with the "$" prefix that is used
* to indicate "special file" directory entries and non-file directory entries.
*/
#define EXFATFS_TEX_FAT_DENTRY_NAME "$TEX_FAT"
/**
* Name for an exFAT access control table directory entry, with the "$" prefix
* that is used to indicate "special file" directory entries and non-file
* directory entries.
*/
#define EXFATFS_ACT_DENTRY_NAME "$ACCESS_CONTROL_TABLE"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \internal
* Master boot record (MBR) structure for exFAT file systems. The MBR will
* be at least 512 bytes in length, but may be padded for larger sector
* sizes. It is part of a larger structure called the volume boot record
* (VBR) that includes OEM parameters, reserved space, and a hash value.
* There should be both a primary and a backup VBR, so there is a primary
* MBR and a backup MBR.
*/
typedef struct {
uint8_t jump_to_boot_code[3]; ///< 0xEB7690
uint8_t fs_name[8]; ///< "EXFAT "
uint8_t must_be_zeros[53]; ///< @brief Must be 0x00
uint8_t partition_offset[8]; ///< @brief Sector address
uint8_t vol_len_in_sectors[8]; ///< @brief Size of total volume in sectors
uint8_t fat_offset[4]; ///< Sector address of first FAT
uint8_t fat_len_in_sectors[4]; ///< Size of FAT in sectors
uint8_t cluster_heap_offset[4]; ///< Sector address of the data region
uint8_t cluster_cnt[4]; ///< Number of clusters in the cluster heap
uint8_t root_dir_cluster[4]; ///< Cluster address of the root directory
uint8_t vol_serial_no[4]; ///< Volume serial number
uint8_t fs_revision[2]; ///< VV.MM
uint8_t vol_flags[2]; ///< Flags: ActiveFAT, Volume Dirty, Media Failure, Clear to Zero, and Reserved
uint8_t bytes_per_sector; ///< Power of 2. Minimum 2^9 = 512 bytes, maximum 2^12 = 4096 bytes
uint8_t sectors_per_cluster; ///< Power of 2. Minimum 2^1 = 2. Maximum is dependant on the fact that the max cluster size is 32 MiB
uint8_t num_fats; ///< 1 or 2 (only 2 if TexFAT is in use)
uint8_t drive_select; ///< Used by INT 13
uint8_t percent_of_cluster_heap_in_use; ///< Percentage of the heap in use
uint8_t reserved[7]; ///< Reserved
uint8_t boot_code[390]; ///< Boot program
uint8_t signature[2]; ///< 0xAA55
} EXFATFS_MASTER_BOOT_REC;
/**
* exFAT directory entry type byte, containing both the type and
* the allocation status
*/
typedef uint8_t EXFATFS_DIR_ENTRY_TYPE;
/**
* exFAT directory entry types, the first byte of a directory entry minus the
* high order bit (which gives allocation status)
*/
enum EXFATFS_DIR_ENTRY_TYPE_ENUM {
EXFATFS_DIR_ENTRY_TYPE_NONE = 0x00, ///< 0x00
EXFATFS_DIR_ENTRY_TYPE_VOLUME_LABEL = 0x03, ///< 0x03
EXFATFS_DIR_ENTRY_TYPE_VOLUME_GUID = 0x20, ///< 0x20
EXFATFS_DIR_ENTRY_TYPE_ALLOC_BITMAP = 0x01, ///< 0x01
EXFATFS_DIR_ENTRY_TYPE_UPCASE_TABLE = 0x02, ///< 0x02
EXFATFS_DIR_ENTRY_TYPE_TEXFAT = 0x21, ///< 0x21
EXFATFS_DIR_ENTRY_TYPE_ACT = 0x62, ///< 0x62
EXFATFS_DIR_ENTRY_TYPE_FILE = 0x05, ///< 0x05
EXFATFS_DIR_ENTRY_TYPE_FILE_STREAM = 0x40, ///< 0x40
EXFATFS_DIR_ENTRY_TYPE_FILE_NAME = 0x41 ///< 0x41
};
typedef enum EXFATFS_DIR_ENTRY_TYPE_ENUM EXFATFS_DIR_ENTRY_TYPE_ENUM;
/**
* Volume label directory entry structure for exFAT file systems. This
* type of entry should be found only in the root directory.
*/
typedef struct {
uint8_t entry_type; ///< 0x83 normally, 0x03 if the media was formatted without a volume label
uint8_t volume_label_length_chars; ///< Number of characters in the volume label
uint8_t volume_label[EXFATFS_MAX_VOLUME_LABEL_LEN_BYTE]; ///< Volume label in UTF16
} EXFATFS_VOL_LABEL_DIR_ENTRY;
/**
* Volume GUID directory entry structure for exFAT file systems. This type
* of entry should be found only in the root directory.
*/
typedef struct {
uint8_t entry_type; ///< 0xA0
uint8_t secondary_entries_count; ///< Always zero
uint8_t check_sum[2]; ///< Set checksum
uint8_t flags[2]; ///< Flags: Allocation possible, no FAT chain, custom
uint8_t volume_guid[16]; ///< Volume GUID
uint8_t reserved[10]; ///< Reserved
} EXFATFS_VOL_GUID_DIR_ENTRY;
/**
* Allocation bitmap directory entry structure for exFAT file systems.
* There will be one allocation bitmap for exFAT and two for TexFAT
* (transactional exFAT). Bit zero of the flags byte is 0 in the directory
* entry for the first bitmap and 1 in the directory entry for the second
* bitmap. This type of entry should be found only in the root directory.
*/
typedef struct {
uint8_t entry_type; ///< 0x81
uint8_t flags; ///< 0x00 for first bitmap, 0x01 for the second
uint8_t reserved[18]; ///< Reserved
uint8_t first_cluster_of_bitmap[4]; ///< Cluster address of first data block
uint8_t length_of_alloc_bitmap_in_bytes[8]; ///< Length of the data
} EXFATFS_ALLOC_BITMAP_DIR_ENTRY;
/**
* UP-Case table directory entry structure for exFAT file systems.
* The UP-Case table is used to convert file names to upper case when
* required. This type of entry should be found only in the root directory.
*/
typedef struct {
uint8_t entry_type; ///< 0x82
uint8_t reserved1[3]; ///< Reserved
uint8_t table_check_sum[4]; ///< UP-Case table checksum
uint8_t reserved2[12]; ///< Reserved
uint8_t first_cluster_of_table[4]; ///< Cluster address of first data block
uint8_t table_length_in_bytes[8]; ///< Length of the data
} EXFATFS_UPCASE_TABLE_DIR_ENTRY;
/**
* TexFAT (transactional exFAT) directory entry structure for exFAT file
* systems. This type of entry should be found only in the root directory.
*/
typedef struct {
uint8_t entry_type; ///< 0xA1
uint8_t reserved[31]; ///< Reserved
} EXFATFS_TEXFAT_DIR_ENTRY;
/**
* Access control table directory entry structure for exFAT file systems.
* This type of entry should be found only in the root directory.
*/
typedef struct {
uint8_t entry_type; ///< 0xE2
uint8_t reserved[31]; ///< Reserved
} EXFATFS_ACCESS_CTRL_TABLE_DIR_ENTRY;
/**
* \internal
* It will be followed by a stream directory entry and 1-17 file name
* entries. The stream and file name entries are secondary entries. A file
* entry and its stream and file name entries constitute a file directory
* entry set.
*/
typedef struct {
uint8_t entry_type; ///< 0x85 if allocated, 0x05 if deleted
uint8_t secondary_entries_count; ///< Number of entries following the primary directory entry (Range: 2 to 18)
uint8_t check_sum[2]; ///< Set checksum
uint8_t attrs[2]; ///< File attributes
uint8_t reserved1[2]; ///< Reserved
uint8_t created_time[2]; ///< Time part of DOS time stamp
uint8_t created_date[2]; ///< Date part of DOS time stamp
uint8_t modified_time[2]; ///< Time part of DOS time stamp
uint8_t modified_date[2]; ///< Date part of DOS time stamp
uint8_t accessed_time[2]; ///< Time part of DOS time stamp
uint8_t accessed_date[2]; ///< Date part of DOS time stamp
uint8_t created_time_tenths_of_sec; ///< Tenths of seconds part of a DOS time stamp, range is 0-199
uint8_t modified_time_tenths_of_sec; ///< Tenths of seconds part of a DOS time stamp, range is 0-199
uint8_t created_time_time_zone_offset; ///< Time zone difference to UTC in 15 minute increments
uint8_t modified_time_time_zone_offset; ///< Time zone difference to UTC in 15 minute increments
uint8_t accessed_time_time_zone_offset; ///< Time zone difference to UTC in 15 minute increments
uint8_t reserved2[7]; ///< Reserved
} EXFATFS_FILE_DIR_ENTRY;
/**
* Stream extension directory entry structure for exFAT file systems.
* It will be preceded by a file directory entry and followed by 1-17
* file name directory entries. The stream and file name entries are
* secondary entries. A file entry and its stream and file name entries
* constitute a file directory entry set.
*/
typedef struct {
uint8_t entry_type; ///< 0xC0 if allocated, 0x40 if deleted
uint8_t flags; ///< Flags: Allocation possible, no FAT chain, custom
uint8_t reserved1; ///< Reserved
uint8_t file_name_length_UTF16_chars; ///< Number of characters in UTF16 name contained in following file name directory entries
uint8_t file_name_hash[2]; ///< Hash of up-cased file name
uint8_t reserved2[2]; ///< Reserved
uint8_t valid_data_length[8]; ///< How much actual data has been written to the file. Must be less than data_length
uint8_t reserved3[4]; ///< Reserved
uint8_t first_cluster_addr[4]; ///< Cluster address of first data block
uint8_t data_length[8]; ///< Length of the data. Max 256M for directories
} EXFATFS_FILE_STREAM_DIR_ENTRY;
/**
* File name directory entry structure for exFAT file systems.
* It will be preceded by 0-16 file name entries, a stream entry, and
* a file entry. A file entry and its stream and file name entries
* constitute a file directory entry set. Note that file names are not
* null-terminated. The length of a file name is stored in the file stream
* entry of the file directory entry set.
*/
typedef struct {
uint8_t entry_type; ///< 0xC1 if allocated, 0x41 if deleted
uint8_t flags; ///< Flags: Allocation possible, no FAT chain, custom
uint8_t utf16_name_chars[30]; ///< UTF16 part of file name, max 15 characters
} EXFATFS_FILE_NAME_DIR_ENTRY;
extern uint8_t
exfatfs_open(FATFS_INFO *a_fatfs);
extern int8_t
exfatfs_is_cluster_alloc(FATFS_INFO *a_fatfs, TSK_DADDR_T a_cluster_addr);
extern uint8_t
exfatfs_fsstat(TSK_FS_INFO *a_fs, FILE *a_hFile);
extern uint8_t
exfatfs_is_dentry(FATFS_INFO *a_fatfs, FATFS_DENTRY *a_dentry,
FATFS_DATA_UNIT_ALLOC_STATUS_ENUM a_cluster_is_alloc,
uint8_t a_do_basic_tests_only);
extern uint8_t
exfatfs_is_vol_label_dentry(FATFS_DENTRY *a_dentry,
FATFS_DATA_UNIT_ALLOC_STATUS_ENUM a_cluster_is_alloc);
extern uint8_t
exfatfs_is_vol_guid_dentry(FATFS_DENTRY *a_dentry,
FATFS_DATA_UNIT_ALLOC_STATUS_ENUM a_alloc_status);
extern uint8_t
exfatfs_is_alloc_bitmap_dentry(FATFS_DENTRY *a_dentry,
FATFS_DATA_UNIT_ALLOC_STATUS_ENUM a_alloc_status, FATFS_INFO *a_fatfs);
extern uint8_t
exfatfs_is_upcase_table_dentry(FATFS_DENTRY *a_dentry,
FATFS_DATA_UNIT_ALLOC_STATUS_ENUM a_alloc_status, FATFS_INFO *a_fatfs);
extern uint8_t
exfatfs_is_texfat_dentry(FATFS_DENTRY *a_dentry,
FATFS_DATA_UNIT_ALLOC_STATUS_ENUM a_alloc_status);
extern uint8_t
exfatfs_is_access_ctrl_table_dentry(FATFS_DENTRY *a_dentry,
FATFS_DATA_UNIT_ALLOC_STATUS_ENUM a_alloc_status);
extern uint8_t
exfatfs_is_file_dentry(FATFS_DENTRY *a_dentry, FATFS_INFO *a_fatfs);
extern uint8_t
exfatfs_is_file_dentry_standalone(FATFS_DENTRY *a_dentry, TSK_ENDIAN_ENUM a_endian);
extern uint8_t
exfatfs_is_file_stream_dentry(FATFS_DENTRY *a_dentry, FATFS_INFO *a_fatfs);
extern uint8_t
exfatfs_is_file_stream_dentry_standalone(FATFS_DENTRY *a_dentry, TSK_ENDIAN_ENUM a_endian,
uint64_t a_cluster_heap_size, TSK_DADDR_T a_last_cluster);
extern uint8_t
exfatfs_find_file_stream_dentry(FATFS_INFO *a_fatfs, TSK_INUM_T a_file_entry_inum,
TSK_DADDR_T a_sector, uint8_t a_sector_is_alloc,
EXFATFS_DIR_ENTRY_TYPE a_file_dentry_type,
FATFS_DENTRY *a_stream_dentry);
extern uint8_t
exfatfs_is_file_name_dentry(FATFS_DENTRY *a_dentry);
extern TSK_RETVAL_ENUM
exfatfs_dinode_copy(FATFS_INFO *a_fatfs, TSK_INUM_T a_inum,
FATFS_DENTRY *a_dentry, uint8_t a_is_alloc, TSK_FS_FILE *a_fs_file);
extern uint8_t
exfatfs_inode_lookup(FATFS_INFO *a_fatfs, TSK_FS_FILE *a_fs_file,
TSK_INUM_T a_inum);
extern uint8_t
exfatfs_istat_attr_flags(FATFS_INFO *a_fatfs, TSK_INUM_T a_inum, FILE *a_hFile);
extern uint8_t
exfatfs_inode_walk_should_skip_dentry(FATFS_INFO *a_fatfs, TSK_INUM_T a_inum,
FATFS_DENTRY *a_dentry, unsigned int a_selection_flags,
int a_cluster_is_alloc);
extern uint8_t
exfatfs_get_alloc_status_from_type(EXFATFS_DIR_ENTRY_TYPE a_dir_entry_type);
extern EXFATFS_DIR_ENTRY_TYPE_ENUM
exfatfs_get_enum_from_type(EXFATFS_DIR_ENTRY_TYPE a_dir_entry_type);
extern TSK_RETVAL_ENUM
exfatfs_dent_parse_buf(FATFS_INFO *a_fatfs, TSK_FS_DIR *a_fs_dir, char *a_buf,
TSK_OFF_T a_buf_len, TSK_DADDR_T *a_sector_addrs);
#ifdef __cplusplus
}
#endif
#endif
|