Coverage Report

Created: 2024-02-25 07:20

/src/libfvde/libfvde/libfvde_volume_data_handle.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Volume data handle functions
3
 *
4
 * Copyright (C) 2011-2024, Omar Choudary <choudary.omar@gmail.com>
5
 *                          Joachim Metz <joachim.metz@gmail.com>
6
 *
7
 * Refer to AUTHORS for acknowledgements.
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
#include <common.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libfvde_definitions.h"
28
#include "libfvde_encryption_context.h"
29
#include "libfvde_io_handle.h"
30
#include "libfvde_libbfio.h"
31
#include "libfvde_libcerror.h"
32
#include "libfvde_libfdata.h"
33
#include "libfvde_sector_data.h"
34
#include "libfvde_volume_data_handle.h"
35
#include "libfvde_unused.h"
36
37
/* Creates volume data handle
38
 * Make sure the value volume_data_handle is referencing, is set to NULL
39
 * Returns 1 if successful or -1 on error
40
 */
41
int libfvde_volume_data_handle_initialize(
42
     libfvde_volume_data_handle_t **volume_data_handle,
43
     libfvde_io_handle_t *io_handle,
44
     off64_t logical_volume_offset,
45
     libcerror_error_t **error )
46
0
{
47
0
  static char *function = "libfvde_volume_data_handle_initialize";
48
49
0
  if( volume_data_handle == NULL )
50
0
  {
51
0
    libcerror_error_set(
52
0
     error,
53
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
54
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
55
0
     "%s: invalid volume data handle.",
56
0
     function );
57
58
0
    return( -1 );
59
0
  }
60
0
  if( *volume_data_handle != NULL )
61
0
  {
62
0
    libcerror_error_set(
63
0
     error,
64
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
65
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
66
0
     "%s: invalid volume data handle value already set.",
67
0
     function );
68
69
0
    return( -1 );
70
0
  }
71
0
  if( io_handle == NULL )
72
0
  {
73
0
    libcerror_error_set(
74
0
     error,
75
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
76
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
77
0
     "%s: invalid IO handle.",
78
0
     function );
79
80
0
    return( -1 );
81
0
  }
82
0
  *volume_data_handle = memory_allocate_structure(
83
0
                         libfvde_volume_data_handle_t );
84
85
0
  if( *volume_data_handle == NULL )
86
0
  {
87
0
    libcerror_error_set(
88
0
     error,
89
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
90
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
91
0
     "%s: unable to volume data handle.",
92
0
     function );
93
94
0
    goto on_error;
95
0
  }
96
0
  if( memory_set(
97
0
       *volume_data_handle,
98
0
       0,
99
0
       sizeof( libfvde_volume_data_handle_t ) ) == NULL )
100
0
  {
101
0
    libcerror_error_set(
102
0
     error,
103
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
104
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
105
0
     "%s: unable to clear volume data handle.",
106
0
     function );
107
108
0
    memory_free(
109
0
     *volume_data_handle );
110
111
0
    *volume_data_handle = NULL;
112
113
0
    return( -1 );
114
0
  }
115
0
  ( *volume_data_handle )->io_handle             = io_handle;
116
0
  ( *volume_data_handle )->logical_volume_offset = logical_volume_offset;
117
118
0
  return( 1 );
119
120
0
on_error:
121
0
  if( *volume_data_handle != NULL )
122
0
  {
123
0
    memory_free(
124
0
     *volume_data_handle );
125
126
0
    *volume_data_handle = NULL;
127
0
  }
128
0
  return( -1 );
129
0
}
130
131
/* Frees volume data handle
132
 * Returns 1 if successful or -1 on error
133
 */
134
int libfvde_volume_data_handle_free(
135
     libfvde_volume_data_handle_t **volume_data_handle,
136
     libcerror_error_t **error )
137
0
{
138
0
  static char *function = "libfvde_volume_data_handle_free";
139
0
  int result            = 1;
140
141
0
  if( volume_data_handle == NULL )
142
0
  {
143
0
    libcerror_error_set(
144
0
     error,
145
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
146
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
147
0
     "%s: invalid volume data handle.",
148
0
     function );
149
150
0
    return( -1 );
151
0
  }
152
0
  if( *volume_data_handle != NULL )
153
0
  {
154
0
    if( ( *volume_data_handle )->encryption_context != NULL )
155
0
    {
156
0
      if( libfvde_encryption_context_free(
157
0
           &( ( *volume_data_handle )->encryption_context ),
158
0
           error ) != 1 )
159
0
      {
160
0
        libcerror_error_set(
161
0
         error,
162
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
163
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
164
0
         "%s: unable to free encryption context.",
165
0
         function );
166
167
0
        result = -1;
168
0
      }
169
0
    }
170
0
    memory_free(
171
0
     *volume_data_handle );
172
173
0
    *volume_data_handle = NULL;
174
0
  }
175
0
  return( result );
176
0
}
177
178
/* Reads a sector
179
 * Callback function for the volume vector
180
 * Returns 1 if successful or -1 on error
181
 */
