Coverage Report

Created: 2025-07-23 06:45

/src/sleuthkit/tsk/vs/tsk_vs.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-2011 Brian Carrier.  All rights reserved
6
*
7
* This software is distributed under the Common Public License 1.0
8
*
9
*/
10
11
/**
12
* \file tsk_vs.h
13
* External header file for media management (volume system) support.
14
* Note that this file is not meant to be directly included.
15
* It is included by both libtsk.h and tsk_vs_i.h.
16
*/
17
18
/**
19
* \defgroup vslib C Volume System Functions
20
 * \defgroup vslib_cpp C++ Volume System Classes
21
*/
22
#ifndef _TSK_VS_H
23
#define _TSK_VS_H
24
25
#ifdef __cplusplus
26
extern "C" {
27
#endif
28
29
    /* Structures */
30
    typedef struct TSK_VS_INFO TSK_VS_INFO;
31
    typedef struct TSK_VS_PART_INFO TSK_VS_PART_INFO;
32
33
    /**
34
    * Definition for callback function that vs_part_walk() calls for
35
    * each partition that it walks.
36
    *
37
    * @param a_vs Pointer to volume system being analyzed
38
    * @param a_vs_part Pointer to current partition in the walk
39
    * @param a_ptr Pointer that was passed to vs_part_walk by caller
40
    * @return Status on whether the vs_part_walk() function should
41
    * continue, stop, or error.
42
    */
43
    typedef TSK_WALK_RET_ENUM(*TSK_VS_PART_WALK_CB) (TSK_VS_INFO *
44
        a_vs, const TSK_VS_PART_INFO * a_vs_part, void *a_ptr);
45
46
    /**
47
    * Flags for the partition type.
48
    */
49
    typedef enum {
50
        TSK_VS_TYPE_DETECT = 0x0000,    ///< Use autodetection methods
51
        TSK_VS_TYPE_DOS = 0x0001,       ///< DOS Partition table
52
        TSK_VS_TYPE_BSD = 0x0002,       ///< BSD Partition table
53
        TSK_VS_TYPE_SUN = 0x0004,       ///< Sun VTOC
54
        TSK_VS_TYPE_MAC = 0x0008,       ///< Mac partition table
55
        TSK_VS_TYPE_GPT = 0x0010,       ///< GPT partition table
56
        TSK_VS_TYPE_APFS =  0x0020,     ///< APFS
57
        TSK_VS_TYPE_LVM =  0x0030,     ///< LVM
58
        TSK_VS_TYPE_DBFILLER = 0x00F0,  ///< fake partition table type for loaddb (for images that do not have a volume system)
59
        TSK_VS_TYPE_UNSUPP = 0xffff,    ///< Unsupported
60
    } TSK_VS_TYPE_ENUM;
61
62
    /**
63
    * Data structure used to store state and basic information
64
    * for open volume systems.
65
    */
66
    struct TSK_VS_INFO {
67
        int tag;                ///< \internal Will be set to TSK_VS_INFO_TAG if structure is still allocated, 0 if not
68
        TSK_IMG_INFO *img_info; ///< Pointer to disk image that VS is in
69
        TSK_VS_TYPE_ENUM vstype;        ///< Type of volume system / media management
70
        int is_backup;          ///< 1 if the partition table found was a backup
71
        TSK_DADDR_T offset;     ///< Byte offset where VS starts in disk image
72
        unsigned int block_size;        ///< Size of blocks in bytes
73
74
        TSK_ENDIAN_ENUM endian; ///< Endian ordering of data
75
76
        TSK_VS_PART_INFO *part_list;    ///< Linked list of partitions
77
78
        TSK_PNUM_T part_count;  ///< number of partitions
79
80
        void (*close) (TSK_VS_INFO *);  ///< \internal Progs should call tsk_vs_close().
81
    };
82
83
14.0k
#define TSK_VS_INFO_TAG  0x52301642
84
85
86
    /***************************************************************
87
    * Generic structures  for partitions / slices
88
    */
89
90
    /**
91
    * Flag values that describe the partitions in the VS.  Refer
92
    * to \ref vs_open2 for more details.
93
    */
94
    typedef enum {
95
        TSK_VS_PART_FLAG_ALLOC = 0x01,  ///< Sectors are allocated to a volume in the volume system
96
        TSK_VS_PART_FLAG_UNALLOC = 0x02,        ///< Sectors are not allocated to a volume
97
        TSK_VS_PART_FLAG_META = 0x04,   ///< Sectors contain volume system metadata and could also be ALLOC or UNALLOC
98
        TSK_VS_PART_FLAG_ALL = 0x07,    ///< Show all sectors in the walk.
99
    } TSK_VS_PART_FLAG_ENUM;
100
101
    /**
102
    * Linked list entry that describes a volume in a generic way.
103
    */
104
    struct TSK_VS_PART_INFO {
105
        int tag;
106
        TSK_VS_PART_INFO *prev; ///< Pointer to previous partition (or NULL)
107
        TSK_VS_PART_INFO *next; ///< Pointer to next partition (or NULL)
108
        TSK_VS_INFO *vs;        ///< Pointer to parent volume system handle
109
110
        TSK_DADDR_T start;      ///< Sector offset of start of partition
111
        TSK_DADDR_T len;        ///< Number of sectors in partition
112
        char *desc;             ///< UTF-8 description of partition (volume system type-specific)
113
        int8_t table_num;       ///< Table address that describes this partition
114
        int16_t slot_num;        ///< Entry in the table that describes this partition
115
        TSK_PNUM_T addr;        ///< Address of this partition
116
        TSK_VS_PART_FLAG_ENUM flags;    ///< Flags for partition
117
    };
118
119
1.58M
#define TSK_VS_PART_INFO_TAG  0x40121253
120
121
    // to and from type ids and names
122
    extern TSK_VS_TYPE_ENUM tsk_vs_type_toid(const TSK_TCHAR *);
123
    extern TSK_VS_TYPE_ENUM tsk_vs_type_toid_utf8(const char *);
124
    extern const char *tsk_vs_type_toname(TSK_VS_TYPE_ENUM);
125
    extern const char *tsk_vs_type_todesc(TSK_VS_TYPE_ENUM);
126
    extern TSK_VS_TYPE_ENUM tsk_vs_type_supported();
127
    extern void tsk_vs_type_print(FILE *);
128
129
    // open a volume system
130
    extern TSK_VS_INFO *tsk_vs_open(TSK_IMG_INFO *, TSK_DADDR_T,
131
        TSK_VS_TYPE_ENUM);
132
    extern void tsk_vs_close(TSK_VS_INFO *);
133
134
    // read data in the volume system
135
    extern ssize_t tsk_vs_read_block(TSK_VS_INFO * a_vs,
136
        TSK_DADDR_T a_addr, char *buf, size_t len);
137
138
    // open a partition
139
    extern const TSK_VS_PART_INFO *tsk_vs_part_get(const TSK_VS_INFO *,
140
        TSK_PNUM_T idx);
141
    extern uint8_t tsk_vs_part_walk(TSK_VS_INFO * vs, TSK_PNUM_T start,
142
        TSK_PNUM_T last, TSK_VS_PART_FLAG_ENUM flags,
143
        TSK_VS_PART_WALK_CB action, void *ptr);
144
145
    // read data in partitions
146
    extern ssize_t tsk_vs_part_read(const TSK_VS_PART_INFO *
147
        a_vs_part, TSK_OFF_T a_off, char *buf, size_t len);
148
    extern ssize_t tsk_vs_part_read_block(const TSK_VS_PART_INFO *
149
        a_vs_part, TSK_DADDR_T a_addr, char *buf, size_t len);
150
151
#ifdef __cplusplus
152
}
153
#endif
154
#ifdef __cplusplus
155
class TskVsInfo;
156
class TskVsPartInfo;
157
158
/**
159
* Definition for callback function that vs_part_walk() calls for
160
* each partition that it walks.
161
*
162
* @param a_vs Pointer to volume system being analyzed
163
* @param a_vs_part Pointer to current partition in the walk
164
* @param a_ptr Pointer that was passed to vs_part_walk by caller
165
* @return Status on whether the vs_part_walk() function should
166
* continue, stop, or error.
167
*/
168
typedef TSK_WALK_RET_ENUM(*TSK_VS_PART_WALK_CPP_CB) (TskVsInfo *
169
    a_vs, const TskVsPartInfo * a_vs_part, void *a_ptr);
