1 /*
2 ** The Sleuth Kit
3 **
4 ** Brian Carrier [carrier <at> sleuthkit [dot] org]
5 ** Copyright (c) 2003-2012 Brian Carrier.  All rights reserved
6 **
7 ** Matt Stillerman [matt@atc-nycorp.com]
8 ** Copyright (c) 2012 ATC-NY.  All rights reserved.
9 ** This file contains data developed with support from the National
10 ** Institute of Justice, Office of Justice Programs, U.S. Department of Justice.
11 **
12 ** TASK
13 ** Copyright (c) 2002 @stake Inc.  All rights reserved
14 **
15 ** Copyright (c) 1997,1998,1999, International Business Machines
16 ** Corporation and others. All Rights Reserved.
17 */
18 
19 /** \file tsk_fs.h
20 * External header file for file system support.
21 * Note that this file is not meant to be directly included.
22 * It is included by both libtsk.h and tsk_fs_i.h.
23 */
24 
25 /* LICENSE
26 * .ad
27 * .fi
28 *	This software is distributed under the IBM Public License.
29 * AUTHOR(S)
30 *	Wietse Venema
31 *	IBM T.J. Watson Research
32 *	P.O. Box 704
33 *	Yorktown Heights, NY 10598, USA
34 --*/
35 
36 /**
37 * \defgroup fslib C File System Functions
38 * \defgroup fslib_cpp C++ File System Classes
39  */
40 
41 #ifndef _TSK_FS_H
42 #define _TSK_FS_H
43 
44 #include <sys/types.h>
45 
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49 
50     typedef struct TSK_FS_INFO TSK_FS_INFO;
51     typedef struct TSK_FS_FILE TSK_FS_FILE;
52 
53 
54 
55 
56     /**************** BLOCK Structure *******************/
57 
58     /** \name Generic File System Block Data Structure */
59     //@{
60 
61     /** Flags that are used in TSK_FS_BLOCK and in callback of file_walk.
62     * Note that some of these are dependent. A block can be either TSK_FS_BLOCK_FLAG_ALLOC
63     * or TSK_FS_BLOCK_FLAG_UNALLOC.  It can be one of TSK_FS_BLOCK_FLAG_RAW, TSK_FS_BLOCK_FLAG_BAD,
64     * TSK_FS_BLOCK_FLAG_RES, TSK_FS_BLOCK_FLAG_SPARSE, or TSK_FS_BLOCK_FLAG_COMP.  Note that some of
65     * these are set only by file_walk because they are file-level details, such as compression and sparse.
66     */
67     enum TSK_FS_BLOCK_FLAG_ENUM {
68         TSK_FS_BLOCK_FLAG_UNUSED = 0x0000,      ///< Used to show that TSK_FS_BLOCK structure has no data in it
69         TSK_FS_BLOCK_FLAG_ALLOC = 0x0001,       ///< Block is allocated (and not TSK_FS_BLOCK_FLAG_UNALLOC)
70         TSK_FS_BLOCK_FLAG_UNALLOC = 0x0002,     ///< Block is unallocated (and not TSK_FS_BLOCK_FLAG_ALLOC)
71         TSK_FS_BLOCK_FLAG_CONT = 0x0004,        ///< Block (could) contain file content (and not TSK_FS_BLOCK_FLAG_META)
72         TSK_FS_BLOCK_FLAG_META = 0x0008,        ///< Block (could) contain file system metadata (and not TSK_FS_BLOCK_FLAG_CONT)
73         TSK_FS_BLOCK_FLAG_BAD = 0x0010, ///< Block has been marked as bad by the file system
74         TSK_FS_BLOCK_FLAG_RAW = 0x0020, ///< The data has been read raw from the disk (and not COMP or SPARSE)
75         TSK_FS_BLOCK_FLAG_SPARSE = 0x0040,      ///< The data passed in the file_walk callback was stored as sparse (all zeros) (and not RAW or COMP)
76         TSK_FS_BLOCK_FLAG_COMP = 0x0080,        ///< The data passed in the file_walk callback was stored in a compressed form (and not RAW or SPARSE)
77         TSK_FS_BLOCK_FLAG_RES = 0x0100, ///< The data passed in the file_walk callback is from an NTFS resident file
78         TSK_FS_BLOCK_FLAG_AONLY = 0x0200        /// < The buffer in TSK_FS_BLOCK has no content (it could be non-empty, but should be ignored), but the flags and such are accurate
79     };
80     typedef enum TSK_FS_BLOCK_FLAG_ENUM TSK_FS_BLOCK_FLAG_ENUM;
81 
82 
83     /**
84     * Flags that are used to specify which blocks to call the tsk_fs_block_walk() callback function with.
85     */
86     enum TSK_FS_BLOCK_WALK_FLAG_ENUM {
87         TSK_FS_BLOCK_WALK_FLAG_NONE = 0x00,     ///< No Flags
88         TSK_FS_BLOCK_WALK_FLAG_ALLOC = 0x01,    ///< Allocated blocks
89         TSK_FS_BLOCK_WALK_FLAG_UNALLOC = 0x02,  ///< Unallocated blocks
90         TSK_FS_BLOCK_WALK_FLAG_CONT = 0x04,     ///< Blocks that could store file content
91         TSK_FS_BLOCK_WALK_FLAG_META = 0x08,     ///< Blocks that could store file system metadata
92         TSK_FS_BLOCK_WALK_FLAG_AONLY = 0x10     ///< Do not include content in callback only address and allocation status
93     };
94     typedef enum TSK_FS_BLOCK_WALK_FLAG_ENUM TSK_FS_BLOCK_WALK_FLAG_ENUM;
95 
96 
97 #define TSK_FS_BLOCK_TAG 0x1b7c3f4a
98     /**
99     * Generic data structure to hold block data with metadata
100     */
101     typedef struct {
102         int tag;                ///< \internal Will be set to TSK_FS_BLOCK_TAG if structure is valid / allocated
103         TSK_FS_INFO *fs_info;   ///< Pointer to file system that block is from
104         char *buf;              ///< Buffer with block data (of size TSK_FS_INFO::block_size)
105         TSK_DADDR_T addr;       ///< Address of block
106         TSK_FS_BLOCK_FLAG_ENUM flags;   /// < Flags for block (alloc or unalloc)
107     } TSK_FS_BLOCK;
108 
109 
110     /**
111     * Function definition used for callback to tsk_fs_block_walk().
112     *
113     * @param a_block Pointer to block structure that holds block content and flags
114     * @param a_ptr Pointer that was supplied by the caller who called tsk_fs_block_walk
115     * @returns Value to identify if walk should continue, stop, or stop because of error
116     */
117     typedef TSK_WALK_RET_ENUM(*TSK_FS_BLOCK_WALK_CB) (const TSK_FS_BLOCK *
118         a_block, void *a_ptr);
119 
120 
121     // external block-level functions
122     extern void tsk_fs_block_free(TSK_FS_BLOCK * a_fs_block);
123     extern TSK_FS_BLOCK *tsk_fs_block_get(TSK_FS_INFO * fs,
124         TSK_FS_BLOCK * fs_block, TSK_DADDR_T addr);
125     extern TSK_FS_BLOCK *tsk_fs_block_get_flag(TSK_FS_INFO * a_fs,
126         TSK_FS_BLOCK * a_fs_block, TSK_DADDR_T a_addr,
127         TSK_FS_BLOCK_FLAG_ENUM a_flags);
128     extern uint8_t tsk_fs_block_walk(TSK_FS_INFO * a_fs,
129         TSK_DADDR_T a_start_blk, TSK_DADDR_T a_end_blk,
130         TSK_FS_BLOCK_WALK_FLAG_ENUM a_flags, TSK_FS_BLOCK_WALK_CB a_action,
131         void *a_ptr);
132 
133     //@}
134 
135     /**************** DATA and DATA_LIST Structures ************/
136 
137     /** \name Generic File System File Content Data Structures */
138     //@{
139 
140     /* The location of "most" file content is stored in the generic TSK
141      * data structures as runs (starting address and length).
142      */
143 
144     /**
145     * Flags used for a TSK_FS_ATTR_RUN entry.
146     */
147     typedef enum {
148         TSK_FS_ATTR_RUN_FLAG_NONE = 0x00,       ///< No Flag
149         TSK_FS_ATTR_RUN_FLAG_FILLER = 0x01,     ///< Entry is a filler for a run that has not been seen yet in the processing (or has been lost)
150         TSK_FS_ATTR_RUN_FLAG_SPARSE = 0x02      ///< Entry is a sparse run where all data in the run is zeros
151     } TSK_FS_ATTR_RUN_FLAG_ENUM;
152 
153 
154     typedef struct TSK_FS_ATTR_RUN TSK_FS_ATTR_RUN;
155 
156     /**
157     * Holds information about a single data run, which has a starting address and length.
158     * A run describes a consecutive list of blocks that have been allocated to a file.
159     * A file may have many such runs and they are stringed together in a linked list.
160     * The entries in the list must be stored in sequential order (based on offset in file).
161     */
162     struct TSK_FS_ATTR_RUN {
163         TSK_FS_ATTR_RUN *next;  ///< Pointer to the next run in the attribute (or NULL)
164         TSK_DADDR_T offset;     ///< Offset (in blocks) of this run in the file
165         TSK_DADDR_T addr;       ///< Starting block address (in file system) of run
166         TSK_DADDR_T len;        ///< Number of blocks in run (0 when entry is not in use)
167         TSK_FS_ATTR_RUN_FLAG_ENUM flags;        ///< Flags for run
168     };
169 
170     /**
171     * Flags used for the TSK_FS_ATTR structure, which is used to
172     * store file content metadata.
173     */
174     typedef enum {
175         TSK_FS_ATTR_FLAG_NONE = 0x00,   ///< No Flag
176         TSK_FS_ATTR_INUSE = 0x01,       ///< data structure is in use
177         TSK_FS_ATTR_NONRES = 0x02,      ///< Contains non-resident data (i.e. located in blocks)
178         TSK_FS_ATTR_RES = 0x04, ///< Contains resident data (i.e. in a small buffer)
179         TSK_FS_ATTR_ENC = 0x10, ///< Contains encrypted data
180         TSK_FS_ATTR_COMP = 0x20,        ///< Contains compressed data
181         TSK_FS_ATTR_SPARSE = 0x40,      ///< Contains sparse data
182         TSK_FS_ATTR_RECOVERY = 0x80,    ///< Data was determined in file recovery mode
183     } TSK_FS_ATTR_FLAG_ENUM;
184 
185     /**
186     * File walk callback function definition.  This is called for
187     * chunks of content in the file being processed.
188     * @param a_fs_file Pointer to file being processed
189     * @param a_off Byte offset in file that this data is for
190     * @param a_addr Address of data being passed (valid only if a_flags have RAW set)
191     * @param a_buf Pointer to buffer with file content
192     * @param a_len Size of data in buffer (in bytes)
193     * @param a_flags Flags about the file content
194     * @param a_ptr Pointer that was specified by caller to inode_walk
195     * @returns Value that tells file walk to continue or stop
196     */
197     typedef TSK_WALK_RET_ENUM(*TSK_FS_FILE_WALK_CB) (TSK_FS_FILE *
198         a_fs_file, TSK_OFF_T a_off, TSK_DADDR_T a_addr, char *a_buf,
199         size_t a_len, TSK_FS_BLOCK_FLAG_ENUM a_flags, void *a_ptr);
200 
201     /**
202     * Flags used by tsk_fs_file_walk to determine when the callback function should
203     * be used. */
204     typedef enum {
205         TSK_FS_FILE_WALK_FLAG_NONE = 0x00,      ///< No Flag
206         TSK_FS_FILE_WALK_FLAG_SLACK = 0x01,     ///< Include the file's slack space in the callback.
207         TSK_FS_FILE_WALK_FLAG_NOID = 0x02,      ///< Ignore the Id argument given in the API (use only the type)
208         TSK_FS_FILE_WALK_FLAG_AONLY = 0x04,     ///< Provide callback with only addresses and no file content.
209         TSK_FS_FILE_WALK_FLAG_NOSPARSE = 0x08,  ///< Do not include sparse blocks in the callback.
210     } TSK_FS_FILE_WALK_FLAG_ENUM;
211 
212 
213     /**
214     * These are based on the NTFS type values.
215     * Added types for HFS+.
216     * NOTE: Update bindings/java/src/org/sleuthkit/datamodel/TskData.java
217     * with any changes.
218     */
219     typedef enum {
220         TSK_FS_ATTR_TYPE_NOT_FOUND = 0x00,      // 0
221         TSK_FS_ATTR_TYPE_DEFAULT = 0x01,        // 1
222         TSK_FS_ATTR_TYPE_NTFS_SI = 0x10,        // 16
223         TSK_FS_ATTR_TYPE_NTFS_ATTRLIST = 0x20,  // 32
224         TSK_FS_ATTR_TYPE_NTFS_FNAME = 0x30,     // 48
225         TSK_FS_ATTR_TYPE_NTFS_VVER = 0x40,      // 64 (NT)
226         TSK_FS_ATTR_TYPE_NTFS_OBJID = 0x40,     // 64 (2K)
227         TSK_FS_ATTR_TYPE_NTFS_SEC = 0x50,       // 80
228         TSK_FS_ATTR_TYPE_NTFS_VNAME = 0x60,     // 96
229         TSK_FS_ATTR_TYPE_NTFS_VINFO = 0x70,     // 112
230         TSK_FS_ATTR_TYPE_NTFS_DATA = 0x80,      // 128
231         TSK_FS_ATTR_TYPE_NTFS_IDXROOT = 0x90,   // 144
232         TSK_FS_ATTR_TYPE_NTFS_IDXALLOC = 0xA0,  // 160
233         TSK_FS_ATTR_TYPE_NTFS_BITMAP = 0xB0,    // 176
234         TSK_FS_ATTR_TYPE_NTFS_SYMLNK = 0xC0,    // 192 (NT)
235         TSK_FS_ATTR_TYPE_NTFS_REPARSE = 0xC0,   // 192 (2K)
236         TSK_FS_ATTR_TYPE_NTFS_EAINFO = 0xD0,    // 208
237         TSK_FS_ATTR_TYPE_NTFS_EA = 0xE0,        // 224
238         TSK_FS_ATTR_TYPE_NTFS_PROP = 0xF0,      //  (NT)
239         TSK_FS_ATTR_TYPE_NTFS_LOG = 0x100,      //  (2K)
240         TSK_FS_ATTR_TYPE_UNIX_INDIR = 0x1001,   //  Indirect blocks for UFS and ExtX file systems
241         TSK_FS_ATTR_TYPE_UNIX_EXTENT = 0x1002,  //  Extents for Ext4 file system
242 
243         // Types for HFS+ File Attributes
244         TSK_FS_ATTR_TYPE_HFS_DEFAULT = 0x01,    // 1    Data fork of fs special files and misc
245         TSK_FS_ATTR_TYPE_HFS_DATA = 0x1100,     // 4352 Data fork of regular files
246         TSK_FS_ATTR_TYPE_HFS_RSRC = 0x1101,     // 4353 Resource fork of regular files
247         TSK_FS_ATTR_TYPE_HFS_EXT_ATTR = 0x1102, // 4354 Extended Attributes, except compression records
248         TSK_FS_ATTR_TYPE_HFS_COMP_REC = 0x1103, // 4355 Compression records
249     } TSK_FS_ATTR_TYPE_ENUM;
250 
251 #define TSK_FS_ATTR_ID_DEFAULT  0       ///< Default Data ID used if file system does not assign one.
252 
253     typedef struct TSK_FS_ATTR TSK_FS_ATTR;
254     /**
255     * Holds information about the location of file content (or a file attribute). For most file systems, a file
256     * has only a single attribute that stores the file content.
257     * Other file systems, such as NTFS, have multiple
258     * attributes.  If multiple attributes exist, they are stored in a linked list.
259     * Attributes can be "resident", which means the data is stored
260     * in a small buffer instead of being stored in a full file system block.
261     * "Non-resident" attributes store data in blocks and they are stored in
262     * the data structure as a series of runs.
263     * This structure is used to represent both of these cases.
264     *
265     * The non-resident data has several size values.
266     * \verbatim
267     * |--------------------------------------------------------------------|
268     * |skiplen|---------------allocsize------------------------------------|
269     * |skiplen|---------------size-----------------------------------|
270     * |skiplen|---------------initsize------------|
271     * \endverbatim
272     */
273     struct TSK_FS_ATTR {
274         TSK_FS_ATTR *next;      ///< Pointer to next attribute in list
275         TSK_FS_FILE *fs_file;   ///< Pointer to the file that this is from
276         TSK_FS_ATTR_FLAG_ENUM flags;    ///< Flags for attribute
277         char *name;             ///< Name of attribute (in UTF-8).  Will be NULL if attribute doesn't have a name.
278         size_t name_size;       ///< Number of bytes allocated to name
279         TSK_FS_ATTR_TYPE_ENUM type;     ///< Type of attribute
280         uint16_t id;            ///< Id of attribute
281 
282         TSK_OFF_T size;         ///< Size in bytes of the attribute resident and non-resident content (does not include skiplen for non-resident attributes)
283 
284         /**
285         * Data associated with a non-resident file / attribute.
286         * The data is stored in one or more data runs.
287         */
288         struct {
289             TSK_FS_ATTR_RUN *run;       ///< Linked list of runs for non-resident attributes
290             TSK_FS_ATTR_RUN *run_end;   ///< Pointer to final run in the list
291             uint32_t skiplen;   ///< Number of initial bytes in run to skip before content begins. The size field does not include this length.
292             TSK_OFF_T allocsize;        ///< Number of bytes that are allocated in all clusters of non-resident run (will be larger than size - does not include skiplen).  This is defined when the attribute is created and used to determine slack space.
293             TSK_OFF_T initsize; ///< Number of bytes (starting from offset 0) that have data (including FILLER) saved for them (smaller then or equal to size).  This is defined when the attribute is created.
294             uint32_t compsize;  ///< Size of compression units (needed only if NTFS file is compressed)
295         } nrd;
296 
297         /**
298         * Data associated with a resident attribute / file.
299         * The data is stored in a buffer.
300         */
301         struct {
302             uint8_t *buf;       ///< Buffer for resident data
303             size_t buf_size;    ///< Number of bytes allocated to buf
304             TSK_OFF_T offset;   ///< Starting offset in bytes relative to start of file system (NOT YET IMPLEMENTED)
305         } rd;
306 
307         /* Special file (compressed, encrypted, etc.) */
308          ssize_t(*r) (const TSK_FS_ATTR * fs_attr,
309             TSK_OFF_T a_offset, char *a_buf, size_t a_len);
310          uint8_t(*w) (const TSK_FS_ATTR * fs_attr,
311             int flags, TSK_FS_FILE_WALK_CB, void *);
312     };
313 
314 
315     /**
316     * Structure used as the head of an attribute list.
317     */
318     typedef struct {
319         TSK_FS_ATTR *head;
320     } TSK_FS_ATTRLIST;
321 
322     extern uint8_t tsk_fs_attr_walk(const TSK_FS_ATTR * a_fs_attr,
323         TSK_FS_FILE_WALK_FLAG_ENUM a_flags, TSK_FS_FILE_WALK_CB a_action,
324         void *a_ptr);
325 
326     //@}
327 
328 
329     /**************** META_NAME_LIST Structure *******************/
330 
331     /** \name Generic File System File Metadata Data Structures */
332     //@{
333 
334     /**
335     * Size of name array in TSK_FS_META_NAME_LIST structure
336     */
337 #define TSK_FS_META_NAME_LIST_NSIZE    512
338 
339 
340     typedef struct TSK_FS_META_NAME_LIST TSK_FS_META_NAME_LIST;
341     /**
342     * Relatively generic structure to hold file names that are stored with
343     * the file metadata.  Note that this is different from the
344     * file name stored in the directory heirarchy, which is
345     * part of the tsk_fs_name_... code.  This is currently
346     * used for NTFS and FAT file systems only.
347     */
348     struct TSK_FS_META_NAME_LIST {
349         TSK_FS_META_NAME_LIST *next;    ///< Pointer to next name (or NULL)
350         char name[TSK_FS_META_NAME_LIST_NSIZE]; ///< Name in UTF-8 (does not include parent directory name)
351         TSK_INUM_T par_inode;   ///< Inode address of parent directory (NTFS only)
352         uint32_t par_seq;       ///< Sequence number of parent directory (NTFS only)
353     };
354 
355 
356 
357     /****************** META Structure ***************/
358 
359     /**
360     * Metadata flags used in TSK_FS_META.flags and in request to inode_walk
361     */
362     enum TSK_FS_META_FLAG_ENUM {
363         TSK_FS_META_FLAG_ALLOC = 0x01,   ///< Metadata structure is currently in an allocated state
364         TSK_FS_META_FLAG_UNALLOC = 0x02, ///< Metadata structure is currently in an unallocated state
365         TSK_FS_META_FLAG_USED = 0x04,    ///< Metadata structure has been allocated at least once
366         TSK_FS_META_FLAG_UNUSED = 0x08,  ///< Metadata structure has never been allocated.
367         TSK_FS_META_FLAG_COMP = 0x10,    ///< The file contents are compressed.
368         TSK_FS_META_FLAG_ORPHAN = 0x20,  ///< Return only metadata structures that have no file name pointing to the (inode_walk flag only)
369     };
370     typedef enum TSK_FS_META_FLAG_ENUM TSK_FS_META_FLAG_ENUM;
371 
372     enum TSK_FS_META_ATTR_FLAG_ENUM {
373         TSK_FS_META_ATTR_EMPTY,   ///< The data in the attributes (if any) is not for this file
374         TSK_FS_META_ATTR_STUDIED, ///< The data in the attributes are for this file
375         TSK_FS_META_ATTR_ERROR,   ///< The attributes for this file could not be loaded
376     };
377     typedef enum TSK_FS_META_ATTR_FLAG_ENUM TSK_FS_META_ATTR_FLAG_ENUM;
378 
379 
380     /**
381     * Values for the mode field -- which identifies the file type
382     * and permissions.
383     */
384     enum TSK_FS_META_TYPE_ENUM {
385         TSK_FS_META_TYPE_UNDEF = 0x00,
386         TSK_FS_META_TYPE_REG = 0x01,    ///< Regular file
387         TSK_FS_META_TYPE_DIR = 0x02,    ///< Directory file
388         TSK_FS_META_TYPE_FIFO = 0x03,   ///< Named pipe (fifo)
389         TSK_FS_META_TYPE_CHR = 0x04,    ///< Character device
390         TSK_FS_META_TYPE_BLK = 0x05,    ///< Block device
391         TSK_FS_META_TYPE_LNK = 0x06,    ///< Symbolic link
392         TSK_FS_META_TYPE_SHAD = 0x07,   ///< SOLARIS ONLY
393         TSK_FS_META_TYPE_SOCK = 0x08,   ///< UNIX domain socket
394         TSK_FS_META_TYPE_WHT = 0x09,    ///< Whiteout
395         TSK_FS_META_TYPE_VIRT = 0x0a,   ///< "Virtual File" created by TSK for file system areas
396         TSK_FS_META_TYPE_VIRT_DIR = 0x0b,   ///< "Virtual Directory" created by TSK to hold data like orphan files
397     };
398     typedef enum TSK_FS_META_TYPE_ENUM TSK_FS_META_TYPE_ENUM;
399 
400 #define TSK_FS_META_TYPE_STR_MAX 0x0c   ///< Number of file types in shortname array
401     extern char tsk_fs_meta_type_str[TSK_FS_META_TYPE_STR_MAX][2];
402 
403 #define TSK_FS_IS_DIR_META(x) ((x == TSK_FS_META_TYPE_DIR) || (x == TSK_FS_META_TYPE_VIRT_DIR))
404 
405     enum TSK_FS_META_MODE_ENUM {
406         /* The following describe the file permissions */
407         TSK_FS_META_MODE_UNSPECIFIED = 0000000,       ///< unspecified
408 
409         TSK_FS_META_MODE_ISUID = 0004000,       ///< set user id on execution
410         TSK_FS_META_MODE_ISGID = 0002000,       ///< set group id on execution
411         TSK_FS_META_MODE_ISVTX = 0001000,       ///< sticky bit
412 
413         TSK_FS_META_MODE_IRUSR = 0000400,       ///< R for owner
414         TSK_FS_META_MODE_IWUSR = 0000200,       ///< W for owner
415         TSK_FS_META_MODE_IXUSR = 0000100,       ///< X for owner
416 
417         TSK_FS_META_MODE_IRGRP = 0000040,       ///< R for group
418         TSK_FS_META_MODE_IWGRP = 0000020,       ///< W for group
419         TSK_FS_META_MODE_IXGRP = 0000010,       ///< X for group
420 
421         TSK_FS_META_MODE_IROTH = 0000004,       ///< R for other
422         TSK_FS_META_MODE_IWOTH = 0000002,       ///< W for other
423         TSK_FS_META_MODE_IXOTH = 0000001        ///< X for other
424     };
425     typedef enum TSK_FS_META_MODE_ENUM TSK_FS_META_MODE_ENUM;
426 
427     typedef enum TSK_FS_META_CONTENT_TYPE_ENUM {
428         TSK_FS_META_CONTENT_TYPE_DEFAULT = 0x0,
429         TSK_FS_META_CONTENT_TYPE_EXT4_EXTENTS = 0x1     ///< Ext4 with extents instead of individual pointers
430     } TSK_FS_META_CONTENT_TYPE_ENUM;
431 
432 
433 #define TSK_FS_META_TAG 0x13524635
434     /**
435     * TSK data structure to store general file and directory metadata.
436     * Note that the file in the file
437     * system may have more metadata than is stored here.
438     * For performance reasons, the run list of the file content is not always known
439     * when the file is loaded.  It may be loaded only when needed by the internal code.
440     * The TSK_FS_META::content_ptr pointer contains file system-specific data that will be
441     * used to determine the full run. After it has been loaded, the TSK_FS_META::attr field
442     * will contain that info.
443     */
444     typedef struct {
445         int tag;                ///< \internal Will be set to TSK_FS_META_TAG if structure is allocated
446 
447         TSK_FS_META_FLAG_ENUM flags;    ///< Flags for this file for its allocation status etc.
448         TSK_INUM_T addr;        ///< Address of the meta data structure for this file
449 
450         TSK_FS_META_TYPE_ENUM type;     ///< File type
451         TSK_FS_META_MODE_ENUM mode;     ///< Unix-style permissions
452         int nlink;              ///< link count (number of file names pointing to this)
453         TSK_OFF_T size;         ///< file size (in bytes)
454         TSK_UID_T uid;          ///< owner id
455         TSK_GID_T gid;          ///< group id
456 
457         /* @@@ Need to make these 64-bits ... ? */
458         time_t mtime;           ///< last file content modification time (stored in number of seconds since Jan 1, 1970 UTC)
459         uint32_t mtime_nano;    ///< nano-second resolution in addition to m_time
460         time_t atime;           ///< last file content accessed time (stored in number of seconds since Jan 1, 1970 UTC)
461         uint32_t atime_nano;    ///< nano-second resolution in addition to a_time
462         time_t ctime;           ///< last file / metadata status change time (stored in number of seconds since Jan 1, 1970 UTC)
463         uint32_t ctime_nano;    ///< nano-second resolution in addition to c_time
464         time_t crtime;          ///< Created time (stored in number of seconds since Jan 1, 1970 UTC)
465         uint32_t crtime_nano;   ///< nano-second resolution in addition to cr_time
466 
467         /* filesystem specific times */
468         union {
469             struct {
470                 time_t dtime;   ///< Linux deletion time
471                 uint32_t dtime_nano;    ///< nano-second resolution in addition to d_time
472             } ext2;
473             struct {
474                 time_t bkup_time;       ///< HFS+ backup time
475                 uint32_t bkup_time_nano;        ///< nano-second resolution in addition to bkup_time
476             } hfs;
477             struct {
478                 time_t fn_crtime;   ///< NTFS Created time stored in FILE_NAME
479                 time_t fn_crtime_nano;   ///< NTFS Created time stored in FILE_NAME in nano-second resolution
480                 time_t fn_mtime;   ///< NTFS mod (content) stored in FILE_NAME
481                 time_t fn_mtime_nano;   ///< NTFS mod time stored in FILE_NAME in nano-second resolution
482                 time_t fn_atime;   ///< NTFS access time stored in FILE_NAME
483                 time_t fn_atime_nano;   ///< NTFS access time stored in FILE_NAME in nano-second resolution
484                 time_t fn_ctime;   ///< NTFS change (MFT Entry) time stored in FILE_NAME
485                 time_t fn_ctime_nano;   ///< NTFS change (MFT Entry) time stored in FILE_NAME in nano-second resolution
486                 uint16_t fn_id; ///< Attribute ID used to populate FN times.
487             } ntfs;
488         } time2;
489 
490         void *content_ptr;      ///< Pointer to file system specific data that is used to store references to file content
491         size_t content_len;     ///< size of content  buffer
492         TSK_FS_META_CONTENT_TYPE_ENUM content_type;     ///< File system-specific and describes type of data in content_ptr in case file systems have multiple ways of storing things.
493 
494         uint32_t seq;           ///< Sequence number for file (NTFS only, is incremented when entry is reallocated)
495 
496         /** Contains run data on the file content (specific locations where content is stored).
497         * Check attr_state to determine if data in here is valid because not all file systems
498         * load this data when a file is loaded.  It may not be loaded until needed by one
499         * of the APIs. Most file systems will have only one attribute, but NTFS will have several. */
500         TSK_FS_ATTRLIST *attr;
501         TSK_FS_META_ATTR_FLAG_ENUM attr_state;  ///< State of the data in the TSK_FS_META::attr structure
502 
503         TSK_FS_META_NAME_LIST *name2;   ///< Name of file stored in metadata (FATXX and NTFS Only)
504         char *link;             ///< Name of target file if this is a symbolic link
505     } TSK_FS_META;
506 
507 
508 
509     /** String that is prepended to orphan FAT & NTFS files when the file
510     * name is known, but the parent is not */
511 #define TSK_FS_ORPHAN_STR "-ORPHAN_FILE-"
512 
513     /* we are using the last inode as the special inode for the orphan directory.  Note that this
514      * macro is defined to abstract this convention, but there are many places in the code where
515      * there is implied logic about this convention. For example, inode_walks will stop before
516      * this value so that special handling can occur. */
517 #define TSK_FS_ORPHANDIR_INUM(fs_info) \
518     (fs_info->last_inum)
519 
520 
521     /**
522     * inode walk callback function definition.  This is called for every file
523     * that meets the criteria specified when inode_walk was called.
524     * @param a_fs_file Pointer to the current file
525     * @param a_ptr Pointer that was specified by caller to inode_walk
526     * @returns Value that tells inode walk to continue or stop
527     */
528     typedef TSK_WALK_RET_ENUM(*TSK_FS_META_WALK_CB) (TSK_FS_FILE *
529         a_fs_file, void *a_ptr);
530 
531 
532     extern uint8_t tsk_fs_meta_walk(TSK_FS_INFO * a_fs, TSK_INUM_T a_start,
533         TSK_INUM_T a_end, TSK_FS_META_FLAG_ENUM a_flags,
534         TSK_FS_META_WALK_CB a_cb, void *a_ptr);
535 
536     extern uint8_t tsk_fs_meta_make_ls(const TSK_FS_META * a_fs_meta,
537         char *a_buf, size_t a_len);
538 
539     //@}
540 
541     /************* NAME / DIR structures **********/
542 
543     /** \name Generic File System File Name Data Structures */
544     //@{
545 
546     /**
547     * File name flags that are used when specifying the status of
548     * a name in the TSK_FS_NAME structure
549     */
550     typedef enum {
551         TSK_FS_NAME_FLAG_ALLOC = 0x01,  ///< Name is in an allocated state
552         TSK_FS_NAME_FLAG_UNALLOC = 0x02,        ///< Name is in an unallocated state
553     } TSK_FS_NAME_FLAG_ENUM;
554 
555 
556     /**
557     * File type values -- as specified in the directory entry structure.
558     */
559     typedef enum {
560         TSK_FS_NAME_TYPE_UNDEF = 0,     ///< Unknown type
561         TSK_FS_NAME_TYPE_FIFO = 1,      ///< Named pipe
562         TSK_FS_NAME_TYPE_CHR = 2,       ///< Character device
563         TSK_FS_NAME_TYPE_DIR = 3,       ///< Directory
564         TSK_FS_NAME_TYPE_BLK = 4,       ///< Block device
565         TSK_FS_NAME_TYPE_REG = 5,       ///< Regular file
566         TSK_FS_NAME_TYPE_LNK = 6,       ///< Symbolic link
567         TSK_FS_NAME_TYPE_SOCK = 7,      ///< Socket
568         TSK_FS_NAME_TYPE_SHAD = 8,      ///< Shadow inode (solaris)
569         TSK_FS_NAME_TYPE_WHT = 9,       ///< Whiteout (openbsd)
570         TSK_FS_NAME_TYPE_VIRT = 10,     ///< Special (TSK added "Virtual" files)
571         TSK_FS_NAME_TYPE_VIRT_DIR = 11, ///< Special (TSK added "Virtual" directories)
572     } TSK_FS_NAME_TYPE_ENUM;
573 
574 #define TSK_FS_NAME_TYPE_STR_MAX 12     ///< Number of types that have a short string name
575 
576     /* ascii representation of above types */
577     extern char tsk_fs_name_type_str[TSK_FS_NAME_TYPE_STR_MAX][2];
578 
579 #define TSK_FS_IS_DIR_NAME(x) \
580     ((x == TSK_FS_NAME_TYPE_DIR) || (x == TSK_FS_NAME_TYPE_VIRT_DIR))
581 
582 #define  TSK_FS_NAME_TAG 0x23147869
583     /**
584     * Generic structure to store the file name information that is stored in
585     * a directory. Most file systems separate the file name from the metadata, but
586     * some do not (such as FAT). This structure contains the name and address of the
587     * metadata.
588     */
589     typedef struct {
590         int tag;                ///< \internal Set to TSK_FS_NAME_ID if allocated, 0 if not
591 
592         char *name;             ///< The name of the file (in UTF-8)
593         size_t name_size;       ///< The number of bytes allocated to name
594 
595         char *shrt_name;        ///< The short name of the file or null (in UTF-8)
596         size_t shrt_name_size;  ///< The number of bytes allocated to shrt_name
597 
598         TSK_INUM_T meta_addr;   ///< Address of the metadata structure that the name points to.
599         uint32_t meta_seq;      ///< Sequence number for metadata structure (NTFS only)
600         TSK_INUM_T par_addr;    ///< Metadata address of parent directory (equal to meta_addr if this entry is for root directory).
601         uint32_t par_seq;       ///< Sequence number for parent directory (NTFS only)
602 
603         TSK_FS_NAME_TYPE_ENUM type;     ///< File type information (directory, file, etc.)
604         TSK_FS_NAME_FLAG_ENUM flags;    ///< Flags that describe allocation status etc.
605     } TSK_FS_NAME;
606 
607 
608     /**
609     * Definition of callback function that is used by tsk_fs_dir_walk().  This is
610     * is called for each file in a directory.
611     * @param a_fs_file Pointer to the current file in the directory
612     * @param a_path Path of the file
613     * @param a_ptr Pointer that was originally passed by caller to tsk_fs_dir_walk.
614     * @returns Value to signal if tsk_fs_dir_walk should stop or continue.
615     */
616     typedef TSK_WALK_RET_ENUM(*TSK_FS_DIR_WALK_CB) (TSK_FS_FILE *
617         a_fs_file, const char *a_path, void *a_ptr);
618 
619 
620 #define TSK_FS_DIR_TAG  0x57531246
621     /**
622     * A handle to a directory so that its files can be individually accessed.
623     */
624     typedef struct {
625         int tag;                ///< \internal Will be set to TSK_FS_DIR_TAG if structure is still allocated, 0 if not
626 
627         TSK_FS_FILE *fs_file;   ///< Pointer to the file structure for the directory.
628 
629         TSK_FS_NAME *names;     ///< Pointer to list of names in directory.
630         size_t names_used;      ///< Number of name structures in queue being used
631         size_t names_alloc;     ///< Number of name structures that were allocated
632 
633         TSK_INUM_T addr;        ///< Metadata address of this directory
634         uint32_t seq;           ///< Metadata address sequence (NTFS Only)
635 
636         TSK_FS_INFO *fs_info;   ///< Pointer to file system the directory is located in
637     } TSK_FS_DIR;
638 
639     /**
640     * Flags that are used when walking names in directories.  These are used to identify
641     * which files to call the callback function on.
642     */
643     typedef enum {
644         TSK_FS_DIR_WALK_FLAG_NONE = 0x00,       ///< No Flags
645         TSK_FS_DIR_WALK_FLAG_ALLOC = 0x01,      ///< Return allocated names in callback
646         TSK_FS_DIR_WALK_FLAG_UNALLOC = 0x02,    ///< Return unallocated names in callback
647         TSK_FS_DIR_WALK_FLAG_RECURSE = 0x04,    ///< Recurse into sub-directories
648         TSK_FS_DIR_WALK_FLAG_NOORPHAN = 0x08,   ///< Do not return (or recurse into) the special Orphan directory
649     } TSK_FS_DIR_WALK_FLAG_ENUM;
650 
651 
652     extern TSK_FS_DIR *tsk_fs_dir_open_meta(TSK_FS_INFO * a_fs,
653         TSK_INUM_T a_addr);
654     extern TSK_FS_DIR *tsk_fs_dir_open(TSK_FS_INFO * a_fs,
655         const char *a_dir);
656     extern uint8_t tsk_fs_dir_walk(TSK_FS_INFO * a_fs, TSK_INUM_T a_inode,
657         TSK_FS_DIR_WALK_FLAG_ENUM a_flags, TSK_FS_DIR_WALK_CB a_action,
658         void *a_ptr);
659     extern size_t tsk_fs_dir_getsize(const TSK_FS_DIR *);
660     extern TSK_FS_FILE *tsk_fs_dir_get(const TSK_FS_DIR *, size_t);
661     extern const TSK_FS_NAME *tsk_fs_dir_get_name(const TSK_FS_DIR * a_fs_dir, size_t a_idx);
662     extern void tsk_fs_dir_close(TSK_FS_DIR *);
663 
664     extern int8_t tsk_fs_path2inum(TSK_FS_INFO * a_fs, const char *a_path,
665         TSK_INUM_T * a_result, TSK_FS_NAME * a_fs_name);
666 
667     //@}
668 
669     /********************* FILE Structure *************************/
670 
671     /** \name Generic File System File  Data Structures */
672     //@{
673 
674 #define  TSK_FS_FILE_TAG 0x11212212
675     /**
676     * Generic structure used to refer to files in the file system.  A file will
677     * typically have a name and metadata.  This structure holds that type of information.
678     * When deleted files are being processed, this structure may have the name defined
679     * but not metadata because it no longer exists. Or, if you are calling meta_walk
680     * and are not processing at the name level, then the name will not be defined.
681     * always check these to make sure they are not null before they are read. */
682     struct TSK_FS_FILE {
683         int tag;                ///< \internal Will be set to TSK_FS_FILE_TAG if structure is allocated
684 
685         TSK_FS_NAME *name;      ///< Pointer to name of file (or NULL if file was opened using metadata address)
686         TSK_FS_META *meta;      ///< Pointer to metadata of file (or NULL if name has invalid metadata address)
687 
688         TSK_FS_INFO *fs_info;   ///< Pointer to file system that the file is located in.
689     };
690 
691     /**
692     * Flags used by tsk_fs_file_read */
693     typedef enum {
694         TSK_FS_FILE_READ_FLAG_NONE = 0x00,      ///< No Flags
695         TSK_FS_FILE_READ_FLAG_SLACK = 0x01,     ///< Allow read access into slack space
696         TSK_FS_FILE_READ_FLAG_NOID = 0x02,      ///< Ignore the Id argument given in the API (use only the type)
697     } TSK_FS_FILE_READ_FLAG_ENUM;
698 
699     extern void tsk_fs_file_close(TSK_FS_FILE * a_fs_file);
700     extern TSK_FS_FILE *tsk_fs_file_open(TSK_FS_INFO * a_fs,
701         TSK_FS_FILE * a_fs_file, const char *a_path);
702     extern TSK_FS_FILE *tsk_fs_file_open_meta(TSK_FS_INFO * fs,
703         TSK_FS_FILE * fs_file, TSK_INUM_T addr);
704     extern ssize_t
705         tsk_fs_file_read(TSK_FS_FILE *, TSK_OFF_T, char *, size_t,
706         TSK_FS_FILE_READ_FLAG_ENUM);
707     extern ssize_t tsk_fs_file_read_type(TSK_FS_FILE *,
708         TSK_FS_ATTR_TYPE_ENUM, uint16_t, TSK_OFF_T, char *, size_t,
709         TSK_FS_FILE_READ_FLAG_ENUM);
710     extern const TSK_FS_ATTR *tsk_fs_file_attr_get(TSK_FS_FILE *
711         a_fs_file);
712     extern int tsk_fs_file_attr_getsize(TSK_FS_FILE * a_fs_file);
713     extern const TSK_FS_ATTR *tsk_fs_file_attr_get_idx(TSK_FS_FILE *
714         a_fs_file, int a_idx);
715     extern const TSK_FS_ATTR *tsk_fs_file_attr_get_type(TSK_FS_FILE *
716         a_fs_file, TSK_FS_ATTR_TYPE_ENUM, uint16_t, uint8_t);
717     extern const TSK_FS_ATTR *tsk_fs_file_attr_get_id(TSK_FS_FILE *
718         a_fs_file, uint16_t);
719 
720     extern uint8_t tsk_fs_file_walk(TSK_FS_FILE * a_fs_file,
721         TSK_FS_FILE_WALK_FLAG_ENUM a_flags, TSK_FS_FILE_WALK_CB a_action,
722         void *a_ptr);
723     extern uint8_t tsk_fs_file_walk_type(TSK_FS_FILE * a_fs_file,
724         TSK_FS_ATTR_TYPE_ENUM a_type, uint16_t a_id,
725         TSK_FS_FILE_WALK_FLAG_ENUM a_flags, TSK_FS_FILE_WALK_CB a_action,
726         void *a_ptr);
727 
728     extern ssize_t tsk_fs_attr_read(const TSK_FS_ATTR * a_fs_attr,
729         TSK_OFF_T a_offset, char *a_buf, size_t a_len,
730         TSK_FS_FILE_READ_FLAG_ENUM a_flags);
731 
732     extern uint8_t tsk_fs_file_get_owner_sid(TSK_FS_FILE *, char **);
733 
734 	typedef struct {
735 		TSK_BASE_HASH_ENUM flags;
736 		unsigned char md5_digest[16];
737 		unsigned char sha1_digest[20];
738 	} TSK_FS_HASH_RESULTS;
739 
740 	extern uint8_t tsk_fs_file_hash_calc(TSK_FS_FILE *, TSK_FS_HASH_RESULTS *, TSK_BASE_HASH_ENUM);
741 
742     //@}
743 
744 
745     /****************** Journal Structures *************/
746 
747     /** \name Generic File System Journal Data Structures */
748     //@{
749 
750     typedef struct {
751         TSK_DADDR_T jblk;       /* journal block address */
752         TSK_DADDR_T fsblk;      /* fs block that journal entry is about */
753     } TSK_FS_JENTRY;
754 
755     typedef TSK_WALK_RET_ENUM(*TSK_FS_JBLK_WALK_CB) (TSK_FS_INFO *, char *,
756         int, void *);
757     typedef TSK_WALK_RET_ENUM(*TSK_FS_JENTRY_WALK_CB) (TSK_FS_INFO *,
758         TSK_FS_JENTRY *, int, void *);
759 
760     //@}
761 
762     //@}
763 
764     /******************************* TSK_FS_INFO ******************/
765 
766     /** \name Generic File System Handle Data Structure */
767     //@{
768 
769     /**
770     * Values for the file system type.  Each bit corresponds to a file
771     * system.
772     */
773     enum TSK_FS_TYPE_ENUM {
774         TSK_FS_TYPE_DETECT = 0x00000000,        ///< Use autodetection methods
775         TSK_FS_TYPE_NTFS = 0x00000001,  ///< NTFS file system
776         TSK_FS_TYPE_NTFS_DETECT = 0x00000001,   ///< NTFS auto detection
777         TSK_FS_TYPE_FAT12 = 0x00000002, ///< FAT12 file system
778         TSK_FS_TYPE_FAT16 = 0x00000004, ///< FAT16 file system
779         TSK_FS_TYPE_FAT32 = 0x00000008, ///< FAT32 file system
780         TSK_FS_TYPE_EXFAT = 0x0000000a, ///< exFAT file system
781         TSK_FS_TYPE_FAT_DETECT = 0x0000000e,    ///< FAT auto detection
782         TSK_FS_TYPE_FFS1 = 0x00000010,  ///< UFS1 (FreeBSD, OpenBSD, BSDI ...)
783         TSK_FS_TYPE_FFS1B = 0x00000020, ///< UFS1b (Solaris - has no type)
784         TSK_FS_TYPE_FFS2 = 0x00000040,  ///< UFS2 - FreeBSD, NetBSD
785         TSK_FS_TYPE_FFS_DETECT = 0x00000070,    ///< UFS auto detection
786         TSK_FS_TYPE_EXT2 = 0x00000080,  ///< Ext2 file system
787         TSK_FS_TYPE_EXT3 = 0x00000100,  ///< Ext3 file system
788         TSK_FS_TYPE_EXT_DETECT = 0x00002180,    ///< ExtX auto detection
789         TSK_FS_TYPE_SWAP = 0x00000200,  ///< SWAP file system
790         TSK_FS_TYPE_SWAP_DETECT = 0x00000200,   ///< SWAP auto detection
791         TSK_FS_TYPE_RAW = 0x00000400,   ///< RAW file system
792         TSK_FS_TYPE_RAW_DETECT = 0x00000400,    ///< RAW auto detection
793         TSK_FS_TYPE_ISO9660 = 0x00000800,       ///< ISO9660 file system
794         TSK_FS_TYPE_ISO9660_DETECT = 0x00000800,        ///< ISO9660 auto detection
795         TSK_FS_TYPE_HFS = 0x00001000,   ///< HFS file system
796         TSK_FS_TYPE_HFS_DETECT = 0x00001000,    ///< HFS auto detection
797         TSK_FS_TYPE_EXT4 = 0x00002000,  ///< Ext4 file system
798         TSK_FS_TYPE_YAFFS2 = 0x00004000,        ///< YAFFS2 file system
799         TSK_FS_TYPE_YAFFS2_DETECT = 0x00004000, ///< YAFFS2 auto detection
800         TSK_FS_TYPE_UNSUPP = 0xffffffff,        ///< Unsupported file system
801     };
802     /* NOTE: Update bindings/java/src/org/sleuthkit/datamodel/TskData.java
803      * with any changes. */
804     typedef enum TSK_FS_TYPE_ENUM TSK_FS_TYPE_ENUM;
805 
806     /**
807     * \ingroup fslib
808     * Macro that takes a file system type and returns 1 if the type
809     * is for an NTFS file system. */
810 #define TSK_FS_TYPE_ISNTFS(ftype) \
811     (((ftype) & TSK_FS_TYPE_NTFS_DETECT)?1:0)
812 
813     /**
814     * \ingroup fslib
815     * Macro that takes a file system type and returns 1 if the type
816     * is for a FAT file system. */
817 #define TSK_FS_TYPE_ISFAT(ftype) \
818     (((ftype) & TSK_FS_TYPE_FAT_DETECT)?1:0)
819 
820     /**
821     * \ingroup fslib
822     * Macro that takes a file system type and returns 1 if the type
823     * is for a FFS file system. */
824 #define TSK_FS_TYPE_ISFFS(ftype) \
825     (((ftype) & TSK_FS_TYPE_FFS_DETECT)?1:0)
826 
827     /**
828     * \ingroup fslib
829     * Macro that takes a file system type and returns 1 if the type
830     * is for a ExtX file system. */
831 #define TSK_FS_TYPE_ISEXT(ftype) \
832     (((ftype) & TSK_FS_TYPE_EXT_DETECT)?1:0)
833 
834     /**
835     * \ingroup fslib
836     * Macro that takes a file system type and returns 1 if the type
837     * is for a ISO9660 file system. */
838 #define TSK_FS_TYPE_ISISO9660(ftype) \
839     (((ftype) & TSK_FS_TYPE_ISO9660_DETECT)?1:0)
840 
841     /**
842     * \ingroup fslib
843     * Macro that takes a file system type and returns 1 if the type
844     * is for a HFS file system. */
845 #define TSK_FS_TYPE_ISHFS(ftype) \
846     (((ftype) & TSK_FS_TYPE_HFS_DETECT)?1:0)
847 
848     /**
849     * \ingroup fslib
850     * Macro that takes a file system type and returns 1 if the type
851     * is for a swap "file system". */
852 #define TSK_FS_TYPE_ISSWAP(ftype) \
853     (((ftype) & TSK_FS_TYPE_SWAP_DETECT)?1:0)
854 
855     /**
856     * \ingroup fslib
857     * Macro that takes a file system type and returns 1 if the type
858     * is for a YAFFS2 file system. */
859 #define TSK_FS_TYPE_ISYAFFS2(ftype) \
860     (((ftype) & TSK_FS_TYPE_YAFFS2_DETECT)?1:0)
861 
862     /**
863     * \ingroup fslib
864     * Macro that takes a file system type and returns 1 if the type
865     * is for a raw "file system". */
866 #define TSK_FS_TYPE_ISRAW(ftype) \
867     (((ftype) & TSK_FS_TYPE_RAW_DETECT)?1:0)
868 
869 
870     /**
871     * Flags for the FS_INFO structure
872     */
873     enum TSK_FS_INFO_FLAG_ENUM {
874         TSK_FS_INFO_FLAG_NONE = 0x00,   ///< No Flags
875         TSK_FS_INFO_FLAG_HAVE_SEQ = 0x01,       ///< File system has sequence numbers in the inode addresses.
876         TSK_FS_INFO_FLAG_HAVE_NANOSEC = 0x02    ///< Nano second field in times will be set.
877     };
878     typedef enum TSK_FS_INFO_FLAG_ENUM TSK_FS_INFO_FLAG_ENUM;
879 
880     enum TSK_FS_ISTAT_FLAG_ENUM {
881         TSK_FS_ISTAT_NONE = 0x00,
882         TSK_FS_ISTAT_RUNLIST = 0x01
883     };
884     typedef enum TSK_FS_ISTAT_FLAG_ENUM TSK_FS_ISTAT_FLAG_ENUM;
885 
886 #define TSK_FS_INFO_TAG  0x10101010
887 #define TSK_FS_INFO_FS_ID_LEN   32      // set based on largest file system / volume ID supported
888 
889     /**
890     * Stores state information for an open file system.
891     * One of these are generated for each open files system and it contains
892     * file system-type specific data.  These values are all filled in by
893     * the file system code and not the caller functions.  This struct
894     * (and its subclasses) should be allocated only by tsk_fs_malloc
895     * and deallocated only by tsk_fs_free, which handle init/deinit
896     * of the locks.
897     */
898     struct TSK_FS_INFO {
899         int tag;                ///< \internal Will be set to TSK_FS_INFO_TAG if structure is still allocated, 0 if not
900         TSK_IMG_INFO *img_info; ///< Pointer to the image layer state
901         TSK_OFF_T offset;       ///< Byte offset into img_info that fs starts
902 
903         /* meta data */
904         TSK_INUM_T inum_count;  ///< Number of metadata addresses
905         TSK_INUM_T root_inum;   ///< Metadata address of root directory
906         TSK_INUM_T first_inum;  ///< First valid metadata address
907         TSK_INUM_T last_inum;   ///< Last valid metadata address
908 
909         /* content */
910         TSK_DADDR_T block_count;        ///< Number of blocks in fs
911         TSK_DADDR_T first_block;        ///< Address of first block
912         TSK_DADDR_T last_block; ///< Address of last block as reported by file system (could be larger than last_block in image if end of image does not exist)
913         TSK_DADDR_T last_block_act;     ///< Address of last block -- adjusted so that it is equal to the last block in the image or volume (if image is not complete)
914         unsigned int block_size;        ///< Size of each block (in bytes)
915         unsigned int dev_bsize; ///< Size of device block (typically always 512)
916 
917         /* The following are used for really RAW images that contain data
918            before and after the actual user sector. For example, a raw cd
919            image may have 16 bytes before the start of each sector.
920          */
921         unsigned int block_pre_size;    ///< Number of bytes that precede each block (currently only used for RAW CDs)
922         unsigned int block_post_size;   ///< Number of bytes that follow each block (currently only used for RAW CDs)
923 
924         /* Journal */
925         TSK_INUM_T journ_inum;  ///< Address of journal inode
926 
927         TSK_FS_TYPE_ENUM ftype; ///< type of file system
928         const char *duname;     ///< string "name" of data unit type
929         TSK_FS_INFO_FLAG_ENUM flags;    ///< flags for file system
930         uint8_t fs_id[TSK_FS_INFO_FS_ID_LEN];   ///< File system id (as reported in boot sector)
931         size_t fs_id_used;      ///< Number of bytes in fs_id that are being used
932 
933         TSK_ENDIAN_ENUM endian; ///< Endian order of data
934 
935         /* list_inum_named_lock protects list_inum_named */
936         tsk_lock_t list_inum_named_lock;        // taken when r/w the list_inum_named list
937         TSK_LIST *list_inum_named;      /**< List of unallocated inodes that
938                                         * are pointed to by a file name --
939                                         * Used to find orphan files.  Is filled
940                                         * after looking for orphans
941                                         * or afer a full name_walk is performed.
942                                         * (r/w shared - lock) */
943 
944         /* orphan_hunt_lock protects orphan_dir */
945         tsk_lock_t orphan_dir_lock;     // taken for the duration of orphan hunting (not just when updating orphan_dir)
946         TSK_FS_DIR *orphan_dir; ///< Files and dirs in the top level of the $OrphanFiles directory.  NULL if orphans have not been hunted for yet. (r/w shared - lock)
947 
948          uint8_t(*block_walk) (TSK_FS_INFO * fs, TSK_DADDR_T start, TSK_DADDR_T end, TSK_FS_BLOCK_WALK_FLAG_ENUM flags, TSK_FS_BLOCK_WALK_CB cb, void *ptr);    ///< FS-specific function: Call tsk_fs_block_walk() instead.
949 
950          TSK_FS_BLOCK_FLAG_ENUM(*block_getflags) (TSK_FS_INFO * a_fs, TSK_DADDR_T a_addr);      ///< \internal
951 
952          uint8_t(*inode_walk) (TSK_FS_INFO * fs, TSK_INUM_T start, TSK_INUM_T end, TSK_FS_META_FLAG_ENUM flags, TSK_FS_META_WALK_CB cb, void *ptr);     ///< FS-specific function: Call tsk_fs_meta_walk() instead.
953 
954          uint8_t(*file_add_meta) (TSK_FS_INFO * fs, TSK_FS_FILE * fs_file, TSK_INUM_T addr);    ///< \internal
955 
956          TSK_FS_ATTR_TYPE_ENUM(*get_default_attr_type) (const TSK_FS_FILE *);   ///< \internal
957 
958          uint8_t(*load_attrs) (TSK_FS_FILE *);  ///< \internal
959 
960 
961         /**
962         * Pointer to file system specific function that prints details on a specific file to a file handle.
963         *
964         * @param fs File system file is located in
965         * @param hFile File handle to print text to
966         * @param inum Address of file in file system
967         * @param numblock The number of blocks in file to force print (can go beyond file size)
968         * @param sec_skew Clock skew in seconds to also print times in
969         *
970         * @returns 1 on error and 0 on success
971         */
972          uint8_t(*istat) (TSK_FS_INFO * fs, TSK_FS_ISTAT_FLAG_ENUM flags, FILE * hFile, TSK_INUM_T inum,
973             TSK_DADDR_T numblock, int32_t sec_skew);
974 
975          TSK_RETVAL_ENUM(*dir_open_meta) (TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir, TSK_INUM_T inode);  ///< \internal Call tsk_fs_dir_open_meta() instead.
976 
977          uint8_t(*jopen) (TSK_FS_INFO *, TSK_INUM_T);   ///< \internal
978 
979          uint8_t(*jblk_walk) (TSK_FS_INFO *, TSK_DADDR_T, TSK_DADDR_T, int, TSK_FS_JBLK_WALK_CB, void *);       ///< \internal
980 
981          uint8_t(*jentry_walk) (TSK_FS_INFO *, int, TSK_FS_JENTRY_WALK_CB, void *);     ///< \internal
982 
983          uint8_t(*fsstat) (TSK_FS_INFO * fs, FILE * hFile);     ///< \internal
984 
985         int (*name_cmp) (TSK_FS_INFO *, const char *, const char *);    ///< \internal
986 
987          uint8_t(*fscheck) (TSK_FS_INFO *, FILE *);     ///< \internal
988 
989         void (*close) (TSK_FS_INFO * fs);       ///< FS-specific function: Call tsk_fs_close() instead.
990 
991          uint8_t(*fread_owner_sid) (TSK_FS_FILE *, char **);    // FS-specific function. Call tsk_fs_file_get_owner_sid() instead.
992     };
993 
994 
995     /* File system level */
996     extern TSK_FS_INFO *tsk_fs_open_img(TSK_IMG_INFO *, TSK_OFF_T,
997         TSK_FS_TYPE_ENUM);
998     extern TSK_FS_INFO *tsk_fs_open_vol(const TSK_VS_PART_INFO *,
999         TSK_FS_TYPE_ENUM);
1000     extern void tsk_fs_close(TSK_FS_INFO *);
1001 
1002     extern TSK_FS_TYPE_ENUM tsk_fs_type_toid_utf8(const char *);
1003     extern TSK_FS_TYPE_ENUM tsk_fs_type_toid(const TSK_TCHAR *);
1004     extern void tsk_fs_type_print(FILE *);
1005     extern const char *tsk_fs_type_toname(TSK_FS_TYPE_ENUM);
1006     extern TSK_FS_TYPE_ENUM tsk_fs_type_supported();
1007 
1008     extern ssize_t tsk_fs_read(TSK_FS_INFO * a_fs, TSK_OFF_T a_off,
1009         char *a_buf, size_t a_len);
1010     extern ssize_t tsk_fs_read_block(TSK_FS_INFO * a_fs,
1011         TSK_DADDR_T a_addr, char *a_buf, size_t a_len);
1012 
1013     //@}
1014 
1015 
1016     /***** LIBRARY ROUTINES FOR COMMAND LINE FUNCTIONS */
1017     enum TSK_FS_BLKCALC_FLAG_ENUM {
1018         TSK_FS_BLKCALC_DD = 0x01,
1019         TSK_FS_BLKCALC_BLKLS = 0x02,
1020         TSK_FS_BLKCALC_SLACK = 0x04
1021     };
1022     typedef enum TSK_FS_BLKCALC_FLAG_ENUM TSK_FS_BLKCALC_FLAG_ENUM;
1023     extern int8_t tsk_fs_blkcalc(TSK_FS_INFO * fs,
1024         TSK_FS_BLKCALC_FLAG_ENUM flags, TSK_DADDR_T cnt);
1025 
1026 
1027     enum TSK_FS_BLKCAT_FLAG_ENUM {
1028         TSK_FS_BLKCAT_NONE = 0x00,
1029         TSK_FS_BLKCAT_HEX = 0x01,
1030         TSK_FS_BLKCAT_ASCII = 0x02,
1031         TSK_FS_BLKCAT_HTML = 0x04,
1032         TSK_FS_BLKCAT_STAT = 0x08
1033     };
1034     typedef enum TSK_FS_BLKCAT_FLAG_ENUM TSK_FS_BLKCAT_FLAG_ENUM;
1035     extern uint8_t tsk_fs_blkcat(TSK_FS_INFO * fs,
1036         TSK_FS_BLKCAT_FLAG_ENUM flags, TSK_DADDR_T addr,
1037         TSK_DADDR_T read_num_units);
1038 
1039 
1040     enum TSK_FS_BLKLS_FLAG_ENUM {
1041         TSK_FS_BLKLS_NONE = 0x00,
1042         TSK_FS_BLKLS_CAT = 0x01,
1043         TSK_FS_BLKLS_LIST = 0x02,
1044         TSK_FS_BLKLS_SLACK = 0x04,
1045     };
1046     typedef enum TSK_FS_BLKLS_FLAG_ENUM TSK_FS_BLKLS_FLAG_ENUM;
1047     extern uint8_t tsk_fs_blkls(TSK_FS_INFO * fs,
1048         TSK_FS_BLKLS_FLAG_ENUM lclflags, TSK_DADDR_T bstart,
1049         TSK_DADDR_T bend, TSK_FS_BLOCK_WALK_FLAG_ENUM flags);
1050 
1051     extern uint8_t tsk_fs_blkstat(TSK_FS_INFO * fs, TSK_DADDR_T addr);
1052 
1053     enum TSK_FS_FFIND_FLAG_ENUM {
1054         TSK_FS_FFIND_ALL = 0x01,
1055     };
1056     typedef enum TSK_FS_FFIND_FLAG_ENUM TSK_FS_FFIND_FLAG_ENUM;
1057     extern uint8_t tsk_fs_ffind(TSK_FS_INFO * fs,
1058         TSK_FS_FFIND_FLAG_ENUM lclflags, TSK_INUM_T inode,
1059         TSK_FS_ATTR_TYPE_ENUM type, uint8_t type_used,
1060         uint16_t id, uint8_t id_used, TSK_FS_DIR_WALK_FLAG_ENUM flags);
1061 
1062 
1063     enum TSK_FS_FLS_FLAG_ENUM {
1064         TSK_FS_FLS_NONE = 0x00,
1065         TSK_FS_FLS_DOT = 0x01,
1066         TSK_FS_FLS_LONG = 0x02,
1067         TSK_FS_FLS_FILE = 0x04,
1068         TSK_FS_FLS_DIR = 0x08,
1069         TSK_FS_FLS_FULL = 0x10,
1070         TSK_FS_FLS_MAC = 0x20,
1071 		TSK_FS_FLS_HASH = 0x40
1072     };
1073     typedef enum TSK_FS_FLS_FLAG_ENUM TSK_FS_FLS_FLAG_ENUM;
1074     extern uint8_t tsk_fs_fls(TSK_FS_INFO * fs,
1075         TSK_FS_FLS_FLAG_ENUM lclflags, TSK_INUM_T inode,
1076         TSK_FS_DIR_WALK_FLAG_ENUM flags, TSK_TCHAR * pre, int32_t skew);
1077 
1078     extern uint8_t tsk_fs_icat(TSK_FS_INFO * fs,
1079         TSK_INUM_T inum,
1080         TSK_FS_ATTR_TYPE_ENUM type, uint8_t type_used,
1081         uint16_t id, uint8_t id_used, TSK_FS_FILE_WALK_FLAG_ENUM flags);
1082 
1083 
1084     enum TSK_FS_IFIND_FLAG_ENUM {
1085         TSK_FS_IFIND_NONE = 0x00,
1086         TSK_FS_IFIND_ALL = 0x01,
1087         TSK_FS_IFIND_PAR_LONG = 0x02,
1088     };
1089     typedef enum TSK_FS_IFIND_FLAG_ENUM TSK_FS_IFIND_FLAG_ENUM;
1090     extern int8_t tsk_fs_ifind_path(TSK_FS_INFO * fs,
1091         TSK_TCHAR * path, TSK_INUM_T * result);
1092     extern uint8_t tsk_fs_ifind_data(TSK_FS_INFO * fs,
1093         TSK_FS_IFIND_FLAG_ENUM flags, TSK_DADDR_T blk);
1094     extern uint8_t tsk_fs_ifind_par(TSK_FS_INFO * fs,
1095         TSK_FS_IFIND_FLAG_ENUM flags, TSK_INUM_T par);
1096 
1097 
1098     enum TSK_FS_ILS_FLAG_ENUM {
1099         TSK_FS_ILS_NONE = 0x00,
1100         TSK_FS_ILS_OPEN = 0x01,
1101         TSK_FS_ILS_MAC = 0x02,
1102         TSK_FS_ILS_LINK = 0x04,
1103         TSK_FS_ILS_UNLINK = 0x08,
1104     };
1105     typedef enum TSK_FS_ILS_FLAG_ENUM TSK_FS_ILS_FLAG_ENUM;
1106     extern uint8_t tsk_fs_ils(TSK_FS_INFO * fs,
1107         TSK_FS_ILS_FLAG_ENUM lclflags, TSK_INUM_T istart, TSK_INUM_T ilast,
1108         TSK_FS_META_FLAG_ENUM flags, int32_t skew, const TSK_TCHAR * img);
1109 
1110     /*
1111      ** Is this string a "." or ".."
1112      */
1113 #define TSK_FS_ISDOT(str) ( ((str[0] == '.') && \
1114     ( ((str[1] == '.') && (str[2] == '\0')) || (str[1] == '\0') ) ) ? 1 : 0 )
1115 
1116 
1117     extern int tsk_fs_parse_inum(const TSK_TCHAR * str, TSK_INUM_T *,
1118         TSK_FS_ATTR_TYPE_ENUM *, uint8_t *, uint16_t *, uint8_t *);
1119 
1120 #ifdef __cplusplus
1121 }
1122 #endif
1123 #ifdef __cplusplus
1124 /**
1125  * \ingroup fslib_cpp
1126  */ class TskFsJEntry {
1127   private:
1128     TSK_FS_JENTRY * m_jEntry;
1129     TskFsJEntry(const TskFsJEntry & rhs);
1130      TskFsJEntry & operator=(const TskFsJEntry & rhs);
1131 
1132   public:
TskFsJEntry(TSK_FS_JENTRY * a_jEntry)1133      TskFsJEntry(TSK_FS_JENTRY * a_jEntry) {
1134         m_jEntry = a_jEntry;
1135     };
1136 
~TskFsJEntry()1137     ~TskFsJEntry() {
1138     };
1139 };
1140 
1141 /**
1142 * \ingroup fslib_cpp
1143 * Contains information about a single data run, which has a starting address and length.
1144 * A run describes a consecutive list of blocks that have been allocated to a file.
1145 * A file may have many such runs and they are stringed together in a linked list.
1146 * The entries in the list must be stored in sequential order (based on offset in file).
1147 * See TSK_FS_ATTR_RUN for more details.
1148 */
1149 class TskFsAttrRun {
1150   private:
1151     TSK_FS_ATTR_RUN * m_fsAttrRun;
1152     TskFsAttrRun(const TskFsAttrRun & rhs);
1153      TskFsAttrRun & operator=(const TskFsAttrRun & rhs);
1154 
1155   public:
1156     /**
1157         * construct a TskFsAttrRun object.
1158     * @param a_fsAttrRun pointer of TSK_FS_ATTR_RUN. If NULL, then the
1159     * getX() method return values are undefined.
1160     */
TskFsAttrRun(TSK_FS_ATTR_RUN * a_fsAttrRun)1161      TskFsAttrRun(TSK_FS_ATTR_RUN * a_fsAttrRun) {
1162         m_fsAttrRun = a_fsAttrRun;
1163     };
1164 
~TskFsAttrRun()1165     ~TskFsAttrRun() {
1166     };
1167 
1168     /**
1169     * get offset (in blocks) of this run in the file
1170     * @return offset of run
1171     */
getOffset()1172     TSK_DADDR_T getOffset() const {
1173         if (m_fsAttrRun != NULL)
1174             return m_fsAttrRun->offset;
1175         else
1176             return 0;
1177     };
1178 
1179     /**
1180         * get starting block address (in file system) of run
1181     * @return starting block address
1182     */
getAddr()1183     TSK_DADDR_T getAddr() const {
1184         if (m_fsAttrRun != NULL)
1185             return m_fsAttrRun->addr;
1186         else
1187             return 0;
1188     };
1189 
1190     /**
1191     * get number of blocks in run (0 when entry is not in use)
1192     * @return offset
1193     */
length()1194     TSK_DADDR_T length() const {
1195         if (m_fsAttrRun != NULL)
1196             return m_fsAttrRun->len;
1197         else
1198             return 0;
1199     };
1200 
1201     /**
1202         * get flags for run
1203     * @return flags for run
1204     */
getFlags()1205     TSK_FS_ATTR_RUN_FLAG_ENUM getFlags() const {
1206         if (m_fsAttrRun != NULL)
1207             return m_fsAttrRun->flags;
1208         else
1209             return (TSK_FS_ATTR_RUN_FLAG_ENUM) 0;
1210     };
1211 };                              //TskFsAttrRun
1212 
1213 /**
1214 * \ingroup fslib_cpp
1215 * Stores the file name information that is stored in
1216 * a directory. Most file systems separate the file name from the metadata, but
1217 * some do not (such as FAT). This structure contains the file name and the
1218 * address of the  metadata. See TSK_FS_NAME for more details.
1219 */
1220 class TskFsName {
1221     friend class TskFsInfo;
1222 
1223   private:
1224      TSK_FS_NAME * m_fsName;
1225      TskFsName(const TskFsName & rhs);
1226      TskFsName & operator=(const TskFsName & rhs);
1227 
1228   public:
1229     /**
1230     * construct a TskFsName object
1231     * @param a_fsName a pointer of TSK_FS_NAME. If NULL, the getX() return values are undefined.
1232     */
TskFsName(TSK_FS_NAME * a_fsName)1233      TskFsName(TSK_FS_NAME * a_fsName) {
1234         m_fsName = a_fsName;
1235     };
1236 
~TskFsName()1237     ~TskFsName() {
1238     };
1239 
1240     /**
1241     * Return the name of the file (in UTF-8)
1242     * @return the name of the file
1243     */
getName()1244     const char *getName() const {
1245         if (m_fsName != NULL)
1246             return m_fsName->name;
1247         else
1248             return NULL;
1249     };
1250     /**
1251         * Return the short name of the file or null (in UTF-8)
1252     * @return the short name of the file
1253     */
getShortName()1254     const char *getShortName() const {
1255         if (m_fsName != NULL)
1256             return m_fsName->shrt_name;
1257         else
1258             return NULL;
1259     };
1260 
1261     /**
1262         * Return the address of the metadata structure that the name points to.
1263     * @return address of the metadata structure that the name points to
1264     */
getMetaAddr()1265     TSK_INUM_T getMetaAddr() const {
1266         if (m_fsName != NULL)
1267             return m_fsName->meta_addr;
1268         else
1269             return 0;
1270     };
1271 
1272     /**
1273         * Return the sequence number for metadata structure (NTFS only)
1274     * @return sequence number for metadata structure
1275     */
getMetaSeq()1276     uint32_t getMetaSeq() const {
1277         if (m_fsName != NULL)
1278             return m_fsName->meta_seq;
1279         else
1280             return 0;
1281     };
1282 
1283     /**
1284         * Return the metadata address of the parent directory (equal to meta_addr if this entry is for root directory).
1285     * @return metadata address of parent directory
1286     */
getParentAddr()1287     TSK_INUM_T getParentAddr() const {
1288         if (m_fsName != NULL)
1289             return m_fsName->par_addr;
1290         else
1291             return 0;
1292     };
1293 
1294     /**
1295         * Return the file type information (directory, file, etc.)
1296     * @return file type information
1297     */
getType()1298     TSK_FS_NAME_TYPE_ENUM getType() const {
1299         if (m_fsName != NULL)
1300             return m_fsName->type;
1301         else
1302             return (TSK_FS_NAME_TYPE_ENUM) 0;
1303     };
1304 
1305     /**
1306         * Return flags that describe allocation status etc.
1307     * @return flags that describe allocation status
1308     */
getFlags()1309     TSK_FS_NAME_FLAG_ENUM getFlags() const {
1310         if (m_fsName != NULL)
1311             return m_fsName->flags;
1312         else
1313             return (TSK_FS_NAME_FLAG_ENUM) 0;
1314     };
1315 };
1316 
1317 class TskFsFile;
1318 /**
1319 * File walk callback function definition.  This is called for
1320 * chunks of content in the file being processed.
1321 * @param a_fs_file Pointer to file being processed
1322 * @param a_off Byte offset in file that this data is for
1323 * @param a_addr Address of data being passed (valid only if a_flags have RAW set)
1324 * @param a_buf Pointer to buffer with file content
1325 * @param a_len Size of data in buffer (in bytes)
1326 * @param a_flags Flags about the file content
1327 * @param a_ptr Pointer that was specified by caller to inode_walk
1328 * @returns Value that tells file walk to continue or stop
1329 */
1330 typedef TSK_WALK_RET_ENUM(*TSK_FS_FILE_WALK_CPP_CB) (TskFsFile *
1331     a_fs_file, TSK_OFF_T a_off, TSK_DADDR_T a_addr, char *a_buf,
1332     size_t a_len, TSK_FS_BLOCK_FLAG_ENUM a_flags, void *a_ptr);
1333 
1334 /** \internal
1335 * Internal structure to pass C++ file walk data into C file walk call back.
1336 */
1337 typedef struct {
1338     TSK_FS_FILE_WALK_CPP_CB cppAction;  // pointer C++ callback
1339     void *cPtr;                 // pointer to data that was passed into C++ walk method
1340 } TSK_FS_FILE_WALK_CPP_DATA;
1341 
1342 /** \internal
1343 * Internal function used to call C++ file Walk callback from C callback.
1344 */
1345 extern TSK_WALK_RET_ENUM tsk_fs_file_cpp_c_cb(TSK_FS_FILE * a_file,
1346     TSK_OFF_T a_off, TSK_DADDR_T a_addr, char *a_buf, size_t a_len,
1347     TSK_FS_BLOCK_FLAG_ENUM a_flags, void *a_ptr);
1348 /**
1349 * \ingroup fslib_cpp
1350 * Stores information about a file attribute.  File attributes store data for a file.
1351 * Most files have at least one attribute that stores the file content.  See TSK_FS_ATTR for
1352 * details on attributes.
1353 */
1354 class TskFsAttribute {
1355   private:
1356     const TSK_FS_ATTR *m_fsAttr;
1357      TskFsAttribute(const TskFsAttribute & rhs);
1358      TskFsAttribute & operator=(const TskFsAttribute & rhs);
1359 
1360   public:
1361     /**
1362         * construct a TskFsAttribute object
1363     * @param a_fsAttr a pointer of TSK_FS_ATTR.  If NULL, the getX() return values are undefi
1364     ned.
1365     */
TskFsAttribute(const TSK_FS_ATTR * a_fsAttr)1366      TskFsAttribute(const TSK_FS_ATTR * a_fsAttr) {
1367         m_fsAttr = a_fsAttr;
1368     };
1369 
~TskFsAttribute()1370     ~TskFsAttribute() {
1371     };
1372 
1373     /**
1374         * Process an attribute and call a callback function with its contents. The callback will be
1375     * called with chunks of data that are fs->block_size or less.  The address given in the callback
1376     * will be correct only for raw files (when the raw file contents were stored in the block).  For
1377     * compressed and sparse attributes, the address may be zero.
1378     *
1379     * See tsk_fs_attr_walk() for details
1380     * @param a_flags Flags to use while processing attribute
1381     * @param a_action Callback action to call with content
1382     * @param a_ptr Pointer that will passed to callback
1383     * @returns 1 on error and 0 on success.
1384     */
walk(TSK_FS_FILE_WALK_FLAG_ENUM a_flags,TSK_FS_FILE_WALK_CPP_CB a_action,void * a_ptr)1385     uint8_t walk(TSK_FS_FILE_WALK_FLAG_ENUM a_flags,
1386         TSK_FS_FILE_WALK_CPP_CB a_action, void *a_ptr) {
1387         TSK_FS_FILE_WALK_CPP_DATA fileData;
1388         fileData.cppAction = a_action;
1389         fileData.cPtr = a_ptr;
1390         if (m_fsAttr)
1391             return tsk_fs_attr_walk(m_fsAttr, a_flags,
1392                 tsk_fs_file_cpp_c_cb, &fileData);
1393         else
1394             return 1;
1395     };
1396 
1397     /**
1398         * Read the contents of this attribute using a typical read() type interface.
1399     * 0s are returned for missing runs.
1400     *
1401     * See tsk_fs_attr_read() for details
1402     * @param a_offset The byte offset to start reading from.
1403     * @param a_buf The buffer to read the data into.
1404     * @param a_len The number of bytes to read from the file.
1405     * @param a_flags Flags to use while reading
1406     * @returns The number of bytes read or -1 on error (incl if offset is past end of file).
1407     */
read(TSK_OFF_T a_offset,char * a_buf,size_t a_len,TSK_FS_FILE_READ_FLAG_ENUM a_flags)1408     ssize_t read(TSK_OFF_T a_offset, char *a_buf, size_t a_len,
1409         TSK_FS_FILE_READ_FLAG_ENUM a_flags) {
1410         if (m_fsAttr != NULL)
1411             return tsk_fs_attr_read(m_fsAttr, a_offset, a_buf, a_len,
1412                 a_flags);
1413         else
1414             return -1;
1415     };
1416 
1417     /**
1418         * get the attribute's flags
1419     * @return flags for attribute
1420     */
getFlags()1421     TSK_FS_ATTR_FLAG_ENUM getFlags() const {
1422         if (m_fsAttr != NULL)
1423             return m_fsAttr->flags;
1424         else
1425             return (TSK_FS_ATTR_FLAG_ENUM) 0;
1426     };
1427     /**
1428         * get the attributes's name (in UTF-8).
1429     * @return name of attribute (or NULL if attribute doesn't have one)
1430     */
getName()1431     const char *getName() const {
1432         if (m_fsAttr != NULL)
1433             return m_fsAttr->name;
1434         else
1435             return NULL;
1436     };
1437 
1438     /**
1439         * get type of attribute
1440     * @return type of attribute
1441     */
getType()1442     TSK_FS_ATTR_TYPE_ENUM getType() const {
1443         if (m_fsAttr != NULL)
1444             return m_fsAttr->type;
1445         else
1446             return (TSK_FS_ATTR_TYPE_ENUM) 0;
1447     };
1448 
1449     /**
1450         * get id of attribute
1451     * @return id of attribute
1452     */
getId()1453     uint16_t getId() const {
1454         if (m_fsAttr != NULL)
1455             return m_fsAttr->id;
1456         else
1457             return 0;
1458     };
1459 
1460     /**
1461         * get size in bytes of attribute (does not include skiplen for non-resident)
1462     * @return size in bytes of attribute
1463     */
getSize()1464     TSK_OFF_T getSize() const {
1465         if (m_fsAttr != NULL)
1466             return m_fsAttr->size;
1467         else
1468             return 0;
1469     };
1470 
1471     /**
1472         * get a run for a non-resident attribute.
1473     * It's caller's responsibility to free memory of TskFsAttrRun
1474     * @param a_idx The index of the run to return.
1475     * @return A run in the attribute.
1476     */
getRun(int a_idx)1477     const TskFsAttrRun *getRun(int a_idx) const {
1478         if (m_fsAttr != NULL) {
1479             TSK_FS_ATTR_RUN *run = m_fsAttr->nrd.run;
1480             int i = 0;
1481             while (run != NULL) {
1482                 if (i == a_idx)
1483                     return new TskFsAttrRun(run);
1484                 i++;
1485                 run = run->next;
1486         }} return NULL;
1487     };
1488 
1489     /**
1490           * gets the number of runs in a non-resident attribute.
1491      * @return number of runs.
1492      */
getRunCount()1493     int getRunCount() const {
1494         int size = 0;
1495         if (m_fsAttr != NULL) {
1496             TSK_FS_ATTR_RUN *run = m_fsAttr->nrd.run;
1497             while (run != NULL) {
1498                 size++;
1499                 run = run->next;
1500         }} return size;
1501     }
1502 
1503     /**
1504         * get number of initial bytes in run to skip before content begins.
1505     * The size field does not include this length.
1506     * @return number of initial bytes in run to skip before content begins
1507     */
getSkipLen()1508     uint32_t getSkipLen() const {
1509         if (m_fsAttr != NULL)
1510             return m_fsAttr->nrd.skiplen;
1511         else
1512             return 0;
1513     };
1514 
1515     /**
1516         * get number of bytes that are allocated in all clusters of non-resident run
1517     * (will be larger than size - does not include skiplen).
1518     * This is defined when the attribute is created and used to determine slack space.
1519     * @return number of bytes that are allocated in all clusters of non-resident run
1520     */
getAllocSize()1521     TSK_OFF_T getAllocSize() const {
1522         if (m_fsAttr != NULL)
1523             return m_fsAttr->nrd.allocsize;
1524         else
1525             return 0;
1526     };
1527 
1528     /**
1529         * get number of bytes (starting from offset 0) that have data
1530     * (including FILLER) saved for them (smaller then or equal to size).
1531     * This is defined when the attribute is created.
1532     * @return number of bytes (starting from offset 0) that have data
1533     */
getInitSize()1534     TSK_OFF_T getInitSize() const {
1535         if (m_fsAttr != NULL)
1536             return m_fsAttr->nrd.initsize;
1537         else
1538             return 0;
1539     };
1540 
1541     /**
1542         * get size of compression units (needed only if NTFS file is compressed)
1543     * @return size of compression units (needed only if NTFS file is compressed)
1544     */
getCompSize()1545     uint32_t getCompSize() const {
1546         if (m_fsAttr != NULL)
1547             return m_fsAttr->nrd.compsize;
1548         return 0;
1549     };
1550 
1551     /**
1552         * Pointer to buffer with resident data.  Only getSize() bytes will be valid.
1553     * @return pointer to buffer with resident data.
1554     */
getBuf()1555     const uint8_t *getBuf() const {
1556         if (m_fsAttr != NULL)
1557             return m_fsAttr->rd.buf;
1558         else
1559             return NULL;
1560     };
1561 
1562 };                              //TskfsAttr
1563 
1564 
1565 class TskFsBlock;
1566 class TskFsInfo;
1567 /**
1568 * Function definition used for callback to blockWalk().
1569 *
1570 * @param a_block Pointer to TskFsBlock object that holds block content and flags
1571 * @param a_ptr Pointer that was supplied by the caller who called tsk_fs_block_walk
1572 * @returns Value to identify if walk should continue, stop, or stop because of error
1573 */
1574 typedef TSK_WALK_RET_ENUM(*TSK_FS_BLOCK_WALK_CPP_CB) (const TskFsBlock *
1575     a_block, void *a_ptr);
1576 
1577 
1578 /** \internal
1579 * Internal structure to pass C++ block walk data into C block walk call back.
1580 */
1581 typedef struct {
1582     TSK_FS_BLOCK_WALK_CPP_CB cppAction; // pointer C++ callback
1583     void *cPtr;                 // pointer to data that was passed into C++ walk method
1584 } TSK_FS_BLOCK_WALK_CPP_DATA;
1585 
1586 /** \internal
1587 * Internal function used to call C++ Block Walk callback from C callback.
1588 */
1589 extern TSK_WALK_RET_ENUM tsk_fs_block_cpp_c_cb(const TSK_FS_BLOCK *
1590     a_block, void *a_ptr);
1591 /**
1592 * Function definition for callback in TskFsInfo.jblkWalk().
1593 *
1594 * @param a_fsInfo File system being analyzed
1595 * @param a_string
1596 * @param a_num
1597 * @param a_ptr Pointer that was supplied by the caller
1598 * @returns Value to identify if walk should continue, stop, or stop because of error
1599 */
1600 typedef TSK_WALK_RET_ENUM(*TSK_FS_JBLK_WALK_CPP_CB) (TskFsInfo * a_fsInfo,
1601     char *a_string, int a_num, void *a_ptr);
1602 
1603 /** \internal
1604 * Internal structure to pass C++ JBLK walk data into C JBLK walk call back.
1605 */
1606 typedef struct {
1607     TSK_FS_JBLK_WALK_CPP_CB cppAction;  // pointer C++ callback
1608     void *cPtr;                 // pointer to data that was passed into C++ walk method
1609 } TSK_FS_JBLK_WALK_CPP_DATA;
1610 
1611 /** \internal
1612 * Internal function used to call C++ JBLK Walk callback from C callback.
1613 */
1614 extern TSK_WALK_RET_ENUM tsk_fs_jblk_walk_cpp_c_cb(TSK_FS_INFO * a_fsInfo,
1615     char *a_string, int a_num, void *a_ptr);
1616 
1617 /**
1618 * Function definition  for callback in TskFsInfo.jentryWalk().
1619 *
1620 * @param a_fsInfo File system being analyzed
1621 * @param a_jentry journal entry
1622 * @param a_num
1623 * @param a_ptr Pointer that was supplied by the caller.
1624 * @returns Value to identify if walk should continue, stop, or stop because of error
1625 */
1626 typedef TSK_WALK_RET_ENUM(*TSK_FS_JENTRY_WALK_CPP_CB) (TskFsInfo *
1627     a_fsInfo, TskFsJEntry * a_jentry, int a_num, void *a_ptr);
1628 
1629 /** \internal
1630 * Internal structure to pass C++ JENTRY walk data into C JENTRY walk call back.
1631 */
1632 typedef struct {
1633     TSK_FS_JENTRY_WALK_CPP_CB cppAction;        // pointer C++ callback
1634     void *cPtr;                 // pointer to data that was passed into C++ walk method
1635 } TSK_FS_JENTRY_WALK_CPP_DATA;
1636 
1637 /** \internal
1638 * Internal function used to call C++ JENTRY Walk callback from C callback.
1639 */
1640 extern TSK_WALK_RET_ENUM tsk_fs_jentry_walk_cpp_c_cb(TSK_FS_INFO *
1641     a_fsInfo, TSK_FS_JENTRY * a_jentry, int a_num, void *a_ptr);
1642 /**
1643 * inode walk callback function definition.  This is called for every file
1644 * that meets the criteria specified when inode_walk was called.
1645 * @param a_fs_file Pointer to the current file
1646 * @param a_ptr Pointer that was specified by caller to inode_walk
1647 * @returns Value that tells inode walk to continue or stop
1648 */
1649 typedef TSK_WALK_RET_ENUM(*TSK_FS_META_WALK_CPP_CB) (TskFsFile *
1650     a_fs_file, void *a_ptr);
1651 /** \internal
1652 * Internal structure to pass C++ metadata walk data into C metadata walk call back.
1653 */
1654 typedef struct {
1655     TSK_FS_META_WALK_CPP_CB cppAction;  // pointer C++ callback
1656     void *cPtr;                 // pointer to data that was passed into C++ walk method
1657 } TSK_FS_META_WALK_CPP_DATA;
1658 
1659 /** \internal
1660 * Internal function used to call C++ Meta Walk callback from C callback.
1661 */
1662 extern TSK_WALK_RET_ENUM tsk_fs_meta_walk_cpp_c_cb(TSK_FS_FILE * a_file,
1663     void *a_ptr);
1664 /**
1665 * Definition of callback function that is used by tsk_fs_dir_walk().  This is
1666 * is called for each file in a directory.
1667 * @param a_fs_file Pointer to the current file in the directory
1668 * @param a_path Path of the file
1669 * @param a_ptr Pointer that was originally passed by caller to tsk_fs_dir_walk.
1670 * @returns Value to signal if tsk_fs_dir_walk should stop or continue.
1671 */
1672 typedef TSK_WALK_RET_ENUM(*TSK_FS_DIR_WALK_CPP_CB) (TskFsFile *
1673     a_fs_file, const char *a_path, void *a_ptr);
1674 
1675 /** \internal
1676 * Internal structure to pass C++ dir walk data into C block walk call back.
1677 */
1678 typedef struct {
1679     TSK_FS_DIR_WALK_CPP_CB cppAction;   // pointer C++ callback
1680     void *cPtr;                 // pointer to data that was passed into C++ walk method
1681 } TSK_FS_DIR_WALK_CPP_DATA;
1682 
1683 /** \internal
1684 * Internal function used to call C++ Dir Walk callback from C callback.
1685 */
1686 extern TSK_WALK_RET_ENUM tsk_fs_dir_walk_cpp_c_cb(TSK_FS_FILE * a_file,
1687     const char *a_path, void *a_ptr);
1688 
1689 /**
1690 * \ingroup fslib_cpp
1691 * Stores information about an open file system.  One of the open()
1692 * commands needs to be used before any of the getX() or read() methods will return
1693 * valid data.  See TSK_FS_INFO for more details.
1694 */
1695 class TskFsInfo {
1696     friend class TskFsBlock;
1697     friend class TskFsFile;
1698     friend class TskFsDir;
1699 
1700   private:
1701      TSK_FS_INFO * m_fsInfo;
1702      TskFsInfo(const TskFsInfo & rhs);
1703      TskFsInfo & operator=(const TskFsInfo & rhs);
1704 
1705   public:
TskFsInfo(TSK_FS_INFO * a_fsInfo)1706      TskFsInfo(TSK_FS_INFO * a_fsInfo) {
1707         m_fsInfo = a_fsInfo;
1708     };
1709 
TskFsInfo()1710     TskFsInfo() {
1711         m_fsInfo = NULL;
1712     };
1713 
~TskFsInfo()1714     ~TskFsInfo() {
1715         close();
1716     }
1717 
1718     /**
1719     * Read arbitrary data from inside of the file system.
1720     * See tsk_fs_block_free() for details
1721     * @param a_off The byte offset to start reading from (relative to start of file system)
1722     * @param a_buf The buffer to store the block in.
1723     * @param a_len The number of bytes to read
1724     * @return The number of bytes read or -1 on error.
1725     */
read(TSK_OFF_T a_off,char * a_buf,size_t a_len)1726     ssize_t read(TSK_OFF_T a_off, char *a_buf, size_t a_len) {
1727         if (m_fsInfo)
1728             return tsk_fs_read(m_fsInfo, a_off, a_buf, a_len);
1729         else
1730             return -1;
1731     };
1732 
1733     /**
1734     * Read a file system block.
1735     * See tsk_fs_read_block() for details
1736     * @param a_addr The starting block file system address.
1737     * @param a_buf The char * buffer to store the block data in.
1738     * @param a_len The number of bytes to read (must be a multiple of the block size)
1739     * @return The number of bytes read or -1 on error.
1740     */
readBlock(TSK_DADDR_T a_addr,char * a_buf,size_t a_len)1741     ssize_t readBlock(TSK_DADDR_T a_addr, char *a_buf, size_t a_len) {
1742         if (m_fsInfo)
1743             return tsk_fs_read_block(m_fsInfo, a_addr, a_buf, a_len);
1744         else
1745             return -1;
1746     };
1747 
1748     /**
1749     * Walk a range of metadata structures and call a callback for each
1750     * structure that matches the flags supplied.   For example, it can
1751     * call the callback on only allocated or unallocated entries.
1752     * See tsk_fs_meta_walk() for details
1753     * @param a_start Metadata address to start walking from
1754     * @param a_end Metadata address to walk to
1755     * @param a_flags Flags that specify the desired metadata features
1756     * @param a_cb Callback function to call
1757     * @param a_ptr Pointer to pass to the callback
1758     * @returns 1 on error and 0 on success
1759     */
metaWalk(TSK_INUM_T a_start,TSK_INUM_T a_end,TSK_FS_META_FLAG_ENUM a_flags,TSK_FS_META_WALK_CPP_CB a_cb,void * a_ptr)1760     uint8_t metaWalk(TSK_INUM_T a_start,
1761         TSK_INUM_T a_end, TSK_FS_META_FLAG_ENUM a_flags,
1762         TSK_FS_META_WALK_CPP_CB a_cb, void *a_ptr) {
1763         TSK_FS_META_WALK_CPP_DATA metaData;
1764         metaData.cppAction = a_cb;
1765         metaData.cPtr = a_ptr;
1766         if (m_fsInfo)
1767             return tsk_fs_meta_walk(m_fsInfo, a_start,
1768                 a_end, a_flags, tsk_fs_meta_walk_cpp_c_cb, &metaData);
1769         else
1770             return 1;
1771     };
1772 
1773     /*    * Walk the file names in a directory and obtain the details of the files via a callback.
1774      * See tsk_fs_dir_walk() for details
1775      * @param a_addr Metadata address of the directory to analyze
1776      * @param a_flags Flags used during analysis
1777      * @param a_action Callback function that is called for each file name
1778      * @param a_ptr Pointer to data that is passed to the callback function each time
1779      * @returns 1 on error and 0 on success
1780      */
dirWalk(TSK_INUM_T a_addr,TSK_FS_DIR_WALK_FLAG_ENUM a_flags,TSK_FS_DIR_WALK_CPP_CB a_action,void * a_ptr)1781     uint8_t dirWalk(TSK_INUM_T a_addr,
1782         TSK_FS_DIR_WALK_FLAG_ENUM a_flags, TSK_FS_DIR_WALK_CPP_CB a_action,
1783         void *a_ptr) {
1784         TSK_FS_DIR_WALK_CPP_DATA dirData;
1785         dirData.cppAction = a_action;
1786         dirData.cPtr = a_ptr;
1787         if (m_fsInfo != NULL)
1788             return tsk_fs_dir_walk(m_fsInfo, a_addr,
1789                 a_flags, tsk_fs_dir_walk_cpp_c_cb, &dirData);
1790         else
1791             return 1;
1792     };
1793 
1794     /**
1795         *
1796     * Walk a range of file system blocks and call the callback function
1797     * with the contents and allocation status of each.
1798     * See tsk_fs_block_walk() for details.
1799     * @param a_start_blk Block address to start walking from
1800     * @param a_end_blk Block address to walk to
1801     * @param a_flags Flags used during walk to determine which blocks to call callback with
1802     * @param a_action Callback function
1803     * @param a_ptr Pointer that will be passed to callback
1804     * @returns 1 on error and 0 on success
1805     */
blockWalk(TSK_DADDR_T a_start_blk,TSK_DADDR_T a_end_blk,TSK_FS_BLOCK_WALK_FLAG_ENUM a_flags,TSK_FS_BLOCK_WALK_CPP_CB a_action,void * a_ptr)1806     uint8_t blockWalk(TSK_DADDR_T a_start_blk,
1807         TSK_DADDR_T a_end_blk, TSK_FS_BLOCK_WALK_FLAG_ENUM a_flags,
1808         TSK_FS_BLOCK_WALK_CPP_CB a_action, void *a_ptr) {
1809 
1810         TSK_FS_BLOCK_WALK_CPP_DATA blockData;
1811         blockData.cppAction = a_action;
1812         blockData.cPtr = a_ptr;
1813 
1814         return tsk_fs_block_walk(m_fsInfo, a_start_blk, a_end_blk, a_flags, tsk_fs_block_cpp_c_cb, &blockData); //tsk_fs_block_walk will check the input data
1815 
1816     };
1817 
1818     /**
1819         * Opens a file system that is inside of a Volume.
1820     * Returns a structure that can be used for analysis and reporting.
1821     * See tsk_fs_open_vol() for details
1822     * @param a_part_info Open volume to read from and analyze
1823     * @param a_ftype Type of file system (or autodetect)
1824     *
1825     * @return 1 on error 0 on success.
1826     */
open(const TskVsPartInfo * a_part_info,TSK_FS_TYPE_ENUM a_ftype)1827     uint8_t open(const TskVsPartInfo * a_part_info,
1828         TSK_FS_TYPE_ENUM a_ftype) {
1829         if ((m_fsInfo =
1830                 tsk_fs_open_vol(a_part_info->m_vsPartInfo, a_ftype))
1831             != NULL)
1832             return 0;
1833         return 1;
1834     };
1835 
1836     /**
1837         * Opens a file system at a given offset in a disk image.
1838     * Returns a structure that can be used for analysis and reporting.
1839     * See tsk_fs_open_img() for details
1840     * @param a_img_info Disk image to analyze
1841     * @param a_offset Byte offset to start analyzing from
1842     * @param a_ftype Type of file system (or autodetect)
1843     *
1844     * @return 1 on error 0 on success.
1845     */
open(TskImgInfo * a_img_info,TSK_OFF_T a_offset,TSK_FS_TYPE_ENUM a_ftype)1846     uint8_t open(TskImgInfo * a_img_info, TSK_OFF_T a_offset,
1847         TSK_FS_TYPE_ENUM a_ftype) {
1848         if ((m_fsInfo =
1849                 tsk_fs_open_img(a_img_info->m_imgInfo, a_offset, a_ftype))
1850             != NULL)
1851             return 0;
1852         return 1;
1853     };
1854 
1855 
1856 
1857     /**
1858     * \internal
1859     */
jopen(TSK_INUM_T a_inum)1860     uint8_t jopen(TSK_INUM_T a_inum) {
1861         if (m_fsInfo == NULL)
1862             return 0;
1863 
1864         return m_fsInfo->jopen(m_fsInfo, a_inum);
1865     }
1866 
1867     /**
1868     * \internal
1869     */
jblkWalk(TSK_DADDR_T a_addr1,TSK_DADDR_T a_addr2,int a_num,TSK_FS_JBLK_WALK_CPP_CB a_action,void * a_ptr)1870     uint8_t jblkWalk(TSK_DADDR_T a_addr1, TSK_DADDR_T a_addr2, int a_num,
1871         TSK_FS_JBLK_WALK_CPP_CB a_action, void *a_ptr) {
1872         if (m_fsInfo == NULL)
1873             return 0;
1874         TSK_FS_JBLK_WALK_CPP_DATA jblkData;
1875         jblkData.cppAction = a_action;
1876         jblkData.cPtr = a_ptr;
1877         return m_fsInfo->jblk_walk(m_fsInfo, a_addr1, a_addr2, a_num,
1878             tsk_fs_jblk_walk_cpp_c_cb, &jblkData);
1879     };
1880 
1881     /**
1882     * \internal
1883     */
jentryWalk(int a_num,TSK_FS_JENTRY_WALK_CPP_CB a_action,void * a_ptr)1884     uint8_t jentryWalk(int a_num, TSK_FS_JENTRY_WALK_CPP_CB a_action,
1885         void *a_ptr) {
1886         if (m_fsInfo == NULL)
1887             return 0;
1888         TSK_FS_JENTRY_WALK_CPP_DATA jentryData;
1889         jentryData.cppAction = a_action;
1890         jentryData.cPtr = a_ptr;
1891         return m_fsInfo->jentry_walk(m_fsInfo, a_num,
1892             tsk_fs_jentry_walk_cpp_c_cb, &jentryData);
1893 
1894     };
1895 
1896     /**
1897         * Parse a string with the file system type and return its internal ID.
1898     * See tsk_fs_type_toid() for details
1899     * @param a_str String to parse.
1900     * @returns ID of string (or unsupported if the name is unknown)
1901     */
typeToId(const TSK_TCHAR * a_str)1902     static TSK_FS_TYPE_ENUM typeToId(const TSK_TCHAR * a_str) {
1903         return tsk_fs_type_toid(a_str);
1904     };
1905 
1906     /**
1907         * Return the string name of a file system type id.
1908     * See tsk_fs_type_toname() for details
1909     * @param a_ftype File system type id
1910     * @returns Name or NULL on error
1911     */
typeToName(TSK_FS_TYPE_ENUM a_ftype)1912     static const char *typeToName(TSK_FS_TYPE_ENUM a_ftype) {
1913         return tsk_fs_type_toname(a_ftype);
1914     };
1915 
1916     /**
1917         * Return the supported file system types.
1918     * See tsk_fs_type_supported() for details
1919     * @returns The bit in the return value is 1 if the type is supported.
1920     */
typeSupported()1921     static TSK_FS_TYPE_ENUM typeSupported() {
1922         return tsk_fs_type_supported();
1923     };
1924 
1925     /**
1926         * Print the supported file system types to a file handle
1927     * See tsk_fs_type_print() for details
1928     * @param a_hFile File handle to print to
1929     */
typePrint(FILE * a_hFile)1930     static void typePrint(FILE * a_hFile) {
1931         tsk_fs_type_print(a_hFile);
1932     };
1933 
1934     /**
1935         *
1936     * Find the meta data address for a given file name (UTF-8).
1937     * See tsk_fs_path2inum() for details
1938 
1939     * @param a_path UTF-8 path of file to search for
1940     * @param [out] a_result Meta data address of file
1941     * @param [out] a_fs_name Copy of name details (or NULL if details not wanted)
1942     * @returns -1 on (system) error, 0 if found, and 1 if not found
1943     */
path2INum(const char * a_path,TSK_INUM_T * a_result,TskFsName * a_fs_name)1944     int8_t path2INum(const char *a_path,
1945         TSK_INUM_T * a_result, TskFsName * a_fs_name) {
1946         if (m_fsInfo != NULL)
1947             return tsk_fs_path2inum(m_fsInfo, a_path, a_result,
1948                 (a_fs_name)? a_fs_name->m_fsName : NULL); /* Avoid derreference of NULL pointer */
1949         else
1950             return -1;
1951     };
1952 
1953     /**
1954         * Parse a TSK_TCHAR string of an inode, type, and id pair (not all parts
1955     * need to be there).  This assumes the string is either:
1956     * INUM, INUM-TYPE, or INUM-TYPE-ID.  Return the values in integer form.
1957     * See tsk_fs_parse_inum() for details
1958     * @param [in] a_str Input string to parse
1959     * @param [out] a_inum Pointer to location where inode can be stored.
1960     * @param [out] a_type Pointer to location where type can be stored (or NULL)
1961     * @param [out] a_type_used Pointer to location where the value can be set
1962     * to 1 if the type was set (to differentiate between meanings of 0) (or NULL).
1963     * @param [out] a_id Pointer to location where id can be stored (or NULL)
1964     * @param [out] a_id_used Pointer to location where the value can be set
1965     * to 1 if the id was set (to differentiate between meanings of 0) (or NULL).
1966     *
1967     * @return 1 on error or if not an inode and 0 on success
1968     */
parseINum(const TSK_TCHAR * a_str,TSK_INUM_T * a_inum,TSK_FS_ATTR_TYPE_ENUM * a_type,uint8_t * a_type_used,uint16_t * a_id,uint8_t * a_id_used)1969     static int parseINum(const TSK_TCHAR * a_str, TSK_INUM_T * a_inum,
1970         TSK_FS_ATTR_TYPE_ENUM * a_type, uint8_t * a_type_used,
1971         uint16_t * a_id, uint8_t * a_id_used) {
1972         return tsk_fs_parse_inum(a_str, a_inum, a_type, a_type_used, a_id,
1973             a_id_used);
1974     };
1975 
1976     /**
1977         * return byte offset in image that fs starts
1978     * @return offset in bytes.
1979     */
getOffset()1980     TSK_OFF_T getOffset() const {
1981         if (m_fsInfo != NULL)
1982             return m_fsInfo->offset;
1983         else
1984             return 0;
1985     };
1986 
1987     /**
1988         * return number of metadata addresses in FS
1989     * @return number of metatdata addresses
1990     */
getINumCount()1991     TSK_INUM_T getINumCount() const {
1992         if (m_fsInfo != NULL)
1993             return m_fsInfo->inum_count;
1994         else
1995             return 0;
1996     };
1997 
1998     /**
1999         * return metadata address of root directory
2000     * @return metadata address of root directory
2001     */
getRootINum()2002     TSK_INUM_T getRootINum() const {
2003         if (m_fsInfo != NULL)
2004             return m_fsInfo->root_inum;
2005         else
2006             return 0;
2007     };
2008     /**
2009         * return first valid metadata address
2010     * @return first valid metadata address
2011     */
getFirstINum()2012     TSK_INUM_T getFirstINum() const {
2013         if (m_fsInfo != NULL)
2014             return m_fsInfo->first_inum;
2015         else
2016             return 0;
2017     };
2018     /**
2019         * return last valid metadata address
2020     * @return last valid metadata address
2021     */
getLastINum()2022     TSK_INUM_T getLastINum() const {
2023         if (m_fsInfo != NULL)
2024             return m_fsInfo->last_inum;
2025         else
2026             return 0;
2027     };
2028     /**
2029         * return address of journal inode
2030     * @return address of journal inode
2031     */
getJournalINum()2032     TSK_INUM_T getJournalINum() const {
2033         if (m_fsInfo != NULL)
2034             return m_fsInfo->journ_inum;
2035         else
2036             return 0;
2037     };
2038 
2039     /**
2040         * return number of blocks in fs
2041     * @return number of blocks in fs
2042     */
getBlockCount()2043     TSK_DADDR_T getBlockCount() const {
2044         if (m_fsInfo != NULL)
2045             return m_fsInfo->block_count;
2046         else
2047             return 0;
2048     };
2049     /**
2050         * return address of first block
2051     * @return address of first block
2052     */
getFirstBlock()2053     TSK_DADDR_T getFirstBlock() const {
2054         if (m_fsInfo != NULL)
2055             return m_fsInfo->first_block;
2056         else
2057             return 0;
2058     };
2059     /**
2060         * return address of last block as reported by file system
2061     * (it is equal to the last block in the image or volume (if image is not complete)
2062     * @return address of last block
2063     */
getLastBlockAct()2064     TSK_DADDR_T getLastBlockAct() const {
2065         if (m_fsInfo != NULL)
2066             return m_fsInfo->last_block_act;
2067         else
2068             return 0;
2069     };
2070     /**
2071         * return address of last block that is adjusted so that
2072     * (could be larger than last_block in image if end of image does not exist)
2073     * @return address of last block
2074     */
getLastBlock()2075     TSK_DADDR_T getLastBlock() const {
2076         if (m_fsInfo != NULL)
2077             return m_fsInfo->last_block;
2078         else
2079             return 0;
2080     };
2081     /**
2082         * return size of each file system block (in bytes)
2083     * @return size of each block
2084     */
getBlockSize()2085     unsigned int getBlockSize() const {
2086         if (m_fsInfo != NULL)
2087             return m_fsInfo->block_size;
2088         else
2089             return 0;
2090     };
2091     /**
2092         * return size of device block (typically always 512)
2093     * @return size of device block
2094     */
getDeviceSize()2095     unsigned int getDeviceSize() const {
2096         if (m_fsInfo != NULL)
2097             return m_fsInfo->dev_bsize;
2098         else
2099             return 0;
2100     };
2101 
2102     /**
2103         * return type of file system
2104     * @return type of file system
2105     */
getFsType()2106     TSK_FS_TYPE_ENUM getFsType() const {
2107         if (m_fsInfo != NULL)
2108             return m_fsInfo->ftype;
2109         else
2110             return (TSK_FS_TYPE_ENUM) 0;
2111     };
2112     /**
2113         * return the "name" of data unit type  as a string ("Cluster", for example)
2114     * @return string "name" of data unit type
2115     */
getDataUnitName()2116     const char *getDataUnitName() const {
2117         if (m_fsInfo != NULL)
2118             return m_fsInfo->duname;
2119         else
2120             return NULL;
2121     };
2122 
2123     /**
2124         * return flags for file system
2125     * @return flags for file system
2126     */
getFlags()2127     TSK_FS_INFO_FLAG_ENUM getFlags() const {
2128         if (m_fsInfo != NULL)
2129             return m_fsInfo->flags;
2130         else
2131             return (TSK_FS_INFO_FLAG_ENUM) 0;
2132     };
2133     /**
2134         * return file system id (as reported in boot sector).  Use getFsIdLen() to determine how many byts in buffer are used.
2135     * @return Buffer with file system id
2136     */
getFsId()2137     const uint8_t *getFsId() const {
2138         if (m_fsInfo != NULL)
2139             return m_fsInfo->fs_id;
2140         else
2141             return 0;
2142     };
2143 
2144     /**
2145         * return the number of bytes used in the buffer returned by getFsId().
2146     * @return number of bytes used.
2147     */
getFsIdLen()2148     size_t getFsIdLen() const {
2149         if (m_fsInfo == NULL)
2150             return 0;
2151 
2152         return m_fsInfo->fs_id_used;
2153     };
2154 
2155     /**
2156       * Close an open file system. See tsk_fs_close() for details.
2157      */
close()2158     void close() {
2159         tsk_fs_close(m_fsInfo);
2160     };
2161 
2162 
2163   private:
getTskImgInfo()2164     const TSK_IMG_INFO *getTskImgInfo() const {
2165         if (m_fsInfo != NULL)
2166             return m_fsInfo->img_info;
2167         else
2168             return NULL;
2169 }};                             //TskFsInfo
2170 
2171 
2172 
2173 /**
2174 * \ingroup fslib_cpp
2175 * Stores information about a file system block.  Must be created by either
2176 * allocating an empty block and opening one or by passing in a TSK_FS_BLOCK struct.
2177 * If NULL is passed to the constructor and open() is not called, the other methods
2178 * return undefined data. See TSK_FS_BLOCK for more details.
2179 */
2180 class TskFsBlock {
2181   private:
2182     TSK_FS_BLOCK * m_fsBlock;
2183     bool m_opened;              // true if open() was called and we need to free it
2184 
2185      TskFsBlock(const TskFsBlock & rhs);
2186      TskFsBlock & operator=(const TskFsBlock & rhs);
2187 
2188   public:
2189     /**
2190     * construct a TskFsBlock using a TSK_FS_BLOCK structure
2191     * @param a_fsBlock a pointer of TSK_FS_BLOCK.  If NULL, the getX() methods return undefined data.
2192     */
TskFsBlock(const TSK_FS_BLOCK * a_fsBlock)2193      TskFsBlock(const TSK_FS_BLOCK * a_fsBlock) {
2194         m_fsBlock = const_cast < TSK_FS_BLOCK * >(a_fsBlock);
2195         m_opened = false;
2196     };
2197 
2198     /**
2199     * default constructor to construct a TskFsBlock.  Must call open() before using other methods.
2200     */
TskFsBlock()2201     TskFsBlock() {
2202         m_fsBlock = NULL;
2203     };
2204 
2205     /**
2206         * Free the memory associated with the TSK_FS_BLOCK structure.
2207     * See tsk_fs_block_free() for details
2208     */
~TskFsBlock()2209     ~TskFsBlock() {
2210         if (m_opened)
2211             tsk_fs_block_free(m_fsBlock);
2212         m_fsBlock = NULL;
2213     };
2214 
2215     /**
2216         * Open a block (use only if created with default constructor).
2217     *
2218     * @param a_fs The file system to read the block from.
2219     * @param a_addr The file system address to read.
2220     * @return 1 on error and 0 on success.
2221     */
open(TskFsInfo * a_fs,TSK_DADDR_T a_addr)2222     uint8_t open(TskFsInfo * a_fs, TSK_DADDR_T a_addr) {
2223         if (m_fsBlock)
2224             return 1;
2225 
2226         if ((m_fsBlock =
2227                 tsk_fs_block_get(a_fs->m_fsInfo, m_fsBlock,
2228                     a_addr)) != NULL) {
2229             m_opened = true;
2230             return 0;
2231         }
2232         else {
2233             return 1;
2234         }
2235     };
2236 
2237     /**
2238         * Get buffer with block data (of size TSK_FS_INFO::block_size)
2239     *
2240     * @return buffer with block data
2241     */
getBuf()2242     const char *getBuf() const {
2243         if (m_fsBlock != NULL)
2244             return m_fsBlock->buf;
2245         else
2246             return NULL;
2247     };
2248 
2249     /**
2250         * Get address of block
2251     * @return address of block
2252     */
getAddr()2253     TSK_DADDR_T getAddr() const {
2254         if (m_fsBlock != NULL)
2255             return m_fsBlock->addr;
2256         else
2257             return 0;
2258     };
2259 
2260     /**
2261         * Get flags for block (alloc or unalloc)
2262     * @return flags for block
2263     */
getFlags()2264     TSK_FS_BLOCK_FLAG_ENUM getFlags() const {
2265         if (m_fsBlock != NULL)
2266             return m_fsBlock->flags;
2267         else
2268             return (TSK_FS_BLOCK_FLAG_ENUM) 0;
2269     };
2270 
2271   private:
2272     /**
2273         * Get pointer to file system that block is from
2274     * @return pointer to file system that block is from
2275     */
getFsInfo()2276     const TSK_FS_INFO *getFsInfo() const {
2277         if (m_fsBlock != NULL)
2278             return m_fsBlock->fs_info;
2279         else
2280             return NULL;
2281     };
2282 };
2283 
2284 
2285 
2286 /**
2287  * \ingroup fslib_cpp
2288  * Stores information about names that are located in metadata structures.  See
2289  * TSK_FS_META_NAME for more details.
2290  */
2291 class TskFsMetaName {
2292   private:
2293     TSK_FS_META_NAME_LIST * m_fsMetaNameList;
2294     TskFsMetaName(const TskFsMetaName & rhs);
2295     TskFsMetaName & operator=(const TskFsMetaName & rhs);
2296 
2297   public:
2298     /**
2299      * Allocates an object based on a C struct.
2300      * @param a_fsMetaNameList C struct of name list. If NULL, get() methods return undefined values.
2301      */
TskFsMetaName(TSK_FS_META_NAME_LIST * a_fsMetaNameList)2302      TskFsMetaName(TSK_FS_META_NAME_LIST * a_fsMetaNameList) {
2303         m_fsMetaNameList = a_fsMetaNameList;
2304     };
2305 
2306     /**
2307      * Get the text name in UTF-8 (does not include parent directory name).
2308      * @returns name of file.
2309      */
getName()2310     const char *getName() const {
2311         if (m_fsMetaNameList != NULL)
2312             return m_fsMetaNameList->name;
2313         else
2314             return NULL;
2315     };
2316 
2317     /**
2318      * Get the parent inode (NTFS Only)
2319      * @return Address of parent directory.
2320      */
getParInode()2321     TSK_INUM_T getParInode() const {
2322         if (m_fsMetaNameList != NULL)
2323             return m_fsMetaNameList->par_inode;
2324         else
2325             return 0;
2326     };
2327 
2328     /**
2329      * get the parent sequence (NTFS Only)
2330      * @return Sequence of parent directory.
2331      */
getParSeq()2332     uint32_t getParSeq() const {
2333         return m_fsMetaNameList->par_seq;
2334     };
2335 };
2336 
2337 /**
2338  * \ingroup fslib_cpp
2339  * Stores metadata about a file. See TSK_FS_META for more details.
2340  */
2341 class TskFsMeta {
2342   private:
2343     TSK_FS_META * m_fsMeta;
2344     TskFsMeta(const TskFsMeta & rhs);
2345     TskFsMeta & operator=(const TskFsMeta & rhs);
2346 
2347   public:
2348     /**
2349           * construct a TskFsMeta object.  If NULL is passed as an argument, the getX() behavior
2350      * is not defined.
2351      * @param a_fsMeta a pointer of TSK_FS_META
2352      */
TskFsMeta(TSK_FS_META * a_fsMeta)2353      TskFsMeta(TSK_FS_META * a_fsMeta) {
2354         m_fsMeta = a_fsMeta;
2355 #if 0
2356         if (m_fsMeta != NULL) {
2357             m_nameList = m_fsMeta->name2;
2358             size_t numOfList = 0;
2359             TSK_FS_META_NAME_LIST *nameList = m_nameList;
2360             while (nameList != NULL) {
2361                 nameList = nameList->next;
2362                 numOfList += 1;
2363             } m_nameListLen = numOfList;
2364         }
2365         else {
2366             m_nameList = NULL;
2367             m_nameListLen = 0;
2368         }
2369 #endif
2370     };
2371 
~TskFsMeta()2372     ~TskFsMeta() {
2373     };
2374 
2375     /**
2376           * Makes the "ls -l" permissions string for a file.
2377      * See tsk_fs_meta_make_ls() for details
2378      * @param a_buf [out] Buffer to write results to (must be 12 bytes or longer)
2379      * @param a_len Length of buffer
2380      */
getLs(char * a_buf,size_t a_len)2381     uint8_t getLs(char *a_buf, size_t a_len) const {
2382         if (m_fsMeta != NULL)
2383             return tsk_fs_meta_make_ls(m_fsMeta, a_buf, a_len);
2384         else
2385             return 0;
2386     };
2387     /**
2388           * get flags for this file for its allocation status etc.
2389      * @return flags for this file
2390      */
getFlags()2391     TSK_FS_META_FLAG_ENUM getFlags() const {
2392         if (m_fsMeta != NULL)
2393             return m_fsMeta->flags;
2394         else
2395             return (TSK_FS_META_FLAG_ENUM) 0;
2396     }
2397     /**
2398           * get address of the meta data structure for this file
2399      * @return address of the meta data structure for this file
getAddr()2400      */ TSK_INUM_T getAddr() const {
2401         if (m_fsMeta != NULL)
2402             return m_fsMeta->addr;
2403         else
2404             return 0;
2405     };
2406     /**
2407           * get file type
2408      * @return file type
2409      */
getType()2410     TSK_FS_META_TYPE_ENUM getType() const {
2411         if (m_fsMeta != NULL)
2412             return m_fsMeta->type;
2413         else
2414             return (TSK_FS_META_TYPE_ENUM) 0;
2415     };
2416     /**
2417           * get Unix-style permissions
2418      * @return Unix-style permissions mode
2419      */
getMode()2420     TSK_FS_META_MODE_ENUM getMode() const {
2421         if (m_fsMeta != NULL)
2422             return m_fsMeta->mode;
2423         else
2424             return (TSK_FS_META_MODE_ENUM) 0;
2425     };
2426     /**
2427           * get link count (number of file names pointing to this)
2428      * @return link count
2429      */
getNLink()2430     int getNLink() const {
2431         if (m_fsMeta != NULL)
2432             return m_fsMeta->nlink;
2433         else
2434             return 0;
2435     };
2436     /**
2437           * get file size (in bytes)
2438      * @return file size
2439      */
getSize()2440     TSK_OFF_T getSize() const {
2441         if (m_fsMeta != NULL)
2442             return m_fsMeta->size;
2443         else
2444             return 0;
2445     };
2446     /**
2447           * get owner id
2448      * @return owner id
2449      */
getUid()2450     TSK_UID_T getUid() const {
2451         if (m_fsMeta != NULL)
2452             return m_fsMeta->uid;
2453         else
2454             return 0;
2455     };
2456 
2457     /**
2458           * get group id
2459      * @return group id
2460      */
getGid()2461     TSK_GID_T getGid() const {
2462         if (m_fsMeta != NULL)
2463             return m_fsMeta->gid;
2464         else
2465             return 0;
2466     };
2467 
2468     /**
2469           * get last file content modification time (stored in number of seconds since Jan 1, 1970 UTC)
2470      * @return last file content modification time
2471      */
getMTime()2472     time_t getMTime() const {
2473         if (m_fsMeta != NULL)
2474             return m_fsMeta->mtime;
2475         else
2476             return 0;
2477     };
2478 
2479     /**
2480           * get nano-second resolution of modification time
2481      * @return nano-second resolution of modification time
2482      */
getMTimeNano()2483     uint32_t getMTimeNano() const {
2484         if (m_fsMeta != NULL)
2485             return m_fsMeta->mtime_nano;
2486         else
2487             return 0;
2488     };
2489 
2490     /**
2491           * get last file content accessed time (stored in number of seconds since Jan 1, 1970 UTC)
2492      * @return last file content accessed time
2493      */
getATime()2494     time_t getATime() const {
2495         if (m_fsMeta != NULL)
2496             return m_fsMeta->atime;
2497         else
2498             return 0;
2499     };
2500 
2501     /**
2502           * get nano-second resolution of accessed time
2503      * @return nano-second resolution of accessed time
2504      */
getATimeNano()2505     uint32_t getATimeNano() const {
2506         if (m_fsMeta != NULL)
2507             return m_fsMeta->atime_nano;
2508         else
2509             return 0;
2510     };
2511 
2512     /**
2513           * get last file / metadata status change time (stored in number of seconds since Jan 1, 1970 UTC)
2514      * @return last file / metadata status change time
2515      */
getCTime()2516     time_t getCTime() const {
2517         if (m_fsMeta != NULL)
2518             return m_fsMeta->ctime;
2519         else
2520             return 0;
2521     };
2522 
2523     /**
2524           * get nano-second resolution of change time
2525      * @return nano-second resolution of change time
2526      */
getCTimeNano()2527     uint32_t getCTimeNano() const {
2528         if (m_fsMeta != NULL)
2529             return m_fsMeta->ctime_nano;
2530         else
2531             return 0;
2532     };
2533 
2534     /**
2535           * get created time (stored in number of seconds since Jan 1, 1970 UTC)
2536      * @return created time
2537      */
getCrTime()2538     time_t getCrTime() const {
2539         if (m_fsMeta != NULL)
2540             return m_fsMeta->crtime;
2541         else
2542             return 0;
2543     };
2544 
2545     /**
2546           * get nano-second resolution of created time
2547      * @return nano-second resolution of created time
2548      */
getCrTimeNano()2549     uint32_t getCrTimeNano() const {
2550         if (m_fsMeta != NULL)
2551             return m_fsMeta->crtime_nano;
2552         else
2553             return 0;
2554     };
2555 
2556     /**
2557           * get linux deletion time
2558      * @return linux deletion time
2559      */
getDTime()2560     time_t getDTime() const {
2561         if (m_fsMeta != NULL)
2562             return m_fsMeta->time2.ext2.dtime;
2563         else
2564             return 0;
2565     };
2566 
2567     /**
2568           * get nano-second resolution of deletion time
2569      * @return nano-second resolution of deletion time
2570      */
getDTimeNano()2571     uint32_t getDTimeNano() const {
2572         if (m_fsMeta != NULL)
2573             return m_fsMeta->time2.ext2.dtime_nano;
2574         else
2575             return 0;
2576     };
2577 
2578     /**
2579           * get HFS+ backup time
2580      * @return HFS+ backup time
2581      */
getBackUpTime()2582     time_t getBackUpTime() const {
2583         if (m_fsMeta != NULL)
2584             return m_fsMeta->time2.hfs.bkup_time;
2585         else
2586             return 0;
2587     };
2588 
2589     /**
2590           * get nano-second resolution of HFS+ backup time
2591      * @return nano-second resolution of HFS+ backup time
2592      */
getBackUpTimeNano()2593     uint32_t getBackUpTimeNano() const {
2594         if (m_fsMeta != NULL)
2595             return m_fsMeta->time2.hfs.bkup_time_nano;
2596         else
2597             return 0;
2598     };
2599 
2600     /**
2601           * get sequence number for file (NTFS only, is incremented when entry is reallocated)
2602      * @return sequence number for file, or 0xFFFF on error.
2603      */
getSeq()2604     uint32_t getSeq() const {
2605         if (m_fsMeta != NULL)
2606             return m_fsMeta->seq;
2607         return 0xFFFF;
2608     };
2609 
2610     /**
2611           * get name of target file if this is a symbolic link
2612      * @return name of target file if this is a symbolic link
2613      */
getLink()2614     const char *getLink() const {
2615         if (m_fsMeta != NULL)
2616             return m_fsMeta->link;
2617         else
2618             return NULL;
2619     };
2620 
2621     /**
2622      * Return the number of names that are stored in the metadata.
2623      * @returns number of names.
2624      */
getName2Count()2625     int getName2Count() const {
2626         int size = 0;
2627         if (m_fsMeta != NULL) {
2628             TSK_FS_META_NAME_LIST *name = m_fsMeta->name2;
2629             while (name != NULL) {
2630                 size++;
2631                 name = name->next;
2632         }} return size;
2633     };
2634 
2635     /**
2636      * Return a name that is stored in the metadata.
2637      * @param a_idx Index of the name to return
2638      * @returns NULL on error.  Caller must free this memory.
2639      */
getName2(int a_idx)2640     const TskFsMetaName *getName2(int a_idx) const {
2641         if (m_fsMeta != NULL) {
2642             TSK_FS_META_NAME_LIST *name = m_fsMeta->name2;
2643             int i = 0;
2644             while (name != NULL) {
2645                 if (i == a_idx)
2646                     return new TskFsMetaName(name);
2647                 i++;
2648                 name = name->next;
2649         }} return NULL;
2650     };
2651 
2652   private:
2653     /**
2654           * get structure used as the head of an attribute list
2655      * @return structure used as the head of an attribute list
2656      */
getAttr()2657     const TSK_FS_ATTRLIST *getAttr() const {
2658         if (m_fsMeta != NULL)
2659             return m_fsMeta->attr;
2660         else
2661             return NULL;
2662     };
2663 };
2664 
2665 
2666 /**
2667  * \ingroup fslib_cpp
2668 * Class that represents an allocated or deleted file. The non-default constructor or
2669 * open method must be called first.  otherwise, the results of the getX() methods are
2670 * undefined. See TSK_FS_FILE for more details.
2671 */
2672 class TskFsFile {
2673   friend class TskFsDir;
2674   private:
2675     TSK_FS_FILE * m_fsFile;
2676     bool m_opened;
2677      TskFsFile(const TskFsFile & rhs);
2678      TskFsFile & operator=(const TskFsFile & rhs);
2679 
2680   public:
2681     /**
2682         * Construct a TskFsFile object from a C struct
2683     * @param a_fsFile a pointer of TSK_FS_FILE
2684     */
TskFsFile(TSK_FS_FILE * a_fsFile)2685      TskFsFile(TSK_FS_FILE * a_fsFile) {
2686         m_fsFile = a_fsFile;
2687         m_opened = false;
2688     };
2689 
2690     /**
2691         * default constructor to construct a TskFsFile object
2692     */
TskFsFile()2693     TskFsFile() {
2694         m_fsFile = NULL;
2695         m_opened = false;
2696     };
2697 
2698     /**
2699         * Close an open file.
2700     */
~TskFsFile()2701     ~TskFsFile() {
2702         close();
2703     };
2704 
2705     /**
2706         * Close an open file.
2707     * See tsk_fs_file_close() for details.
2708     */
close()2709     void close() {
2710         if (m_opened)
2711             tsk_fs_file_close(m_fsFile);
2712         m_fsFile = NULL;
2713     };
2714 
2715     /**
2716         *
2717     * Open a file given its metadata address. This function loads the metadata
2718     * and returns a handle that can be used to read and process the file.   Note
2719     * that the returned class will not have the file name set because
2720     * it was not used to load the file and this function does not search the
2721     * directory structure to find the name that points to the address.   In general,
2722     * if you know the metadata address of a file, this function is more efficient
2723     * then tsk_fs_file_open, which first maps a file name to the metadata address
2724     * and then open the file using this function.
2725     * See tsk_fs_file_open_meta() for details
2726     * @param a_fs File system to analyze
2727     * @param a_fs_file object to store file data in or NULL to have one allocated.
2728     * @param a_addr Metadata address of file to lookup
2729     * @returns 1 on error and 0 on success.
2730     */
open(TskFsInfo * a_fs,TskFsFile * a_fs_file,TSK_INUM_T a_addr)2731     uint8_t open(TskFsInfo * a_fs, TskFsFile * a_fs_file,
2732         TSK_INUM_T a_addr) {
2733         if ((m_fsFile =
2734                 tsk_fs_file_open_meta(a_fs->m_fsInfo, a_fs_file->m_fsFile,
2735                     a_addr)) != NULL) {
2736             m_opened = true;
2737             return 0;
2738         }
2739         else {
2740             return 1;
2741         }
2742     };
2743 
2744     /**
2745         * Return the handle structure for a specific file, given its full path. Note that
2746     * if you have the metadata address fo the file, then tsk_fs_file_open_meta() is a
2747     * more efficient approach.
2748     * See tsk_fs_file_open() for details
2749     * @param a_fs File system to analyze
2750     * @param a_fs_file Structure to store file data in or NULL to have one allocated.
2751     * @param a_path Path of file to open
2752     * @returns 1 on error and 0 on success.
2753     */
open(TskFsInfo * a_fs,TskFsFile * a_fs_file,const char * a_path)2754     uint8_t open(TskFsInfo * a_fs, TskFsFile * a_fs_file,
2755         const char *a_path) {
2756         if ((m_fsFile =
2757                 tsk_fs_file_open(a_fs->m_fsInfo, a_fs_file->m_fsFile,
2758                     a_path))
2759             != NULL) {
2760             m_opened = true;
2761             return 0;
2762         }
2763         else {
2764             return 1;
2765         }
2766     };
2767 
2768     /*    * Return the number of attributes in the file.
2769      * See tsk_fs_file_attr_getsize() for details
2770      * @returns number of attributes in file
2771      */
getAttrSize()2772     int getAttrSize() {
2773         return tsk_fs_file_attr_getsize(m_fsFile);      //m_fsFile is checked by this C function
2774     };
2775 
2776     /*    * Get a file's attribute based on the 0-based index in the list (and not type, id pair).
2777      * It's caller's responsibility to free TskFsAttribute*
2778      * See tsk_fs_file_attr_get_idx() for details
2779      * @param a_idx 0-based index of attribute to return.
2780      * @returns Pointer to attribute or NULL on error
2781      */
getAttr(int a_idx)2782     const TskFsAttribute *getAttr(int a_idx) {
2783         TskFsAttribute *fsAttr = new TskFsAttribute(tsk_fs_file_attr_get_idx(m_fsFile, a_idx)); //m_fsFile is checked by this C function
2784         return fsAttr;
2785     };
2786 
2787     /*    * Return the default attribute for the file
2788      * It's caller's responsibility to free TskFsAttribute*
2789      * See tsk_fs_file_attr_get() for details
2790      * @returns Pointer to attribute or NULL on error
2791      */
getAttrDefault()2792     const TskFsAttribute *getAttrDefault() {
2793         TskFsAttribute *fsAttr = new TskFsAttribute(tsk_fs_file_attr_get(m_fsFile));    //m_fsFile is checked by this C function
2794         return fsAttr;
2795     };
2796 
2797     /*    * Return a specific type and id attribute for the file.
2798      * It's caller's responsibility to free TskFsAttribute*
2799      * See tsk_fs_file_attr_get_type() for details
2800      * @param a_type Type of attribute to load
2801      * @param a_id Id of attribute to load
2802      * @param a_id_used Set to 1 if ID is actually set or 0 to use default
2803      * @returns Pointer to attribute or NULL on error
2804      */
getAttr(TSK_FS_ATTR_TYPE_ENUM a_type,uint16_t a_id,uint8_t a_id_used)2805     const TskFsAttribute *getAttr(TSK_FS_ATTR_TYPE_ENUM a_type,
2806         uint16_t a_id, uint8_t a_id_used) {
2807         TskFsAttribute *fsAttr = new TskFsAttribute(tsk_fs_file_attr_get_type(m_fsFile, //m_fsFile is checked by this C function
2808                 a_type, a_id, a_id_used));
2809         return fsAttr;
2810     };
2811 
2812     /**
2813         * Process a specific attribute in a file and call a callback function with the file contents.
2814     * See tsk_fs_file_walk_type() for details
2815     * @param a_type Attribute type to process
2816     * @param a_id Id if attribute to process
2817     * @param a_flags Flags to use while processing file
2818     * @param a_action Callback action to call with content
2819     * @param a_ptr Pointer that will passed to callback
2820     * @returns 1 on error and 0 on success.
2821     */
walk(TSK_FS_ATTR_TYPE_ENUM a_type,uint16_t a_id,TSK_FS_FILE_WALK_FLAG_ENUM a_flags,TSK_FS_FILE_WALK_CPP_CB a_action,void * a_ptr)2822     uint8_t walk(TSK_FS_ATTR_TYPE_ENUM a_type, uint16_t a_id,
2823         TSK_FS_FILE_WALK_FLAG_ENUM a_flags,
2824         TSK_FS_FILE_WALK_CPP_CB a_action, void *a_ptr) {
2825         TSK_FS_FILE_WALK_CPP_DATA fileData;
2826         fileData.cppAction = a_action;
2827         fileData.cPtr = a_ptr;
2828         return tsk_fs_file_walk_type(m_fsFile, a_type, a_id, a_flags, tsk_fs_file_cpp_c_cb, &fileData); //m_fsFile is checked by this C function
2829     };
2830 
2831     /**
2832      * Process the default attribute for the file and call a callback function with the file contents.
2833     * See tsk_fs_file_walk_type() for details
2834     * @param a_flags Flags to use while processing file
2835     * @param a_action Callback action to call with content
2836     * @param a_ptr Pointer that will passed to callback
2837     * @returns 1 on error and 0 on success.
2838     */
walk(TSK_FS_FILE_WALK_FLAG_ENUM a_flags,TSK_FS_FILE_WALK_CPP_CB a_action,void * a_ptr)2839     uint8_t walk(TSK_FS_FILE_WALK_FLAG_ENUM a_flags,
2840         TSK_FS_FILE_WALK_CPP_CB a_action, void *a_ptr) {
2841         TSK_FS_FILE_WALK_CPP_DATA fileData;
2842         fileData.cppAction = a_action;
2843         fileData.cPtr = a_ptr;
2844         return tsk_fs_file_walk(m_fsFile, a_flags, tsk_fs_file_cpp_c_cb, &fileData);    //m_fsFile is checked by this C function
2845     };
2846 
2847     /**
2848      * Read the contents of a specific attribute of a file using a typical read() type interface.
2849     * 0s are returned for missing runs of files.
2850     * See tsk_fs_file_read_type() for details
2851     * @param a_type The type of attribute to load
2852     * @param a_id The id of attribute to load (use 0 and set a_flags if you do not care)
2853     * @param a_offset The byte offset to start reading from.
2854     * @param a_buf The buffer to read the data into.
2855     * @param a_len The number of bytes to read from the file.
2856     * @param a_flags Flags to use while reading
2857     * @returns The number of bytes read or -1 on error (incl if offset is past EOF).
2858     */
read(TSK_FS_ATTR_TYPE_ENUM a_type,uint16_t a_id,TSK_OFF_T a_offset,char * a_buf,size_t a_len,TSK_FS_FILE_READ_FLAG_ENUM a_flags)2859     ssize_t read(TSK_FS_ATTR_TYPE_ENUM a_type, uint16_t a_id,
2860         TSK_OFF_T a_offset, char *a_buf, size_t a_len,
2861         TSK_FS_FILE_READ_FLAG_ENUM a_flags) {
2862         return tsk_fs_file_read_type(m_fsFile, a_type, a_id, a_offset, a_buf, a_len, a_flags);  //m_fsFile is checked by this C function
2863     };
2864     /**
2865      * Read the contents of the default attribute of a file using a typical read() type interface.
2866     * 0s are returned for missing runs of files.
2867     * See tsk_fs_file_read() for details
2868     * @param a_offset The byte offset to start reading from.
2869     * @param a_buf The buffer to read the data into.
2870     * @param a_len The number of bytes to read from the file.
2871     * @param a_flags Flags to use while reading
2872     * @returns The number of bytes read or -1 on error (incl if offset is past EOF).
2873     */
read(TSK_OFF_T a_offset,char * a_buf,size_t a_len,TSK_FS_FILE_READ_FLAG_ENUM a_flags)2874     ssize_t read(TSK_OFF_T a_offset, char *a_buf, size_t a_len,
2875         TSK_FS_FILE_READ_FLAG_ENUM a_flags) {
2876         return tsk_fs_file_read(m_fsFile, a_offset, a_buf, a_len, a_flags);     //m_fsFile is checked by this C function
2877     };
2878 
2879     /**
2880      * Return pointer to the file's name (or NULL if file was opened using metadata address)
2881     * @returns pointer to name of file.  It is the caller's responsibility to free this.
2882     */
getName()2883     TskFsName *getName() {
2884         if (m_fsFile != NULL)
2885             return new TskFsName(m_fsFile->name);
2886         else
2887             return NULL;
2888     };
2889 
2890     /**
2891      * Return pointer to the file's metadata (or NULL if name has invalid metadata address)
2892     * @returns pointer metadata of file. It is the caller's responsibility to free this.
2893     */
getMeta()2894     TskFsMeta *getMeta() {
2895         if (m_fsFile != NULL)
2896             return new TskFsMeta(m_fsFile->meta);
2897         else
2898             return NULL;
2899     };
2900 
2901     /**
2902     * Return pointer file system that the file is located in.
2903     * @returns pointer to file system that the file is located in.
2904     */
getFsInfo()2905     TskFsInfo *getFsInfo() {
2906         if (m_fsFile != NULL)
2907             return new TskFsInfo(m_fsFile->fs_info);
2908         else
2909             return NULL;
2910     };
2911 };                              //TskFsFile
2912 
2913 /**
2914  * \ingroup fslib_cpp
2915 * Stores information about a directory in the file system. The open() method
2916 * must be called before any of hte other methods return defined data. See
2917 * TSK_FS_DIR for more details.
2918 */
2919 class TskFsDir {
2920   private:
2921     TSK_FS_DIR * m_fsDir;
2922     TskFsDir(const TskFsDir & rhs);
2923     TskFsDir & operator=(const TskFsDir & rhs);
2924 
2925   public:
TskFsDir()2926      TskFsDir() {
2927         m_fsDir = NULL;
2928     };
2929     /*
2930      * Close the directory that was opened with tsk_fs_dir_open()
2931      */
~TskFsDir()2932     ~TskFsDir() {
2933         close();
2934     }
2935 
2936     /*
2937      * Open a directory (using its metadata addr) so that each of the files in it can be accessed.
2938      * See for tsk_fs_dir_open_meta() details.
2939      * @param a_fs File system to analyze
2940      * @param a_addr Metadata address of the directory to open
2941      * @returns 1 on error and 0 on success
2942      */
open(TskFsInfo * a_fs,TSK_INUM_T a_addr)2943     uint8_t open(TskFsInfo * a_fs, TSK_INUM_T a_addr) {
2944         if ((m_fsDir =
2945                 tsk_fs_dir_open_meta(a_fs->m_fsInfo, a_addr)) != NULL)
2946             return 0;
2947         else
2948             return 1;
2949     };
2950 
2951     /*
2952      * Open a directory (using its path) so that each of the files in it can be accessed.
2953      * See for tsk_fs_dir_open() details.
2954      * @param a_fs File system to analyze
2955      * @param a_dir Path of the directory to open
2956      * @returns 1 on error and 0 on success
2957      */
open(TskFsInfo * a_fs,const char * a_dir)2958     uint8_t open(TskFsInfo * a_fs, const char *a_dir) {
2959         if ((m_fsDir = tsk_fs_dir_open(a_fs->m_fsInfo, a_dir)) != NULL)
2960             return 0;
2961         else
2962             return 1;
2963     };
2964 
2965     /*
2966      * Close the directory that was opened with tsk_fs_dir_open()
2967      * See tsk_fs_dir_close() for details
2968      */
close()2969     void close() {
2970         tsk_fs_dir_close(m_fsDir);
2971     };
2972 
2973     /*
2974      * Returns the number of files and subdirectories in a directory.
2975      * See tsk_fs_dir_getsize() for details
2976      * @returns Number of files and subdirectories (or 0 on error)
2977      */
getSize()2978     size_t getSize() const {
2979         return tsk_fs_dir_getsize(m_fsDir);     //m_fsDir is checked by this C function
2980     };
2981 
2982     /*
2983      * Return a specific file or subdirectory from an open directory.
2984      * It's caller's responsibility to free TskFsFile*
2985      * See tsk_fs_dir_getsize() for details
2986      * @param a_idx Index of file in directory to open (0-based)
2987      * @returns NULL on error
2988      */
getFile(size_t a_idx)2989     TskFsFile *getFile(size_t a_idx) const {
2990         TSK_FS_FILE *fs_file = tsk_fs_dir_get(m_fsDir, a_idx);
2991         if (fs_file != NULL) {
2992              TskFsFile *f = new TskFsFile(fs_file);
2993              f->m_opened = true;
2994              return f;
2995         } else
2996              return NULL;
2997     };
2998 
2999     /*
3000      * Return metadata address of this directory
3001      * @returns metadata address of this directory
3002      */
getMetaAddr()3003     TSK_INUM_T getMetaAddr() const {
3004         if (m_fsDir != NULL)
3005             return m_fsDir->addr;
3006         else
3007             return 0;
3008     };
3009 
3010     /*
3011      * Return pointer to the file structure for the directory.
3012      * @returns NULL on error. it is the caller's responsibility to free this object.
3013      */
getFsFile()3014     const TskFsFile *getFsFile() const {
3015         if (m_fsDir != NULL)
3016             return new TskFsFile(m_fsDir->fs_file);
3017         else
3018             return NULL;
3019     };
3020 
3021   private:
3022 
3023     /*
3024      * Return pointer to file system the directory is located in
3025      * @returns NULL on error
3026      */
getFsInfo()3027     const TSK_FS_INFO *getFsInfo() const {
3028         if (m_fsDir != NULL)
3029             return m_fsDir->fs_info;
3030         else
3031             return NULL;
3032     };
3033 };
3034 
3035 #endif
3036 #endif
3037