Coverage Report

Created: 2024-02-25 07:20

/src/libbde/libbde/libbde_io_handle.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Input/Output (IO) handle functions
3
 *
4
 * Copyright (C) 2011-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libbde_definitions.h"
28
#include "libbde_encryption_context.h"
29
#include "libbde_io_handle.h"
30
#include "libbde_libbfio.h"
31
#include "libbde_libcerror.h"
32
#include "libbde_libcnotify.h"
33
#include "libbde_ntfs_volume_header.h"
34
#include "libbde_sector_data.h"
35
#include "libbde_unused.h"
36
37
#include "bde_volume.h"
38
39
/* Creates an IO handle
40
 * Make sure the value io_handle is referencing, is set to NULL
41
 * Returns 1 if successful or -1 on error
42
 */
43
int libbde_io_handle_initialize(
44
     libbde_io_handle_t **io_handle,
45
     libcerror_error_t **error )
46
2.46k
{
47
2.46k
  static char *function = "libbde_io_handle_initialize";
48
49
2.46k
  if( io_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 IO handle.",
56
0
     function );
57
58
0
    return( -1 );
59
0
  }
60
2.46k
  if( *io_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 IO handle value already set.",
67
0
     function );
68
69
0
    return( -1 );
70
0
  }
71
2.46k
  *io_handle = memory_allocate_structure(
72
2.46k
                libbde_io_handle_t );
73
74
2.46k
  if( *io_handle == NULL )
75
0
  {
76
0
    libcerror_error_set(
77
0
     error,
78
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
79
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
80
0
     "%s: unable to create IO handle.",
81
0
     function );
82
83
0
    goto on_error;
84
0
  }
85
2.46k
  if( memory_set(
86
2.46k
       *io_handle,
87
2.46k
       0,
88
2.46k
       sizeof( libbde_io_handle_t ) ) == NULL )
89
0
  {
90
0
    libcerror_error_set(
91
0
     error,
92
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
93
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
94
0
     "%s: unable to clear IO handle.",
95
0
     function );
96
97
0
    goto on_error;
98
0
  }
99
2.46k
  ( *io_handle )->bytes_per_sector = 512;
100
101
2.46k
  return( 1 );
102
103
0
on_error:
104
0
  if( *io_handle != NULL )
105
0
  {
106
0
    memory_free(
107
0
     *io_handle );
108
109
0
    *io_handle = NULL;
110
0
  }
111
0
  return( -1 );
112
2.46k
}
113
114
/* Frees an IO handle
115
 * Returns 1 if successful or -1 on error
116
 */
117
int libbde_io_handle_free(
118
     libbde_io_handle_t **io_handle,
119
     libcerror_error_t **error )
120
2.46k
{
121
2.46k
  static char *function = "libbde_io_handle_free";
122
2.46k
  int result            = 1;
123
124
2.46k
  if( io_handle == NULL )
125
0
  {
126
0
    libcerror_error_set(
127
0
     error,
128
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
129
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
130
0
     "%s: invalid IO handle.",
131
0
     function );
132
133
0
    return( -1 );
134
0
  }
135
2.46k
  if( *io_handle != NULL )
136
2.46k
  {
137
2.46k
    if( libbde_io_handle_clear(
138
2.46k
         *io_handle,
139
2.46k
         error ) != 1 )
140
0
    {
141
0
      libcerror_error_set(
142
0
       error,
143
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
144
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
145
0
       "%s: unable to clear IO handle.",
146
0
       function );
147
148
0
      result = -1;
149
0
    }
150
2.46k
    memory_free(
151
2.46k
     *io_handle );
152
153
2.46k
    *io_handle = NULL;
154
2.46k
  }
155
2.46k
  return( result );
156
2.46k
}
157
158
/* Clears the IO handle
159
 * Returns 1 if successful or -1 on error
160
 */
161
int libbde_io_handle_clear(
162
     libbde_io_handle_t *io_handle,
163
     libcerror_error_t **error )
164
2.81k
{
165
2.81k
  static char *function = "libbde_io_handle_clear";
166
167
2.81k
  if( io_handle == NULL )
168
0
  {
169
0
    libcerror_error_set(
170
0
     error,
171
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
172
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
173
0
     "%s: invalid IO handle.",
174
0
     function );
175
176
0
    return( -1 );
177
0
  }
178
2.81k
  io_handle->bytes_per_sector = 512;
179
180
2.81k
  return( 1 );
181
2.81k
}
182
183
/* Reads the unencrypted volume header
184
 * Returns 1 if successful or -1 on error
185
 */
