Coverage Report

Created: 2024-06-12 07:07

/src/libscca/libscca/libscca_volume_information.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Volume information 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 <memory.h>
24
#include <types.h>
25
26
#include "libscca_definitions.h"
27
#include "libscca_libcerror.h"
28
#include "libscca_libfvalue.h"
29
#include "libscca_libuna.h"
30
#include "libscca_volume_information.h"
31
32
/* Creates volume information
33
 * Make sure the value volume_information is referencing, is set to NULL
34
 * Returns 1 if successful or -1 on error
35
 */
36
int libscca_volume_information_initialize(
37
     libscca_volume_information_t **volume_information,
38
     libcerror_error_t **error )
39
3.75k
{
40
3.75k
  libscca_internal_volume_information_t *internal_volume_information = NULL;
41
3.75k
  static char *function                                              = "libscca_volume_information_initialize";
42
43
3.75k
  if( volume_information == NULL )
44
0
  {
45
0
    libcerror_error_set(
46
0
     error,
47
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
48
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
49
0
     "%s: invalid volume information.",
50
0
     function );
51
52
0
    return( -1 );
53
0
  }
54
3.75k
  if( *volume_information != NULL )
55
0
  {
56
0
    libcerror_error_set(
57
0
     error,
58
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
59
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
60
0
     "%s: invalid volume information value already set.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
3.75k
  internal_volume_information = memory_allocate_structure(
66
3.75k
                                 libscca_internal_volume_information_t );
67
68
3.75k
  if( internal_volume_information == NULL )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
73
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
74
0
     "%s: unable to create volume information.",
75
0
     function );
76
77
0
    goto on_error;
78
0
  }
79
3.75k
  if( memory_set(
80
3.75k
       internal_volume_information,
81
3.75k
       0,
82
3.75k
       sizeof( libscca_internal_volume_information_t ) ) == NULL )
83
0
  {
84
0
    libcerror_error_set(
85
0
     error,
86
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
87
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
88
0
     "%s: unable to clear volume information.",
89
0
     function );
90
91
0
    goto on_error;
92
0
  }
93
3.75k
  *volume_information = (libscca_volume_information_t *) internal_volume_information;
94
95
3.75k
  return( 1 );
96
97
0
on_error:
98
0
  if( internal_volume_information != NULL )
99
0
  {
100
0
    memory_free(
101
0
     internal_volume_information );
102
0
  }
103
0
  return( -1 );
104
3.75k
}
105
106
/* Frees volume information
107
 * Returns 1 if successful or -1 on error
108
 */
109
int libscca_volume_information_free(
110
     libscca_volume_information_t **volume_information,
111
     libcerror_error_t **error )
112
0
{
113
0
  static char *function = "libscca_volume_information_free";
114
115
0
  if( volume_information == NULL )
116
0
  {
117
0
    libcerror_error_set(
118
0
     error,
119
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
120
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
121
0
     "%s: invalid volume information.",
122
0
     function );
123
124
0
    return( -1 );
125
0
  }
126
0
  if( *volume_information != NULL )
127
0
  {
128
0
    *volume_information = NULL;
129
0
  }
130
0
  return( 1 );
131
0
}
132
133
/* Frees volume information
134
 * Returns 1 if successful or -1 on error
135
 */
136
int libscca_internal_volume_information_free(
137
     libscca_internal_volume_information_t **internal_volume_information,
138
     libcerror_error_t **error )
139
3.75k
{
140
3.75k
  static char *function = "libscca_internal_volume_information_free";
141
3.75k
  int result            = 1;
142
143
3.75k
  if( internal_volume_information == NULL )
144
0
  {
145
0
    libcerror_error_set(
146
0
     error,
147
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
148
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
149
0
     "%s: invalid volume information.",
150
0
     function );
151
152
0
    return( -1 );
153
0
  }
154
3.75k
  if( *internal_volume_information != NULL )
155
3.75k
  {
156
3.75k
    if( ( *internal_volume_information )->device_path != NULL )
157
71
    {
158
71
      memory_free(
159
71
       ( *internal_volume_information )->device_path );
160
71
    }
161
3.75k
    if( ( *internal_volume_information )->directory_strings != NULL )
162
410
    {
163
410
      if( libfvalue_value_free(
164
410
           &( ( *internal_volume_information )->directory_strings ),
165
410
           error ) != 1 )
166
0
      {
167
0
        libcerror_error_set(
168
0
         error,
169
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
170
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
171
0
         "%s: unable to free directory strings.",
172
0
         function );
173
174
0
        result = -1;
175
0
      }
176
410
    }
177
3.75k
    memory_free(
178
3.75k
     ( *internal_volume_information ) );
179
180
3.75k
    *internal_volume_information = NULL;
181
3.75k
  }
182
3.75k
  return( result );
183
3.75k
}
184
185
/* Retrieves the 64-bit FILETIME value containing the volume creation date and time
186
 * Returns 1 if successful or -1 on error
187
 */
