1 /*
2 * The Sleuth Kit
3 *
4 * Contact: Brian Carrier [carrier <at> sleuthkit [dot] org]
5 * Copyright (c) 2010-2012 Basis Technology Corporation. All Rights
6 * reserved.
7 *
8 * This software is distributed under the Common Public License 1.0
9 */
10
11 #include "SectorRuns.h"
12 #include "tsk/framework/services/TskServices.h"
13
14 /* This class is used to store a list of sector runs. It is
15 * used to identify which runs contain unallocated data.
16 */
SectorRuns()17 SectorRuns::SectorRuns() :
18 m_runs(NULL),
19 m_numRunsUsed(0),
20 m_numRunsAlloc(0),
21 m_curRun(0)
22 {
23 // @@@
24 // Constructor should query the DB
25 // and build a list of IDs to empty sectors.
26 // The list is what will be iterated over.
27 }
28
~SectorRuns()29 SectorRuns::~SectorRuns()
30 {
31 if (m_runs)
32 free(m_runs);
33 m_runs = NULL;
34 }
35
36
37 /**
38 * Add a run to the list.
39 *
40 * @param a_start Starting sector address relative to start of image file
41 * @param a_len Length of run in sectors.
42 * @param a_vol_id Volume ID that run is located in
43 * @returns -1 on error
44 */
addRun(uint64_t a_start,uint64_t a_len,int a_vol_id)45 int SectorRuns::addRun(uint64_t a_start, uint64_t a_len, int a_vol_id)
46 {
47 if (m_numRunsUsed == m_numRunsAlloc)
48 {
49 m_numRunsAlloc += 64;
50 if ((m_runs = (SectorRun *)realloc(m_runs, m_numRunsAlloc * sizeof(SectorRun))) == NULL)
51 {
52 TskServices::Instance().getLog().logError(L"SectorRuns::addRun - Error allocating sector runs\n");
53 return -1;
54 }
55 }
56 m_runs[m_numRunsUsed].start = a_start;
57 m_runs[m_numRunsUsed].len = a_len;
58 m_runs[m_numRunsUsed].vol_id = a_vol_id;
59 m_numRunsUsed++;
60 return 0;
61 }
62
63 /**
64 * reset so that the next get() returns data on the first entry.
65 */
reset()66 void SectorRuns::reset()
67 {
68 m_curRun = 0;
69 }
70
71 /**
72 * Advances internal pointer to next run.
73 *
74 * @returns -1 when at end of list
75 */
next()76 int SectorRuns::next()
77 {
78 if (m_curRun + 1 == m_numRunsUsed)
79 return -1;
80
81 m_curRun++;
82 return 0;
83 }
84
85 /**
86 * Get the length of the current entry.
87 * @returns length of run in sectors
88 */
getDataLen() const89 uint64_t SectorRuns::getDataLen() const
90 {
91 if (m_curRun >= m_numRunsUsed)
92 return 0;
93 return m_runs[m_curRun].len;
94 }
95
96 /**
97 * Get starting address of current entry.
98 * @returns start of run in sectors
99 */
getDataStart() const100 uint64_t SectorRuns::getDataStart() const
101 {
102 if (m_curRun >= m_numRunsUsed)
103 return 0;
104 return m_runs[m_curRun].start;
105 }
106
107 /**
108 * Get volume id of current entry.
109 * @returns volume ID of run in sectors
110 */
getVolID() const111 int SectorRuns::getVolID() const
112 {
113 if (m_curRun >= m_numRunsUsed)
114 return 0;
115 return m_runs[m_curRun].vol_id;
116 }
117
118 /**
119 * Read data in the current entry into the buffer.
120 *
121 * @param a_offsetSect Sector offset to start reading from (relative to start of current sector run)
122 * @param a_lenSect Number of sectors to read
123 * @param a_buffer Buffer to read into (must be of size a_len * 512 or larger)
124 * @returns -1 on error or number of sectors read
125 */
getData(uint64_t a_offsetSect,int a_lenSect,char * a_buffer) const126 int SectorRuns::getData(uint64_t a_offsetSect, int a_lenSect, char * a_buffer) const
127 {
128 if (m_curRun >= m_numRunsUsed)
129 return -1;
130
131 if (a_offsetSect > m_runs[m_curRun].len)
132 return -1;
133
134 uint64_t len_toread = a_lenSect;
135 if (a_offsetSect + a_lenSect > m_runs[m_curRun].len)
136 len_toread = m_runs[m_curRun].len - a_offsetSect;
137
138 return TskServices::Instance().getImageFile().getSectorData(m_runs[m_curRun].start + a_offsetSect, len_toread, a_buffer);
139 }
140