186
int libbde_io_handle_read_unencrypted_volume_header(
187
     libbde_io_handle_t *io_handle,
188
     libbfio_handle_t *file_io_handle,
189
     off64_t volume_header_offset,
190
     libbde_encryption_context_t *encryption_context,
191
     libcerror_error_t **error )
192
766
{
193
766
  libbde_ntfs_volume_header_t *ntfs_volume_header = NULL;
194
766
  libbde_sector_data_t *sector_data               = NULL;
195
766
  static char *function                           = "libbde_io_handle_read_unencrypted_volume_header";
196
197
766
  if( io_handle == NULL )
198
0
  {
199
0
    libcerror_error_set(
200
0
     error,
201
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
202
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
203
0
     "%s: invalid IO handle.",
204
0
     function );
205
206
0
    goto on_error;
207
0
  }
208
#if defined( HAVE_DEBUG_OUTPUT )
209
  if( libcnotify_verbose != 0 )
210
  {
211
    libcnotify_printf(
212
     "%s: reading unencrypted volume header at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
213
     function,
214
     volume_header_offset,
215
     volume_header_offset );
216
  }
217
#endif
218
766
  if( libbde_sector_data_initialize(
219
766
       &sector_data,
220
766
       io_handle->bytes_per_sector,
221
766
       error ) != 1 )
222
0
  {
223
0
    libcerror_error_set(
224
0
     error,
225
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
226
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
227
0
     "%s: unable to create sector data.",
228
0
     function );
229
230
0
    goto on_error;
231
0
  }
232
766
  if( libbde_sector_data_read_file_io_handle(
233
766
       sector_data,
234
766
       io_handle,
235
766
       file_io_handle,
236
766
       volume_header_offset,
237
766
       encryption_context,
238
766
       0,
239
766
       error ) != 1 )
240
274
  {
241
274
    libcerror_error_set(
242
274
     error,
243
274
     LIBCERROR_ERROR_DOMAIN_IO,
244
274
     LIBCERROR_IO_ERROR_READ_FAILED,
245
274
     "%s: unable to read volume header sector data.",
246
274
     function );
247
248
274
    goto on_error;
249
274
  }
250
492
  if( io_handle->volume_size == 0 )
251
311
  {
252
311
    if( libbde_ntfs_volume_header_initialize(
253
311
         &ntfs_volume_header,
254
311
         error ) != 1 )
255
0
    {
256
0
      libcerror_error_set(
257
0
       error,
258
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
259
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
260
0
       "%s: unable to create NTFS volume header.",
261
0
       function );
262
263
0
      goto on_error;
264
0
    }
265
311
    if( libbde_ntfs_volume_header_read_data(
266
311
         ntfs_volume_header,
267
311
         sector_data->data,
268
311
         sector_data->data_size,
269
311
         error ) != 1 )
270
253
    {
271
253
      libcerror_error_set(
272
253
       error,
273
253
       LIBCERROR_ERROR_DOMAIN_IO,
274
253
       LIBCERROR_IO_ERROR_READ_FAILED,
275
253
       "%s: unable to read NTFS volume header.",
276
253
       function );
277
278
253
      goto on_error;
279
253
    }
280
58
    io_handle->volume_size = ntfs_volume_header->volume_size;
281
282
58
    if( libbde_ntfs_volume_header_free(
283
58
         &ntfs_volume_header,
284
58
         error ) != 1 )
285
0
    {
286
0
      libcerror_error_set(
287
0
       error,
288
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
289
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
290
0
       "%s: unable to free NTFS volume header.",
291
0
       function );
292
293
0
      goto on_error;
294
0
    }
295
58
  }
296
239
  if( libbde_sector_data_free(
297
239
       &sector_data,
298
239
       error ) != 1 )
299
0
  {
300
0
    libcerror_error_set(
301
0
     error,
302
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
303
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
304
0
     "%s: unable to free sector data.",
305
0
     function );
306
307
0
    goto on_error;
308
0
  }
309
239
  return( 1 );
310
311
527
on_error:
312
527
  if( ntfs_volume_header != NULL )
313
253
  {
314
253
    libbde_ntfs_volume_header_free(
315
253
     &ntfs_volume_header,
316
253
     NULL );
317
253
  }
318
527
  if( sector_data != NULL )
319
527
  {
320
527
    libbde_sector_data_free(
321
527
     &sector_data,
322
527
     NULL );
323
527
  }
324
527
  return( -1 );
325
239
}
326