188
int libscca_volume_information_get_creation_time(
189
     libscca_volume_information_t *volume_information,
190
     uint64_t *filetime,
191
     libcerror_error_t **error )
192
0
{
193
0
  libscca_internal_volume_information_t *internal_volume_information = NULL;
194
0
  static char *function                                              = "libscca_volume_information_get_creation_time";
195
196
0
  if( volume_information == NULL )
197
0
  {
198
0
    libcerror_error_set(
199
0
     error,
200
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
201
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
202
0
     "%s: invalid volume information.",
203
0
     function );
204
205
0
    return( -1 );
206
0
  }
207
0
  internal_volume_information = (libscca_internal_volume_information_t *) volume_information;
208
209
0
  if( filetime == NULL )
210
0
  {
211
0
    libcerror_error_set(
212
0
     error,
213
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
214
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
215
0
     "%s: invalid filetime.",
216
0
     function );
217
218
0
    return( -1 );
219
0
  }
220
0
  *filetime = internal_volume_information->creation_time;
221
222
0
  return( 1 );
223
0
}
224
225
/* Retrieves the serial number
226
 * Returns 1 if successful or -1 on error
227
 */
228
int libscca_volume_information_get_serial_number(
229
     libscca_volume_information_t *volume_information,
230
     uint32_t *serial_number,
231
     libcerror_error_t **error )
232
0
{
233
0
  libscca_internal_volume_information_t *internal_volume_information = NULL;
234
0
  static char *function                                              = "libscca_volume_information_get_serial_number";
235
236
0
  if( volume_information == NULL )
237
0
  {
238
0
    libcerror_error_set(
239
0
     error,
240
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
241
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
242
0
     "%s: invalid volume information.",
243
0
     function );
244
245
0
    return( -1 );
246
0
  }
247
0
  internal_volume_information = (libscca_internal_volume_information_t *) volume_information;
248
249
0
  if( serial_number == NULL )
250
0
  {
251
0
    libcerror_error_set(
252
0
     error,
253
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
254
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
255
0
     "%s: invalid serial number.",
256
0
     function );
257
258
0
    return( -1 );
259
0
  }
260
0
  *serial_number = internal_volume_information->serial_number;
261
262
0
  return( 1 );
263
0
}
264
265
/* Retrieves the size of the UTF-8 encoded device path
266
 * The returned size includes the end of string character
267
 * Returns 1 if successful or -1 on error
268
 */
269
int libscca_volume_information_get_utf8_device_path_size(
270
     libscca_volume_information_t *volume_information,
271
     size_t *utf8_string_size,
272
     libcerror_error_t **error )
273
0
{
274
0
  libscca_internal_volume_information_t *internal_volume_information = NULL;
275
0
  static char *function                                              = "libscca_volume_information_get_utf8_device_path_size";
276
277
0
  if( volume_information == NULL )
278
0
  {
279
0
    libcerror_error_set(
280
0
     error,
281
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
282
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
283
0
     "%s: invalid volume information.",
284
0
     function );
285
286
0
    return( -1 );
287
0
  }
288
0
  internal_volume_information = (libscca_internal_volume_information_t *) volume_information;
289
290
0
  if( libuna_utf8_string_size_from_utf16_stream(
291
0
       internal_volume_information->device_path,
292
0
       internal_volume_information->device_path_size,
293
0
       LIBUNA_ENDIAN_LITTLE,
294
0
       utf8_string_size,
295
0
       error ) != 1 )
296
0
  {
297
0
    libcerror_error_set(
298
0
     error,
299
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
300
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
301
0
     "%s: unable to retrieve device path UTF-8 string size.",
302
0
     function );
303
304
0
    return( -1 );
305
0
  }
306
0
  return( 1 );
307
0
}
308
309
/* Retrieves the UTF-8 encoded device path
310
 * The size should include the end of string character
311
 * Returns 1 if successful or -1 on error
312
 */