170
/** \internal
171
* Internal structure to pass C++ volume system part walk data into C block walk call back.
172
*/
173
typedef struct {
174
    TSK_VS_PART_WALK_CPP_CB cppAction;  // pointer C++ callback
175
    void *cPtr;                 // pointer to data that was passed into C++ walk method
176
} TSK_VS_PART_WALK_CPP_DATA;
177
178
/** \internal
179
* Internal function used to call C++ Block Walk callback from C callback.
180
*/
181
extern TSK_WALK_RET_ENUM tsk_vs_part_walk_cpp_c_cb(TSK_VS_INFO * a_vs,
182
    const TSK_VS_PART_INFO * a_vs_part, void *a_ptr);
183
184
/**
185
 * \ingroup vslib_cpp
186
* Stores information about a volume / partition inside of an open volume
187
* system.
188
*/
189
class TskVsPartInfo {
190
    friend class TskFsInfo;
191
192
  private:
193
     TSK_VS_PART_INFO * m_vsPartInfo;
194
     TskVsPartInfo(const TskVsPartInfo & rhs);
195
     TskVsPartInfo & operator=(const TskVsPartInfo & rhs);
196
197
  public:
198
199
    /**
200
     * Create an object from its C struct.
201
     * @param a_vsPartInfo Pointer to C struct for partition.  If NULL, the
202
     * remaining getX() methods will be undefined.
203
     */
204
0
     TskVsPartInfo(TSK_VS_PART_INFO * a_vsPartInfo) {
205
0
        m_vsPartInfo = a_vsPartInfo;
206
0
    };
207
208
    /**
209
    * Reads data starting at a byte address relative to the start of a VOLUME in a volume system.
210
    * See tsk_vs_part_read() for details.
211
    * @param a_off Byte offset to read from, relative to start of VOLUME in volume system.
212
    * @param a_buf Buffer to store data in
213
    * @param a_len Amount of data to read (in bytes)
214
    * @return Number of bytes read or -1 on error
215
    */
216
0
    ssize_t read(TSK_OFF_T a_off, char *a_buf, size_t a_len) {
217
0
        if (m_vsPartInfo != NULL)
218
0
            return tsk_vs_part_read(m_vsPartInfo, a_off, a_buf, a_len);
219
0
        else
220
0
            return 0;
221
0
    };
222
223
    /**
224
    * Reads one or more blocks of data with an address relative to the start of a VOLUME in a volume system.
225
    * See tsk_vs_part_read_block() for details.
226
    * @param a_addr Block address to start reading from, relative to start of VOLUME in volume system.
227
    * @param a_buf Buffer to store data in
228
    * @param a_len Amount of data to read (in bytes - must be a multiple of block_size)
229
    * @return Number of bytes read or -1 on error
230
    */
231
0
    ssize_t readBlock(TSK_DADDR_T a_addr, char *a_buf, size_t a_len) {
232
0
        if (m_vsPartInfo != NULL)
233
0
            return tsk_vs_part_read_block(m_vsPartInfo, a_addr, a_buf,
234
0
                a_len);
235
0
        else
236
0
            return 0;
237
0
    };
238
239
    /**
240
    * Return sector offset of start of partition
241
    * @return sector offset of start of partition
242
    */
243
0
    TSK_DADDR_T getStart() const {
244
0
        if (m_vsPartInfo != NULL)
245
0
            return m_vsPartInfo->start;
246
0
        else
247
0
            return 0;
248
0
    };
249
250
    /**
251
    * Return number of sectors in partition
252
    * @return number of sectors in partition
253
    */
254
0
    TSK_DADDR_T getLen() const {
255
0
        if (m_vsPartInfo != NULL)
256
0
            return m_vsPartInfo->len;
257
0
        else
258
0
            return 0;
259
0
    };
260
261
    /**
262
    * Return UTF-8 description of partition (volume system type-specific)
263
    * @return description of partition
264
    */
265
0
    const char *getDesc() const {
266
0
        if (m_vsPartInfo != NULL)
267
0
            return m_vsPartInfo->desc;
268
0
        else
269
0
            return NULL;
270
0
    };
271
272
    /**
273
    * Return table address that describes this partition
274
    * @return table address that describes this partition
275
    */
276
0
    int8_t getTableNum() const {
277
0
        if (m_vsPartInfo != NULL)
278
0
            return m_vsPartInfo->table_num;
279
0
        else
280
0
            return 0;
281
0
    };
282
283
    /**
284
    * Return entry in the table that describes this partition
285
    * @return entry in the table that describes this partition
286
    */
287
0
    int16_t getSlotNum() const {
288
0
        if (m_vsPartInfo != NULL)
289
0
            return m_vsPartInfo->slot_num;
290
0
        else
291
0
            return 0;
292
0
    };
293
294
    /**
295
    * Return address of this partition
296
    * @return address of this partition
297
    */
298
0
    TSK_PNUM_T getAddr() const {
299
0
        if (m_vsPartInfo != NULL)
300
0
            return m_vsPartInfo->addr;
301
0
        else
302
0
            return 0;
303
0
    };
304
305
    /**
306
    * Return flags for partition
307
    * @return flags for partition
308
    */
309
0
    TSK_VS_PART_FLAG_ENUM getFlags() const {
310
0
        if (m_vsPartInfo != NULL)
311
0
            return m_vsPartInfo->flags;
312
0
        else
313
0
            return (TSK_VS_PART_FLAG_ENUM) 0;
314
0
    };
315
};
316
317
318
/**
319
 * \ingroup vslib_cpp
320
* Stores information about an open volume system.
321
* To use this object, open() should be called first.
322
*/
323
class TskVsInfo {
324
  private:
325
    TSK_VS_INFO * m_vsInfo;
326
    bool m_opened;              // true if open() was called and we need to free it
327
     TskVsInfo(const TskVsInfo & rhs);
328
     TskVsInfo & operator=(const TskVsInfo & rhs);
329
330
  public:
331
0
     TskVsInfo(TSK_VS_INFO * a_vsInfo) {
332
0
        m_vsInfo = a_vsInfo;
333
0
        m_opened = false;
334
0
    };
335
336
0
    TskVsInfo() {
337
0
        m_vsInfo = NULL;
338
0
        m_opened = false;
339
0
    };
340
341
0
    ~TskVsInfo() {
342
0
        close();
343
0
    };
344
345
    /**
346
    * Walk a range of partitions and pass the data to a callback function.
347
    * See tsk_vs_part_walk() for details.
348
    * @param a_start Address of first partition to walk from.
349
    * @param a_last Address of last partition to walk to.
350
    * @param a_flags Flags that are used to identify which of the partitions in the range should be returned (if 0, all partitions will be returned).
351
    * @param a_action Callback action to call for each partition.
352
    * @param a_ptr Pointer to data that will be passed to callback.
353
    * @return 1 on error and 0 on success
354
    */
355
    uint8_t vsPartWalk(TSK_PNUM_T a_start, TSK_PNUM_T a_last,
356
        TSK_VS_PART_FLAG_ENUM a_flags, TSK_VS_PART_WALK_CPP_CB a_action,
357
0
        void *a_ptr) {
358
0
        TSK_VS_PART_WALK_CPP_DATA vsPartData;
359
0
        vsPartData.cppAction = a_action;
360
0
        vsPartData.cPtr = a_ptr;
361
0
        return tsk_vs_part_walk(m_vsInfo, a_start, a_last,
362
0
            a_flags, tsk_vs_part_walk_cpp_c_cb, &vsPartData);
363
0
    };
364
365
    /**
366
    * Open a disk image and process the media management system
367
    * data. See tsk_vs_open() for details.
368
    *
369
    * @param a_imgInfo The opened disk image.
370
    * @param a_offset Byte offset in the disk image to start analyzing from.
371
    * @param a_type Type of volume system (including auto detect)
372
    *
373
    * @return 1 on error and 0 on success.
374
    */
375
    uint8_t open(TskImgInfo * a_imgInfo, TSK_DADDR_T a_offset,
376
0
        TSK_VS_TYPE_ENUM a_type) {
377
0
        if ((m_vsInfo =
378
0
                tsk_vs_open(a_imgInfo->m_imgInfo, a_offset,
379
0
                    a_type)) != NULL) {
380
0
            m_opened = true;
381
0
            return 0;
382
0
        }
383
0
        else {
384
0
            return 1;
385
0
        }
386
0
    };
387
388
    /**
389
    * Reads one or more blocks of data with an address relative to the start of the volume system.
390
    * See tsk_vs_read_block() for details.
391
    * @param a_addr Sector address to read from, relative to start of VOLUME SYSTEM.
392
    * @param a_buf Buffer to store data in
393
    * @param a_len Amount of data to read (in bytes - must be a multiple of block_size)
394
    * @return Number of bytes read or -1 on error
395
    */
396
0
    ssize_t readBlock(TSK_DADDR_T a_addr, char *a_buf, size_t a_len) {
397
0
        if (m_vsInfo != NULL)
398
0
            return tsk_vs_read_block(m_vsInfo, a_addr, a_buf, a_len);
399
0
        else
400
0
            return 0;
401
0
    };
402
403
    /**
404
    * Closes an open volume system. See for tsk_vs_close() details.
405
    */
406
0
    void close() {
407
0
        if ((m_vsInfo) && (m_opened))
408
0
            tsk_vs_close(m_vsInfo);
409
0
        m_vsInfo = NULL;
410
0
    };
411
412
    /**
413
    * Return the byte offset where volume system starts in disk image
414
    * @return byte offset
415
    */
416
0
    TSK_DADDR_T getOffset() const {
417
0
        if (m_vsInfo != NULL)
418
0
            return m_vsInfo->offset;
419
0
        else
420
0
            return 0;
421
0
    };
422
423
    /**
424
    * Return size of volume system blocks in bytes
425
    * @return size of a block in bytes
426
    */
427
0
    unsigned int getBlockSize() const {
428
0
        if (m_vsInfo != NULL)
429
0
            return m_vsInfo->block_size;
430
0
        else
431
0
            return 0;
432
0
    };
433
434
    /**
435
    * Return number of partitions
436
    * @return number of partitions
437
    */
438
0
    TSK_PNUM_T getPartCount() const {
439
0
        if (m_vsInfo != NULL)
440
0
            return m_vsInfo->part_count;
441
0
        else
442
0
            return 0;
443
0
    };
444
445
    /**
446
    * Get reference to a volume in the volume system.
447
    * See tsk_vs_part_get() for details.
448
    * @param a_idx Index for volume to return (0-based)
449
    * @return Pointer to partition or NULL on error.  Caller is responsible for freeing object.
450
    */
451
0
    const TskVsPartInfo *getPart(TSK_PNUM_T a_idx) const {
452
0
        // @@@ Error handling.
453
0
        return new TskVsPartInfo(const_cast <
454
0
            TSK_VS_PART_INFO * >(tsk_vs_part_get(m_vsInfo, a_idx)));
455
0
    };
456
457
    /**
458
    * Get a reference to the parent image object.
459
    * @return Pointer to object or NULL on error.  Caller is responsible for freeing object.
460
    */
461
0
    const TskImgInfo *getImgInfo() const {
462
0
        if (m_vsInfo == NULL)
463
0
            return 0;
464
0
        return new TskImgInfo(m_vsInfo->img_info);
465
0
    };
466
467
    /**
468
    * Return type of volume system / media management
469
    * @return type of volume system / media management
470
    */
471
0
    TSK_VS_TYPE_ENUM getVsType() const {
472
0
        if (m_vsInfo != NULL)
473
0
            return m_vsInfo->vstype;
474
0
        else
475
0
            return (TSK_VS_TYPE_ENUM) 0;
476
0
    };
477
478
    /**
479
     * Parse a string with the volume system type and return its internal ID.
480
     * See tsk_vs_type_toid() for details.
481
     * @param a_str String to parse.
482
     * @return ID of string (or unsupported if the name is unknown)
483
     */
484
0
    static TSK_VS_TYPE_ENUM typeToId(const TSK_TCHAR * a_str) {
485
0
        return tsk_vs_type_toid(a_str);
486
0
    };
487
    /**
488
     * Print the supported volume system type names to an open handle.
489
     * See tsk_vs_type_print() for details.
490
     * @param a_hFile Handle to print to.
491
     */
492
0
    static void typePrint(FILE * a_hFile) {
493
0
        tsk_vs_type_print(a_hFile);
494
0
    };
495
496
    /**
497
     * Return the supported volume system types.
498
     * See tsk_vs_type_supported() for details.
499
     * @return The bit in the return value is 1 if the type is supported.
500
     */
501
0
    static TSK_VS_TYPE_ENUM typeSupported() {
502
0
        return tsk_vs_type_supported();
503
0
    };
504
505
    /**
506
     * Return the string name of a partition type ID.
507
     * See tsk_vs_type_toname() for details.
508
     * @param a_type Volume system type
509
     * @return name of type or NULL on error
510
     */
511
0
    static const char *typeToName(TSK_VS_TYPE_ENUM a_type) {
512
0
        return tsk_vs_type_toname(a_type);
513
0
    };
514
515
    /**
516
     * Return the string description of a partition type ID.
517
     * See tsk_vs_type_todesc() for details.
518
     * @param a_type Volume system type
519
     * @return description of type or NULL on error
520
     */
521
0
    static const char *typeToDesc(TSK_VS_TYPE_ENUM a_type) {
522
0
        return tsk_vs_type_todesc(a_type);
523
0
    };
524
};
525
526
#endif
527
#endif