182
int libfvde_volume_data_handle_read_sector(
183
     libfvde_volume_data_handle_t *volume_data_handle,
184
     libbfio_pool_t *file_io_pool,
185
     libfdata_vector_t *vector,
186
     libfdata_cache_t *cache,
187
     int element_index,
188
     int element_data_file_index,
189
     off64_t element_data_offset,
190
     size64_t element_data_size LIBFVDE_ATTRIBUTE_UNUSED,
191
     uint32_t element_data_flags,
192
     uint8_t read_flags LIBFVDE_ATTRIBUTE_UNUSED,
193
     libcerror_error_t **error )
194
0
{
195
0
  libfvde_sector_data_t *sector_data = NULL;
196
0
  static char *function              = "libfvde_volume_data_handle_read_sector";
197
198
0
  LIBFVDE_UNREFERENCED_PARAMETER( element_data_size );
199
0
  LIBFVDE_UNREFERENCED_PARAMETER( read_flags );
200
201
0
  if( volume_data_handle == NULL )
202
0
  {
203
0
    libcerror_error_set(
204
0
     error,
205
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
206
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
207
0
     "%s: invalid volume data handle.",
208
0
     function );
209
210
0
    return( -1 );
211
0
  }
212
0
  if( volume_data_handle->io_handle == NULL )
213
0
  {
214
0
    libcerror_error_set(
215
0
     error,
216
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
217
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
218
0
     "%s: invalid volume data handle - missing IO handle.",
219
0
     function );
220
221
0
    return( -1 );
222
0
  }
223
0
  if( libfvde_sector_data_initialize(
224
0
       &sector_data,
225
0
       (size_t) volume_data_handle->io_handle->bytes_per_sector,
226
0
       error ) != 1 )
227
0
  {
228
0
    libcerror_error_set(
229
0
     error,
230
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
231
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
232
0
     "%s: unable to create sector data.",
233
0
     function );
234
235
0
    goto on_error;
236
0
  }
237
0
  if( ( element_data_flags & LIBFVDE_RANGE_FLAG_IS_SPARSE ) != 0 )
238
0
  {
239
0
    if( memory_set(
240
0
         sector_data->data,
241
0
         0,
242
0
         sector_data->data_size ) == NULL )
243
0
    {
244
0
      libcerror_error_set(
245
0
       error,
246
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
247
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
248
0
       "%s: unable to clear sector data.",
249
0
       function );
250
251
0
      goto on_error;
252
0
    }
253
0
  }
254
0
  else
255
0
  {
256
0
    if( libfvde_sector_data_read(
257
0
         sector_data,
258
0
         volume_data_handle->encryption_context,
259
0
         file_io_pool,
260
0
         element_data_file_index,
261
0
         element_data_offset,
262
0
         (uint64_t) element_index,
263
0
         volume_data_handle->is_encrypted,
264
0
         error ) != 1 )
265
0
    {
266
0
      libcerror_error_set(
267
0
       error,
268
0
       LIBCERROR_ERROR_DOMAIN_IO,
269
0
       LIBCERROR_IO_ERROR_READ_FAILED,
270
0
       "%s: unable to read sector data.",
271
0
       function );
272
273
0
      goto on_error;
274
0
    }
275
0
  }
276
0
  if( libfdata_vector_set_element_value_by_index(
277
0
       vector,
278
0
       (intptr_t *) file_io_pool,
279
0
       cache,
280
0
       element_index,
281
0
       (intptr_t *) sector_data,
282
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfvde_sector_data_free,
283
0
       LIBFDATA_LIST_ELEMENT_VALUE_FLAG_MANAGED,
284
0
       error ) != 1 )
285
0
  {
286
0
    libcerror_error_set(
287
0
     error,
288
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
289
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
290
0
     "%s: unable to set sector data as element value.",
291
0
     function );
292
293
0
    goto on_error;
294
0
  }
295
0
  return( 1 );
296
297
0
on_error:
298
0
  if( sector_data != NULL )
299
0
  {
300
0
    libfvde_sector_data_free(
301
0
     &sector_data,
302
0
     NULL );
303
0
  }
304
0
  return( -1 );
305
0
}
306