Coverage Report

Created: 2025-07-01 06:59

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