313
int libscca_volume_information_get_utf8_device_path(
314
     libscca_volume_information_t *volume_information,
315
     uint8_t *utf8_string,
316
     size_t utf8_string_size,
317
     libcerror_error_t **error )
318
0
{
319
0
  libscca_internal_volume_information_t *internal_volume_information = NULL;
320
0
  static char *function                                              = "libscca_volume_information_get_utf8_device_path";
321
322
0
  if( volume_information == NULL )
323
0
  {
324
0
    libcerror_error_set(
325
0
     error,
326
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
327
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
328
0
     "%s: invalid volume information.",
329
0
     function );
330
331
0
    return( -1 );
332
0
  }
333
0
  internal_volume_information = (libscca_internal_volume_information_t *) volume_information;
334
335
0
  if( libuna_utf8_string_copy_from_utf16_stream(
336
0
       utf8_string,
337
0
       utf8_string_size,
338
0
       internal_volume_information->device_path,
339
0
       internal_volume_information->device_path_size,
340
0
       LIBUNA_ENDIAN_LITTLE,
341
0
       error ) != 1 )
342
0
  {
343
0
    libcerror_error_set(
344
0
     error,
345
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
346
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
347
0
     "%s: unable to copy device path to UTF-8 string.",
348
0
     function );
349
350
0
    return( -1 );
351
0
  }
352
0
  return( 1 );
353
0
}
354
355
/* Retrieves the size of the UTF-16 encoded device path
356
 * The returned size includes the end of string character
357
 * Returns 1 if successful or -1 on error
358
 */
359
int libscca_volume_information_get_utf16_device_path_size(
360
     libscca_volume_information_t *volume_information,
361
     size_t *utf16_string_size,
362
     libcerror_error_t **error )
363
0
{
364
0
  libscca_internal_volume_information_t *internal_volume_information = NULL;
365
0
  static char *function                                              = "libscca_volume_information_get_utf16_device_path_size";
366
367
0
  if( volume_information == NULL )
368
0
  {
369
0
    libcerror_error_set(
370
0
     error,
371
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
372
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
373
0
     "%s: invalid volume information.",
374
0
     function );
375
376
0
    return( -1 );
377
0
  }
378
0
  internal_volume_information = (libscca_internal_volume_information_t *) volume_information;
379
380
0
  if( libuna_utf16_string_size_from_utf16_stream(
381
0
       internal_volume_information->device_path,
382
0
       internal_volume_information->device_path_size,
383
0
       LIBUNA_ENDIAN_LITTLE,
384
0
       utf16_string_size,
385
0
       error ) != 1 )
386
0
  {
387
0
    libcerror_error_set(
388
0
     error,
389
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
390
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
391
0
     "%s: unable to retrieve device path UTF-16 string size.",
392
0
     function );
393
394
0
    return( -1 );
395
0
  }
396
0
  return( 1 );
397
0
}
398
399
/* Retrieves the UTF-16 encoded device path
400
 * The size should include the end of string character
401
 * Returns 1 if successful or -1 on error
402
 */
403
int libscca_volume_information_get_utf16_device_path(
404
     libscca_volume_information_t *volume_information,
405
     uint16_t *utf16_string,
406
     size_t utf16_string_size,
407
     libcerror_error_t **error )
408
0
{
409
0
  libscca_internal_volume_information_t *internal_volume_information = NULL;
410
0
  static char *function                                              = "libscca_volume_information_get_utf16_device_path";
411
412
0
  if( volume_information == NULL )
413
0
  {
414
0
    libcerror_error_set(
415
0
     error,
416
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
417
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
418
0
     "%s: invalid volume information.",
419
0
     function );
420
421
0
    return( -1 );
422
0
  }
423
0
  internal_volume_information = (libscca_internal_volume_information_t *) volume_information;
424
425
0
  if( libuna_utf16_string_copy_from_utf16_stream(
426
0
       utf16_string,
427
0
       utf16_string_size,
428
0
       internal_volume_information->device_path,
429
0
       internal_volume_information->device_path_size,
430
0
       LIBUNA_ENDIAN_LITTLE,
431
0
       error ) != 1 )
432
0
  {
433
0
    libcerror_error_set(
434
0
     error,
435
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
436
0
     LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
437
0
     "%s: unable to copy device path to UTF-16 string.",
438
0
     function );
439
440
0
    return( -1 );
441
0
  }
442
0
  return( 1 );
443
0
}
444